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