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