|
|
1.1 ! root 1: // gl_vidnt.c -- NT GL vid component ! 2: ! 3: #include "quakedef.h" ! 4: #include "winquake.h" ! 5: #include "resource.h" ! 6: ! 7: #define MAX_MODE_LIST 30 ! 8: #define VID_ROW_SIZE 3 ! 9: #define WARP_WIDTH 320 ! 10: #define WARP_HEIGHT 200 ! 11: #define MAXWIDTH 10000 ! 12: #define MAXHEIGHT 10000 ! 13: #define BASEWIDTH 320 ! 14: #define BASEHEIGHT 200 ! 15: ! 16: #define MODE_WINDOWED 0 ! 17: #define NO_MODE (MODE_WINDOWED - 1) ! 18: #define MODE_FULLSCREEN_DEFAULT (MODE_WINDOWED + 1) ! 19: ! 20: typedef struct { ! 21: modestate_t type; ! 22: int width; ! 23: int height; ! 24: int modenum; ! 25: int dib; ! 26: int fullscreen; ! 27: int bpp; ! 28: int halfscreen; ! 29: char modedesc[17]; ! 30: } vmode_t; ! 31: ! 32: typedef struct { ! 33: int width; ! 34: int height; ! 35: } lmode_t; ! 36: ! 37: lmode_t lowresmodes[] = { ! 38: {320, 200}, ! 39: {320, 240}, ! 40: {400, 300}, ! 41: {512, 384}, ! 42: }; ! 43: ! 44: const char *gl_vendor; ! 45: const char *gl_renderer; ! 46: const char *gl_version; ! 47: const char *gl_extensions; ! 48: ! 49: qboolean DDActive; ! 50: qboolean scr_skipupdate; ! 51: ! 52: static vmode_t modelist[MAX_MODE_LIST]; ! 53: static int nummodes; ! 54: static vmode_t *pcurrentmode; ! 55: static vmode_t badmode; ! 56: ! 57: static DEVMODE gdevmode; ! 58: static qboolean vid_initialized = false; ! 59: static qboolean windowed, leavecurrentmode; ! 60: static int windowed_mouse; ! 61: static HICON hIcon; ! 62: ! 63: int DIBWidth, DIBHeight; ! 64: RECT WindowRect; ! 65: DWORD WindowStyle, ExWindowStyle; ! 66: ! 67: HWND mainwindow, dibwindow; ! 68: ! 69: int vid_modenum = NO_MODE; ! 70: int vid_realmode; ! 71: int vid_default = MODE_WINDOWED; ! 72: static int windowed_default; ! 73: ! 74: unsigned char vid_curpal[256*3]; ! 75: ! 76: HGLRC baseRC; ! 77: HDC maindc; ! 78: ! 79: glvert_t glv; ! 80: ! 81: cvar_t gl_ztrick = {"gl_ztrick","1"}; ! 82: ! 83: HWND WINAPI InitializeWindow (HINSTANCE hInstance, int nCmdShow); ! 84: ! 85: viddef_t vid; // global video state ! 86: ! 87: unsigned short d_8to16table[256]; ! 88: unsigned d_8to24table[256]; ! 89: ! 90: float gldepthmin, gldepthmax; ! 91: ! 92: modestate_t modestate = MS_UNINIT; ! 93: ! 94: void VID_MenuDraw (void); ! 95: void VID_MenuKey (int key); ! 96: ! 97: LONG WINAPI MainWndProc (HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam); ! 98: void AppActivate(BOOL fActive, BOOL minimize); ! 99: char *VID_GetModeDescription (int mode); ! 100: void ClearAllStates (void); ! 101: void VID_UpdateWindowStatus (void); ! 102: void GL_Init (void); ! 103: ! 104: PROC glArrayElementEXT; ! 105: PROC glColorPointerEXT; ! 106: PROC glTexCoordPointerEXT; ! 107: PROC glVertexPointerEXT; ! 108: ! 109: //==================================== ! 110: ! 111: cvar_t vid_mode = {"vid_mode","0", false}; ! 112: // Note that 0 is MODE_WINDOWED ! 113: cvar_t _vid_default_mode = {"_vid_default_mode","0", true}; ! 114: // Note that 3 is MODE_FULLSCREEN_DEFAULT ! 115: cvar_t _vid_default_mode_win = {"_vid_default_mode_win","3", true}; ! 116: cvar_t vid_wait = {"vid_wait","0"}; ! 117: cvar_t vid_nopageflip = {"vid_nopageflip","0", true}; ! 118: cvar_t _vid_wait_override = {"_vid_wait_override", "0", true}; ! 119: cvar_t vid_config_x = {"vid_config_x","800", true}; ! 120: cvar_t vid_config_y = {"vid_config_y","600", true}; ! 121: cvar_t vid_stretch_by_2 = {"vid_stretch_by_2","1", true}; ! 122: cvar_t _windowed_mouse = {"_windowed_mouse","0", true}; ! 123: ! 124: int window_center_x, window_center_y, window_x, window_y, window_width, window_height; ! 125: RECT window_rect; ! 126: ! 127: // direct draw software compatability stuff ! 128: ! 129: void VID_HandlePause (qboolean pause) ! 130: { ! 131: } ! 132: ! 133: void VID_ForceLockState (int lk) ! 134: { ! 135: } ! 136: ! 137: void VID_LockBuffer (void) ! 138: { ! 139: } ! 140: ! 141: void VID_UnlockBuffer (void) ! 142: { ! 143: } ! 144: ! 145: int VID_ForceUnlockedAndReturnState (void) ! 146: { ! 147: return 0; ! 148: } ! 149: ! 150: void D_BeginDirectRect (int x, int y, byte *pbitmap, int width, int height) ! 151: { ! 152: } ! 153: ! 154: void D_EndDirectRect (int x, int y, int width, int height) ! 155: { ! 156: } ! 157: ! 158: ! 159: void CenterWindow(HWND hWndCenter, int width, int height, BOOL lefttopjustify) ! 160: { ! 161: RECT rect; ! 162: int CenterX, CenterY; ! 163: ! 164: CenterX = (GetSystemMetrics(SM_CXSCREEN) - width) / 2; ! 165: CenterY = (GetSystemMetrics(SM_CYSCREEN) - height) / 2; ! 166: if (CenterX > CenterY*2) ! 167: CenterX >>= 1; // dual screens ! 168: CenterX = (CenterX < 0) ? 0: CenterX; ! 169: CenterY = (CenterY < 0) ? 0: CenterY; ! 170: SetWindowPos (hWndCenter, NULL, CenterX, CenterY, 0, 0, ! 171: SWP_NOSIZE | SWP_NOZORDER | SWP_SHOWWINDOW | SWP_DRAWFRAME); ! 172: } ! 173: ! 174: qboolean VID_SetWindowedMode (int modenum) ! 175: { ! 176: HDC hdc; ! 177: int lastmodestate, width, height; ! 178: RECT rect; ! 179: ! 180: lastmodestate = modestate; ! 181: ! 182: WindowRect.top = WindowRect.left = 0; ! 183: ! 184: WindowRect.right = modelist[modenum].width; ! 185: WindowRect.bottom = modelist[modenum].height; ! 186: ! 187: DIBWidth = modelist[modenum].width; ! 188: DIBHeight = modelist[modenum].height; ! 189: ! 190: WindowStyle = WS_OVERLAPPED | WS_BORDER | WS_CAPTION | WS_SYSMENU | ! 191: WS_MINIMIZEBOX; ! 192: ExWindowStyle = 0; ! 193: ! 194: rect = WindowRect; ! 195: AdjustWindowRectEx(&rect, WindowStyle, FALSE, 0); ! 196: ! 197: width = rect.right - rect.left; ! 198: height = rect.bottom - rect.top; ! 199: ! 200: // Create the DIB window ! 201: dibwindow = CreateWindowEx ( ! 202: ExWindowStyle, ! 203: "WinQuake", ! 204: "GLQuake", ! 205: WindowStyle, ! 206: rect.left, rect.top, ! 207: width, ! 208: height, ! 209: NULL, ! 210: NULL, ! 211: global_hInstance, ! 212: NULL); ! 213: ! 214: if (!dibwindow) ! 215: Sys_Error ("Couldn't create DIB window"); ! 216: ! 217: // Center and show the DIB window ! 218: CenterWindow(dibwindow, WindowRect.right - WindowRect.left, ! 219: WindowRect.bottom - WindowRect.top, false); ! 220: ! 221: ShowWindow (dibwindow, SW_SHOWDEFAULT); ! 222: UpdateWindow (dibwindow); ! 223: ! 224: modestate = MS_WINDOWED; ! 225: ! 226: // because we have set the background brush for the window to NULL ! 227: // (to avoid flickering when re-sizing the window on the desktop), ! 228: // we clear the window to black when created, otherwise it will be ! 229: // empty while Quake starts up. ! 230: hdc = GetDC(dibwindow); ! 231: PatBlt(hdc,0,0,WindowRect.right,WindowRect.bottom,BLACKNESS); ! 232: ReleaseDC(dibwindow, hdc); ! 233: ! 234: vid.height = vid.conheight = BASEHEIGHT; ! 235: vid.width = vid.conwidth = BASEWIDTH; ! 236: vid.numpages = 2; ! 237: ! 238: mainwindow = dibwindow; ! 239: ! 240: SendMessage (mainwindow, WM_SETICON, (WPARAM)TRUE, (LPARAM)hIcon); ! 241: SendMessage (mainwindow, WM_SETICON, (WPARAM)FALSE, (LPARAM)hIcon); ! 242: ! 243: return true; ! 244: } ! 245: ! 246: ! 247: qboolean VID_SetFullDIBMode (int modenum) ! 248: { ! 249: HDC hdc; ! 250: int lastmodestate, width, height; ! 251: RECT rect; ! 252: ! 253: if (!leavecurrentmode) ! 254: { ! 255: gdevmode.dmFields = DM_BITSPERPEL | DM_PELSWIDTH | DM_PELSHEIGHT; ! 256: gdevmode.dmBitsPerPel = modelist[modenum].bpp; ! 257: gdevmode.dmPelsWidth = modelist[modenum].width << ! 258: modelist[modenum].halfscreen; ! 259: gdevmode.dmPelsHeight = modelist[modenum].height; ! 260: gdevmode.dmSize = sizeof (gdevmode); ! 261: ! 262: if (ChangeDisplaySettings (&gdevmode, CDS_FULLSCREEN) != DISP_CHANGE_SUCCESSFUL) ! 263: Sys_Error ("Couldn't set fullscreen DIB mode"); ! 264: } ! 265: ! 266: lastmodestate = modestate; ! 267: modestate = MS_FULLDIB; ! 268: ! 269: WindowRect.top = WindowRect.left = 0; ! 270: ! 271: WindowRect.right = modelist[modenum].width; ! 272: WindowRect.bottom = modelist[modenum].height; ! 273: ! 274: DIBWidth = modelist[modenum].width; ! 275: DIBHeight = modelist[modenum].height; ! 276: ! 277: WindowStyle = WS_POPUP; ! 278: ExWindowStyle = 0; ! 279: ! 280: rect = WindowRect; ! 281: AdjustWindowRectEx(&rect, WindowStyle, FALSE, 0); ! 282: ! 283: width = rect.right - rect.left; ! 284: height = rect.bottom - rect.top; ! 285: ! 286: // Create the DIB window ! 287: dibwindow = CreateWindowEx ( ! 288: ExWindowStyle, ! 289: "WinQuake", ! 290: "GLQuake", ! 291: WindowStyle, ! 292: rect.left, rect.top, ! 293: width, ! 294: height, ! 295: NULL, ! 296: NULL, ! 297: global_hInstance, ! 298: NULL); ! 299: ! 300: if (!dibwindow) ! 301: Sys_Error ("Couldn't create DIB window"); ! 302: ! 303: ShowWindow (dibwindow, SW_SHOWDEFAULT); ! 304: UpdateWindow (dibwindow); ! 305: ! 306: // Because we have set the background brush for the window to NULL ! 307: // (to avoid flickering when re-sizing the window on the desktop), we ! 308: // clear the window to black when created, otherwise it will be ! 309: // empty while Quake starts up. ! 310: hdc = GetDC(dibwindow); ! 311: PatBlt(hdc,0,0,WindowRect.right,WindowRect.bottom,BLACKNESS); ! 312: ReleaseDC(dibwindow, hdc); ! 313: ! 314: vid.height = vid.conheight = BASEHEIGHT; ! 315: vid.width = vid.conwidth = BASEWIDTH; ! 316: vid.numpages = 2; ! 317: ! 318: // needed because we're not getting WM_MOVE messages fullscreen on NT ! 319: window_x = 0; ! 320: window_y = 0; ! 321: ! 322: mainwindow = dibwindow; ! 323: ! 324: SendMessage (mainwindow, WM_SETICON, (WPARAM)TRUE, (LPARAM)hIcon); ! 325: SendMessage (mainwindow, WM_SETICON, (WPARAM)FALSE, (LPARAM)hIcon); ! 326: ! 327: return true; ! 328: } ! 329: ! 330: ! 331: int VID_SetMode (int modenum, unsigned char *palette) ! 332: { ! 333: int original_mode, temp; ! 334: qboolean stat; ! 335: MSG msg; ! 336: HDC hdc; ! 337: ! 338: if ((windowed && (modenum != 0)) || ! 339: (!windowed && (modenum < 1)) || ! 340: (!windowed && (modenum >= nummodes))) ! 341: { ! 342: Sys_Error ("Bad video mode\n"); ! 343: } ! 344: ! 345: // so Con_Printfs don't mess us up by forcing vid and snd updates ! 346: temp = scr_disabled_for_loading; ! 347: scr_disabled_for_loading = true; ! 348: ! 349: Snd_ReleaseBuffer (); ! 350: CDAudio_Pause (); ! 351: ! 352: if (vid_modenum == NO_MODE) ! 353: original_mode = windowed_default; ! 354: else ! 355: original_mode = vid_modenum; ! 356: ! 357: // Set either the fullscreen or windowed mode ! 358: if (modelist[modenum].type == MS_WINDOWED) ! 359: { ! 360: if (_windowed_mouse.value) ! 361: { ! 362: stat = VID_SetWindowedMode(modenum); ! 363: IN_ActivateMouse (); ! 364: IN_HideMouse (); ! 365: } ! 366: else ! 367: { ! 368: IN_DeactivateMouse (); ! 369: IN_ShowMouse (); ! 370: stat = VID_SetWindowedMode(modenum); ! 371: } ! 372: } ! 373: else if (modelist[modenum].type == MS_FULLDIB) ! 374: { ! 375: stat = VID_SetFullDIBMode(modenum); ! 376: IN_ActivateMouse (); ! 377: IN_HideMouse (); ! 378: } ! 379: else ! 380: { ! 381: Sys_Error ("VID_SetMode: Bad mode type in modelist"); ! 382: } ! 383: ! 384: window_width = DIBWidth; ! 385: window_height = DIBHeight; ! 386: VID_UpdateWindowStatus (); ! 387: ! 388: CDAudio_Resume (); ! 389: Snd_AcquireBuffer (); ! 390: scr_disabled_for_loading = temp; ! 391: ! 392: if (!stat) ! 393: { ! 394: Sys_Error ("Couldn't set video mode"); ! 395: } ! 396: ! 397: // now we try to make sure we get the focus on the mode switch, because ! 398: // sometimes in some systems we don't. We grab the foreground, then ! 399: // finish setting up, pump all our messages, and sleep for a little while ! 400: // to let messages finish bouncing around the system, then we put ! 401: // ourselves at the top of the z order, then grab the foreground again, ! 402: // Who knows if it helps, but it probably doesn't hurt ! 403: SetForegroundWindow (mainwindow); ! 404: VID_SetPalette (palette); ! 405: vid_modenum = modenum; ! 406: Cvar_SetValue ("vid_mode", (float)vid_modenum); ! 407: ! 408: while (PeekMessage (&msg, NULL, 0, 0, PM_REMOVE)) ! 409: { ! 410: TranslateMessage (&msg); ! 411: DispatchMessage (&msg); ! 412: } ! 413: ! 414: Sleep (100); ! 415: ! 416: SetWindowPos (mainwindow, HWND_TOP, 0, 0, 0, 0, ! 417: SWP_DRAWFRAME | SWP_NOMOVE | SWP_NOSIZE | SWP_SHOWWINDOW | ! 418: SWP_NOCOPYBITS); ! 419: ! 420: SetForegroundWindow (mainwindow); ! 421: ! 422: // fix the leftover Alt from any Alt-Tab or the like that switched us away ! 423: ClearAllStates (); ! 424: ! 425: if (!msg_suppress_1) ! 426: Con_SafePrintf ("%s\n", VID_GetModeDescription (vid_modenum)); ! 427: ! 428: VID_SetPalette (palette); ! 429: ! 430: vid.recalc_refdef = 1; ! 431: ! 432: return true; ! 433: } ! 434: ! 435: ! 436: /* ! 437: ================ ! 438: VID_UpdateWindowStatus ! 439: ================ ! 440: */ ! 441: void VID_UpdateWindowStatus (void) ! 442: { ! 443: ! 444: window_rect.left = window_x; ! 445: window_rect.top = window_y; ! 446: window_rect.right = window_x + window_width; ! 447: window_rect.bottom = window_y + window_height; ! 448: window_center_x = (window_rect.left + window_rect.right) / 2; ! 449: window_center_y = (window_rect.top + window_rect.bottom) / 2; ! 450: ! 451: IN_UpdateClipCursor (); ! 452: } ! 453: ! 454: ! 455: //==================================== ! 456: ! 457: BINDTEXFUNCPTR bindTexFunc; ! 458: ! 459: #define TEXTURE_EXT_STRING "GL_EXT_texture_object" ! 460: ! 461: ! 462: void CheckTextureExtensions (void) ! 463: { ! 464: char *tmp; ! 465: qboolean texture_ext; ! 466: HINSTANCE hInstGL; ! 467: ! 468: texture_ext = FALSE; ! 469: /* check for texture extension */ ! 470: tmp = (unsigned char *)glGetString(GL_EXTENSIONS); ! 471: while (*tmp) ! 472: { ! 473: if (strncmp((const char*)tmp, TEXTURE_EXT_STRING, strlen(TEXTURE_EXT_STRING)) == 0) ! 474: texture_ext = TRUE; ! 475: tmp++; ! 476: } ! 477: ! 478: if (!texture_ext || COM_CheckParm ("-gl11") ) ! 479: { ! 480: hInstGL = LoadLibrary("opengl32.dll"); ! 481: ! 482: if (hInstGL == NULL) ! 483: Sys_Error ("Couldn't load opengl32.dll\n"); ! 484: ! 485: bindTexFunc = (void *)GetProcAddress(hInstGL,"glBindTexture"); ! 486: ! 487: if (!bindTexFunc) ! 488: Sys_Error ("No texture objects!"); ! 489: return; ! 490: } ! 491: ! 492: /* load library and get procedure adresses for texture extension API */ ! 493: if ((bindTexFunc = (BINDTEXFUNCPTR) ! 494: wglGetProcAddress((LPCSTR) "glBindTextureEXT")) == NULL) ! 495: { ! 496: Sys_Error ("GetProcAddress for BindTextureEXT failed"); ! 497: return; ! 498: } ! 499: } ! 500: ! 501: void CheckArrayExtensions (void) ! 502: { ! 503: char *tmp; ! 504: ! 505: /* check for texture extension */ ! 506: tmp = (unsigned char *)glGetString(GL_EXTENSIONS); ! 507: while (*tmp) ! 508: { ! 509: if (strncmp((const char*)tmp, "GL_EXT_vertex_array", strlen("GL_EXT_vertex_array")) == 0) ! 510: { ! 511: if ( ! 512: ((glArrayElementEXT = wglGetProcAddress("glArrayElementEXT")) == NULL) || ! 513: ((glColorPointerEXT = wglGetProcAddress("glColorPointerEXT")) == NULL) || ! 514: ((glTexCoordPointerEXT = wglGetProcAddress("glTexCoordPointerEXT")) == NULL) || ! 515: ((glVertexPointerEXT = wglGetProcAddress("glVertexPointerEXT")) == NULL) ) ! 516: { ! 517: Sys_Error ("GetProcAddress for vertex extension failed"); ! 518: return; ! 519: } ! 520: return; ! 521: } ! 522: tmp++; ! 523: } ! 524: ! 525: Sys_Error ("Vertex array extension not present"); ! 526: } ! 527: ! 528: //int texture_mode = GL_NEAREST; ! 529: //int texture_mode = GL_NEAREST_MIPMAP_NEAREST; ! 530: //int texture_mode = GL_NEAREST_MIPMAP_LINEAR; ! 531: int texture_mode = GL_LINEAR; ! 532: //int texture_mode = GL_LINEAR_MIPMAP_NEAREST; ! 533: //int texture_mode = GL_LINEAR_MIPMAP_LINEAR; ! 534: ! 535: int texture_extension_number = 1; ! 536: ! 537: /* ! 538: =============== ! 539: GL_Init ! 540: =============== ! 541: */ ! 542: void GL_Init (void) ! 543: { ! 544: gl_vendor = glGetString (GL_VENDOR); ! 545: Con_Printf ("GL_VENDOR: %s\n", gl_vendor); ! 546: gl_renderer = glGetString (GL_RENDERER); ! 547: Con_Printf ("GL_RENDERER: %s\n", gl_renderer); ! 548: ! 549: gl_version = glGetString (GL_VERSION); ! 550: Con_Printf ("GL_VERSION: %s\n", gl_version); ! 551: gl_extensions = glGetString (GL_EXTENSIONS); ! 552: Con_Printf ("GL_EXTENSIONS: %s\n", gl_extensions); ! 553: ! 554: CheckTextureExtensions (); ! 555: ! 556: glClearColor (1,0,0,0); ! 557: glCullFace(GL_FRONT); ! 558: glEnable(GL_TEXTURE_2D); ! 559: ! 560: glEnable(GL_ALPHA_TEST); ! 561: glAlphaFunc(GL_GREATER, 0.666); ! 562: ! 563: glPolygonMode (GL_FRONT_AND_BACK, GL_FILL); ! 564: glShadeModel (GL_FLAT); ! 565: ! 566: glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); ! 567: glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); ! 568: glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); ! 569: glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); ! 570: ! 571: glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); ! 572: ! 573: // glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); ! 574: glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); ! 575: ! 576: #if 0 ! 577: CheckArrayExtensions (); ! 578: ! 579: glEnable (GL_VERTEX_ARRAY_EXT); ! 580: glEnable (GL_TEXTURE_COORD_ARRAY_EXT); ! 581: glVertexPointerEXT (3, GL_FLOAT, 0, 0, &glv.x); ! 582: glTexCoordPointerEXT (2, GL_FLOAT, 0, 0, &glv.s); ! 583: glColorPointerEXT (3, GL_FLOAT, 0, 0, &glv.r); ! 584: #endif ! 585: } ! 586: ! 587: /* ! 588: ================= ! 589: GL_BeginRendering ! 590: ! 591: ================= ! 592: */ ! 593: void GL_BeginRendering (int *x, int *y, int *width, int *height) ! 594: { ! 595: extern cvar_t gl_clear; ! 596: ! 597: *x = *y = 0; ! 598: *width = WindowRect.right - WindowRect.left; ! 599: *height = WindowRect.bottom - WindowRect.top; ! 600: ! 601: // if (!wglMakeCurrent( maindc, baseRC )) ! 602: // Sys_Error ("wglMakeCurrent failed"); ! 603: ! 604: // glViewport (*x, *y, *width, *height); ! 605: } ! 606: ! 607: ! 608: void GL_EndRendering (void) ! 609: { ! 610: if (!scr_skipupdate) ! 611: SwapBuffers(maindc); ! 612: ! 613: // handle the mouse state when windowed if that's changed ! 614: if (modestate == MS_WINDOWED) ! 615: { ! 616: if ((int)_windowed_mouse.value != windowed_mouse) ! 617: { ! 618: if (_windowed_mouse.value) ! 619: { ! 620: IN_ActivateMouse (); ! 621: IN_HideMouse (); ! 622: } ! 623: else ! 624: { ! 625: IN_DeactivateMouse (); ! 626: IN_ShowMouse (); ! 627: } ! 628: ! 629: windowed_mouse = (int)_windowed_mouse.value; ! 630: } ! 631: } ! 632: } ! 633: ! 634: ! 635: ! 636: void VID_SetPalette (unsigned char *palette) ! 637: { ! 638: byte *pal; ! 639: int r,g,b,v; ! 640: int i; ! 641: unsigned *table; ! 642: ! 643: ! 644: // ! 645: // 8 8 8 encoding ! 646: // ! 647: pal = palette; ! 648: table = d_8to24table; ! 649: ! 650: for (i=0 ; i<256 ; i++) ! 651: { ! 652: r = pal[0]; ! 653: g = pal[1]; ! 654: b = pal[2]; ! 655: pal += 3; ! 656: ! 657: // v = (255<<24) + (r<<16) + (g<<8) + (b<<0); ! 658: // v = (255<<0) + (r<<8) + (g<<16) + (b<<24); ! 659: v = (255<<24) + (r<<0) + (g<<8) + (b<<16); ! 660: *table++ = v; ! 661: } ! 662: ! 663: d_8to24table[255] &= 0xffffff; // 255 is transparent ! 664: } ! 665: ! 666: BOOL gammaworks; ! 667: void VID_ShiftPalette (unsigned char *palette) ! 668: { ! 669: extern byte ramps[3][256]; ! 670: ! 671: // VID_SetPalette (palette); ! 672: ! 673: // gammaworks = SetDeviceGammaRamp (maindc, ramps); ! 674: } ! 675: ! 676: ! 677: void VID_SetDefaultMode (void) ! 678: { ! 679: IN_DeactivateMouse (); ! 680: } ! 681: ! 682: ! 683: void VID_Shutdown (void) ! 684: { ! 685: HGLRC hRC; ! 686: HDC hDC; ! 687: ! 688: if (vid_initialized) ! 689: { ! 690: hRC = wglGetCurrentContext(); ! 691: hDC = wglGetCurrentDC(); ! 692: ! 693: wglMakeCurrent(NULL, NULL); ! 694: ! 695: if (hRC) ! 696: wglDeleteContext(hRC); ! 697: ! 698: if (hDC && dibwindow) ! 699: ReleaseDC(dibwindow, hDC); ! 700: ! 701: if (modestate == MS_FULLDIB) ! 702: ChangeDisplaySettings (NULL, 0); ! 703: ! 704: if (maindc && dibwindow) ! 705: ReleaseDC (dibwindow, maindc); ! 706: ! 707: AppActivate(false, false); ! 708: } ! 709: } ! 710: ! 711: ! 712: //========================================================================== ! 713: ! 714: ! 715: BOOL bSetupPixelFormat(HDC hDC) ! 716: { ! 717: static PIXELFORMATDESCRIPTOR pfd = { ! 718: sizeof(PIXELFORMATDESCRIPTOR), // size of this pfd ! 719: 1, // version number ! 720: PFD_DRAW_TO_WINDOW // support window ! 721: | PFD_SUPPORT_OPENGL // support OpenGL ! 722: | PFD_DOUBLEBUFFER , // double buffered ! 723: PFD_TYPE_RGBA, // RGBA type ! 724: 24, // 24-bit color depth ! 725: 0, 0, 0, 0, 0, 0, // color bits ignored ! 726: 0, // no alpha buffer ! 727: 0, // shift bit ignored ! 728: 0, // no accumulation buffer ! 729: 0, 0, 0, 0, // accum bits ignored ! 730: 32, // 32-bit z-buffer ! 731: 0, // no stencil buffer ! 732: 0, // no auxiliary buffer ! 733: PFD_MAIN_PLANE, // main layer ! 734: 0, // reserved ! 735: 0, 0, 0 // layer masks ignored ! 736: }; ! 737: int pixelformat; ! 738: ! 739: if ( (pixelformat = ChoosePixelFormat(hDC, &pfd)) == 0 ) ! 740: { ! 741: MessageBox(NULL, "ChoosePixelFormat failed", "Error", MB_OK); ! 742: return FALSE; ! 743: } ! 744: ! 745: if (SetPixelFormat(hDC, pixelformat, &pfd) == FALSE) ! 746: { ! 747: MessageBox(NULL, "SetPixelFormat failed", "Error", MB_OK); ! 748: return FALSE; ! 749: } ! 750: ! 751: return TRUE; ! 752: } ! 753: ! 754: ! 755: ! 756: byte scantokey[128] = ! 757: { ! 758: // 0 1 2 3 4 5 6 7 ! 759: // 8 9 A B C D E F ! 760: 0 , 27, '1', '2', '3', '4', '5', '6', ! 761: '7', '8', '9', '0', '-', '=', K_BACKSPACE, 9, // 0 ! 762: 'q', 'w', 'e', 'r', 't', 'y', 'u', 'i', ! 763: 'o', 'p', '[', ']', 13 , K_CTRL,'a', 's', // 1 ! 764: 'd', 'f', 'g', 'h', 'j', 'k', 'l', ';', ! 765: '\'' , '`', K_SHIFT,'\\', 'z', 'x', 'c', 'v', // 2 ! 766: 'b', 'n', 'm', ',', '.', '/', K_SHIFT,'*', ! 767: K_ALT,' ', 0 , K_F1, K_F2, K_F3, K_F4, K_F5, // 3 ! 768: K_F6, K_F7, K_F8, K_F9, K_F10,0 , 0 , K_HOME, ! 769: K_UPARROW,K_PGUP,'-',K_LEFTARROW,'5',K_RIGHTARROW,'+',K_END, //4 ! 770: K_DOWNARROW,K_PGDN,K_INS,K_DEL,0,0, 0, K_F11, ! 771: K_F12,0 , 0 , 0 , 0 , 0 , 0 , 0, // 5 ! 772: 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0, ! 773: 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0, // 6 ! 774: 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0, ! 775: 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 // 7 ! 776: }; ! 777: ! 778: byte shiftscantokey[128] = ! 779: { ! 780: // 0 1 2 3 4 5 6 7 ! 781: // 8 9 A B C D E F ! 782: 0 , 27, '!', '@', '#', '$', '%', '^', ! 783: '&', '*', '(', ')', '_', '+', K_BACKSPACE, 9, // 0 ! 784: 'Q', 'W', 'E', 'R', 'T', 'Y', 'U', 'I', ! 785: 'O', 'P', '{', '}', 13 , K_CTRL,'A', 'S', // 1 ! 786: 'D', 'F', 'G', 'H', 'J', 'K', 'L', ':', ! 787: '"' , '~', K_SHIFT,'|', 'Z', 'X', 'C', 'V', // 2 ! 788: 'B', 'N', 'M', '<', '>', '?', K_SHIFT,'*', ! 789: K_ALT,' ', 0 , K_F1, K_F2, K_F3, K_F4, K_F5, // 3 ! 790: K_F6, K_F7, K_F8, K_F9, K_F10,0 , 0 , K_HOME, ! 791: K_UPARROW,K_PGUP,'_',K_LEFTARROW,'%',K_RIGHTARROW,'+',K_END, //4 ! 792: K_DOWNARROW,K_PGDN,K_INS,K_DEL,0,0, 0, K_F11, ! 793: K_F12,0 , 0 , 0 , 0 , 0 , 0 , 0, // 5 ! 794: 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0, ! 795: 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0, // 6 ! 796: 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0, ! 797: 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 // 7 ! 798: }; ! 799: ! 800: ! 801: /* ! 802: ======= ! 803: MapKey ! 804: ! 805: Map from windows to quake keynums ! 806: ======= ! 807: */ ! 808: int MapKey (int key) ! 809: { ! 810: key = (key>>16)&255; ! 811: if (key > 127) ! 812: return 0; ! 813: return scantokey[key]; ! 814: } ! 815: ! 816: /* ! 817: =================================================================== ! 818: ! 819: MAIN WINDOW ! 820: ! 821: =================================================================== ! 822: */ ! 823: ! 824: /* ! 825: ================ ! 826: ClearAllStates ! 827: ================ ! 828: */ ! 829: void ClearAllStates (void) ! 830: { ! 831: int i; ! 832: ! 833: // send an up event for each key, to make sure the server clears them all ! 834: for (i=0 ; i<256 ; i++) ! 835: { ! 836: Key_Event (i, false); ! 837: } ! 838: ! 839: Key_ClearStates (); ! 840: IN_ClearStates (); ! 841: } ! 842: ! 843: void AppActivate(BOOL fActive, BOOL minimize) ! 844: /**************************************************************************** ! 845: * ! 846: * Function: AppActivate ! 847: * Parameters: fActive - True if app is activating ! 848: * ! 849: * Description: If the application is activating, then swap the system ! 850: * into SYSPAL_NOSTATIC mode so that our palettes will display ! 851: * correctly. ! 852: * ! 853: ****************************************************************************/ ! 854: { ! 855: HDC hdc; ! 856: int i, t; ! 857: static BOOL sound_active; ! 858: ! 859: ActiveApp = fActive; ! 860: Minimized = minimize; ! 861: ! 862: // enable/disable sound on focus gain/loss ! 863: if (!ActiveApp && sound_active) ! 864: { ! 865: S_BlockSound (); ! 866: sound_active = false; ! 867: } ! 868: else if (ActiveApp && !sound_active) ! 869: { ! 870: S_UnblockSound (); ! 871: sound_active = true; ! 872: } ! 873: ! 874: if (fActive) ! 875: { ! 876: if (modestate == MS_FULLDIB) ! 877: { ! 878: IN_ActivateMouse (); ! 879: IN_HideMouse (); ! 880: } ! 881: else if ((modestate == MS_WINDOWED) && _windowed_mouse.value) ! 882: { ! 883: IN_ActivateMouse (); ! 884: IN_HideMouse (); ! 885: } ! 886: } ! 887: ! 888: if (!fActive) ! 889: { ! 890: if (modestate == MS_FULLDIB) ! 891: { ! 892: IN_DeactivateMouse (); ! 893: IN_ShowMouse (); ! 894: } ! 895: else if ((modestate == MS_WINDOWED) && _windowed_mouse.value) ! 896: { ! 897: IN_DeactivateMouse (); ! 898: IN_ShowMouse (); ! 899: } ! 900: } ! 901: } ! 902: ! 903: ! 904: /* main window procedure */ ! 905: LONG WINAPI MainWndProc ( ! 906: HWND hWnd, ! 907: UINT uMsg, ! 908: WPARAM wParam, ! 909: LPARAM lParam) ! 910: { ! 911: LONG lRet = 1; ! 912: int fwKeys, xPos, yPos, fActive, fMinimized, temp; ! 913: ! 914: switch (uMsg) ! 915: { ! 916: case WM_CREATE: ! 917: break; ! 918: ! 919: case WM_MOVE: ! 920: window_x = (int) LOWORD(lParam); ! 921: window_y = (int) HIWORD(lParam); ! 922: VID_UpdateWindowStatus (); ! 923: break; ! 924: ! 925: case WM_KEYDOWN: ! 926: case WM_SYSKEYDOWN: ! 927: Key_Event (MapKey(lParam), true); ! 928: break; ! 929: ! 930: case WM_KEYUP: ! 931: case WM_SYSKEYUP: ! 932: Key_Event (MapKey(lParam), false); ! 933: break; ! 934: ! 935: case WM_SYSCHAR: ! 936: // keep Alt-Space from happening ! 937: break; ! 938: ! 939: // this is complicated because Win32 seems to pack multiple mouse events into ! 940: // one update sometimes, so we always check all states and look for events ! 941: case WM_LBUTTONDOWN: ! 942: case WM_LBUTTONUP: ! 943: case WM_RBUTTONDOWN: ! 944: case WM_RBUTTONUP: ! 945: case WM_MBUTTONDOWN: ! 946: case WM_MBUTTONUP: ! 947: case WM_MOUSEMOVE: ! 948: temp = 0; ! 949: ! 950: if (wParam & MK_LBUTTON) ! 951: temp |= 1; ! 952: ! 953: if (wParam & MK_RBUTTON) ! 954: temp |= 2; ! 955: ! 956: if (wParam & MK_MBUTTON) ! 957: temp |= 4; ! 958: ! 959: IN_MouseEvent (temp); ! 960: ! 961: break; ! 962: ! 963: ! 964: case WM_SIZE: ! 965: break; ! 966: ! 967: case WM_CLOSE: ! 968: if (MessageBox (mainwindow, "Are you sure you want to quit?", "Confirm Exit", ! 969: MB_YESNO | MB_SETFOREGROUND | MB_ICONQUESTION) == IDYES) ! 970: { ! 971: Sys_Quit (); ! 972: } ! 973: ! 974: break; ! 975: ! 976: case WM_ACTIVATE: ! 977: fActive = LOWORD(wParam); ! 978: fMinimized = (BOOL) HIWORD(wParam); ! 979: AppActivate(!(fActive == WA_INACTIVE), fMinimized); ! 980: ! 981: // fix the leftover Alt from any Alt-Tab or the like that switched us away ! 982: ClearAllStates (); ! 983: ! 984: break; ! 985: ! 986: case WM_DESTROY: ! 987: { ! 988: if (dibwindow) ! 989: DestroyWindow (dibwindow); ! 990: ! 991: PostQuitMessage (0); ! 992: } ! 993: break; ! 994: ! 995: case MM_MCINOTIFY: ! 996: lRet = CDAudio_MessageHandler (hWnd, uMsg, wParam, lParam); ! 997: break; ! 998: ! 999: default: ! 1000: /* pass all unhandled messages to DefWindowProc */ ! 1001: lRet = DefWindowProc (hWnd, uMsg, wParam, lParam); ! 1002: break; ! 1003: } ! 1004: ! 1005: /* return 1 if handled message, 0 if not */ ! 1006: return lRet; ! 1007: } ! 1008: ! 1009: ! 1010: /* ! 1011: ================= ! 1012: VID_NumModes ! 1013: ================= ! 1014: */ ! 1015: int VID_NumModes (void) ! 1016: { ! 1017: return nummodes; ! 1018: } ! 1019: ! 1020: ! 1021: /* ! 1022: ================= ! 1023: VID_GetModePtr ! 1024: ================= ! 1025: */ ! 1026: vmode_t *VID_GetModePtr (int modenum) ! 1027: { ! 1028: ! 1029: if ((modenum >= 0) && (modenum < nummodes)) ! 1030: return &modelist[modenum]; ! 1031: else ! 1032: return &badmode; ! 1033: } ! 1034: ! 1035: ! 1036: /* ! 1037: ================= ! 1038: VID_GetModeDescription ! 1039: ================= ! 1040: */ ! 1041: char *VID_GetModeDescription (int mode) ! 1042: { ! 1043: char *pinfo; ! 1044: vmode_t *pv; ! 1045: static char temp[100]; ! 1046: ! 1047: if ((mode < 0) || (mode >= nummodes)) ! 1048: return NULL; ! 1049: ! 1050: if (!leavecurrentmode) ! 1051: { ! 1052: pv = VID_GetModePtr (mode); ! 1053: pinfo = pv->modedesc; ! 1054: } ! 1055: else ! 1056: { ! 1057: sprintf (temp, "Desktop resolution (%dx%d)", ! 1058: modelist[MODE_FULLSCREEN_DEFAULT].width, ! 1059: modelist[MODE_FULLSCREEN_DEFAULT].height); ! 1060: pinfo = temp; ! 1061: } ! 1062: ! 1063: return pinfo; ! 1064: } ! 1065: ! 1066: ! 1067: // KJB: Added this to return the mode driver name in description for console ! 1068: ! 1069: char *VID_GetExtModeDescription (int mode) ! 1070: { ! 1071: static char pinfo[40]; ! 1072: vmode_t *pv; ! 1073: ! 1074: if ((mode < 0) || (mode >= nummodes)) ! 1075: return NULL; ! 1076: ! 1077: pv = VID_GetModePtr (mode); ! 1078: if (modelist[mode].type == MS_FULLDIB) ! 1079: { ! 1080: if (!leavecurrentmode) ! 1081: { ! 1082: sprintf(pinfo,"%s fullscreen", pv->modedesc); ! 1083: } ! 1084: else ! 1085: { ! 1086: sprintf (pinfo, "Desktop resolution (%dx%d)", ! 1087: modelist[MODE_FULLSCREEN_DEFAULT].width, ! 1088: modelist[MODE_FULLSCREEN_DEFAULT].height); ! 1089: } ! 1090: } ! 1091: else ! 1092: { ! 1093: if (modestate == MS_WINDOWED) ! 1094: sprintf(pinfo, "%s windowed", pv->modedesc); ! 1095: else ! 1096: sprintf(pinfo, "windowed"); ! 1097: } ! 1098: ! 1099: return pinfo; ! 1100: } ! 1101: ! 1102: ! 1103: /* ! 1104: ================= ! 1105: VID_DescribeCurrentMode_f ! 1106: ================= ! 1107: */ ! 1108: void VID_DescribeCurrentMode_f (void) ! 1109: { ! 1110: Con_Printf ("%s\n", VID_GetExtModeDescription (vid_modenum)); ! 1111: } ! 1112: ! 1113: ! 1114: /* ! 1115: ================= ! 1116: VID_NumModes_f ! 1117: ================= ! 1118: */ ! 1119: void VID_NumModes_f (void) ! 1120: { ! 1121: ! 1122: if (nummodes == 1) ! 1123: Con_Printf ("%d video mode is available\n", nummodes); ! 1124: else ! 1125: Con_Printf ("%d video modes are available\n", nummodes); ! 1126: } ! 1127: ! 1128: ! 1129: /* ! 1130: ================= ! 1131: VID_DescribeMode_f ! 1132: ================= ! 1133: */ ! 1134: void VID_DescribeMode_f (void) ! 1135: { ! 1136: int t, modenum; ! 1137: ! 1138: modenum = Q_atoi (Cmd_Argv(1)); ! 1139: ! 1140: t = leavecurrentmode; ! 1141: leavecurrentmode = 0; ! 1142: ! 1143: Con_Printf ("%s\n", VID_GetExtModeDescription (modenum)); ! 1144: ! 1145: leavecurrentmode = t; ! 1146: } ! 1147: ! 1148: ! 1149: /* ! 1150: ================= ! 1151: VID_DescribeModes_f ! 1152: ================= ! 1153: */ ! 1154: void VID_DescribeModes_f (void) ! 1155: { ! 1156: int i, lnummodes, t; ! 1157: char *pinfo; ! 1158: vmode_t *pv; ! 1159: ! 1160: lnummodes = VID_NumModes (); ! 1161: ! 1162: t = leavecurrentmode; ! 1163: leavecurrentmode = 0; ! 1164: ! 1165: for (i=1 ; i<lnummodes ; i++) ! 1166: { ! 1167: pv = VID_GetModePtr (i); ! 1168: pinfo = VID_GetExtModeDescription (i); ! 1169: Con_Printf ("%2d: %s\n", i, pinfo); ! 1170: } ! 1171: ! 1172: leavecurrentmode = t; ! 1173: } ! 1174: ! 1175: ! 1176: void VID_InitDIB (HINSTANCE hInstance) ! 1177: { ! 1178: WNDCLASS wc; ! 1179: HDC hdc; ! 1180: int i; ! 1181: ! 1182: /* Register the frame class */ ! 1183: wc.style = 0; ! 1184: wc.lpfnWndProc = (WNDPROC)MainWndProc; ! 1185: wc.cbClsExtra = 0; ! 1186: wc.cbWndExtra = 0; ! 1187: wc.hInstance = hInstance; ! 1188: wc.hIcon = 0; ! 1189: wc.hCursor = LoadCursor (NULL,IDC_ARROW); ! 1190: wc.hbrBackground = NULL; ! 1191: wc.lpszMenuName = 0; ! 1192: wc.lpszClassName = "WinQuake"; ! 1193: ! 1194: if (!RegisterClass (&wc) ) ! 1195: Sys_Error ("Couldn't register window class"); ! 1196: ! 1197: modelist[0].type = MS_WINDOWED; ! 1198: ! 1199: if (COM_CheckParm("-width")) ! 1200: modelist[0].width = Q_atoi(com_argv[COM_CheckParm("-width")+1]); ! 1201: else ! 1202: modelist[0].width = 640; ! 1203: ! 1204: if (modelist[0].width < 320) ! 1205: modelist[0].width = 320; ! 1206: ! 1207: if (COM_CheckParm("-height")) ! 1208: modelist[0].height= Q_atoi(com_argv[COM_CheckParm("-height")+1]); ! 1209: else ! 1210: modelist[0].height = modelist[0].width * 240/320; ! 1211: ! 1212: if (modelist[0].height < 240) ! 1213: modelist[0].height = 240; ! 1214: ! 1215: sprintf (modelist[0].modedesc, "%dx%d", ! 1216: modelist[0].width, modelist[0].height); ! 1217: ! 1218: modelist[0].modenum = MODE_WINDOWED; ! 1219: modelist[0].dib = 1; ! 1220: modelist[0].fullscreen = 0; ! 1221: modelist[0].halfscreen = 0; ! 1222: modelist[0].bpp = 0; ! 1223: ! 1224: nummodes = 1; ! 1225: } ! 1226: ! 1227: ! 1228: /* ! 1229: ================= ! 1230: VID_InitFullDIB ! 1231: ================= ! 1232: */ ! 1233: void VID_InitFullDIB (HINSTANCE hInstance) ! 1234: { ! 1235: DEVMODE devmode; ! 1236: int i, modenum, cmodes, originalnummodes, existingmode, numlowresmodes; ! 1237: int j, bpp, done; ! 1238: BOOL stat; ! 1239: ! 1240: // enumerate >8 bpp modes ! 1241: originalnummodes = nummodes; ! 1242: modenum = 0; ! 1243: ! 1244: do ! 1245: { ! 1246: stat = EnumDisplaySettings (NULL, modenum, &devmode); ! 1247: ! 1248: if ((devmode.dmBitsPerPel >= 15) && ! 1249: (devmode.dmPelsWidth <= MAXWIDTH) && ! 1250: (devmode.dmPelsHeight <= MAXHEIGHT) && ! 1251: (nummodes < MAX_MODE_LIST)) ! 1252: { ! 1253: devmode.dmFields = DM_BITSPERPEL | ! 1254: DM_PELSWIDTH | ! 1255: DM_PELSHEIGHT; ! 1256: ! 1257: if (ChangeDisplaySettings (&devmode, CDS_TEST | CDS_FULLSCREEN) == ! 1258: DISP_CHANGE_SUCCESSFUL) ! 1259: { ! 1260: modelist[nummodes].type = MS_FULLDIB; ! 1261: modelist[nummodes].width = devmode.dmPelsWidth; ! 1262: modelist[nummodes].height = devmode.dmPelsHeight; ! 1263: modelist[nummodes].modenum = 0; ! 1264: modelist[nummodes].halfscreen = 0; ! 1265: modelist[nummodes].dib = 1; ! 1266: modelist[nummodes].fullscreen = 1; ! 1267: modelist[nummodes].bpp = devmode.dmBitsPerPel; ! 1268: sprintf (modelist[nummodes].modedesc, "%dx%dx%d", ! 1269: devmode.dmPelsWidth, devmode.dmPelsHeight, ! 1270: devmode.dmBitsPerPel); ! 1271: ! 1272: // if the width is more than twice the height, reduce it by half because this ! 1273: // is probably a dual-screen monitor ! 1274: if (!COM_CheckParm("-noadjustaspect")) ! 1275: { ! 1276: if (modelist[nummodes].width > (modelist[nummodes].height << 1)) ! 1277: { ! 1278: modelist[nummodes].width >>= 1; ! 1279: modelist[nummodes].halfscreen = 1; ! 1280: sprintf (modelist[nummodes].modedesc, "%dx%dx%d", ! 1281: modelist[nummodes].width, ! 1282: modelist[nummodes].height, ! 1283: modelist[nummodes].bpp); ! 1284: } ! 1285: } ! 1286: ! 1287: for (i=originalnummodes, existingmode = 0 ; i<nummodes ; i++) ! 1288: { ! 1289: if ((modelist[nummodes].width == modelist[i].width) && ! 1290: (modelist[nummodes].height == modelist[i].height) && ! 1291: (modelist[nummodes].bpp == modelist[i].bpp)) ! 1292: { ! 1293: existingmode = 1; ! 1294: break; ! 1295: } ! 1296: } ! 1297: ! 1298: if (!existingmode) ! 1299: { ! 1300: nummodes++; ! 1301: } ! 1302: } ! 1303: } ! 1304: ! 1305: modenum++; ! 1306: } while (stat); ! 1307: ! 1308: // see if there are any low-res modes that aren't being reported ! 1309: numlowresmodes = sizeof(lowresmodes) / sizeof(lowresmodes[0]); ! 1310: bpp = 16; ! 1311: done = 0; ! 1312: ! 1313: do ! 1314: { ! 1315: for (j=0 ; (j<numlowresmodes) && (nummodes < MAX_MODE_LIST) ; j++) ! 1316: { ! 1317: devmode.dmBitsPerPel = bpp; ! 1318: devmode.dmPelsWidth = lowresmodes[j].width; ! 1319: devmode.dmPelsHeight = lowresmodes[j].height; ! 1320: devmode.dmFields = DM_BITSPERPEL | DM_PELSWIDTH | DM_PELSHEIGHT; ! 1321: ! 1322: if (ChangeDisplaySettings (&devmode, CDS_TEST | CDS_FULLSCREEN) == ! 1323: DISP_CHANGE_SUCCESSFUL) ! 1324: { ! 1325: modelist[nummodes].type = MS_FULLDIB; ! 1326: modelist[nummodes].width = devmode.dmPelsWidth; ! 1327: modelist[nummodes].height = devmode.dmPelsHeight; ! 1328: modelist[nummodes].modenum = 0; ! 1329: modelist[nummodes].halfscreen = 0; ! 1330: modelist[nummodes].dib = 1; ! 1331: modelist[nummodes].fullscreen = 1; ! 1332: modelist[nummodes].bpp = devmode.dmBitsPerPel; ! 1333: sprintf (modelist[nummodes].modedesc, "%dx%dx%d", ! 1334: devmode.dmPelsWidth, devmode.dmPelsHeight, ! 1335: devmode.dmBitsPerPel); ! 1336: ! 1337: for (i=originalnummodes, existingmode = 0 ; i<nummodes ; i++) ! 1338: { ! 1339: if ((modelist[nummodes].width == modelist[i].width) && ! 1340: (modelist[nummodes].height == modelist[i].height) && ! 1341: (modelist[nummodes].bpp == modelist[i].bpp)) ! 1342: { ! 1343: existingmode = 1; ! 1344: break; ! 1345: } ! 1346: } ! 1347: ! 1348: if (!existingmode) ! 1349: { ! 1350: nummodes++; ! 1351: } ! 1352: } ! 1353: } ! 1354: switch (bpp) ! 1355: { ! 1356: case 16: ! 1357: bpp = 32; ! 1358: break; ! 1359: ! 1360: case 32: ! 1361: bpp = 24; ! 1362: break; ! 1363: ! 1364: case 24: ! 1365: done = 1; ! 1366: break; ! 1367: } ! 1368: } while (!done); ! 1369: ! 1370: if (nummodes == originalnummodes) ! 1371: Con_SafePrintf ("No fullscreen DIB modes found\n"); ! 1372: } ! 1373: ! 1374: ! 1375: /* ! 1376: =================== ! 1377: VID_Init ! 1378: =================== ! 1379: */ ! 1380: void VID_Init (unsigned char *palette) ! 1381: { ! 1382: int i, existingmode; ! 1383: int basenummodes, width, height, bpp, findbpp, done; ! 1384: byte *ptmp; ! 1385: char gldir[MAX_OSPATH]; ! 1386: HDC hdc; ! 1387: DEVMODE devmode; ! 1388: ! 1389: Cvar_RegisterVariable (&vid_mode); ! 1390: Cvar_RegisterVariable (&vid_wait); ! 1391: Cvar_RegisterVariable (&vid_nopageflip); ! 1392: Cvar_RegisterVariable (&_vid_wait_override); ! 1393: Cvar_RegisterVariable (&_vid_default_mode); ! 1394: Cvar_RegisterVariable (&_vid_default_mode_win); ! 1395: Cvar_RegisterVariable (&vid_config_x); ! 1396: Cvar_RegisterVariable (&vid_config_y); ! 1397: Cvar_RegisterVariable (&vid_stretch_by_2); ! 1398: Cvar_RegisterVariable (&_windowed_mouse); ! 1399: Cvar_RegisterVariable (&gl_ztrick); ! 1400: ! 1401: Cmd_AddCommand ("vid_nummodes", VID_NumModes_f); ! 1402: Cmd_AddCommand ("vid_describecurrentmode", VID_DescribeCurrentMode_f); ! 1403: Cmd_AddCommand ("vid_describemode", VID_DescribeMode_f); ! 1404: Cmd_AddCommand ("vid_describemodes", VID_DescribeModes_f); ! 1405: ! 1406: hIcon = LoadIcon (global_hInstance, MAKEINTRESOURCE (IDI_ICON2)); ! 1407: ! 1408: VID_InitDIB (global_hInstance); ! 1409: basenummodes = nummodes = 1; ! 1410: ! 1411: VID_InitFullDIB (global_hInstance); ! 1412: ! 1413: if (COM_CheckParm("-window")) ! 1414: { ! 1415: hdc = GetDC (NULL); ! 1416: ! 1417: if (GetDeviceCaps(hdc, RASTERCAPS) & RC_PALETTE) ! 1418: { ! 1419: Sys_Error ("Can't run in non-RGB mode"); ! 1420: } ! 1421: ! 1422: ReleaseDC (NULL, hdc); ! 1423: ! 1424: windowed = true; ! 1425: ! 1426: vid_default = MODE_WINDOWED; ! 1427: } ! 1428: else ! 1429: { ! 1430: if (nummodes == 1) ! 1431: Sys_Error ("No RGB fullscreen modes available"); ! 1432: ! 1433: windowed = false; ! 1434: ! 1435: if (COM_CheckParm("-mode")) ! 1436: { ! 1437: vid_default = Q_atoi(com_argv[COM_CheckParm("-mode")+1]); ! 1438: } ! 1439: else ! 1440: { ! 1441: if (COM_CheckParm("-current")) ! 1442: { ! 1443: modelist[MODE_FULLSCREEN_DEFAULT].width = ! 1444: GetSystemMetrics (SM_CXSCREEN); ! 1445: modelist[MODE_FULLSCREEN_DEFAULT].height = ! 1446: GetSystemMetrics (SM_CYSCREEN); ! 1447: vid_default = MODE_FULLSCREEN_DEFAULT; ! 1448: leavecurrentmode = 1; ! 1449: } ! 1450: else ! 1451: { ! 1452: if (COM_CheckParm("-width")) ! 1453: { ! 1454: width = Q_atoi(com_argv[COM_CheckParm("-width")+1]); ! 1455: } ! 1456: else ! 1457: { ! 1458: width = 640; ! 1459: } ! 1460: ! 1461: if (COM_CheckParm("-bpp")) ! 1462: { ! 1463: bpp = Q_atoi(com_argv[COM_CheckParm("-bpp")+1]); ! 1464: findbpp = 0; ! 1465: } ! 1466: else ! 1467: { ! 1468: bpp = 15; ! 1469: findbpp = 1; ! 1470: } ! 1471: ! 1472: if (COM_CheckParm("-height")) ! 1473: height = Q_atoi(com_argv[COM_CheckParm("-height")+1]); ! 1474: ! 1475: // if they want to force it, add the specified mode to the list ! 1476: if (COM_CheckParm("-force") && (nummodes < MAX_MODE_LIST)) ! 1477: { ! 1478: modelist[nummodes].type = MS_FULLDIB; ! 1479: modelist[nummodes].width = width; ! 1480: modelist[nummodes].height = height; ! 1481: modelist[nummodes].modenum = 0; ! 1482: modelist[nummodes].halfscreen = 0; ! 1483: modelist[nummodes].dib = 1; ! 1484: modelist[nummodes].fullscreen = 1; ! 1485: modelist[nummodes].bpp = bpp; ! 1486: sprintf (modelist[nummodes].modedesc, "%dx%dx%d", ! 1487: devmode.dmPelsWidth, devmode.dmPelsHeight, ! 1488: devmode.dmBitsPerPel); ! 1489: ! 1490: for (i=nummodes, existingmode = 0 ; i<nummodes ; i++) ! 1491: { ! 1492: if ((modelist[nummodes].width == modelist[i].width) && ! 1493: (modelist[nummodes].height == modelist[i].height) && ! 1494: (modelist[nummodes].bpp == modelist[i].bpp)) ! 1495: { ! 1496: existingmode = 1; ! 1497: break; ! 1498: } ! 1499: } ! 1500: ! 1501: if (!existingmode) ! 1502: { ! 1503: nummodes++; ! 1504: } ! 1505: } ! 1506: ! 1507: done = 0; ! 1508: ! 1509: do ! 1510: { ! 1511: if (COM_CheckParm("-height")) ! 1512: { ! 1513: height = Q_atoi(com_argv[COM_CheckParm("-height")+1]); ! 1514: ! 1515: for (i=1, vid_default=0 ; i<nummodes ; i++) ! 1516: { ! 1517: if ((modelist[i].width == width) && ! 1518: (modelist[i].height == height) && ! 1519: (modelist[i].bpp == bpp)) ! 1520: { ! 1521: vid_default = i; ! 1522: done = 1; ! 1523: break; ! 1524: } ! 1525: } ! 1526: } ! 1527: else ! 1528: { ! 1529: for (i=1, vid_default=0 ; i<nummodes ; i++) ! 1530: { ! 1531: if ((modelist[i].width == width) && (modelist[i].bpp == bpp)) ! 1532: { ! 1533: vid_default = i; ! 1534: done = 1; ! 1535: break; ! 1536: } ! 1537: } ! 1538: } ! 1539: ! 1540: if (!done) ! 1541: { ! 1542: if (findbpp) ! 1543: { ! 1544: switch (bpp) ! 1545: { ! 1546: case 15: ! 1547: bpp = 16; ! 1548: break; ! 1549: case 16: ! 1550: bpp = 32; ! 1551: break; ! 1552: case 32: ! 1553: bpp = 24; ! 1554: break; ! 1555: case 24: ! 1556: done = 1; ! 1557: break; ! 1558: } ! 1559: } ! 1560: else ! 1561: { ! 1562: done = 1; ! 1563: } ! 1564: } ! 1565: } while (!done); ! 1566: ! 1567: if (!vid_default) ! 1568: { ! 1569: Sys_Error ("Specified video mode not available"); ! 1570: } ! 1571: } ! 1572: } ! 1573: } ! 1574: ! 1575: vid_initialized = true; ! 1576: ! 1577: vid.maxwarpwidth = WARP_WIDTH; ! 1578: vid.maxwarpheight = WARP_HEIGHT; ! 1579: vid.colormap = host_colormap; ! 1580: vid.fullbright = 256 - LittleLong (*((int *)vid.colormap + 2048)); ! 1581: ! 1582: DestroyWindow (hwnd_dialog); ! 1583: ! 1584: VID_SetMode (vid_default, palette); ! 1585: ! 1586: maindc = GetDC(mainwindow); ! 1587: bSetupPixelFormat(maindc); ! 1588: ! 1589: baseRC = wglCreateContext( maindc ); ! 1590: if (!baseRC) ! 1591: Sys_Error ("wglCreateContect failed"); ! 1592: if (!wglMakeCurrent( maindc, baseRC )) ! 1593: Sys_Error ("wglMakeCurrent failed"); ! 1594: ! 1595: GL_Init (); ! 1596: ! 1597: sprintf (gldir, "%s/glquake", com_gamedir); ! 1598: Sys_mkdir (gldir); ! 1599: ! 1600: vid_realmode = vid_modenum; ! 1601: ! 1602: VID_SetPalette (palette); ! 1603: ! 1604: vid_menudrawfn = VID_MenuDraw; ! 1605: vid_menukeyfn = VID_MenuKey; ! 1606: ! 1607: strcpy (badmode.modedesc, "Bad mode"); ! 1608: } ! 1609: ! 1610: ! 1611: //======================================================== ! 1612: // Video menu stuff ! 1613: //======================================================== ! 1614: ! 1615: extern void M_Menu_Options_f (void); ! 1616: extern void M_Print (int cx, int cy, char *str); ! 1617: extern void M_PrintWhite (int cx, int cy, char *str); ! 1618: extern void M_DrawCharacter (int cx, int line, int num); ! 1619: extern void M_DrawTransPic (int x, int y, qpic_t *pic); ! 1620: extern void M_DrawPic (int x, int y, qpic_t *pic); ! 1621: ! 1622: static int vid_line, vid_wmodes; ! 1623: ! 1624: typedef struct ! 1625: { ! 1626: int modenum; ! 1627: char *desc; ! 1628: int iscur; ! 1629: } modedesc_t; ! 1630: ! 1631: #define MAX_COLUMN_SIZE 9 ! 1632: #define MODE_AREA_HEIGHT (MAX_COLUMN_SIZE + 2) ! 1633: #define MAX_MODEDESCS (MAX_COLUMN_SIZE*3) ! 1634: ! 1635: static modedesc_t modedescs[MAX_MODEDESCS]; ! 1636: ! 1637: /* ! 1638: ================ ! 1639: VID_MenuDraw ! 1640: ================ ! 1641: */ ! 1642: void VID_MenuDraw (void) ! 1643: { ! 1644: qpic_t *p; ! 1645: char *ptr; ! 1646: int lnummodes, i, j, k, column, row, dup, dupmode; ! 1647: char temp[100]; ! 1648: vmode_t *pv; ! 1649: ! 1650: p = Draw_CachePic ("gfx/vidmodes.lmp"); ! 1651: M_DrawPic ( (320-p->width)/2, 4, p); ! 1652: ! 1653: vid_wmodes = 0; ! 1654: lnummodes = VID_NumModes (); ! 1655: ! 1656: for (i=1 ; (i<lnummodes) && (vid_wmodes < MAX_MODEDESCS) ; i++) ! 1657: { ! 1658: ptr = VID_GetModeDescription (i); ! 1659: pv = VID_GetModePtr (i); ! 1660: ! 1661: k = vid_wmodes; ! 1662: ! 1663: modedescs[k].modenum = i; ! 1664: modedescs[k].desc = ptr; ! 1665: modedescs[k].iscur = 0; ! 1666: ! 1667: if (i == vid_modenum) ! 1668: modedescs[k].iscur = 1; ! 1669: ! 1670: vid_wmodes++; ! 1671: ! 1672: } ! 1673: ! 1674: if (vid_wmodes > 0) ! 1675: { ! 1676: M_Print (2*8, 36+0*8, "Fullscreen Modes (WIDTHxHEIGHTxBPP)"); ! 1677: ! 1678: column = 8; ! 1679: row = 36+2*8; ! 1680: ! 1681: for (i=0 ; i<vid_wmodes ; i++) ! 1682: { ! 1683: if (modedescs[i].iscur) ! 1684: M_PrintWhite (column, row, modedescs[i].desc); ! 1685: else ! 1686: M_Print (column, row, modedescs[i].desc); ! 1687: ! 1688: column += 13*8; ! 1689: ! 1690: if ((i % VID_ROW_SIZE) == (VID_ROW_SIZE - 1)) ! 1691: { ! 1692: column = 8; ! 1693: row += 8; ! 1694: } ! 1695: } ! 1696: } ! 1697: ! 1698: M_Print (3*8, 36 + MODE_AREA_HEIGHT * 8 + 8*2, ! 1699: "Video modes must be set from the"); ! 1700: M_Print (3*8, 36 + MODE_AREA_HEIGHT * 8 + 8*3, ! 1701: "command line with -width <width>"); ! 1702: M_Print (3*8, 36 + MODE_AREA_HEIGHT * 8 + 8*4, ! 1703: "and -bpp <bits-per-pixel>"); ! 1704: M_Print (3*8, 36 + MODE_AREA_HEIGHT * 8 + 8*6, ! 1705: "Select windowed mode with -window"); ! 1706: } ! 1707: ! 1708: ! 1709: /* ! 1710: ================ ! 1711: VID_MenuKey ! 1712: ================ ! 1713: */ ! 1714: void VID_MenuKey (int key) ! 1715: { ! 1716: switch (key) ! 1717: { ! 1718: case K_ESCAPE: ! 1719: S_LocalSound ("misc/menu1.wav"); ! 1720: M_Menu_Options_f (); ! 1721: break; ! 1722: ! 1723: default: ! 1724: break; ! 1725: } ! 1726: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.