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