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