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