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