1 /*
2 Copyright (C) 1999-2006 Id Software, Inc. and contributors.
3 For a list of contributors, see the accompanying CONTRIBUTORS file.
4
5 This file is part of GtkRadiant.
6
7 GtkRadiant is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
11
12 GtkRadiant is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with GtkRadiant; if not, write to the Free Software
19 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
20 */
21
22 // Nurail: Swiped from quake3/common
23
24 #include "cmdlib.h"
25 #include "mathlib.h"
26 #include "inout.h"
27 #include <sys/types.h>
28 #include <sys/stat.h>
29
30 #ifdef WIN32
31 #include <direct.h>
32 #include <windows.h>
33 #endif
34
35 #if defined ( __DragonFly__ ) || defined ( __APPLE__ )
36 #include <unistd.h>
37 #endif
38
39 #ifdef NeXT
40 #include <libc.h>
41 #endif
42
43 #define BASEDIRNAME "quake" // assumed to have a 2 or 3 following
44 #define HERETIC2_BASEDIRNAME "h"
45 #define PATHSEPERATOR '/'
46
47 // qboolean verbose = false;
48
49 #ifdef SAFE_MALLOC
safe_malloc(size_t size)50 void *safe_malloc( size_t size ){
51 void *p;
52
53 p = malloc( size );
54 if ( !p ) {
55 Error( "safe_malloc failed on allocation of %i bytes", size );
56 }
57
58 memset( p, 0, size );
59 return p;
60 }
61
safe_malloc_info(size_t size,char * info)62 void *safe_malloc_info( size_t size, char* info ){
63 void *p;
64
65 p = malloc( size );
66 if ( !p ) {
67 Error( "%s: safe_malloc failed on allocation of %i bytes", info, size );
68 }
69
70 memset( p, 0, size );
71 return p;
72 }
73 #endif
74
75 // set these before calling CheckParm
76 int myargc;
77 char **myargv;
78
79 char com_token[1024];
80 qboolean com_eof;
81
82 qboolean archive;
83 char archivedir[1024];
84
85
86 /*
87 ===================
88 ExpandWildcards
89
90 Mimic unix command line expansion
91 ===================
92 */
93 #define MAX_EX_ARGC 1024
94 int ex_argc;
95 char *ex_argv[MAX_EX_ARGC];
96 #ifdef WIN32
97 #include "io.h"
ExpandWildcards(int * argc,char *** argv)98 void ExpandWildcards( int *argc, char ***argv ){
99 struct _finddata_t fileinfo;
100 int handle;
101 int i;
102 char filename[1024];
103 char filebase[1024];
104 char *path;
105
106 ex_argc = 0;
107 for ( i = 0 ; i < *argc ; i++ )
108 {
109 path = ( *argv )[i];
110 if ( path[0] == '-'
111 || ( !strstr( path, "*" ) && !strstr( path, "?" ) ) ) {
112 ex_argv[ex_argc++] = path;
113 continue;
114 }
115
116 handle = _findfirst( path, &fileinfo );
117 if ( handle == -1 ) {
118 return;
119 }
120
121 ExtractFilePath( path, filebase );
122
123 do
124 {
125 sprintf( filename, "%s%s", filebase, fileinfo.name );
126 ex_argv[ex_argc++] = copystring( filename );
127 } while ( _findnext( handle, &fileinfo ) != -1 );
128
129 _findclose( handle );
130 }
131
132 *argc = ex_argc;
133 *argv = ex_argv;
134 }
135 #else
ExpandWildcards(int * argc,char *** argv)136 void ExpandWildcards( int *argc, char ***argv ){
137 }
138 #endif
139
140 /*
141
142 qdir will hold the path up to the quake directory, including the slash
143
144 f:\quake\
145 /raid/quake/
146
147 gamedir will hold qdir + the game directory (id1, id2, etc)
148
149 */
150
151 char qdir[1024];
152 char gamedir[1024];
153 char writedir[1024];
154
SetQdirFromPath(const char * path)155 void SetQdirFromPath( const char *path ){
156 char temp[1024];
157 const char *c;
158 const char *sep;
159 int len, count;
160 char basedirname[256];
161
162 if ( !( path[0] == '/' || path[0] == '\\' || path[1] == ':' ) ) { // path is partial
163 Q_getwd( temp );
164 strcat( temp, path );
165 path = temp;
166 }
167
168 // search for "quake2" in path
169
170 if ( !strcmp( game, "heretic2" ) ) {
171 strncpy( basedirname, HERETIC2_BASEDIRNAME, 256 );
172 }
173 else{
174 strncpy( basedirname, BASEDIRNAME, 256 );
175 }
176
177 len = strlen( basedirname );
178 for ( c = path + strlen( path ) - 1 ; c != path ; c-- )
179 {
180 int i;
181
182 if ( !Q_strncasecmp( c, basedirname, len ) ) {
183 //
184 //strncpy (qdir, path, c+len+2-path);
185 // the +2 assumes a 2 or 3 following quake which is not the
186 // case with a retail install
187 // so we need to add up how much to the next separator
188 sep = c + len;
189 count = 1;
190 while ( *sep && *sep != '/' && *sep != '\\' )
191 {
192 sep++;
193 count++;
194 }
195 strncpy( qdir, path, c + len + count - path );
196 Sys_FPrintf( SYS_VRB, "qdir: %s\n", qdir );
197 for ( i = 0; i < strlen( qdir ); i++ )
198 {
199 if ( qdir[i] == '\\' ) {
200 qdir[i] = '/';
201 }
202 }
203
204 c += len + count;
205 while ( *c )
206 {
207 if ( *c == '/' || *c == '\\' ) {
208 strncpy( gamedir, path, c + 1 - path );
209
210 for ( i = 0; i < strlen( gamedir ); i++ )
211 {
212 if ( gamedir[i] == '\\' ) {
213 gamedir[i] = '/';
214 }
215 }
216
217 Sys_FPrintf( SYS_VRB, "gamedir: %s\n", gamedir );
218
219 if ( !writedir[0] ) {
220 strcpy( writedir, gamedir );
221 }
222 else if ( writedir[strlen( writedir ) - 1] != '/' ) {
223 writedir[strlen( writedir )] = '/';
224 writedir[strlen( writedir ) + 1] = 0;
225 }
226
227 return;
228 }
229 c++;
230 }
231 Error( "No gamedir in %s", path );
232 return;
233 }
234 }
235 Error( "SetQdirFromPath: no '%s' in %s", basedirname, path );
236 }
237
ExpandArg(const char * path)238 char *ExpandArg( const char *path ){
239 static char full[1024];
240
241 if ( path[0] != '/' && path[0] != '\\' && path[1] != ':' ) {
242 Q_getwd( full );
243 strcat( full, path );
244 }
245 else{
246 strcpy( full, path );
247 }
248 return full;
249 }
250
ExpandPath(const char * path)251 char *ExpandPath( const char *path ){
252 static char full[1024];
253 if ( !qdir ) {
254 Error( "ExpandPath called without qdir set" );
255 }
256 if ( path[0] == '/' || path[0] == '\\' || path[1] == ':' ) {
257 strcpy( full, path );
258 return full;
259 }
260 sprintf( full, "%s%s", qdir, path );
261 return full;
262 }
263
ExpandGamePath(const char * path)264 char *ExpandGamePath( const char *path ){
265 static char full[1024];
266 if ( !qdir ) {
267 Error( "ExpandGamePath called without qdir set" );
268 }
269 if ( path[0] == '/' || path[0] == '\\' || path[1] == ':' ) {
270 strcpy( full, path );
271 return full;
272 }
273 sprintf( full, "%s%s", gamedir, path );
274 return full;
275 }
276
ExpandPathAndArchive(const char * path)277 char *ExpandPathAndArchive( const char *path ){
278 char *expanded;
279 char archivename[1024];
280
281 expanded = ExpandPath( path );
282
283 if ( archive ) {
284 sprintf( archivename, "%s/%s", archivedir, path );
285 QCopyFile( expanded, archivename );
286 }
287 return expanded;
288 }
289
290
copystring(const char * s)291 char *copystring( const char *s ){
292 char *b;
293 b = safe_malloc( strlen( s ) + 1 );
294 strcpy( b, s );
295 return b;
296 }
297
298
299
300 /*
301 ================
302 I_FloatTime
303 ================
304 */
I_FloatTime(void)305 double I_FloatTime( void ){
306 time_t t;
307
308 time( &t );
309
310 return t;
311 #if 0
312 // more precise, less portable
313 struct timeval tp;
314 struct timezone tzp;
315 static int secbase;
316
317 gettimeofday( &tp, &tzp );
318
319 if ( !secbase ) {
320 secbase = tp.tv_sec;
321 return tp.tv_usec / 1000000.0;
322 }
323
324 return ( tp.tv_sec - secbase ) + tp.tv_usec / 1000000.0;
325 #endif
326 }
327
Q_getwd(char * out)328 void Q_getwd( char *out ){
329 int i = 0;
330
331 #ifdef WIN32
332 _getcwd( out, 256 );
333 strcat( out, "\\" );
334 #else
335 // Gef: Changed from getwd() to getcwd() to avoid potential buffer overflow
336 getcwd( out, 256 );
337 strcat( out, "/" );
338 #endif
339 while ( out[i] != 0 )
340 {
341 if ( out[i] == '\\' ) {
342 out[i] = '/';
343 }
344 i++;
345 }
346 }
347
348
Q_mkdir(const char * path)349 void Q_mkdir( const char *path ){
350 #ifdef WIN32
351 if ( _mkdir( path ) != -1 ) {
352 return;
353 }
354 #else
355 if ( mkdir( path, 0777 ) != -1 ) {
356 return;
357 }
358 #endif
359 if ( errno != EEXIST ) {
360 Error( "mkdir %s: %s",path, strerror( errno ) );
361 }
362 }
363
364 /*
365 ============
366 FileTime
367
368 returns -1 if not present
369 ============
370 */
FileTime(const char * path)371 int FileTime( const char *path ){
372 struct stat buf;
373
374 if ( stat( path,&buf ) == -1 ) {
375 return -1;
376 }
377
378 return buf.st_mtime;
379 }
380
381
382
383 /*
384 ==============
385 COM_Parse
386
387 Parse a token out of a string
388 ==============
389 */
COM_Parse(char * data)390 char *COM_Parse( char *data ){
391 int c;
392 int len;
393
394 len = 0;
395 com_token[0] = 0;
396
397 if ( !data ) {
398 return NULL;
399 }
400
401 // skip whitespace
402 skipwhite:
403 while ( ( c = *data ) <= ' ' )
404 {
405 if ( c == 0 ) {
406 com_eof = true;
407 return NULL; // end of file;
408 }
409 data++;
410 }
411
412 // skip // comments
413 if ( c == '/' && data[1] == '/' ) {
414 while ( *data && *data != '\n' )
415 data++;
416 goto skipwhite;
417 }
418
419
420 // handle quoted strings specially
421 if ( c == '\"' ) {
422 data++;
423 do
424 {
425 c = *data++;
426 if ( c == '\"' ) {
427 com_token[len] = 0;
428 return data;
429 }
430 com_token[len] = c;
431 len++;
432 } while ( 1 );
433 }
434
435 // parse single characters
436 if ( c == '{' || c == '}' || c == ')' || c == '(' || c == '\'' || c == ':' ) {
437 com_token[len] = c;
438 len++;
439 com_token[len] = 0;
440 return data + 1;
441 }
442
443 // parse a regular word
444 do
445 {
446 com_token[len] = c;
447 data++;
448 len++;
449 c = *data;
450 if ( c == '{' || c == '}' || c == ')' || c == '(' || c == '\'' || c == ':' ) {
451 break;
452 }
453 } while ( c > 32 );
454
455 com_token[len] = 0;
456 return data;
457 }
458
Q_strncasecmp(const char * s1,const char * s2,int n)459 int Q_strncasecmp( const char *s1, const char *s2, int n ){
460 int c1, c2;
461
462 do
463 {
464 c1 = *s1++;
465 c2 = *s2++;
466
467 if ( !n-- ) {
468 return 0; // strings are equal until end point
469
470 }
471 if ( c1 != c2 ) {
472 if ( c1 >= 'a' && c1 <= 'z' ) {
473 c1 -= ( 'a' - 'A' );
474 }
475 if ( c2 >= 'a' && c2 <= 'z' ) {
476 c2 -= ( 'a' - 'A' );
477 }
478 if ( c1 != c2 ) {
479 return -1; // strings not equal
480 }
481 }
482 } while ( c1 );
483
484 return 0; // strings are equal
485 }
486
Q_stricmp(const char * s1,const char * s2)487 int Q_stricmp( const char *s1, const char *s2 ){
488 return Q_strncasecmp( s1, s2, 99999 );
489 }
490
Q_strcasecmp(const char * s1,const char * s2)491 int Q_strcasecmp( const char *s1, const char *s2 ){
492 return Q_strncasecmp( s1, s2, 99999 );
493 }
494
495
496 // NOTE TTimo when switching to Multithread DLL (Release/Debug) in the config
497 // started getting warnings about that function, prolly a duplicate with the runtime function
498 // maybe we still need to have it in linux builds
499 /*
500 char *strupr (char *start)
501 {
502 char *in;
503 in = start;
504 while (*in)
505 {
506 *in = toupper(*in);
507 in++;
508 }
509 return start;
510 }
511 */
512
strlower(char * start)513 char *strlower( char *start ){
514 char *in;
515 in = start;
516 while ( *in )
517 {
518 *in = tolower( *in );
519 in++;
520 }
521 return start;
522 }
523
524
525 /*
526 =============================================================================
527
528 MISC FUNCTIONS
529
530 =============================================================================
531 */
532
533
534 /*
535 =================
536 CheckParm
537
538 Checks for the given parameter in the program's command line arguments
539 Returns the argument number (1 to argc-1) or 0 if not present
540 =================
541 */
CheckParm(const char * check)542 int CheckParm( const char *check ){
543 int i;
544
545 for ( i = 1; i < myargc; i++ )
546 {
547 if ( !Q_stricmp( check, myargv[i] ) ) {
548 return i;
549 }
550 }
551
552 return 0;
553 }
554
555
556
557 /*
558 ================
559 Q_filelength
560 ================
561 */
Q_filelength(FILE * f)562 int Q_filelength( FILE *f ){
563 int pos;
564 int end;
565
566 pos = ftell( f );
567 fseek( f, 0, SEEK_END );
568 end = ftell( f );
569 fseek( f, pos, SEEK_SET );
570
571 return end;
572 }
573
574
SafeOpenWrite(const char * filename)575 FILE *SafeOpenWrite( const char *filename ){
576 FILE *f;
577
578 f = fopen( filename, "wb" );
579
580 if ( !f ) {
581 Error( "Error opening %s: %s",filename,strerror( errno ) );
582 }
583
584 return f;
585 }
586
SafeOpenRead(const char * filename)587 FILE *SafeOpenRead( const char *filename ){
588 FILE *f;
589
590 f = fopen( filename, "rb" );
591
592 if ( !f ) {
593 Error( "Error opening %s: %s",filename,strerror( errno ) );
594 }
595
596 return f;
597 }
598
599
SafeRead(FILE * f,void * buffer,int count)600 void SafeRead( FILE *f, void *buffer, int count ){
601 if ( fread( buffer, 1, count, f ) != (size_t)count ) {
602 Error( "File read failure" );
603 }
604 }
605
606
SafeWrite(FILE * f,const void * buffer,int count)607 void SafeWrite( FILE *f, const void *buffer, int count ){
608 if ( fwrite( buffer, 1, count, f ) != (size_t)count ) {
609 Error( "File write failure" );
610 }
611 }
612
613
614 /*
615 ==============
616 FileExists
617 ==============
618 */
FileExists(const char * filename)619 qboolean FileExists( const char *filename ){
620 FILE *f;
621
622 f = fopen( filename, "r" );
623 if ( !f ) {
624 return false;
625 }
626 fclose( f );
627 return true;
628 }
629
630 /*
631 ==============
632 LoadFile
633 ==============
634 */
LoadFile(const char * filename,void ** bufferptr)635 int LoadFile( const char *filename, void **bufferptr ){
636 FILE *f;
637 int length;
638 void *buffer;
639
640 f = SafeOpenRead( filename );
641 length = Q_filelength( f );
642 buffer = safe_malloc( length + 1 );
643 ( (char *)buffer )[length] = 0;
644 SafeRead( f, buffer, length );
645 fclose( f );
646
647 *bufferptr = buffer;
648 return length;
649 }
650
651
652 /*
653 ==============
654 LoadFileBlock
655 -
656 rounds up memory allocation to 4K boundry
657 -
658 ==============
659 */
LoadFileBlock(const char * filename,void ** bufferptr)660 int LoadFileBlock( const char *filename, void **bufferptr ){
661 FILE *f;
662 int length, nBlock, nAllocSize;
663 void *buffer;
664
665 f = SafeOpenRead( filename );
666 length = Q_filelength( f );
667 nAllocSize = length;
668 nBlock = nAllocSize % MEM_BLOCKSIZE;
669 if ( nBlock > 0 ) {
670 nAllocSize += MEM_BLOCKSIZE - nBlock;
671 }
672 buffer = safe_malloc( nAllocSize + 1 );
673 memset( buffer, 0, nAllocSize + 1 );
674 SafeRead( f, buffer, length );
675 fclose( f );
676
677 *bufferptr = buffer;
678 return length;
679 }
680
681
682 /*
683 ==============
684 TryLoadFile
685
686 Allows failure
687 ==============
688 */
TryLoadFile(const char * filename,void ** bufferptr)689 int TryLoadFile( const char *filename, void **bufferptr ){
690 FILE *f;
691 int length;
692 void *buffer;
693
694 *bufferptr = NULL;
695
696 f = fopen( filename, "rb" );
697 if ( !f ) {
698 return -1;
699 }
700 length = Q_filelength( f );
701 buffer = safe_malloc( length + 1 );
702 ( (char *)buffer )[length] = 0;
703 SafeRead( f, buffer, length );
704 fclose( f );
705
706 *bufferptr = buffer;
707 return length;
708 }
709
710
711 /*
712 ==============
713 SaveFile
714 ==============
715 */
SaveFile(const char * filename,const void * buffer,int count)716 void SaveFile( const char *filename, const void *buffer, int count ){
717 FILE *f;
718
719 f = SafeOpenWrite( filename );
720 SafeWrite( f, buffer, count );
721 fclose( f );
722 }
723
724
725
DefaultExtension(char * path,const char * extension)726 void DefaultExtension( char *path, const char *extension ){
727 char *src;
728 //
729 // if path doesnt have a .EXT, append extension
730 // (extension should include the .)
731 //
732 src = path + strlen( path ) - 1;
733
734 while ( *src != '/' && *src != '\\' && src != path )
735 {
736 if ( *src == '.' ) {
737 return; // it has an extension
738 }
739 src--;
740 }
741
742 strcat( path, extension );
743 }
744
745
DefaultPath(char * path,const char * basepath)746 void DefaultPath( char *path, const char *basepath ){
747 char temp[128];
748
749 if ( path[ 0 ] == '/' || path[ 0 ] == '\\' ) {
750 return; // absolute path location
751 }
752 strcpy( temp,path );
753 strcpy( path,basepath );
754 strcat( path,temp );
755 }
756
757
StripFilename(char * path)758 void StripFilename( char *path ){
759 int length;
760
761 length = strlen( path ) - 1;
762 while ( length > 0 && path[length] != '/' && path[ length ] != '\\' )
763 length--;
764 path[length] = 0;
765 }
766
StripExtension(char * path)767 void StripExtension( char *path ){
768 int length;
769
770 length = strlen( path ) - 1;
771 while ( length > 0 && path[length] != '.' )
772 {
773 length--;
774 if ( path[length] == '/' || path[ length ] == '\\' ) {
775 return; // no extension
776 }
777 }
778 if ( length ) {
779 path[length] = 0;
780 }
781 }
782
783
784 /*
785 ====================
786 Extract file parts
787 ====================
788 */
789 // FIXME: should include the slash, otherwise
790 // backing to an empty path will be wrong when appending a slash
ExtractFilePath(const char * path,char * dest)791 void ExtractFilePath( const char *path, char *dest ){
792 const char *src;
793
794 src = path + strlen( path ) - 1;
795
796 //
797 // back up until a \ or the start
798 //
799 while ( src != path && *( src - 1 ) != '\\' && *( src - 1 ) != '/' )
800 src--;
801
802 memcpy( dest, path, src - path );
803 dest[src - path] = 0;
804 }
805
ExtractFileBase(const char * path,char * dest)806 void ExtractFileBase( const char *path, char *dest ){
807 const char *src;
808
809 src = path + strlen( path ) - 1;
810
811 //
812 // back up until a \ or the start
813 //
814 while ( src != path && *( src - 1 ) != '/' && *( src - 1 ) != '\\' )
815 src--;
816
817 while ( *src && *src != '.' )
818 {
819 *dest++ = *src++;
820 }
821 *dest = 0;
822 }
823
ExtractFileExtension(const char * path,char * dest)824 void ExtractFileExtension( const char *path, char *dest ){
825 const char *src;
826
827 src = path + strlen( path ) - 1;
828
829 //
830 // back up until a . or the start
831 //
832 while ( src != path && *( src - 1 ) != '.' )
833 src--;
834 if ( src == path ) {
835 *dest = 0; // no extension
836 return;
837 }
838
839 strcpy( dest,src );
840 }
841
842
843 /*
844 ==============
845 ParseNum / ParseHex
846 ==============
847 */
ParseHex(const char * hex)848 int ParseHex( const char *hex ){
849 const char *str;
850 int num;
851
852 num = 0;
853 str = hex;
854
855 while ( *str )
856 {
857 num <<= 4;
858 if ( *str >= '0' && *str <= '9' ) {
859 num += *str - '0';
860 }
861 else if ( *str >= 'a' && *str <= 'f' ) {
862 num += 10 + *str - 'a';
863 }
864 else if ( *str >= 'A' && *str <= 'F' ) {
865 num += 10 + *str - 'A';
866 }
867 else{
868 Error( "Bad hex number: %s",hex );
869 }
870 str++;
871 }
872
873 return num;
874 }
875
876
ParseNum(const char * str)877 int ParseNum( const char *str ){
878 if ( str[0] == '$' ) {
879 return ParseHex( str + 1 );
880 }
881 if ( str[0] == '0' && str[1] == 'x' ) {
882 return ParseHex( str + 2 );
883 }
884 return atol( str );
885 }
886 /*
887 // all output ends up through here
888 void FPrintf (int flag, char *buf)
889 {
890 printf(buf);
891
892 }
893
894 void Sys_FPrintf (int flag, const char *format, ...)
895 {
896 char out_buffer[4096];
897 va_list argptr;
898
899 if ((flag == SYS_VRB) && (verbose == false))
900 return;
901
902 va_start (argptr, format);
903 vsprintf (out_buffer, format, argptr);
904 va_end (argptr);
905
906 FPrintf (flag, out_buffer);
907 }
908
909 void Sys_Printf (const char *format, ...)
910 {
911 char out_buffer[4096];
912 va_list argptr;
913
914 va_start (argptr, format);
915 vsprintf (out_buffer, format, argptr);
916 va_end (argptr);
917
918 FPrintf (SYS_STD, out_buffer);
919 }
920
921
922 //=================
923 //Error
924 //
925 //For abnormal program terminations
926 //=================
927
928 void Error( const char *error, ...)
929 {
930 char out_buffer[4096];
931 char tmp[4096];
932 va_list argptr;
933
934 va_start (argptr,error);
935 vsprintf (tmp, error, argptr);
936 va_end (argptr);
937
938 sprintf( out_buffer, "************ ERROR ************\n%s\n", tmp );
939
940 FPrintf( SYS_ERR, out_buffer );
941
942 exit (1);
943 }
944 */
945
946
947 /*
948 ============================================================================
949
950 BYTE ORDER FUNCTIONS
951
952 ============================================================================
953 */
954
955 #ifdef _SGI_SOURCE
956 #define __BIG_ENDIAN__
957 #endif
958
959 #ifdef __BIG_ENDIAN__
960
LittleShort(short l)961 short LittleShort( short l ){
962 byte b1,b2;
963
964 b1 = l & 255;
965 b2 = ( l >> 8 ) & 255;
966
967 return ( b1 << 8 ) + b2;
968 }
969
BigShort(short l)970 short BigShort( short l ){
971 return l;
972 }
973
974
LittleLong(int l)975 int LittleLong( int l ){
976 byte b1,b2,b3,b4;
977
978 b1 = l & 255;
979 b2 = ( l >> 8 ) & 255;
980 b3 = ( l >> 16 ) & 255;
981 b4 = ( l >> 24 ) & 255;
982
983 return ( (int)b1 << 24 ) + ( (int)b2 << 16 ) + ( (int)b3 << 8 ) + b4;
984 }
985
BigLong(int l)986 int BigLong( int l ){
987 return l;
988 }
989
990
LittleFloat(float l)991 float LittleFloat( float l ){
992 union {byte b[4]; float f; } in, out;
993
994 in.f = l;
995 out.b[0] = in.b[3];
996 out.b[1] = in.b[2];
997 out.b[2] = in.b[1];
998 out.b[3] = in.b[0];
999
1000 return out.f;
1001 }
1002
BigFloat(float l)1003 float BigFloat( float l ){
1004 return l;
1005 }
1006
1007
1008 #else
1009
1010
BigShort(short l)1011 short BigShort( short l ){
1012 byte b1,b2;
1013
1014 b1 = l & 255;
1015 b2 = ( l >> 8 ) & 255;
1016
1017 return ( b1 << 8 ) + b2;
1018 }
1019
LittleShort(short l)1020 short LittleShort( short l ){
1021 return l;
1022 }
1023
1024
BigLong(int l)1025 int BigLong( int l ){
1026 byte b1,b2,b3,b4;
1027
1028 b1 = l & 255;
1029 b2 = ( l >> 8 ) & 255;
1030 b3 = ( l >> 16 ) & 255;
1031 b4 = ( l >> 24 ) & 255;
1032
1033 return ( (int)b1 << 24 ) + ( (int)b2 << 16 ) + ( (int)b3 << 8 ) + b4;
1034 }
1035
LittleLong(int l)1036 int LittleLong( int l ){
1037 return l;
1038 }
1039
BigFloat(float l)1040 float BigFloat( float l ){
1041 union {byte b[4]; float f; } in, out;
1042
1043 in.f = l;
1044 out.b[0] = in.b[3];
1045 out.b[1] = in.b[2];
1046 out.b[2] = in.b[1];
1047 out.b[3] = in.b[0];
1048
1049 return out.f;
1050 }
1051
LittleFloat(float l)1052 float LittleFloat( float l ){
1053 return l;
1054 }
1055
1056
1057 #endif
1058
1059
1060 //=======================================================
1061
1062
1063 // FIXME: byte swap?
1064
1065 // this is a 16 bit, non-reflected CRC using the polynomial 0x1021
1066 // and the initial and final xor values shown below... in other words, the
1067 // CCITT standard CRC used by XMODEM
1068
1069 #define CRC_INIT_VALUE 0xffff
1070 #define CRC_XOR_VALUE 0x0000
1071
1072 static unsigned short crctable[256] =
1073 {
1074 0x0000, 0x1021, 0x2042, 0x3063, 0x4084, 0x50a5, 0x60c6, 0x70e7,
1075 0x8108, 0x9129, 0xa14a, 0xb16b, 0xc18c, 0xd1ad, 0xe1ce, 0xf1ef,
1076 0x1231, 0x0210, 0x3273, 0x2252, 0x52b5, 0x4294, 0x72f7, 0x62d6,
1077 0x9339, 0x8318, 0xb37b, 0xa35a, 0xd3bd, 0xc39c, 0xf3ff, 0xe3de,
1078 0x2462, 0x3443, 0x0420, 0x1401, 0x64e6, 0x74c7, 0x44a4, 0x5485,
1079 0xa56a, 0xb54b, 0x8528, 0x9509, 0xe5ee, 0xf5cf, 0xc5ac, 0xd58d,
1080 0x3653, 0x2672, 0x1611, 0x0630, 0x76d7, 0x66f6, 0x5695, 0x46b4,
1081 0xb75b, 0xa77a, 0x9719, 0x8738, 0xf7df, 0xe7fe, 0xd79d, 0xc7bc,
1082 0x48c4, 0x58e5, 0x6886, 0x78a7, 0x0840, 0x1861, 0x2802, 0x3823,
1083 0xc9cc, 0xd9ed, 0xe98e, 0xf9af, 0x8948, 0x9969, 0xa90a, 0xb92b,
1084 0x5af5, 0x4ad4, 0x7ab7, 0x6a96, 0x1a71, 0x0a50, 0x3a33, 0x2a12,
1085 0xdbfd, 0xcbdc, 0xfbbf, 0xeb9e, 0x9b79, 0x8b58, 0xbb3b, 0xab1a,
1086 0x6ca6, 0x7c87, 0x4ce4, 0x5cc5, 0x2c22, 0x3c03, 0x0c60, 0x1c41,
1087 0xedae, 0xfd8f, 0xcdec, 0xddcd, 0xad2a, 0xbd0b, 0x8d68, 0x9d49,
1088 0x7e97, 0x6eb6, 0x5ed5, 0x4ef4, 0x3e13, 0x2e32, 0x1e51, 0x0e70,
1089 0xff9f, 0xefbe, 0xdfdd, 0xcffc, 0xbf1b, 0xaf3a, 0x9f59, 0x8f78,
1090 0x9188, 0x81a9, 0xb1ca, 0xa1eb, 0xd10c, 0xc12d, 0xf14e, 0xe16f,
1091 0x1080, 0x00a1, 0x30c2, 0x20e3, 0x5004, 0x4025, 0x7046, 0x6067,
1092 0x83b9, 0x9398, 0xa3fb, 0xb3da, 0xc33d, 0xd31c, 0xe37f, 0xf35e,
1093 0x02b1, 0x1290, 0x22f3, 0x32d2, 0x4235, 0x5214, 0x6277, 0x7256,
1094 0xb5ea, 0xa5cb, 0x95a8, 0x8589, 0xf56e, 0xe54f, 0xd52c, 0xc50d,
1095 0x34e2, 0x24c3, 0x14a0, 0x0481, 0x7466, 0x6447, 0x5424, 0x4405,
1096 0xa7db, 0xb7fa, 0x8799, 0x97b8, 0xe75f, 0xf77e, 0xc71d, 0xd73c,
1097 0x26d3, 0x36f2, 0x0691, 0x16b0, 0x6657, 0x7676, 0x4615, 0x5634,
1098 0xd94c, 0xc96d, 0xf90e, 0xe92f, 0x99c8, 0x89e9, 0xb98a, 0xa9ab,
1099 0x5844, 0x4865, 0x7806, 0x6827, 0x18c0, 0x08e1, 0x3882, 0x28a3,
1100 0xcb7d, 0xdb5c, 0xeb3f, 0xfb1e, 0x8bf9, 0x9bd8, 0xabbb, 0xbb9a,
1101 0x4a75, 0x5a54, 0x6a37, 0x7a16, 0x0af1, 0x1ad0, 0x2ab3, 0x3a92,
1102 0xfd2e, 0xed0f, 0xdd6c, 0xcd4d, 0xbdaa, 0xad8b, 0x9de8, 0x8dc9,
1103 0x7c26, 0x6c07, 0x5c64, 0x4c45, 0x3ca2, 0x2c83, 0x1ce0, 0x0cc1,
1104 0xef1f, 0xff3e, 0xcf5d, 0xdf7c, 0xaf9b, 0xbfba, 0x8fd9, 0x9ff8,
1105 0x6e17, 0x7e36, 0x4e55, 0x5e74, 0x2e93, 0x3eb2, 0x0ed1, 0x1ef0
1106 };
1107
CRC_Init(unsigned short * crcvalue)1108 void CRC_Init( unsigned short *crcvalue ){
1109 *crcvalue = CRC_INIT_VALUE;
1110 }
1111
CRC_ProcessByte(unsigned short * crcvalue,byte data)1112 void CRC_ProcessByte( unsigned short *crcvalue, byte data ){
1113 *crcvalue = ( *crcvalue << 8 ) ^ crctable[( *crcvalue >> 8 ) ^ data];
1114 }
1115
CRC_Value(unsigned short crcvalue)1116 unsigned short CRC_Value( unsigned short crcvalue ){
1117 return crcvalue ^ CRC_XOR_VALUE;
1118 }
1119 //=============================================================================
1120
1121 /*
1122 ============
1123 CreatePath
1124 ============
1125 */
CreatePath(const char * path)1126 void CreatePath( const char *path ){
1127 const char *ofs;
1128 char c;
1129 char dir[1024];
1130
1131 #ifdef WIN32
1132 int olddrive = -1;
1133
1134 if ( path[1] == ':' ) {
1135 olddrive = _getdrive();
1136 _chdrive( toupper( path[0] ) - 'A' + 1 );
1137 }
1138 #endif
1139
1140 if ( path[1] == ':' ) {
1141 path += 2;
1142 }
1143
1144 for ( ofs = path + 1 ; *ofs ; ofs++ )
1145 {
1146 c = *ofs;
1147 if ( c == '/' || c == '\\' ) { // create the directory
1148 memcpy( dir, path, ofs - path );
1149 dir[ ofs - path ] = 0;
1150 Q_mkdir( dir );
1151 }
1152 }
1153
1154 #ifdef WIN32
1155 if ( olddrive != -1 ) {
1156 _chdrive( olddrive );
1157 }
1158 #endif
1159 }
1160
1161
1162 /*
1163 ============
1164 QCopyFile
1165
1166 Used to archive source files
1167 ============
1168 */
QCopyFile(const char * from,const char * to)1169 void QCopyFile( const char *from, const char *to ){
1170 void *buffer;
1171 int length;
1172
1173 length = LoadFile( from, &buffer );
1174 CreatePath( to );
1175 SaveFile( to, buffer, length );
1176 free( buffer );
1177 }
1178
Sys_Sleep(int n)1179 void Sys_Sleep( int n ){
1180 #ifdef WIN32
1181 Sleep( n );
1182 #endif
1183 #if defined ( __DragonFly__ ) || defined ( __APPLE__ )
1184 usleep( n * 1000 );
1185 #endif
1186 }
1187