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