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