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__) || defined (__FreeBSD__)
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
safe_malloc(size_t size)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
safe_malloc_info(size_t size,char * info)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
SafeMalloc(size_t n,char * desc)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__) || defined (__FreeBSD__)
strlwr(char * conv_str)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"
ExpandWildcards(int * argc,char *** argv)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
ExpandWildcards(int * argc,char *** argv)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
SetQdirFromPath(const char * path)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
ExpandArg(const char * path)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
ExpandPath(const char * path)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
ExpandGamePath(const char * path)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
ExpandPathAndArchive(const char * path)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
copystring(const char * s)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 */
I_FloatTime(void)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
Q_getwd(char * out)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
Q_mkdir(const char * path)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 */
FileTime(const char * path)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 */
COM_Parse(char * data)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
Q_strncasecmp(const char * s1,const char * s2,int n)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
Q_stricmp(const char * s1,const char * s2)514 int Q_stricmp (const char *s1, const char *s2)
515 {
516 return Q_strncasecmp (s1, s2, 99999);
517 }
518
Q_strcasecmp(const char * s1,const char * s2)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
strlower(char * start)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 */
CheckParm(const char * check)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 */
Q_filelength(FILE * f)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
SafeOpenWrite(const char * filename)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
SafeOpenRead(const char * filename)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
SafeRead(FILE * f,void * buffer,int count)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
SafeWrite(FILE * f,const void * buffer,int count)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 */
FileExists(const char * filename)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 */
LoadFile(const char * filename,void ** bufferptr)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 */
LoadFileBlock(const char * filename,void ** bufferptr)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 */
TryLoadFile(const char * filename,void ** bufferptr)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 */
SaveFile(const char * filename,const void * buffer,int count)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
DefaultExtension(char * path,const char * extension)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
DefaultPath(char * path,const char * basepath)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
StripFilename(char * path)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
StripExtension(char * path)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
ExtractFilePath(const char * path,char * dest)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
ExtractFileBase(const char * path,char * dest)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
ExtractFileExtension(const char * path,char * dest)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 */
ParseHex(const char * hex)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
ParseNum(const char * str)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
LittleShort(short l)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
BigShort(short l)1003 short BigShort (short l)
1004 {
1005 return l;
1006 }
1007
1008
LittleLong(int l)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
BigLong(int l)1021 int BigLong (int l)
1022 {
1023 return l;
1024 }
1025
1026
LittleFloat(float l)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
BigFloat(float l)1040 float BigFloat (float l)
1041 {
1042 return l;
1043 }
1044
1045
1046 #else
1047
1048
BigShort(short l)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
LittleShort(short l)1059 short LittleShort (short l)
1060 {
1061 return l;
1062 }
1063
1064
BigLong(int l)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
LittleLong(int l)1077 int LittleLong (int l)
1078 {
1079 return l;
1080 }
1081
BigFloat(float l)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
LittleFloat(float l)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
CRC_Init(unsigned short * crcvalue)1152 void CRC_Init(unsigned short *crcvalue)
1153 {
1154 *crcvalue = CRC_INIT_VALUE;
1155 }
1156
CRC_ProcessByte(unsigned short * crcvalue,byte data)1157 void CRC_ProcessByte(unsigned short *crcvalue, byte data)
1158 {
1159 *crcvalue = (*crcvalue << 8) ^ crctable[(*crcvalue >> 8) ^ data];
1160 }
1161
CRC_Value(unsigned short crcvalue)1162 unsigned short CRC_Value(unsigned short crcvalue)
1163 {
1164 return crcvalue ^ CRC_XOR_VALUE;
1165 }
1166 //=============================================================================
1167
1168 /*
1169 ============
1170 CreatePath
1171 ============
1172 */
CreatePath(const char * path)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 */
QCopyFile(const char * from,const char * to)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
Sys_Sleep(int n)1230 void Sys_Sleep(int n)
1231 {
1232 #ifdef WIN32
1233 Sleep (n);
1234 #endif
1235 #if defined (__linux__) || defined (__APPLE__) || defined (__FreeBSD__)
1236 usleep (n * 1000);
1237 #endif
1238 }
1239