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