|
|
1.1 root 1: // sys_win.h 1.1.1.2 ! root 2: 1.1 root 3: #include "../qcommon/qcommon.h" 4: #include "winquake.h" 5: #include "resource.h" 6: #include <errno.h> 7: #include <float.h> 8: #include <fcntl.h> 9: #include <stdio.h> 10: #include <direct.h> 11: #include <io.h> 12: #include <conio.h> 13: #include "../win32/conproc.h" 1.1.1.2 ! root 14: 1.1 root 15: #define MINIMUM_WIN_MEMORY 0x0a00000 16: #define MAXIMUM_WIN_MEMORY 0x1000000 17: 1.1.1.2 ! root 18: //#define DEMO 1.1 root 19: 20: qboolean s_win95; 1.1.1.2 ! root 21: 1.1 root 22: int starttime; 23: int ActiveApp; 24: qboolean Minimized; 1.1.1.2 ! root 25: 1.1 root 26: static HANDLE hinput, houtput; 27: 28: unsigned sys_msg_time; 29: unsigned sys_frame_time; 1.1.1.2 ! root 30: ! 31: 1.1 root 32: static HANDLE qwclsemaphore; 1.1.1.2 ! root 33: 1.1 root 34: #define MAX_NUM_ARGVS 128 35: int argc; 36: char *argv[MAX_NUM_ARGVS]; 37: 1.1.1.2 ! root 38: 1.1 root 39: /* 40: =============================================================================== 1.1.1.2 ! root 41: 1.1 root 42: SYSTEM IO 1.1.1.2 ! root 43: 1.1 root 44: =============================================================================== 45: */ 1.1.1.2 ! root 46: ! 47: 1.1 root 48: void Sys_Error (char *error, ...) 49: { 50: va_list argptr; 51: char text[1024]; 1.1.1.2 ! root 52: 1.1 root 53: CL_Shutdown (); 54: Qcommon_Shutdown (); 1.1.1.2 ! root 55: 1.1 root 56: va_start (argptr, error); 57: vsprintf (text, error, argptr); 58: va_end (argptr); 1.1.1.2 ! root 59: 1.1 root 60: MessageBox(NULL, text, "Error", 0 /* MB_OK */ ); 1.1.1.2 ! root 61: 1.1 root 62: if (qwclsemaphore) 63: CloseHandle (qwclsemaphore); 1.1.1.2 ! root 64: 1.1 root 65: // shut down QHOST hooks if necessary 66: DeinitConProc (); 67: 68: exit (1); 69: } 1.1.1.2 ! root 70: 1.1 root 71: void Sys_Quit (void) 72: { 73: timeEndPeriod( 1 ); 1.1.1.2 ! root 74: 1.1 root 75: CL_Shutdown(); 76: Qcommon_Shutdown (); 77: CloseHandle (qwclsemaphore); 78: if (dedicated && dedicated->value) 79: FreeConsole (); 1.1.1.2 ! root 80: 1.1 root 81: // shut down QHOST hooks if necessary 82: DeinitConProc (); 83: 84: exit (0); 85: } 86: 87: 88: void WinError (void) 89: { 90: LPVOID lpMsgBuf; 91: 92: FormatMessage( 93: FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM, 94: NULL, 95: GetLastError(), 96: MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language 97: (LPTSTR) &lpMsgBuf, 98: 0, 99: NULL 100: ); 101: 102: // Display the string. 103: MessageBox( NULL, lpMsgBuf, "GetLastError", MB_OK|MB_ICONINFORMATION ); 104: 105: // Free the buffer. 106: LocalFree( lpMsgBuf ); 107: } 108: 109: //================================================================ 110: 111: 112: /* 113: ================ 114: Sys_ScanForCD 115: 116: ================ 117: */ 118: char *Sys_ScanForCD (void) 119: { 120: static char cddir[MAX_OSPATH]; 121: static qboolean done; 122: #ifndef DEMO 123: char drive[4]; 124: FILE *f; 125: char test[MAX_QPATH]; 126: 127: if (done) // don't re-check 128: return cddir; 129: 130: // no abort/retry/fail errors 131: SetErrorMode (SEM_FAILCRITICALERRORS); 132: 133: drive[0] = 'c'; 134: drive[1] = ':'; 135: drive[2] = '\\'; 136: drive[3] = 0; 137: 138: done = true; 139: 140: // scan the drives 141: for (drive[0] = 'c' ; drive[0] <= 'z' ; drive[0]++) 142: { 143: // where activision put the stuff... 144: sprintf (cddir, "%sinstall\\data", drive); 145: sprintf (test, "%sinstall\\data\\quake2.exe", drive); 146: f = fopen(test, "r"); 147: if (f) 148: { 149: fclose (f); 150: if (GetDriveType (drive) == DRIVE_CDROM) 151: return cddir; 152: } 153: } 154: #endif 155: 156: cddir[0] = 0; 157: 158: return NULL; 159: } 160: 161: /* 162: ================ 163: Sys_CopyProtect 164: 165: ================ 166: */ 167: void Sys_CopyProtect (void) 168: { 169: #ifndef DEMO 170: char *cddir; 171: 172: cddir = Sys_ScanForCD(); 173: if (!cddir[0]) 174: Com_Error (ERR_FATAL, "You must have the Quake2 CD in the drive to play."); 175: #endif 176: } 177: 1.1.1.2 ! root 178: 1.1 root 179: //================================================================ 180: 1.1.1.2 ! root 181: 1.1 root 182: /* 183: ================ 184: Sys_Init 185: ================ 186: */ 187: void Sys_Init (void) 188: { 189: OSVERSIONINFO vinfo; 1.1.1.2 ! root 190: 1.1 root 191: #if 0 192: // allocate a named semaphore on the client so the 193: // front end can tell if it is alive 1.1.1.2 ! root 194: 1.1 root 195: // mutex will fail if semephore already exists 196: qwclsemaphore = CreateMutex( 197: NULL, /* Security attributes */ 198: 0, /* owner */ 199: "qwcl"); /* Semaphore name */ 200: if (!qwclsemaphore) 201: Sys_Error ("QWCL is already running on this system"); 202: CloseHandle (qwclsemaphore); 1.1.1.2 ! root 203: 1.1 root 204: qwclsemaphore = CreateSemaphore( 205: NULL, /* Security attributes */ 206: 0, /* Initial count */ 207: 1, /* Maximum count */ 208: "qwcl"); /* Semaphore name */ 209: #endif 210: 211: timeBeginPeriod( 1 ); 1.1.1.2 ! root 212: 1.1 root 213: vinfo.dwOSVersionInfoSize = sizeof(vinfo); 1.1.1.2 ! root 214: 1.1 root 215: if (!GetVersionEx (&vinfo)) 216: Sys_Error ("Couldn't get OS info"); 1.1.1.2 ! root 217: 1.1 root 218: if (vinfo.dwMajorVersion < 4) 219: Sys_Error ("Quake2 requires windows version 4 or greater"); 220: if (vinfo.dwPlatformId == VER_PLATFORM_WIN32s) 221: Sys_Error ("Quake2 doesn't run on Win32s"); 222: else if ( vinfo.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS ) 223: s_win95 = true; 1.1.1.2 ! root 224: 1.1 root 225: if (dedicated->value) 226: { 227: if (!AllocConsole ()) 228: Sys_Error ("Couldn't create dedicated server console"); 229: hinput = GetStdHandle (STD_INPUT_HANDLE); 230: houtput = GetStdHandle (STD_OUTPUT_HANDLE); 231: 232: // let QHOST hook in 233: InitConProc (argc, argv); 234: } 235: } 1.1.1.2 ! root 236: ! 237: 1.1 root 238: static char console_text[256]; 239: static int console_textlen; 240: 241: /* 242: ================ 243: Sys_ConsoleInput 244: ================ 245: */ 246: char *Sys_ConsoleInput (void) 247: { 248: INPUT_RECORD recs[1024]; 249: int dummy; 250: int ch, numread, numevents; 1.1.1.2 ! root 251: 1.1 root 252: if (!dedicated || !dedicated->value) 253: return NULL; 1.1.1.2 ! root 254: ! 255: 1.1 root 256: for ( ;; ) 257: { 258: if (!GetNumberOfConsoleInputEvents (hinput, &numevents)) 259: Sys_Error ("Error getting # of console events"); 1.1.1.2 ! root 260: 1.1 root 261: if (numevents <= 0) 262: break; 1.1.1.2 ! root 263: 1.1 root 264: if (!ReadConsoleInput(hinput, recs, 1, &numread)) 265: Sys_Error ("Error reading console input"); 1.1.1.2 ! root 266: 1.1 root 267: if (numread != 1) 268: Sys_Error ("Couldn't read console input"); 1.1.1.2 ! root 269: 1.1 root 270: if (recs[0].EventType == KEY_EVENT) 271: { 272: if (!recs[0].Event.KeyEvent.bKeyDown) 273: { 274: ch = recs[0].Event.KeyEvent.uChar.AsciiChar; 1.1.1.2 ! root 275: 1.1 root 276: switch (ch) 277: { 278: case '\r': 279: WriteFile(houtput, "\r\n", 2, &dummy, NULL); 1.1.1.2 ! root 280: 1.1 root 281: if (console_textlen) 282: { 283: console_text[console_textlen] = 0; 284: console_textlen = 0; 285: return console_text; 286: } 287: break; 1.1.1.2 ! root 288: 1.1 root 289: case '\b': 290: if (console_textlen) 291: { 292: console_textlen--; 293: WriteFile(houtput, "\b \b", 3, &dummy, NULL); 294: } 295: break; 1.1.1.2 ! root 296: 1.1 root 297: default: 298: if (ch >= ' ') 299: { 300: if (console_textlen < sizeof(console_text)-2) 301: { 302: WriteFile(houtput, &ch, 1, &dummy, NULL); 303: console_text[console_textlen] = ch; 304: console_textlen++; 305: } 306: } 1.1.1.2 ! root 307: 1.1 root 308: break; 1.1.1.2 ! root 309: 1.1 root 310: } 311: } 312: } 313: } 1.1.1.2 ! root 314: 1.1 root 315: return NULL; 316: } 1.1.1.2 ! root 317: ! 318: 1.1 root 319: /* 320: ================ 321: Sys_ConsoleOutput 1.1.1.2 ! root 322: 1.1 root 323: Print text to the dedicated console 324: ================ 325: */ 326: void Sys_ConsoleOutput (char *string) 327: { 328: int dummy; 329: char text[256]; 1.1.1.2 ! root 330: 1.1 root 331: if (!dedicated || !dedicated->value) 332: return; 333: 334: if (console_textlen) 335: { 336: text[0] = '\r'; 337: memset(&text[1], ' ', console_textlen); 338: text[console_textlen+1] = '\r'; 339: text[console_textlen+2] = 0; 340: WriteFile(houtput, text, console_textlen+2, &dummy, NULL); 341: } 1.1.1.2 ! root 342: 1.1 root 343: WriteFile(houtput, string, strlen(string), &dummy, NULL); 344: 345: if (console_textlen) 346: WriteFile(houtput, console_text, console_textlen, &dummy, NULL); 347: } 1.1.1.2 ! root 348: ! 349: 1.1 root 350: /* 351: ================ 352: Sys_SendKeyEvents 1.1.1.2 ! root 353: 1.1 root 354: Send Key_Event calls 355: ================ 356: */ 357: void Sys_SendKeyEvents (void) 358: { 359: MSG msg; 1.1.1.2 ! root 360: 1.1 root 361: while (PeekMessage (&msg, NULL, 0, 0, PM_NOREMOVE)) 362: { 363: if (!GetMessage (&msg, NULL, 0, 0)) 364: Sys_Quit (); 365: sys_msg_time = msg.time; 366: TranslateMessage (&msg); 367: DispatchMessage (&msg); 368: } 369: 370: // grab frame time 371: sys_frame_time = timeGetTime(); // FIXME: should this be at start? 372: } 1.1.1.2 ! root 373: ! 374: ! 375: 1.1 root 376: /* 377: ================ 378: Sys_GetClipboardData 379: 380: ================ 381: */ 382: char *Sys_GetClipboardData( void ) 383: { 384: char *data = NULL; 385: char *cliptext; 386: 387: if ( OpenClipboard( NULL ) != 0 ) 388: { 389: HANDLE hClipboardData; 390: 391: if ( ( hClipboardData = GetClipboardData( CF_TEXT ) ) != 0 ) 392: { 393: if ( ( cliptext = GlobalLock( hClipboardData ) ) != 0 ) 394: { 395: data = malloc( GlobalSize( hClipboardData ) + 1 ); 396: strcpy( data, cliptext ); 397: GlobalUnlock( hClipboardData ); 398: } 399: } 400: CloseClipboard(); 401: } 402: return data; 403: } 1.1.1.2 ! root 404: 1.1 root 405: /* 406: ============================================================================== 1.1.1.2 ! root 407: 1.1 root 408: WINDOWS CRAP 1.1.1.2 ! root 409: 1.1 root 410: ============================================================================== 411: */ 1.1.1.2 ! root 412: 1.1 root 413: /* 414: ================= 415: Sys_AppActivate 416: ================= 417: */ 418: void Sys_AppActivate (void) 419: { 420: ShowWindow ( cl_hwnd, SW_RESTORE); 421: SetForegroundWindow ( cl_hwnd ); 422: } 1.1.1.2 ! root 423: 1.1 root 424: /* 425: ======================================================================== 1.1.1.2 ! root 426: 1.1 root 427: GAME DLL 1.1.1.2 ! root 428: 1.1 root 429: ======================================================================== 430: */ 1.1.1.2 ! root 431: 1.1 root 432: static HINSTANCE game_library; 1.1.1.2 ! root 433: 1.1 root 434: /* 435: ================= 436: Sys_UnloadGame 437: ================= 438: */ 439: void Sys_UnloadGame (void) 440: { 441: if (!FreeLibrary (game_library)) 442: Com_Error (ERR_FATAL, "FreeLibrary failed for game library"); 443: game_library = NULL; 444: } 1.1.1.2 ! root 445: 1.1 root 446: /* 447: ================= 448: Sys_GetGameAPI 1.1.1.2 ! root 449: 1.1 root 450: Loads the game dll 451: ================= 452: */ 453: void *Sys_GetGameAPI (void *parms) 454: { 455: void *(*GetGameAPI) (void *); 456: char name[MAX_OSPATH]; 457: char *path; 458: char cwd[MAX_OSPATH]; 459: #if defined _M_IX86 460: const char *gamename = "gamex86.dll"; 461: 462: #ifdef NDEBUG 463: const char *debugdir = "release"; 464: #else 465: const char *debugdir = "debug"; 466: #endif 467: 468: #elif defined _M_ALPHA 469: const char *gamename = "gameaxp.dll"; 470: 471: #ifdef NDEBUG 472: const char *debugdir = "releaseaxp"; 473: #else 474: const char *debugdir = "debugaxp"; 475: #endif 476: 477: #endif 1.1.1.2 ! root 478: 1.1 root 479: if (game_library) 480: Com_Error (ERR_FATAL, "Sys_GetGameAPI without Sys_UnloadingGame"); 481: 482: // check the current debug directory first for development purposes 483: _getcwd (cwd, sizeof(cwd)); 484: Com_sprintf (name, sizeof(name), "%s/%s/%s", cwd, debugdir, gamename); 485: game_library = LoadLibrary ( name ); 486: if (game_library) 487: { 488: Com_DPrintf ("LoadLibrary (%s)\n", name); 489: } 490: else 491: { 492: // check the current directory for other development purposes 493: Com_sprintf (name, sizeof(name), "%s/%s", cwd, gamename); 494: game_library = LoadLibrary ( name ); 495: if (game_library) 496: { 497: Com_DPrintf ("LoadLibrary (%s)\n", name); 498: } 499: else 500: { 501: // now run through the search paths 502: path = NULL; 503: while (1) 504: { 505: path = FS_NextPath (path); 506: if (!path) 507: return NULL; // couldn't find one anywhere 508: Com_sprintf (name, sizeof(name), "%s/%s", path, gamename); 509: game_library = LoadLibrary (name); 510: if (game_library) 511: { 512: Com_DPrintf ("LoadLibrary (%s)\n",name); 513: break; 514: } 515: } 516: } 517: } 1.1.1.2 ! root 518: 1.1 root 519: GetGameAPI = (void *)GetProcAddress (game_library, "GetGameAPI"); 520: if (!GetGameAPI) 521: { 522: Sys_UnloadGame (); 523: return NULL; 524: } 1.1.1.2 ! root 525: 1.1 root 526: return GetGameAPI (parms); 527: } 1.1.1.2 ! root 528: 1.1 root 529: //======================================================================= 1.1.1.2 ! root 530: ! 531: 1.1 root 532: /* 533: ================== 534: ParseCommandLine 1.1.1.2 ! root 535: 1.1 root 536: ================== 537: */ 538: void ParseCommandLine (LPSTR lpCmdLine) 539: { 540: argc = 1; 541: argv[0] = "exe"; 1.1.1.2 ! root 542: 1.1 root 543: while (*lpCmdLine && (argc < MAX_NUM_ARGVS)) 544: { 545: while (*lpCmdLine && ((*lpCmdLine <= 32) || (*lpCmdLine > 126))) 546: lpCmdLine++; 1.1.1.2 ! root 547: 1.1 root 548: if (*lpCmdLine) 549: { 550: argv[argc] = lpCmdLine; 551: argc++; 1.1.1.2 ! root 552: 1.1 root 553: while (*lpCmdLine && ((*lpCmdLine > 32) && (*lpCmdLine <= 126))) 554: lpCmdLine++; 1.1.1.2 ! root 555: 1.1 root 556: if (*lpCmdLine) 557: { 558: *lpCmdLine = 0; 559: lpCmdLine++; 560: } 561: 562: } 563: } 1.1.1.2 ! root 564: 1.1 root 565: } 1.1.1.2 ! root 566: 1.1 root 567: /* 568: ================== 569: WinMain 1.1.1.2 ! root 570: 1.1 root 571: ================== 572: */ 573: HINSTANCE global_hInstance; 1.1.1.2 ! root 574: 1.1 root 575: int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) 576: { 577: MSG msg; 578: int time, oldtime, newtime; 579: char *cddir; 580: 581: /* previous instances do not exist in Win32 */ 582: if (hPrevInstance) 583: return 0; 584: 585: global_hInstance = hInstance; 1.1.1.2 ! root 586: 1.1 root 587: ParseCommandLine (lpCmdLine); 1.1.1.2 ! root 588: 1.1 root 589: // if we find the CD, add a +set cddir xxx command line 590: cddir = Sys_ScanForCD (); 591: if (cddir && argc < MAX_NUM_ARGVS - 3) 592: { 593: int i; 594: 595: // don't override a cddir on the command line 596: for (i=0 ; i<argc ; i++) 597: if (!strcmp(argv[i], "cddir")) 598: break; 599: if (i == argc) 600: { 601: argv[argc++] = "+set"; 602: argv[argc++] = "cddir"; 603: argv[argc++] = cddir; 604: } 605: } 1.1.1.2 ! root 606: 1.1 root 607: Qcommon_Init (argc, argv); 608: oldtime = Sys_Milliseconds (); 1.1.1.2 ! root 609: 1.1 root 610: /* main window message loop */ 611: while (1) 612: { 613: // if at a full screen console, don't update unless needed 614: if (Minimized || (dedicated && dedicated->value) ) 615: { 616: Sleep (1); 617: } 618: 619: while (PeekMessage (&msg, NULL, 0, 0, PM_NOREMOVE)) 620: { 621: if (!GetMessage (&msg, NULL, 0, 0)) 622: Com_Quit (); 623: sys_msg_time = msg.time; 624: TranslateMessage (&msg); 625: DispatchMessage (&msg); 626: } 1.1.1.2 ! root 627: 1.1 root 628: do 629: { 630: newtime = Sys_Milliseconds (); 631: time = newtime - oldtime; 632: } while (time < 1); 633: // Con_Printf ("time:%5.2f - %5.2f = %5.2f\n", newtime, oldtime, time); 634: 635: // _controlfp( ~( _EM_ZERODIVIDE /*| _EM_INVALID*/ ), _MCW_EM ); 636: _controlfp( _PC_24, _MCW_PC ); 637: Qcommon_Frame (time); 1.1.1.2 ! root 638: 1.1 root 639: oldtime = newtime; 640: } 1.1.1.2 ! root 641: 1.1 root 642: // never gets here 643: return TRUE; 644: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.