Lib.cpp 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586
  1. /*
  2. ===========================================================================
  3. Doom 3 GPL Source Code
  4. Copyright (C) 1999-2011 id Software LLC, a ZeniMax Media company.
  5. This file is part of the Doom 3 GPL Source Code (?Doom 3 Source Code?).
  6. Doom 3 Source Code is free software: you can redistribute it and/or modify
  7. it under the terms of the GNU General Public License as published by
  8. the Free Software Foundation, either version 3 of the License, or
  9. (at your option) any later version.
  10. Doom 3 Source Code is distributed in the hope that it will be useful,
  11. but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. GNU General Public License for more details.
  14. You should have received a copy of the GNU General Public License
  15. along with Doom 3 Source Code. If not, see <http://www.gnu.org/licenses/>.
  16. In addition, the Doom 3 Source Code is also subject to certain additional terms. You should have received a copy of these additional terms immediately following the terms and conditions of the GNU General Public License which accompanied the Doom 3 Source Code. If not, please request a copy in writing from id Software at the address below.
  17. If you have questions concerning this license or the applicable additional terms, you may contact in writing id Software LLC, c/o ZeniMax Media Inc., Suite 120, Rockville, Maryland 20850 USA.
  18. ===========================================================================
  19. */
  20. #include "precompiled.h"
  21. #pragma hdrstop
  22. #if defined( MACOS_X )
  23. #include <signal.h>
  24. #include <sys/types.h>
  25. #include <unistd.h>
  26. #endif
  27. /*
  28. ===============================================================================
  29. idLib
  30. ===============================================================================
  31. */
  32. idSys * idLib::sys = NULL;
  33. idCommon * idLib::common = NULL;
  34. idCVarSystem * idLib::cvarSystem = NULL;
  35. idFileSystem * idLib::fileSystem = NULL;
  36. int idLib::frameNumber = 0;
  37. /*
  38. ================
  39. idLib::Init
  40. ================
  41. */
  42. void idLib::Init( void ) {
  43. assert( sizeof( bool ) == 1 );
  44. // initialize little/big endian conversion
  45. Swap_Init();
  46. // initialize memory manager
  47. Mem_Init();
  48. // init string memory allocator
  49. idStr::InitMemory();
  50. // initialize generic SIMD implementation
  51. idSIMD::Init();
  52. // initialize math
  53. idMath::Init();
  54. // test idMatX
  55. //idMatX::Test();
  56. // test idPolynomial
  57. idPolynomial::Test();
  58. // initialize the dictionary string pools
  59. idDict::Init();
  60. }
  61. /*
  62. ================
  63. idLib::ShutDown
  64. ================
  65. */
  66. void idLib::ShutDown( void ) {
  67. // shut down the dictionary string pools
  68. idDict::Shutdown();
  69. // shut down the string memory allocator
  70. idStr::ShutdownMemory();
  71. // shut down the SIMD engine
  72. idSIMD::Shutdown();
  73. // shut down the memory manager
  74. Mem_Shutdown();
  75. }
  76. /*
  77. ===============================================================================
  78. Colors
  79. ===============================================================================
  80. */
  81. idVec4 colorBlack = idVec4( 0.00f, 0.00f, 0.00f, 1.00f );
  82. idVec4 colorWhite = idVec4( 1.00f, 1.00f, 1.00f, 1.00f );
  83. idVec4 colorRed = idVec4( 1.00f, 0.00f, 0.00f, 1.00f );
  84. idVec4 colorGreen = idVec4( 0.00f, 1.00f, 0.00f, 1.00f );
  85. idVec4 colorBlue = idVec4( 0.00f, 0.00f, 1.00f, 1.00f );
  86. idVec4 colorYellow = idVec4( 1.00f, 1.00f, 0.00f, 1.00f );
  87. idVec4 colorMagenta= idVec4( 1.00f, 0.00f, 1.00f, 1.00f );
  88. idVec4 colorCyan = idVec4( 0.00f, 1.00f, 1.00f, 1.00f );
  89. idVec4 colorOrange = idVec4( 1.00f, 0.50f, 0.00f, 1.00f );
  90. idVec4 colorPurple = idVec4( 0.60f, 0.00f, 0.60f, 1.00f );
  91. idVec4 colorPink = idVec4( 0.73f, 0.40f, 0.48f, 1.00f );
  92. idVec4 colorBrown = idVec4( 0.40f, 0.35f, 0.08f, 1.00f );
  93. idVec4 colorLtGrey = idVec4( 0.75f, 0.75f, 0.75f, 1.00f );
  94. idVec4 colorMdGrey = idVec4( 0.50f, 0.50f, 0.50f, 1.00f );
  95. idVec4 colorDkGrey = idVec4( 0.25f, 0.25f, 0.25f, 1.00f );
  96. static dword colorMask[2] = { 255, 0 };
  97. /*
  98. ================
  99. ColorFloatToByte
  100. ================
  101. */
  102. ID_INLINE static byte ColorFloatToByte( float c ) {
  103. return (byte) ( ( (dword) ( c * 255.0f ) ) & colorMask[FLOATSIGNBITSET(c)] );
  104. }
  105. /*
  106. ================
  107. PackColor
  108. ================
  109. */
  110. dword PackColor( const idVec4 &color ) {
  111. dword dw, dx, dy, dz;
  112. dx = ColorFloatToByte( color.x );
  113. dy = ColorFloatToByte( color.y );
  114. dz = ColorFloatToByte( color.z );
  115. dw = ColorFloatToByte( color.w );
  116. #if defined(_WIN32) || defined(__linux__) || (defined(MACOS_X) && defined(__i386__))
  117. return ( dx << 0 ) | ( dy << 8 ) | ( dz << 16 ) | ( dw << 24 );
  118. #elif (defined(MACOS_X) && defined(__ppc__))
  119. return ( dx << 24 ) | ( dy << 16 ) | ( dz << 8 ) | ( dw << 0 );
  120. #else
  121. #error OS define is required!
  122. #endif
  123. }
  124. /*
  125. ================
  126. UnpackColor
  127. ================
  128. */
  129. void UnpackColor( const dword color, idVec4 &unpackedColor ) {
  130. #if defined(_WIN32) || defined(__linux__) || (defined(MACOS_X) && defined(__i386__))
  131. unpackedColor.Set( ( ( color >> 0 ) & 255 ) * ( 1.0f / 255.0f ),
  132. ( ( color >> 8 ) & 255 ) * ( 1.0f / 255.0f ),
  133. ( ( color >> 16 ) & 255 ) * ( 1.0f / 255.0f ),
  134. ( ( color >> 24 ) & 255 ) * ( 1.0f / 255.0f ) );
  135. #elif (defined(MACOS_X) && defined(__ppc__))
  136. unpackedColor.Set( ( ( color >> 24 ) & 255 ) * ( 1.0f / 255.0f ),
  137. ( ( color >> 16 ) & 255 ) * ( 1.0f / 255.0f ),
  138. ( ( color >> 8 ) & 255 ) * ( 1.0f / 255.0f ),
  139. ( ( color >> 0 ) & 255 ) * ( 1.0f / 255.0f ) );
  140. #else
  141. #error OS define is required!
  142. #endif
  143. }
  144. /*
  145. ================
  146. PackColor
  147. ================
  148. */
  149. dword PackColor( const idVec3 &color ) {
  150. dword dx, dy, dz;
  151. dx = ColorFloatToByte( color.x );
  152. dy = ColorFloatToByte( color.y );
  153. dz = ColorFloatToByte( color.z );
  154. #if defined(_WIN32) || defined(__linux__) || (defined(MACOS_X) && defined(__i386__))
  155. return ( dx << 0 ) | ( dy << 8 ) | ( dz << 16 );
  156. #elif (defined(MACOS_X) && defined(__ppc__))
  157. return ( dy << 16 ) | ( dz << 8 ) | ( dx << 0 );
  158. #else
  159. #error OS define is required!
  160. #endif
  161. }
  162. /*
  163. ================
  164. UnpackColor
  165. ================
  166. */
  167. void UnpackColor( const dword color, idVec3 &unpackedColor ) {
  168. #if defined(_WIN32) || defined(__linux__) || (defined(MACOS_X) && defined(__i386__))
  169. unpackedColor.Set( ( ( color >> 0 ) & 255 ) * ( 1.0f / 255.0f ),
  170. ( ( color >> 8 ) & 255 ) * ( 1.0f / 255.0f ),
  171. ( ( color >> 16 ) & 255 ) * ( 1.0f / 255.0f ) );
  172. #elif (defined(MACOS_X) && defined(__ppc__))
  173. unpackedColor.Set( ( ( color >> 16 ) & 255 ) * ( 1.0f / 255.0f ),
  174. ( ( color >> 8 ) & 255 ) * ( 1.0f / 255.0f ),
  175. ( ( color >> 0 ) & 255 ) * ( 1.0f / 255.0f ) );
  176. #else
  177. #error OS define is required!
  178. #endif
  179. }
  180. /*
  181. ===============
  182. idLib::Error
  183. ===============
  184. */
  185. void idLib::Error( const char *fmt, ... ) {
  186. va_list argptr;
  187. char text[MAX_STRING_CHARS];
  188. va_start( argptr, fmt );
  189. idStr::vsnPrintf( text, sizeof( text ), fmt, argptr );
  190. va_end( argptr );
  191. common->Error( "%s", text );
  192. }
  193. /*
  194. ===============
  195. idLib::Warning
  196. ===============
  197. */
  198. void idLib::Warning( const char *fmt, ... ) {
  199. va_list argptr;
  200. char text[MAX_STRING_CHARS];
  201. va_start( argptr, fmt );
  202. idStr::vsnPrintf( text, sizeof( text ), fmt, argptr );
  203. va_end( argptr );
  204. common->Warning( "%s", text );
  205. }
  206. /*
  207. ===============================================================================
  208. Byte order functions
  209. ===============================================================================
  210. */
  211. // can't just use function pointers, or dll linkage can mess up
  212. static short (*_BigShort)( short l );
  213. static short (*_LittleShort)( short l );
  214. static int (*_BigLong)( int l );
  215. static int (*_LittleLong)( int l );
  216. static float (*_BigFloat)( float l );
  217. static float (*_LittleFloat)( float l );
  218. static void (*_BigRevBytes)( void *bp, int elsize, int elcount );
  219. static void (*_LittleRevBytes)( void *bp, int elsize, int elcount );
  220. static void (*_LittleBitField)( void *bp, int elsize );
  221. static void (*_SixtetsForInt)( byte *out, int src );
  222. static int (*_IntForSixtets)( byte *in );
  223. short BigShort( short l ) { return _BigShort( l ); }
  224. short LittleShort( short l ) { return _LittleShort( l ); }
  225. int BigLong( int l ) { return _BigLong( l ); }
  226. int LittleLong( int l ) { return _LittleLong( l ); }
  227. float BigFloat( float l ) { return _BigFloat( l ); }
  228. float LittleFloat( float l ) { return _LittleFloat( l ); }
  229. void BigRevBytes( void *bp, int elsize, int elcount ) { _BigRevBytes( bp, elsize, elcount ); }
  230. void LittleRevBytes( void *bp, int elsize, int elcount ){ _LittleRevBytes( bp, elsize, elcount ); }
  231. void LittleBitField( void *bp, int elsize ){ _LittleBitField( bp, elsize ); }
  232. void SixtetsForInt( byte *out, int src) { _SixtetsForInt( out, src ); }
  233. int IntForSixtets( byte *in ) { return _IntForSixtets( in ); }
  234. /*
  235. ================
  236. ShortSwap
  237. ================
  238. */
  239. short ShortSwap( short l ) {
  240. byte b1,b2;
  241. b1 = l&255;
  242. b2 = (l>>8)&255;
  243. return (b1<<8) + b2;
  244. }
  245. /*
  246. ================
  247. ShortNoSwap
  248. ================
  249. */
  250. short ShortNoSwap( short l ) {
  251. return l;
  252. }
  253. /*
  254. ================
  255. LongSwap
  256. ================
  257. */
  258. int LongSwap ( int l ) {
  259. byte b1,b2,b3,b4;
  260. b1 = l&255;
  261. b2 = (l>>8)&255;
  262. b3 = (l>>16)&255;
  263. b4 = (l>>24)&255;
  264. return ((int)b1<<24) + ((int)b2<<16) + ((int)b3<<8) + b4;
  265. }
  266. /*
  267. ================
  268. LongNoSwap
  269. ================
  270. */
  271. int LongNoSwap( int l ) {
  272. return l;
  273. }
  274. /*
  275. ================
  276. FloatSwap
  277. ================
  278. */
  279. float FloatSwap( float f ) {
  280. union {
  281. float f;
  282. byte b[4];
  283. } dat1, dat2;
  284. dat1.f = f;
  285. dat2.b[0] = dat1.b[3];
  286. dat2.b[1] = dat1.b[2];
  287. dat2.b[2] = dat1.b[1];
  288. dat2.b[3] = dat1.b[0];
  289. return dat2.f;
  290. }
  291. /*
  292. ================
  293. FloatNoSwap
  294. ================
  295. */
  296. float FloatNoSwap( float f ) {
  297. return f;
  298. }
  299. /*
  300. =====================================================================
  301. RevBytesSwap
  302. Reverses byte order in place.
  303. INPUTS
  304. bp bytes to reverse
  305. elsize size of the underlying data type
  306. elcount number of elements to swap
  307. RESULTS
  308. Reverses the byte order in each of elcount elements.
  309. ===================================================================== */
  310. void RevBytesSwap( void *bp, int elsize, int elcount ) {
  311. register unsigned char *p, *q;
  312. p = ( unsigned char * ) bp;
  313. if ( elsize == 2 ) {
  314. q = p + 1;
  315. while ( elcount-- ) {
  316. *p ^= *q;
  317. *q ^= *p;
  318. *p ^= *q;
  319. p += 2;
  320. q += 2;
  321. }
  322. return;
  323. }
  324. while ( elcount-- ) {
  325. q = p + elsize - 1;
  326. while ( p < q ) {
  327. *p ^= *q;
  328. *q ^= *p;
  329. *p ^= *q;
  330. ++p;
  331. --q;
  332. }
  333. p += elsize >> 1;
  334. }
  335. }
  336. /*
  337. =====================================================================
  338. RevBytesSwap
  339. Reverses byte order in place, then reverses bits in those bytes
  340. INPUTS
  341. bp bitfield structure to reverse
  342. elsize size of the underlying data type
  343. RESULTS
  344. Reverses the bitfield of size elsize.
  345. ===================================================================== */
  346. void RevBitFieldSwap( void *bp, int elsize) {
  347. int i;
  348. unsigned char *p, t, v;
  349. LittleRevBytes( bp, elsize, 1 );
  350. p = (unsigned char *) bp;
  351. while ( elsize-- ) {
  352. v = *p;
  353. t = 0;
  354. for (i = 7; i; i--) {
  355. t <<= 1;
  356. v >>= 1;
  357. t |= v & 1;
  358. }
  359. *p++ = t;
  360. }
  361. }
  362. /*
  363. ================
  364. RevBytesNoSwap
  365. ================
  366. */
  367. void RevBytesNoSwap( void *bp, int elsize, int elcount ) {
  368. return;
  369. }
  370. /*
  371. ================
  372. RevBytesNoSwap
  373. ================
  374. */
  375. void RevBitFieldNoSwap( void *bp, int elsize ) {
  376. return;
  377. }
  378. /*
  379. ================
  380. SixtetsForIntLittle
  381. ================
  382. */
  383. void SixtetsForIntLittle( byte *out, int src) {
  384. byte *b = (byte *)&src;
  385. out[0] = ( b[0] & 0xfc ) >> 2;
  386. out[1] = ( ( b[0] & 0x3 ) << 4 ) + ( ( b[1] & 0xf0 ) >> 4 );
  387. out[2] = ( ( b[1] & 0xf ) << 2 ) + ( ( b[2] & 0xc0 ) >> 6 );
  388. out[3] = b[2] & 0x3f;
  389. }
  390. /*
  391. ================
  392. SixtetsForIntBig
  393. TTimo: untested - that's the version from initial base64 encode
  394. ================
  395. */
  396. void SixtetsForIntBig( byte *out, int src) {
  397. for( int i = 0 ; i < 4 ; i++ ) {
  398. out[i] = src & 0x3f;
  399. src >>= 6;
  400. }
  401. }
  402. /*
  403. ================
  404. IntForSixtetsLittle
  405. ================
  406. */
  407. int IntForSixtetsLittle( byte *in ) {
  408. int ret = 0;
  409. byte *b = (byte *)&ret;
  410. b[0] |= in[0] << 2;
  411. b[0] |= ( in[1] & 0x30 ) >> 4;
  412. b[1] |= ( in[1] & 0xf ) << 4;
  413. b[1] |= ( in[2] & 0x3c ) >> 2;
  414. b[2] |= ( in[2] & 0x3 ) << 6;
  415. b[2] |= in[3];
  416. return ret;
  417. }
  418. /*
  419. ================
  420. IntForSixtetsBig
  421. TTimo: untested - that's the version from initial base64 decode
  422. ================
  423. */
  424. int IntForSixtetsBig( byte *in ) {
  425. int ret = 0;
  426. ret |= in[0];
  427. ret |= in[1] << 6;
  428. ret |= in[2] << 2*6;
  429. ret |= in[3] << 3*6;
  430. return ret;
  431. }
  432. /*
  433. ================
  434. Swap_Init
  435. ================
  436. */
  437. void Swap_Init( void ) {
  438. byte swaptest[2] = {1,0};
  439. // set the byte swapping variables in a portable manner
  440. if ( *(short *)swaptest == 1) {
  441. // little endian ex: x86
  442. _BigShort = ShortSwap;
  443. _LittleShort = ShortNoSwap;
  444. _BigLong = LongSwap;
  445. _LittleLong = LongNoSwap;
  446. _BigFloat = FloatSwap;
  447. _LittleFloat = FloatNoSwap;
  448. _BigRevBytes = RevBytesSwap;
  449. _LittleRevBytes = RevBytesNoSwap;
  450. _LittleBitField = RevBitFieldNoSwap;
  451. _SixtetsForInt = SixtetsForIntLittle;
  452. _IntForSixtets = IntForSixtetsLittle;
  453. } else {
  454. // big endian ex: ppc
  455. _BigShort = ShortNoSwap;
  456. _LittleShort = ShortSwap;
  457. _BigLong = LongNoSwap;
  458. _LittleLong = LongSwap;
  459. _BigFloat = FloatNoSwap;
  460. _LittleFloat = FloatSwap;
  461. _BigRevBytes = RevBytesNoSwap;
  462. _LittleRevBytes = RevBytesSwap;
  463. _LittleBitField = RevBitFieldSwap;
  464. _SixtetsForInt = SixtetsForIntBig;
  465. _IntForSixtets = IntForSixtetsBig;
  466. }
  467. }
  468. /*
  469. ==========
  470. Swap_IsBigEndian
  471. ==========
  472. */
  473. bool Swap_IsBigEndian( void ) {
  474. byte swaptest[2] = {1,0};
  475. return *(short *)swaptest != 1;
  476. }
  477. /*
  478. ===============================================================================
  479. Assertion
  480. ===============================================================================
  481. */
  482. void AssertFailed( const char *file, int line, const char *expression ) {
  483. idLib::sys->DebugPrintf( "\n\nASSERTION FAILED!\n%s(%d): '%s'\n", file, line, expression );
  484. #ifdef _WIN32
  485. __asm int 0x03
  486. #elif defined( __linux__ )
  487. __asm__ __volatile__ ("int $0x03");
  488. #elif defined( MACOS_X )
  489. kill( getpid(), SIGINT );
  490. #endif
  491. }