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