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