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