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