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