1 /*
2 * gl_vidamiga.c -- GL vid component for AmigaOS & variants.
3 * $Id: gl_vidamiga.c 6046 2018-06-02 08:52:39Z bszili $
4 *
5 * Copyright (C) 1996-1997 Id Software, Inc.
6 * Copyright (C) 1997-1998 Raven Software Corp.
7 * Copyright (C) 2004-2005 Steven Atkinson <stevenaaus@yahoo.com>
8 * Copyright (C) 2005-2016 O.Sezer <sezero@users.sourceforge.net>
9 * Copyright (C) 2012-2016 Szil�rd Bir� <col.lawrence@gmail.com>
10 *
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or (at
14 * your option) any later version.
15 *
16 * This program is distributed in the hope that it will be useful, but
17 * WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
19 *
20 * See the GNU General Public License for more details.
21 *
22 * You should have received a copy of the GNU General Public License along
23 * with this program; if not, write to the Free Software Foundation, Inc.,
24 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
25 */
26
27 #ifdef GL_DLSYM
28 #error GL_DLSYM not supported.
29 #endif
30 #define __GL_FUNC_EXTERN
31
32 #include <cybergraphx/cybergraphics.h>
33 #include <proto/exec.h>
34 #include <proto/intuition.h>
35 #include <proto/graphics.h>
36 #include <proto/cybergraphics.h>
37
38 #if defined(__AROS__) && defined(AROS_USE_GLA)
39 #include <GL/gla.h>
40 #elif defined(__AROS__)
41 #include <GL/arosmesa.h>
42 #elif defined __MORPHOS__
43 #include <intuition/intuitionbase.h>
44 #elif defined __amigaos4__
45 #error AmigaOS4 support not yet available
46 #elif defined(__AMIGA__) && defined(REFGL_MINIGL)
47 #include <mgl/gl.h>
48 #elif defined(__AMIGA__) && defined(REFGL_AMESA)
49 #include <GL/Amigamesa.h>
50 #else
51 #error Unknown / Unsupported AmigaOS variant.
52 #endif
53
54 #if defined(__AROS__) && defined(AROS_USE_GLA)
55 typedef GLAProc AMIGAGL_Proc;
56 #elif defined(__AROS__)
57 typedef AROSMesaProc AMIGAGL_Proc;
58 #else
59 typedef void (*AMIGAGL_Proc)();
60 #endif
61
62 #include "quakedef.h"
63 #include "cfgfile.h"
64 #include "bgmusic.h"
65 #include "cdaudio.h"
66 #include "filenames.h"
67
68 #include <SDI/SDI_compiler.h> /* IPTR */
69
70 #define WARP_WIDTH 320
71 #define WARP_HEIGHT 200
72 #define MAXWIDTH 10000
73 #define MAXHEIGHT 10000
74 #define MIN_WIDTH 320
75 //#define MIN_HEIGHT 200
76 #define MIN_HEIGHT 240
77 #define MAX_DESC 33
78
79 typedef struct {
80 modestate_t type;
81 int width;
82 int height;
83 int modenum;
84 int fullscreen;
85 int bpp;
86 /* int halfscreen;*/
87 char modedesc[MAX_DESC];
88 } vmode_t;
89
90 typedef struct {
91 int width;
92 int height;
93 } stdmode_t;
94
95 #define RES_640X480 3
96 static const stdmode_t std_modes[] = {
97 // NOTE: keep this list in order
98 {320, 240}, // 0
99 {400, 300}, // 1
100 {512, 384}, // 2
101 {640, 480}, // 3 == RES_640X480, this is our default, below
102 // this is the lowresmodes region.
103 // either do not change its order,
104 // or change the above define, too
105 {800, 600}, // 4, RES_640X480 + 1
106 {1024, 768}, // 5, RES_640X480 + 2
107 {1280, 1024}, // 6
108 {1600, 1200} // 7
109 };
110
111 #define MAX_MODE_LIST 128
112 #define MAX_STDMODES (sizeof(std_modes) / sizeof(std_modes[0]))
113 #define NUM_LOWRESMODES (RES_640X480)
114 static vmode_t fmodelist[MAX_MODE_LIST+1]; // list of enumerated fullscreen modes
115 static vmode_t wmodelist[MAX_STDMODES +1]; // list of standart 4:3 windowed modes
116 static vmode_t *modelist; // modelist in use, points to one of the above lists
117
118 static int num_fmodes;
119 static int num_wmodes;
120 static int *nummodes;
121 static int bpp = 16;
122
123 #if defined(H2W)
124 # define WM_TITLEBAR_TEXT "HexenWorld"
125 /*# define WM_ICON_TEXT "HexenWorld"*/
126 #else
127 # define WM_TITLEBAR_TEXT "Hexen II"
128 /*# define WM_ICON_TEXT "HEXEN2"*/
129 #endif
130
131 typedef struct {
132 int red,
133 green,
134 blue,
135 alpha,
136 depth,
137 stencil;
138 } attributes_t;
139 static attributes_t vid_attribs;
140
141 static void VID_KillContext (void);
142 struct Window *window = NULL; /* used by in_amiga.c */
143 static struct Screen *screen = NULL;
144 #if defined(__AROS__) && defined(AROS_USE_GLA)
145 static GLAContext context = NULL;
146 #elif defined(__AROS__)
147 static AROSMesaContext context = NULL;
148 #elif defined __MORPHOS__
149 GLContext *__tglContext = NULL;
150 static qboolean contextinit = false;
151 #elif defined(__AMIGA__) && defined(REFGL_MINIGL)
152 #ifdef __CLIB2__
153 struct GfxBase *GfxBase = NULL;
154 #endif
155 static int lockmode = MGL_LOCK_MANUAL;
156 static cvar_t gl_lockmode = {"gl_lockmode", "manual", CVAR_ARCHIVE};
157 #elif defined(__AMIGA__) && defined(REFGL_AMESA)
158 #ifdef __CLIB2__
159 struct GfxBase *GfxBase = NULL;
160 #endif
161 struct Library *CyberGfxBase = NULL;
162 static AmigaMesaContext context = NULL;
163 #endif
164 static qboolean vid_menu_fs;
165 static qboolean fs_toggle_works = false;
166
167 // vars for vid state
168 viddef_t vid; // global video state
169 modestate_t modestate = MS_UNINIT;
170 static int vid_default = -1; // modenum of 640x480 as a safe default
171 static int vid_modenum = -1; // current video mode, set after mode setting succeeds
172 static int vid_maxwidth = 640, vid_maxheight = 480;
173 static qboolean vid_conscale = false;
174 static int WRHeight, WRWidth;
175
176 static qboolean vid_initialized = false;
177 qboolean in_mode_set = false;
178
179 // cvar vid_mode must be set before calling
180 // VID_SetMode, VID_ChangeVideoMode or VID_Restart_f
181 static cvar_t vid_mode = {"vid_mode", "0", CVAR_NONE};
182 static cvar_t vid_config_consize = {"vid_config_consize", "640", CVAR_ARCHIVE};
183 static cvar_t vid_config_glx = {"vid_config_glx", "640", CVAR_ARCHIVE};
184 static cvar_t vid_config_gly = {"vid_config_gly", "480", CVAR_ARCHIVE};
185 #ifdef PLATFORM_AMIGAOS3
186 static cvar_t vid_config_fscr= {"vid_config_fscr", "1", CVAR_ARCHIVE};
187 #else
188 static cvar_t vid_config_fscr= {"vid_config_fscr", "0", CVAR_ARCHIVE};
189 #endif
190 // cvars for compatibility with the software version
191 static cvar_t vid_config_swx = {"vid_config_swx", "320", CVAR_ARCHIVE};
192 static cvar_t vid_config_swy = {"vid_config_swy", "240", CVAR_ARCHIVE};
193 static cvar_t vid_config_mon = {"vid_config_mon", "0", CVAR_ARCHIVE};
194
195 byte globalcolormap[VID_GRADES*256];
196 float RTint[256], GTint[256], BTint[256];
197 unsigned short d_8to16table[256];
198 unsigned int d_8to24table[256];
199 unsigned int d_8to24TranslucentTable[256];
200 unsigned char *inverse_pal;
201
202 // gl stuff
203 static void GL_Init (void);
204
205 static const char *gl_vendor;
206 static const char *gl_renderer;
207 static const char *gl_version;
208 static const char *gl_extensions;
209 qboolean is_3dfx = false;
210
211 GLint gl_max_size = 256;
212 static qboolean have_NPOT = false;
213 qboolean gl_tex_NPOT = false;
214 static cvar_t gl_texture_NPOT = {"gl_texture_NPOT", "0", CVAR_ARCHIVE};
215 GLfloat gl_max_anisotropy;
216 float gldepthmin, gldepthmax;
217
218 // palettized textures
219 static qboolean have8bit = false;
220 qboolean is8bit = false;
221 static cvar_t vid_config_gl8bit = {"vid_config_gl8bit", "0", CVAR_ARCHIVE};
222
223 static qboolean gammaworks = false; // whether hw-gamma works
224
225 // multitexturing
226 qboolean gl_mtexable = false;
227 static GLint num_tmus = 1;
228 static qboolean have_mtex = false;
229 static cvar_t gl_multitexture = {"gl_multitexture", "0", CVAR_ARCHIVE};
230
231 // stencil buffer
232 qboolean have_stencil = false;
233
234 // this is useless: things aren't like those in quake
235 //static qboolean fullsbardraw = false;
236
237 // menu drawing
238 static void VID_MenuDraw (void);
239 static void VID_MenuKey (int key);
240
241 // input stuff
242 static void ClearAllStates (void);
243 static int enable_mouse;
244 cvar_t _enable_mouse = {"_enable_mouse", "1", CVAR_ARCHIVE};
245
246
247 //====================================
248
GL_ParseExtensionList(const char * list,const char * name)249 static qboolean GL_ParseExtensionList (const char *list, const char *name)
250 {
251 const char *start;
252 const char *where, *terminator;
253
254 if (!list || !name || !*name)
255 return false;
256 if (strchr(name, ' ') != NULL)
257 return false; // extension names must not have spaces
258
259 start = list;
260 while (1) {
261 where = strstr (start, name);
262 if (!where)
263 break;
264 terminator = where + strlen (name);
265 if (where == start || where[-1] == ' ')
266 if (*terminator == ' ' || *terminator == '\0')
267 return true;
268 start = terminator;
269 }
270 return false;
271 }
272
273 //====================================
274
VID_LockBuffer(void)275 void VID_LockBuffer (void)
276 {
277 // nothing to do
278 }
279
VID_UnlockBuffer(void)280 void VID_UnlockBuffer (void)
281 {
282 // nothing to do
283 }
284
VID_HandlePause(qboolean paused)285 void VID_HandlePause (qboolean paused)
286 {
287 if (_enable_mouse.integer/* && (modestate == MS_WINDOWED)*/)
288 {
289 // for consistency, don't show pointer - S.A
290 if (paused)
291 {
292 IN_DeactivateMouse ();
293 // IN_ShowMouse ();
294 }
295 else
296 {
297 IN_ActivateMouse ();
298 // IN_HideMouse ();
299 }
300 }
301 }
302
303
304 //====================================
305
VID_ConWidth(int modenum)306 static void VID_ConWidth (int modenum)
307 {
308 int w, h;
309
310 if (!vid_conscale)
311 {
312 Cvar_SetValueQuick (&vid_config_consize, modelist[modenum].width);
313 return;
314 }
315
316 w = vid_config_consize.integer;
317 w &= ~7; /* make it a multiple of eight */
318 if (w < MIN_WIDTH)
319 w = MIN_WIDTH;
320 else if (w > modelist[modenum].width)
321 w = modelist[modenum].width;
322
323 h = w * modelist[modenum].height / modelist[modenum].width;
324 if (h < 200 /* MIN_HEIGHT */ ||
325 h > modelist[modenum].height || w > modelist[modenum].width)
326 {
327 vid_conscale = false;
328 Cvar_SetValueQuick (&vid_config_consize, modelist[modenum].width);
329 return;
330 }
331 vid.width = vid.conwidth = w;
332 vid.height = vid.conheight = h;
333 if (w != modelist[modenum].width)
334 vid_conscale = true;
335 else vid_conscale = false;
336 }
337
VID_ChangeConsize(int dir)338 void VID_ChangeConsize (int dir)
339 {
340 int w, h;
341
342 switch (dir)
343 {
344 case -1: /* smaller text */
345 w = ((float)vid.conwidth/(float)vid.width + 0.05f) * vid.width; /* use 0.10f increment ?? */
346 w &= ~7; /* make it a multiple of eight */
347 if (w > modelist[vid_modenum].width)
348 w = modelist[vid_modenum].width;
349 break;
350
351 case 1: /* bigger text */
352 w = ((float)vid.conwidth/(float)vid.width - 0.05f) * vid.width;
353 w &= ~7; /* make it a multiple of eight */
354 if (w < MIN_WIDTH)
355 w = MIN_WIDTH;
356 break;
357
358 default: /* bad key */
359 return;
360 }
361
362 h = w * modelist[vid_modenum].height / modelist[vid_modenum].width;
363 if (h < 200)
364 return;
365 vid.width = vid.conwidth = w;
366 vid.height = vid.conheight = h;
367 Cvar_SetValueQuick (&vid_config_consize, vid.conwidth);
368 vid.recalc_refdef = 1;
369 if (vid.conwidth != modelist[vid_modenum].width)
370 vid_conscale = true;
371 else vid_conscale = false;
372 }
373
VID_ReportConsize(void)374 float VID_ReportConsize(void)
375 {
376 return (float)modelist[vid_modenum].width/vid.conwidth;
377 }
378
379
VID_SetMode(int modenum)380 static qboolean VID_SetMode (int modenum)
381 {
382 ULONG flags;
383
384 in_mode_set = true;
385
386 VID_KillContext();
387
388 flags = WFLG_ACTIVATE | WFLG_RMBTRAP;
389
390 Con_SafePrintf ("Requested mode %d: %dx%dx%d\n", modenum, modelist[modenum].width, modelist[modenum].height, bpp);
391
392 #if defined(REFGL_MINIGL)
393 /* Hyperion's MiniGL 1.2 handles window creation within itself. */
394 if (vid_config_fscr.integer)
395 mglChooseWindowMode(GL_FALSE);
396 else mglChooseWindowMode(GL_TRUE );
397
398 #else /* ! REFGL_MINIGL */
399 if (vid_config_fscr.integer)
400 {
401 ULONG ModeID;
402
403 ModeID = BestCModeIDTags(
404 CYBRBIDTG_Depth, bpp,
405 CYBRBIDTG_NominalWidth, modelist[modenum].width,
406 CYBRBIDTG_NominalHeight, modelist[modenum].height,
407 TAG_DONE);
408
409 #ifndef __MORPHOS__
410 screen = OpenScreenTags(0,
411 ModeID != INVALID_ID ? SA_DisplayID : TAG_IGNORE, ModeID,
412 SA_Width, modelist[modenum].width,
413 SA_Height, modelist[modenum].height,
414 SA_Depth, bpp,
415 SA_Quiet, TRUE,
416 TAG_DONE);
417 #else
418 screen = OpenScreenTags(0,
419 ModeID != INVALID_ID ? SA_DisplayID : TAG_IGNORE, ModeID,
420 SA_Width, modelist[modenum].width,
421 SA_Height, modelist[modenum].height,
422 SA_Depth, bpp,
423 SA_Quiet, TRUE,
424 SA_GammaControl, TRUE,
425 SA_3DSupport, TRUE,
426 TAG_DONE);
427 #endif
428 }
429
430 if (screen)
431 {
432 flags |= WFLG_BACKDROP | WFLG_BORDERLESS;
433 }
434 else
435 {
436 Cvar_SetValueQuick (&vid_config_fscr, 0);
437 flags |= WFLG_DRAGBAR | WFLG_DEPTHGADGET | WFLG_CLOSEGADGET;
438 }
439
440 window = OpenWindowTags(0,
441 WA_InnerWidth, modelist[modenum].width,
442 WA_InnerHeight, modelist[modenum].height,
443 WA_Title, (IPTR)WM_TITLEBAR_TEXT,
444 WA_Flags, flags,
445 screen ? WA_CustomScreen : TAG_IGNORE, (IPTR)screen,
446 WA_IDCMP, IDCMP_CLOSEWINDOW | IDCMP_ACTIVEWINDOW | IDCMP_INACTIVEWINDOW,
447 TAG_DONE);
448
449 if (!window) goto fail;
450 #endif /* ! REFGL_MINIGL */
451
452 WRWidth = vid.width = vid.conwidth = modelist[modenum].width;
453 WRHeight = vid.height = vid.conheight = modelist[modenum].height;
454
455 #if defined(__AROS__) && defined(AROS_USE_GLA)
456 context = glACreateContextTags(
457 GLA_Window, window,
458 GLA_Left, screen ? 0 : window->BorderLeft,
459 GLA_Top, screen ? 0 : window->BorderTop,
460 GLA_Width, vid.width,
461 GLA_Height, vid.height,
462 screen ? GLA_Screen : TAG_IGNORE, screen,
463 GLA_DoubleBuf, GL_TRUE,
464 GLA_RGBMode, GL_TRUE,
465 GLA_NoAccum, GL_TRUE,
466 TAG_DONE);
467
468 if (!context) goto fail;
469 glAMakeCurrent(context);
470
471 #elif defined(__AROS__)
472 context = AROSMesaCreateContextTags(
473 AMA_Window, window,
474 AMA_Left, screen ? 0 : window->BorderLeft,
475 AMA_Top, screen ? 0 : window->BorderTop,
476 AMA_Width, vid.width,
477 AMA_Height, vid.height,
478 screen ? AMA_Screen : TAG_IGNORE, screen,
479 AMA_DoubleBuf, GL_TRUE,
480 AMA_RGBMode, GL_TRUE,
481 AMA_NoAccum, GL_TRUE,
482 TAG_DONE);
483
484 if (!context) goto fail;
485 AROSMesaMakeCurrent(context);
486
487 #elif defined __MORPHOS__
488 __tglContext = GLInit();
489 if (!__tglContext) goto fail;
490 if (screen && !(TinyGLBase->lib_Version == 0 && TinyGLBase->lib_Revision < 4)) {
491 if (!(contextinit = glAInitializeContextScreen(screen)))
492 goto fail;
493 } else {
494 if (!(contextinit = glAInitializeContextWindowed(window)))
495 goto fail;
496 }
497
498 #elif defined(__AMIGA__) && defined(REFGL_MINIGL)
499 if (!mglCreateContext(0,0,vid.width,vid.height))
500 goto fail;
501 mglLockMode(lockmode);
502 window = MGLGetWindowHandle(mini_CurrentContext);
503 ModifyIDCMP(window, IDCMP_CLOSEWINDOW | IDCMP_ACTIVEWINDOW | IDCMP_INACTIVEWINDOW);
504
505 #elif defined(__AMIGA__) && defined(REFGL_AMESA)
506 context = AmigaMesaCreateContextTags(
507 AMA_Window, window,
508 AMA_Left, screen ? 0 : window->BorderLeft,
509 AMA_Bottom, screen ? 0 : window->BorderBottom,
510 AMA_Width, vid.width,
511 AMA_Height, vid.height,
512 screen ? AMA_Screen : TAG_IGNORE, screen,
513 AMA_DoubleBuf, GL_TRUE,
514 AMA_RGBMode, GL_TRUE,
515 AMA_NoAccum, GL_TRUE,
516 TAG_DONE);
517
518 if (!context) goto fail;
519 AmigaMesaMakeCurrent(context, context->buffer);
520 #endif
521
522 vid.height = vid.conheight = modelist[modenum].height;
523 vid.rowbytes = vid.conrowbytes = vid.width = vid.conwidth = modelist[modenum].width;
524
525 // set vid_modenum properly and adjust other vars
526 vid_modenum = modenum;
527 modestate = (screen) ? MS_FULLDIB : MS_WINDOWED;
528 Cvar_SetValueQuick (&vid_config_glx, modelist[vid_modenum].width);
529 Cvar_SetValueQuick (&vid_config_gly, modelist[vid_modenum].height);
530
531 // setup the effective console width
532 VID_ConWidth(modenum);
533
534 Con_SafePrintf ("Video Mode Set : %dx%dx%d\n", modelist[modenum].width, modelist[modenum].height, bpp);
535
536 //IN_HideMouse ();
537
538 in_mode_set = false;
539
540 return true;
541
542 fail:
543 VID_KillContext();
544
545 in_mode_set = false;
546
547 return false;
548 }
549
550
551 //====================================
552
553 #if defined(__AROS__) && defined(AROS_USE_GLA)
AMIGAGL_GetProcAddress(const char * s)554 static AMIGAGL_Proc AMIGAGL_GetProcAddress (const char *s)
555 {
556 return glAGetProcAddress((const GLubyte *) s);
557 }
558
559 #elif defined(__AROS__)
AMIGAGL_GetProcAddress(const char * s)560 static AMIGAGL_Proc AMIGAGL_GetProcAddress (const char *s)
561 {
562 return AROSMesaGetProcAddress((const GLubyte *) s);
563 }
564
565 #elif defined(__MORPHOS__)
MY_glMultiTexCoord2fARB(GLenum unit,GLfloat s,GLfloat t)566 static void MY_glMultiTexCoord2fARB (GLenum unit, GLfloat s, GLfloat t)
567 {
568 GLMultiTexCoord2fARB(__tglContext, unit, s, t);
569 }
570
MY_glActiveTextureARB(GLenum unit)571 static void MY_glActiveTextureARB (GLenum unit)
572 {
573 GLActiveTextureARB(__tglContext, unit);
574 }
575
AMIGAGL_GetProcAddress(const char * s)576 static AMIGAGL_Proc AMIGAGL_GetProcAddress (const char *s)
577 {
578 if (strcmp(s, "glMultiTexCoord2fARB") == 0)
579 return (AMIGAGL_Proc)MY_glMultiTexCoord2fARB;
580 if (strcmp(s, "glActiveTextureARB") == 0)
581 return (AMIGAGL_Proc)MY_glActiveTextureARB;
582
583 return NULL;
584 }
585
586 #elif defined(__AMIGA__) && defined(REFGL_MINIGL)
MY_glMultiTexCoord2fARB(GLenum unit,GLfloat s,GLfloat t)587 static void MY_glMultiTexCoord2fARB (GLenum unit, GLfloat s, GLfloat t)
588 {
589 GLMultiTexCoord2fARB(mini_CurrentContext, unit, s, t);
590 }
591
MY_glActiveTextureARB(GLenum unit)592 static void MY_glActiveTextureARB (GLenum unit)
593 {
594 GLActiveTextureARB(mini_CurrentContext, unit);
595 }
596
AMIGAGL_GetProcAddress(const char * s)597 static AMIGAGL_Proc AMIGAGL_GetProcAddress (const char *s)
598 {
599 if (strcmp(s, "glMultiTexCoord2fARB") == 0)
600 return (AMIGAGL_Proc)MY_glMultiTexCoord2fARB;
601 if (strcmp(s, "glActiveTextureARB") == 0)
602 return (AMIGAGL_Proc)MY_glActiveTextureARB;
603
604 return NULL;
605 }
606
607 #elif defined(__AMIGA__) && defined(REFGL_AMESA)
608 /* NOTE: StormMesa 3.0 has EXT_multitexture, not ARB_multitexture.. */
609 /* 250 == ( GL_TEXTURE0_ARB - GL_TEXTURE0_EXT ) */
MY_glMultiTexCoord2fARB(GLenum unit,GLfloat s,GLfloat t)610 static void MY_glMultiTexCoord2fARB (GLenum unit, GLfloat s, GLfloat t)
611 {
612 glMultiTexCoord2fEXT (unit - 250, s, t);
613 }
614
MY_glActiveTextureARB(GLenum unit)615 static void MY_glActiveTextureARB (GLenum unit)
616 {
617 glSelectTextureEXT (unit - 250);
618 }
619
MY_glColorTableEXT(GLenum target,GLenum internalfmt,GLsizei width,GLenum format,GLenum type,const GLvoid * table)620 static void MY_glColorTableEXT (GLenum target, GLenum internalfmt, GLsizei width, GLenum format, GLenum type, const GLvoid *table)
621 {
622 glColorTableEXT (target, internalfmt, width, format, type, table);
623 }
624
MY_glGetTexParameterfv(GLenum target,GLenum pname,GLfloat * params)625 static void MY_glGetTexParameterfv (GLenum target, GLenum pname, GLfloat *params)
626 {
627 glGetTexParameterfv (target, pname, params);
628 }
629
AMIGAGL_GetProcAddress(const char * s)630 static AMIGAGL_Proc AMIGAGL_GetProcAddress (const char *s)
631 {
632 if (strcmp(s, "glMultiTexCoord2fARB") == 0)
633 return (AMIGAGL_Proc)MY_glMultiTexCoord2fARB;
634 if (strcmp(s, "glActiveTextureARB") == 0)
635 return (AMIGAGL_Proc)MY_glActiveTextureARB;
636 if (strcmp(s, "glColorTableEXT") == 0)
637 return (AMIGAGL_Proc)MY_glColorTableEXT;
638 if (strcmp(s, "glGetTexParameterfv") == 0)
639 return (AMIGAGL_Proc)MY_glGetTexParameterfv;
640
641 return NULL;
642 }
643 #endif
644
645 #if 0 /* No.. */
646 static void CheckSetGlobalPalette (void)
647 {
648 gl3DfxSetPaletteEXT_f gl3DfxSetPaletteEXT_fp;
649
650 if (GL_ParseExtensionList(gl_extensions, "3DFX_set_global_palette"))
651 {
652 gl3DfxSetPaletteEXT_fp = (gl3DfxSetPaletteEXT_f) AMIGAGL_GetProcAddress("gl3DfxSetPaletteEXT");
653 if (!gl3DfxSetPaletteEXT_fp)
654 gl3DfxSetPaletteEXT_fp = (gl3DfxSetPaletteEXT_f) AMIGAGL_GetProcAddress("3DFX_set_global_palette");
655 if (!gl3DfxSetPaletteEXT_fp)
656 return;
657 Con_SafePrintf("Found 3DFX_set_global_palette\n");
658 }
659 else if (GL_ParseExtensionList(gl_extensions, "POWERVR_set_global_palette"))
660 {
661 gl3DfxSetPaletteEXT_fp = (gl3DfxSetPaletteEXT_f) AMIGAGL_GetProcAddress("glSetGlobalPalettePOWERVR");
662 if (!gl3DfxSetPaletteEXT_fp)
663 gl3DfxSetPaletteEXT_fp = (gl3DfxSetPaletteEXT_f) AMIGAGL_GetProcAddress("POWERVR_set_global_palette");
664 if (!gl3DfxSetPaletteEXT_fp)
665 return;
666 Con_SafePrintf("Found POWERVR_set_global_palette\n");
667 }
668 else {
669 return;
670 }
671
672 have8bit = true;
673 if (!vid_config_gl8bit.integer)
674 return;
675 else
676 {
677 int i;
678 GLubyte table[256][4];
679 char *oldpal;
680
681 is8bit = true;
682 oldpal = (char *) d_8to24table;
683 for (i = 0; i < 256; i++) {
684 table[i][2] = *oldpal++;
685 table[i][1] = *oldpal++;
686 table[i][0] = *oldpal++;
687 table[i][3] = 255;
688 oldpal++;
689 }
690 glEnable_fp (GL_SHARED_TEXTURE_PALETTE_EXT);
691 gl3DfxSetPaletteEXT_fp ((GLuint *)table);
692 }
693 }
694 #endif /* #if 0 */
695
CheckSharedTexturePalette(void)696 static void CheckSharedTexturePalette (void)
697 {
698 glColorTableEXT_f glColorTableEXT_fp;
699
700 if (!GL_ParseExtensionList(gl_extensions, "GL_EXT_shared_texture_palette"))
701 return;
702
703 glColorTableEXT_fp = (glColorTableEXT_f) AMIGAGL_GetProcAddress("glColorTableEXT");
704 if (glColorTableEXT_fp == NULL)
705 return;
706
707 have8bit = true;
708 Con_SafePrintf("Found GL_EXT_shared_texture_palette\n");
709 if (!vid_config_gl8bit.integer)
710 return;
711 else
712 {
713 int i;
714 char thePalette[256*3];
715 char *oldPalette, *newPalette;
716
717 is8bit = true;
718 oldPalette = (char *) d_8to24table;
719 newPalette = thePalette;
720 for (i = 0; i < 256; i++) {
721 *newPalette++ = *oldPalette++;
722 *newPalette++ = *oldPalette++;
723 *newPalette++ = *oldPalette++;
724 oldPalette++;
725 }
726
727 glEnable_fp (GL_SHARED_TEXTURE_PALETTE_EXT);
728 glColorTableEXT_fp (GL_SHARED_TEXTURE_PALETTE_EXT, GL_RGB, 256,
729 GL_RGB, GL_UNSIGNED_BYTE, (void *) thePalette);
730 }
731 }
732
VID_Init8bitPalette(void)733 static void VID_Init8bitPalette (void)
734 {
735 have8bit = false;
736 is8bit = false;
737
738 /* Check for 8bit Extensions and initialize them */
739 CheckSharedTexturePalette();
740 #if 0 /* No.. */
741 if (!have8bit)
742 CheckSetGlobalPalette();
743 #endif
744
745 if (is8bit)
746 Con_SafePrintf("8-bit palettized textures enabled\n");
747 }
748
749
VID_InitGamma(void)750 static void VID_InitGamma (void)
751 {
752 gammaworks = false;
753
754 #ifdef __MORPHOS__
755 if (screen && (IntuitionBase->LibNode.lib_Version > 50 ||
756 (IntuitionBase->LibNode.lib_Version == 50 && IntuitionBase->LibNode.lib_Revision >= 74)))
757 gammaworks = true;
758 #endif
759
760 if (!gammaworks)
761 Con_SafePrintf("gamma adjustment not available\n");
762 }
763
VID_ShiftPalette(const unsigned char * palette)764 void VID_ShiftPalette (const unsigned char *palette)
765 {
766 #ifdef __MORPHOS__
767 if (screen)
768 {
769 SetAttrs(screen,
770 SA_GammaRed, gammatable,
771 SA_GammaGreen, gammatable,
772 SA_GammaBlue, gammatable,
773 TAG_DONE);
774 }
775 #endif
776 }
777
778
CheckMultiTextureExtensions(void)779 static void CheckMultiTextureExtensions (void)
780 {
781 gl_mtexable = have_mtex = false;
782
783 if (COM_CheckParm("-nomtex"))
784 {
785 Con_SafePrintf("Multitexture extensions disabled\n");
786 }
787 #if defined (REFGL_AMESA) /* StormMesa 3.0 has EXT_multitexture .. */
788 else if (GL_ParseExtensionList(gl_extensions, "GL_EXT_multitexture"))
789 #else
790 else if (GL_ParseExtensionList(gl_extensions, "GL_ARB_multitexture"))
791 #endif
792 {
793 Con_SafePrintf("ARB Multitexture extensions found\n");
794
795 #if defined (REFGL_AMESA)
796 glGetIntegerv_fp(GL_MAX_TEXTURES_EXT, &num_tmus);
797 #else
798 glGetIntegerv_fp(GL_MAX_TEXTURE_UNITS_ARB, &num_tmus);
799 #endif
800 if (num_tmus < 2)
801 {
802 Con_SafePrintf("ignoring multitexture (%i TMUs)\n", (int) num_tmus);
803 return;
804 }
805
806 glMultiTexCoord2fARB_fp = (glMultiTexCoord2fARB_f) AMIGAGL_GetProcAddress("glMultiTexCoord2fARB");
807 glActiveTextureARB_fp = (glActiveTextureARB_f) AMIGAGL_GetProcAddress("glActiveTextureARB");
808 if (glMultiTexCoord2fARB_fp == NULL || glActiveTextureARB_fp == NULL)
809 {
810 Con_SafePrintf ("Couldn't link to multitexture functions\n");
811 return;
812 }
813
814 have_mtex = true;
815 if (!gl_multitexture.integer)
816 {
817 Con_SafePrintf("ignoring multitexture (cvar disabled)\n");
818 return;
819 }
820
821 Con_SafePrintf("Found %i TMUs support\n", (int) num_tmus);
822 gl_mtexable = true;
823 glDisable_fp(GL_TEXTURE_2D);
824 glActiveTextureARB_fp(GL_TEXTURE0_ARB);
825 }
826 else
827 {
828 Con_SafePrintf("GL_ARB_multitexture not found\n");
829 }
830 }
831
CheckAnisotropyExtensions(void)832 static void CheckAnisotropyExtensions (void)
833 {
834 gl_max_anisotropy = 1;
835
836 Con_SafePrintf("Anisotropic filtering ");
837 if (GL_ParseExtensionList(gl_extensions, "GL_EXT_texture_filter_anisotropic"))
838 {
839 GLfloat test1 = 0, test2 = 0;
840 GLuint tex;
841 glGetTexParameterfv_f glGetTexParameterfv_fp;
842
843 glGetTexParameterfv_fp = (glGetTexParameterfv_f) AMIGAGL_GetProcAddress("glGetTexParameterfv");
844 if (glGetTexParameterfv_fp == NULL)
845 {
846 Con_SafePrintf("... can't check driver-lock status\n... ");
847 goto _skiptest;
848 }
849 // test to make sure we really have control over it
850 // 1.0 and 2.0 should always be legal values.
851 glGenTextures_fp(1, &tex);
852 glBindTexture_fp(GL_TEXTURE_2D, tex);
853 glTexParameterf_fp(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, 1.0f);
854 glGetTexParameterfv_fp(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, &test1);
855 glTexParameterf_fp(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, 2.0f);
856 glGetTexParameterfv_fp(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, &test2);
857 glDeleteTextures_fp(1, &tex);
858 if (test1 != 1 || test2 != 2)
859 {
860 Con_SafePrintf("driver-locked @ %.1f\n", test1);
861 }
862 else
863 {
864 _skiptest:
865 glGetFloatv_fp(GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, &gl_max_anisotropy);
866 if (gl_max_anisotropy < 2)
867 Con_SafePrintf("broken\n");
868 else Con_SafePrintf("found, max %.1f\n", gl_max_anisotropy);
869 }
870 }
871 else
872 {
873 Con_SafePrintf("not found\n");
874 }
875 }
876
CheckNonPowerOfTwoTextures(void)877 static void CheckNonPowerOfTwoTextures (void)
878 {
879 /* On Mac OS X, old Radeons lie about NPOT textures capability, they
880 * fallback to software with mipmap NPOT textures. see, e.g.:
881 * http://lists.apple.com/archives/mac-opengl/2006/Dec/msg00000.html
882 * http://lists.apple.com/archives/mac-opengl/2009/Oct/msg00040.html
883 * http://www.idevgames.com/forums/printthread.php?tid=3814&page=2
884 * MH says NVIDIA once did the same with their GeForce FX on Windows:
885 * http://forums.inside3d.com/viewtopic.php?f=10&t=4832
886 * Therefore, advertisement of this extension is an unreliable way of
887 * detecting the actual capability.
888 */
889 gl_tex_NPOT = have_NPOT = false;
890 if (GL_ParseExtensionList(gl_extensions, "GL_ARB_texture_non_power_of_two"))
891 {
892 have_NPOT = true;
893 Con_SafePrintf("Found ARB_texture_non_power_of_two\n");
894 if (!gl_texture_NPOT.integer) {
895 Con_SafePrintf("ignoring texture_NPOT (cvar disabled)\n");
896 }
897 else {
898 gl_tex_NPOT = true;
899 }
900 }
901 else
902 {
903 Con_SafePrintf("GL_ARB_texture_non_power_of_two not found\n");
904 }
905 }
906
CheckStencilBuffer(void)907 static void CheckStencilBuffer (void)
908 {
909 have_stencil = !!vid_attribs.stencil;
910 }
911
GL_ResetFunctions(void)912 static void GL_ResetFunctions (void)
913 {
914 #define GL_FUNCTION_OPT(ret, func, params) \
915 func##_fp = NULL;
916 #include "gl_func.h"
917
918 have_stencil = false;
919 gl_mtexable = false;
920 have_mtex = false;
921 have8bit = false;
922 is8bit = false;
923 have_NPOT = false;
924 gl_tex_NPOT = false;
925 }
926
927 /*
928 ===============
929 GL_Init
930 ===============
931 */
GL_Init(void)932 static void GL_Init (void)
933 {
934 // collect the visual attributes
935 memset (&vid_attribs, 0, sizeof(attributes_t));
936 glGetIntegerv_fp(GL_RED_BITS, &vid_attribs.red);
937 glGetIntegerv_fp(GL_GREEN_BITS, &vid_attribs.green);
938 glGetIntegerv_fp(GL_BLUE_BITS, &vid_attribs.blue);
939 glGetIntegerv_fp(GL_ALPHA_BITS, &vid_attribs.alpha);
940 glGetIntegerv_fp(GL_DEPTH_BITS, &vid_attribs.depth);
941 glGetIntegerv_fp(GL_STENCIL_BITS, &vid_attribs.stencil);
942 Con_SafePrintf ("R:%d G:%d B:%d A:%d, Z:%d, S:%d\n",
943 vid_attribs.red, vid_attribs.green, vid_attribs.blue, vid_attribs.alpha,
944 vid_attribs.depth, vid_attribs.stencil);
945
946 gl_vendor = (const char *)glGetString_fp (GL_VENDOR);
947 Con_SafePrintf ("GL_VENDOR: %s\n", gl_vendor);
948 gl_renderer = (const char *)glGetString_fp (GL_RENDERER);
949 Con_SafePrintf ("GL_RENDERER: %s\n", gl_renderer);
950
951 gl_version = (const char *)glGetString_fp (GL_VERSION);
952 Con_SafePrintf ("GL_VERSION: %s\n", gl_version);
953 gl_extensions = (const char *)glGetString_fp (GL_EXTENSIONS);
954 Con_SafeDPrintf ("GL_EXTENSIONS: %s\n", gl_extensions);
955
956 glGetIntegerv_fp(GL_MAX_TEXTURE_SIZE, &gl_max_size);
957 if (gl_max_size < 256) // Refuse to work when less than 256
958 Sys_Error ("hardware capable of min. 256k opengl texture size needed");
959 Con_SafePrintf("OpenGL max.texture size: %i\n", (int) gl_max_size);
960
961 CheckMultiTextureExtensions();
962 CheckAnisotropyExtensions();
963 CheckNonPowerOfTwoTextures();
964 CheckStencilBuffer();
965
966 glClearColor_fp (1,0,0,0);
967 glCullFace_fp(GL_FRONT);
968 glEnable_fp(GL_TEXTURE_2D);
969
970 glEnable_fp(GL_ALPHA_TEST);
971 glAlphaFunc_fp(GL_GREATER, 0.632); // 1 - e^-1 : replaced 0.666 to avoid clipping of smaller fonts/graphics
972 #if 0 /* causes side effects at least in 16 bpp. */
973 /* Get rid of Z-fighting for textures by offsetting the
974 * drawing of entity models compared to normal polygons.
975 * (See: R_DrawBrushModel.)
976 * (Only works if gl_ztrick is turned off) */
977 #if defined(__AMIGA__) && defined(REFGL_MINIGL)
978 #error port to use mglSetZOffset() instead of glPolygonOffset()
979 #else
980 glPolygonOffset_fp(0.05f, 25.0f);
981 #endif
982 #endif /* #if 0 */
983 glPolygonMode_fp (GL_FRONT_AND_BACK, GL_FILL);
984 glShadeModel_fp (GL_FLAT);
985
986 glTexParameterf_fp(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
987 glTexParameterf_fp(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
988
989 glTexParameterf_fp(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
990 glTexParameterf_fp(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
991
992 glBlendFunc_fp (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
993
994 // glTexEnvf_fp(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
995 glTexEnvf_fp(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
996
997 #if defined(__AMIGA__) && defined(REFGL_MINIGL)
998 glHint_fp (GL_PERSPECTIVE_CORRECTION_HINT, GL_FASTEST);
999 #endif
1000 }
1001
1002 /*
1003 =================
1004 GL_BeginRendering
1005 =================
1006 */
GL_BeginRendering(int * x,int * y,int * width,int * height)1007 void GL_BeginRendering (int *x, int *y, int *width, int *height)
1008 {
1009 *x = *y = 0;
1010 *width = WRWidth;
1011 *height = WRHeight;
1012
1013 // glViewport_fp (*x, *y, *width, *height);
1014 #if defined(__AMIGA__) && defined(REFGL_MINIGL)
1015 mglLockDisplay();
1016 #endif
1017 }
1018
1019
GL_EndRendering(void)1020 void GL_EndRendering (void)
1021 {
1022 if (!scr_skipupdate)
1023 #if defined(__AROS__) && defined(AROS_USE_GLA)
1024 glASwapBuffers(context);
1025 #elif defined(__AROS__)
1026 AROSMesaSwapBuffers(context);
1027 #elif defined __MORPHOS__
1028 glASwapBuffers();
1029 //GLASwapBuffers(__tglContext);
1030 #elif defined(__AMIGA__) && defined(REFGL_MINIGL)
1031 mglSwitchDisplay(); //performs unlock
1032 #elif defined(__AMIGA__) && defined(REFGL_AMESA)
1033 AmigaMesaSwapBuffers(context);
1034 #endif
1035
1036 // handle the mouse state when windowed if that's changed
1037 if (_enable_mouse.integer != enable_mouse /*&& modestate == MS_WINDOWED*/)
1038 {
1039 if (_enable_mouse.integer)
1040 IN_ActivateMouse ();
1041 else IN_DeactivateMouse ();
1042
1043 enable_mouse = _enable_mouse.integer;
1044 }
1045
1046 // if (fullsbardraw)
1047 // Sbar_Changed();
1048 }
1049
1050
1051 const int ColorIndex[16] = {
1052 0, 31, 47, 63, 79, 95, 111, 127, 143, 159, 175, 191, 199, 207, 223, 231
1053 };
1054
1055 const unsigned int ColorPercent[16] = {
1056 25, 51, 76, 102, 114, 127, 140, 153, 165, 178, 191, 204, 216, 229, 237, 247
1057 };
1058
1059 #define INVERSE_PALNAME "gfx/invpal.lmp"
ConvertTrueColorToPal(const unsigned char * true_color,const unsigned char * palette)1060 static int ConvertTrueColorToPal (const unsigned char *true_color, const unsigned char *palette)
1061 {
1062 int i;
1063 long min_dist;
1064 int min_index;
1065 long r, g, b;
1066
1067 min_dist = 256 * 256 + 256 * 256 + 256 * 256;
1068 min_index = -1;
1069 r = (long) true_color[0];
1070 g = (long) true_color[1];
1071 b = (long) true_color[2];
1072
1073 for (i = 0; i < 256; i++)
1074 {
1075 long palr, palg, palb, dist;
1076 long dr, dg, db;
1077
1078 palr = palette[3*i];
1079 palg = palette[3*i+1];
1080 palb = palette[3*i+2];
1081 dr = palr - r;
1082 dg = palg - g;
1083 db = palb - b;
1084 dist = dr * dr + dg * dg + db * db;
1085 if (dist < min_dist)
1086 {
1087 min_dist = dist;
1088 min_index = i;
1089 }
1090 }
1091 return min_index;
1092 }
1093
VID_CreateInversePalette(const unsigned char * palette)1094 static void VID_CreateInversePalette (const unsigned char *palette)
1095 {
1096 long r, g, b;
1097 long idx = 0;
1098 unsigned char true_color[3];
1099
1100 Con_SafePrintf ("Creating inverse palette\n");
1101
1102 for (r = 0; r < (1 << INVERSE_PAL_R_BITS); r++)
1103 {
1104 for (g = 0; g < (1 << INVERSE_PAL_G_BITS); g++)
1105 {
1106 for (b = 0; b < (1 << INVERSE_PAL_B_BITS); b++)
1107 {
1108 true_color[0] = (unsigned char)(r << (8 - INVERSE_PAL_R_BITS));
1109 true_color[1] = (unsigned char)(g << (8 - INVERSE_PAL_G_BITS));
1110 true_color[2] = (unsigned char)(b << (8 - INVERSE_PAL_B_BITS));
1111 inverse_pal[idx] = ConvertTrueColorToPal(true_color, palette);
1112 idx++;
1113 }
1114 }
1115 }
1116
1117 FS_CreatePath(FS_MakePath(FS_USERDIR, NULL, INVERSE_PALNAME));
1118 FS_WriteFile (INVERSE_PALNAME, inverse_pal, INVERSE_PAL_SIZE);
1119 }
1120
VID_InitPalette(const unsigned char * palette)1121 static void VID_InitPalette (const unsigned char *palette)
1122 {
1123 const unsigned char *pal;
1124 unsigned short r, g, b;
1125 unsigned short i, p, c;
1126 unsigned int v, *table;
1127 int mark;
1128
1129 #if ENDIAN_RUNTIME_DETECT
1130 switch (host_byteorder)
1131 {
1132 case BIG_ENDIAN: /* R G B A */
1133 MASK_r = 0xff000000;
1134 MASK_g = 0x00ff0000;
1135 MASK_b = 0x0000ff00;
1136 MASK_a = 0x000000ff;
1137 SHIFT_r = 24;
1138 SHIFT_g = 16;
1139 SHIFT_b = 8;
1140 SHIFT_a = 0;
1141 break;
1142 case LITTLE_ENDIAN: /* A B G R */
1143 MASK_r = 0x000000ff;
1144 MASK_g = 0x0000ff00;
1145 MASK_b = 0x00ff0000;
1146 MASK_a = 0xff000000;
1147 SHIFT_r = 0;
1148 SHIFT_g = 8;
1149 SHIFT_b = 16;
1150 SHIFT_a = 24;
1151 break;
1152 default:
1153 break;
1154 }
1155 MASK_rgb = (MASK_r|MASK_g|MASK_b);
1156 #endif /* ENDIAN_RUNTIME_DETECT */
1157
1158 //
1159 // 8 8 8 encoding
1160 //
1161 pal = palette;
1162 table = d_8to24table;
1163 for (i = 0; i < 256; i++)
1164 {
1165 r = pal[0];
1166 g = pal[1];
1167 b = pal[2];
1168 pal += 3;
1169
1170 v = (255 << SHIFT_a) + (r << SHIFT_r) + (g << SHIFT_g) + (b << SHIFT_b);
1171 *table++ = v;
1172 }
1173
1174 d_8to24table[255] &= MASK_rgb; // 255 is transparent
1175
1176 pal = palette;
1177 table = d_8to24TranslucentTable;
1178
1179 for (i = 0; i < 16; i++)
1180 {
1181 c = ColorIndex[i] * 3;
1182
1183 r = pal[c];
1184 g = pal[c + 1];
1185 b = pal[c + 2];
1186
1187 for (p = 0; p < 16; p++)
1188 {
1189 v = (ColorPercent[15 - p] << SHIFT_a) + (r << SHIFT_r) + (g << SHIFT_g) + (b << SHIFT_b);
1190 *table++ = v;
1191
1192 RTint[i*16 + p] = ((float)r) / ((float)ColorPercent[15-p]);
1193 GTint[i*16 + p] = ((float)g) / ((float)ColorPercent[15-p]);
1194 BTint[i*16 + p] = ((float)b) / ((float)ColorPercent[15-p]);
1195 }
1196 }
1197
1198 // Initialize the palettized textures data
1199 mark = Hunk_LowMark ();
1200 inverse_pal = (unsigned char *) FS_LoadHunkFile (INVERSE_PALNAME, NULL);
1201 if (inverse_pal != NULL && fs_filesize != INVERSE_PAL_SIZE)
1202 {
1203 Hunk_FreeToLowMark (mark);
1204 inverse_pal = NULL;
1205 }
1206 if (inverse_pal == NULL)
1207 {
1208 inverse_pal = (unsigned char *) Hunk_AllocName (INVERSE_PAL_SIZE + 1, INVERSE_PALNAME);
1209 VID_CreateInversePalette (palette);
1210 }
1211 }
1212
VID_SetPalette(const unsigned char * palette)1213 void VID_SetPalette (const unsigned char *palette)
1214 {
1215 // nothing to do
1216 }
1217
1218
1219 /*
1220 ===================================================================
1221
1222 MAIN WINDOW
1223
1224 ===================================================================
1225 */
1226
1227 /*
1228 ================
1229 ClearAllStates
1230 ================
1231 */
ClearAllStates(void)1232 static void ClearAllStates (void)
1233 {
1234 Key_ClearStates ();
1235 IN_ClearStates ();
1236 }
1237
1238 /*
1239 =================
1240 VID_ChangeVideoMode
1241 intended only as a callback for VID_Restart_f
1242 =================
1243 */
VID_ChangeVideoMode(int newmode)1244 static void VID_ChangeVideoMode (int newmode)
1245 {
1246 int temp;
1247
1248 temp = scr_disabled_for_loading;
1249 scr_disabled_for_loading = true;
1250
1251 // restore gamma, reset gamma function pointers
1252 /*VID_ShutdownGamma();*/
1253 CDAudio_Pause ();
1254 BGM_Pause ();
1255 S_ClearBuffer ();
1256
1257 // Unload all textures and reset texture counts
1258 D_ClearOpenGLTextures(0);
1259 memset (lightmap_textures, 0, sizeof(lightmap_textures));
1260
1261 // reset all opengl function pointers
1262 GL_ResetFunctions();
1263
1264 // Avoid re-registering commands and re-allocating memory
1265 draw_reinit = true;
1266
1267 // temporarily disable input devices
1268 IN_DeactivateMouse();
1269 //IN_ShowMouse ();
1270
1271 if (!VID_SetMode (newmode))
1272 Sys_Error ("Couldn't set video mode");
1273
1274 // Reload graphics wad file (Draw_PicFromWad writes glpic_t data (sizes,
1275 // texnums) right on top of the original pic data, so the pic data will
1276 // be dirty after gl textures are loaded the first time; we need to load
1277 // a clean version)
1278 W_LoadWadFile ("gfx.wad");
1279
1280 // Initialize extensions and default OpenGL parameters
1281 GL_Init();
1282 VID_InitGamma();
1283 VID_Init8bitPalette();
1284
1285 // Reload pre-map pics, fonts, console, etc
1286 Draw_Init();
1287 SCR_Init();
1288 // R_Init() stuff:
1289 R_InitParticleTexture();
1290 R_InitExtraTextures ();
1291 #if defined(H2W)
1292 R_InitNetgraphTexture();
1293 #endif /* H2W */
1294 Sbar_Init();
1295 vid.recalc_refdef = 1;
1296
1297 IN_ReInit ();
1298 ClearAllStates ();
1299 CDAudio_Resume ();
1300 BGM_Resume ();
1301
1302 // Reload model textures and player skins
1303 Mod_ReloadTextures();
1304 // rebuild the lightmaps
1305 GL_BuildLightmaps();
1306 // finished reloading all images
1307 draw_reinit = false;
1308 scr_disabled_for_loading = temp;
1309 // apply our gamma
1310 VID_ShiftPalette(NULL);
1311 }
1312
VID_Restart_f(void)1313 static void VID_Restart_f (void)
1314 {
1315 if (vid_mode.integer < 0 || vid_mode.integer >= *nummodes)
1316 {
1317 Con_Printf ("Bad video mode %d\n", vid_mode.integer);
1318 Cvar_SetValueQuick (&vid_mode, vid_modenum);
1319 return;
1320 }
1321
1322 Con_Printf ("Re-initializing video:\n");
1323 VID_ChangeVideoMode (vid_mode.integer);
1324 }
1325
sort_modes(const void * arg1,const void * arg2)1326 static int sort_modes (const void *arg1, const void *arg2)
1327 {
1328 const vmode_t *a1, *a2;
1329 a1 = (const vmode_t *) arg1;
1330 a2 = (const vmode_t *) arg2;
1331
1332 if (a1->width == a2->width)
1333 return a1->height - a2->height; // lowres-to-highres
1334 // return a2->height - a1->height; // highres-to-lowres
1335 else
1336 return a1->width - a2->width; // lowres-to-highres
1337 // return a2->width - a1->width; // highres-to-lowres
1338 }
1339
VID_PrepareModes(void)1340 static void VID_PrepareModes (void)
1341 {
1342 int i;
1343 ULONG id;
1344 APTR handle;
1345 struct DimensionInfo diminfo;
1346
1347 num_fmodes = 0;
1348 num_wmodes = 0;
1349
1350 // Add the standart 4:3 modes to the windowed modes list
1351 // In an unlikely case that we receive no fullscreen modes,
1352 // this will be our modes list (kind of...)
1353 for (i = 0; i < (int)MAX_STDMODES; i++)
1354 {
1355 wmodelist[num_wmodes].width = std_modes[i].width;
1356 wmodelist[num_wmodes].height = std_modes[i].height;
1357 /*wmodelist[num_wmodes].halfscreen = 0;*/
1358 wmodelist[num_wmodes].fullscreen = 0;
1359 wmodelist[num_wmodes].bpp = 16;
1360 q_snprintf (wmodelist[num_wmodes].modedesc, MAX_DESC,
1361 "%d x %d", std_modes[i].width, std_modes[i].height);
1362 num_wmodes++;
1363 }
1364
1365 // fullscreen modes
1366 id = INVALID_ID;
1367
1368 while((id = NextDisplayInfo(id)) != INVALID_ID)
1369 {
1370 handle = FindDisplayInfo(id);
1371
1372 if (handle)
1373 {
1374 if (!GetDisplayInfoData(handle, (UBYTE *) &diminfo, sizeof(diminfo), DTAG_DIMS, 0))
1375 continue;
1376
1377 #ifdef __AROS__
1378 if (diminfo.MaxDepth != 24)
1379 #else
1380 if (diminfo.MaxDepth != 16)
1381 #endif
1382 continue;
1383
1384 fmodelist[num_fmodes].width = diminfo.Nominal.MaxX + 1;
1385 fmodelist[num_fmodes].height = diminfo.Nominal.MaxY + 1;
1386 fmodelist[num_fmodes].fullscreen = 1;
1387 fmodelist[num_fmodes].bpp = 16; // diminfo.MaxDepth
1388 q_snprintf (fmodelist[num_fmodes].modedesc, MAX_DESC, "%d x %d", (fmodelist[num_fmodes].width), (fmodelist[num_fmodes].height));
1389 //Con_SafePrintf ("fmodelist[%d].modedesc = %s maxdepth %d\n", num_fmodes, fmodelist[num_fmodes].modedesc, diminfo.MaxDepth);
1390
1391 if (++num_fmodes == MAX_MODE_LIST)
1392 break;
1393 }
1394 }
1395
1396 if (num_fmodes > 1)
1397 qsort(fmodelist, num_fmodes, sizeof(vmode_t), sort_modes);
1398
1399 // disaster scenario #1: no fullscreen modes. bind to the
1400 // windowed modes list. limit it to 640x480 max. because
1401 // we don't know the desktop dimensions
1402 if (num_fmodes == 0)
1403 {
1404 Con_SafePrintf ("No fullscreen video modes available\n");
1405 num_wmodes = RES_640X480 + 1;
1406 modelist = wmodelist;
1407 nummodes = &num_wmodes;
1408 vid_default = RES_640X480;
1409 Cvar_SetValueQuick (&vid_config_glx, modelist[vid_default].width);
1410 Cvar_SetValueQuick (&vid_config_gly, modelist[vid_default].height);
1411 return;
1412 }
1413
1414 // At his point, we have a list of valid fullscreen modes:
1415 // Let's bind to it and use it for windowed modes, as well.
1416 // The only downside is that if SDL doesn't report any low
1417 // resolutions to us, we shall not have any for windowed
1418 // rendering where they would be perfectly legitimate...
1419 // Since our fullscreen/windowed toggling is instant and
1420 // doesn't require a vid_restart, switching lists won't be
1421 // feasible, either. The -width/-height commandline args
1422 // remain as the user's trusty old friends here.
1423 nummodes = &num_fmodes;
1424 modelist = fmodelist;
1425
1426 vid_maxwidth = fmodelist[num_fmodes-1].width;
1427 vid_maxheight = fmodelist[num_fmodes-1].height;
1428
1429 // find the 640x480 default resolution. this shouldn't fail
1430 // at all (for any adapter suporting the VGA/XGA legacy).
1431 for (i = 0; i < num_fmodes; i++)
1432 {
1433 if (fmodelist[i].width == 640 && fmodelist[i].height == 480)
1434 {
1435 vid_default = i;
1436 break;
1437 }
1438 }
1439
1440 if (vid_default < 0)
1441 {
1442 // No 640x480? Unexpected, at least today..
1443 // Easiest thing is to set the default mode
1444 // as the highest reported one.
1445 Con_SafePrintf ("WARNING: 640x480 not found in fullscreen modes\n"
1446 "Using the largest reported dimension as default\n");
1447 vid_default = num_fmodes;
1448 }
1449
1450 // limit the windowed (standart) modes list to desktop dimensions
1451 for (i = 0; i < num_wmodes; i++)
1452 {
1453 if (wmodelist[i].width > vid_maxwidth || wmodelist[i].height > vid_maxheight)
1454 break;
1455 }
1456 if (i < num_wmodes)
1457 num_wmodes = i;
1458
1459 Cvar_SetValueQuick (&vid_config_glx, modelist[vid_default].width);
1460 Cvar_SetValueQuick (&vid_config_gly, modelist[vid_default].height);
1461 }
1462
VID_ListModes_f(void)1463 static void VID_ListModes_f (void)
1464 {
1465 int i;
1466
1467 Con_Printf ("Maximum allowed mode: %d x %d\n", vid_maxwidth, vid_maxheight);
1468 Con_Printf ("Windowed modes enabled:\n");
1469 for (i = 0; i < num_wmodes; i++)
1470 Con_Printf ("%2d: %d x %d\n", i, wmodelist[i].width, wmodelist[i].height);
1471 Con_Printf ("Fullscreen modes enumerated:");
1472 if (num_fmodes)
1473 {
1474 Con_Printf ("\n");
1475 for (i = 0; i < num_fmodes; i++)
1476 Con_Printf ("%2d: %d x %d\n", i, fmodelist[i].width, fmodelist[i].height);
1477 }
1478 else
1479 {
1480 Con_Printf (" None\n");
1481 }
1482 }
1483
VID_NumModes_f(void)1484 static void VID_NumModes_f (void)
1485 {
1486 Con_Printf ("%d video modes in current list\n", *nummodes);
1487 }
1488
1489 #if defined(__AMIGA__) && defined(REFGL_MINIGL)
gl_lockmode_f(cvar_t * var)1490 static void gl_lockmode_f (cvar_t *var)
1491 {
1492 if (!q_strcasecmp(var->string, "smart"))
1493 lockmode = MGL_LOCK_SMART;
1494 else if (!q_strcasecmp(var->string, "auto"))
1495 lockmode = MGL_LOCK_AUTOMATIC;
1496 else if (!q_strcasecmp(var->string, "manual"))
1497 lockmode = MGL_LOCK_MANUAL;
1498 else {
1499 Con_Printf("Bad lock mode %s, setting to manual\n", var->string);
1500 lockmode = MGL_LOCK_MANUAL;
1501 Cvar_SetQuick(var, "manual");
1502 return;
1503 }
1504 if (mini_CurrentContext) {
1505 mglLockMode(lockmode);
1506 }
1507 }
1508 #endif
1509
1510 /*
1511 ===================
1512 VID_Init
1513 ===================
1514 */
VID_Init(const unsigned char * palette)1515 void VID_Init (const unsigned char *palette)
1516 {
1517 int i, temp, width, height;
1518 const char *read_vars[] = {
1519 "vid_config_fscr",
1520 "vid_config_gl8bit",
1521 "vid_config_glx",
1522 "vid_config_gly",
1523 "vid_config_consize",
1524 #if defined(__AMIGA__) && defined(REFGL_MINIGL)
1525 "gl_lockmode",
1526 #endif
1527 "gl_texture_NPOT",
1528 "gl_multitexture",
1529 "gl_lightmapfmt" };
1530 #define num_readvars ( sizeof(read_vars)/sizeof(read_vars[0]) )
1531
1532 Cvar_RegisterVariable (&vid_config_gl8bit);
1533 Cvar_RegisterVariable (&vid_config_fscr);
1534 Cvar_RegisterVariable (&vid_config_swy);
1535 Cvar_RegisterVariable (&vid_config_swx);
1536 Cvar_RegisterVariable (&vid_config_mon);
1537 Cvar_RegisterVariable (&vid_config_gly);
1538 Cvar_RegisterVariable (&vid_config_glx);
1539 Cvar_RegisterVariable (&vid_config_consize);
1540 Cvar_RegisterVariable (&vid_mode);
1541 Cvar_RegisterVariable (&_enable_mouse);
1542 Cvar_RegisterVariable (&gl_texture_NPOT);
1543 Cvar_RegisterVariable (&gl_lightmapfmt);
1544 Cvar_RegisterVariable (&gl_multitexture);
1545
1546 Cmd_AddCommand ("vid_listmodes", VID_ListModes_f);
1547 Cmd_AddCommand ("vid_nummodes", VID_NumModes_f);
1548 Cmd_AddCommand ("vid_restart", VID_Restart_f);
1549
1550 VID_InitPalette (palette);
1551
1552 vid.numpages = 2;
1553
1554 #if defined(REFGL_MINIGL)
1555 #ifdef __CLIB2__
1556 GfxBase = (struct GfxBase *)OpenLibrary("graphics.library", 0);
1557 if (!GfxBase)
1558 Sys_Error ("Cannot open graphics.library!");
1559 #endif
1560 mini_CurrentContext = NULL;/* should I do this? */
1561 Cvar_RegisterVariable (&gl_lockmode);
1562 Cvar_SetCallback (&gl_lockmode, gl_lockmode_f);
1563 if (MGLInit() == GL_FALSE) {
1564 Sys_Error ("Couldn't initialize MiniGL");
1565 }
1566 mglChoosePixelDepth (16);/* set pixel depth to 16 */
1567 mglChooseVertexBufferSize (3000); /* default 30 not enough */
1568 if (COM_CheckParm("-guardband"))
1569 mglChooseGuardBand (GL_TRUE);/* helps with Voodoo3 */
1570 else
1571 mglChooseGuardBand (GL_FALSE);
1572 #endif
1573 #if defined(REFGL_AMESA)
1574 #ifdef __CLIB2__
1575 GfxBase = (struct GfxBase *)OpenLibrary("graphics.library", 0);
1576 if (!GfxBase)
1577 Sys_Error ("Cannot open graphics.library!");
1578 #endif
1579 CyberGfxBase = OpenLibrary("cybergraphics.library", 0);
1580 if (!CyberGfxBase)
1581 Sys_Error ("Cannot open cybergraphics.library!");
1582 #endif
1583
1584 // prepare the modelists, find the actual modenum for vid_default
1585 VID_PrepareModes();
1586
1587 // set vid_mode to our safe default first
1588 Cvar_SetValueQuick (&vid_mode, vid_default);
1589
1590 // perform an early read of config.cfg
1591 CFG_ReadCvars (read_vars, num_readvars);
1592
1593 // windowed mode is default
1594 // see if the user wants fullscreen
1595 if (COM_CheckParm("-fullscreen") || COM_CheckParm("-f"))
1596 {
1597 Cvar_SetQuick (&vid_config_fscr, "1");
1598 }
1599 else if (COM_CheckParm("-window") || COM_CheckParm("-w"))
1600 {
1601 Cvar_SetQuick (&vid_config_fscr, "0");
1602 }
1603
1604 if (vid_config_fscr.integer && !num_fmodes) // FIXME: see below, as well
1605 Sys_Error ("No fullscreen modes available at this color depth");
1606
1607 width = vid_config_glx.integer;
1608 height = vid_config_gly.integer;
1609
1610 if (vid_config_consize.integer != width)
1611 vid_conscale = true;
1612
1613 // user is always right ...
1614 i = COM_CheckParm("-width");
1615 if (i && i < com_argc-1)
1616 { // FIXME: this part doesn't know about a disaster case
1617 // like we aren't reported any fullscreen modes.
1618 width = atoi(com_argv[i+1]);
1619
1620 i = COM_CheckParm("-height");
1621 if (i && i < com_argc-1)
1622 height = atoi(com_argv[i+1]);
1623 else // proceed with 4/3 ratio
1624 height = 3 * width / 4;
1625 }
1626 i = COM_CheckParm("-bpp");
1627 if (i && i < com_argc-1)
1628 {
1629 bpp = atoi(com_argv[i+1]);
1630 }
1631
1632 // user requested a mode either from the config or from the
1633 // command line
1634 // scan existing modes to see if this is already available
1635 // if not, add this as the last "valid" video mode and set
1636 // vid_mode to it only if it doesn't go beyond vid_maxwidth
1637 i = 0;
1638 while (i < *nummodes)
1639 {
1640 if (modelist[i].width == width && modelist[i].height == height)
1641 break;
1642 i++;
1643 }
1644 if (i < *nummodes)
1645 {
1646 Cvar_SetValueQuick (&vid_mode, i);
1647 }
1648 else if ( (width <= vid_maxwidth && width >= MIN_WIDTH &&
1649 height <= vid_maxheight && height >= MIN_HEIGHT) ||
1650 COM_CheckParm("-force") )
1651 {
1652 modelist[*nummodes].width = width;
1653 modelist[*nummodes].height = height;
1654 /*modelist[*nummodes].halfscreen = 0;*/
1655 modelist[*nummodes].fullscreen = 1;
1656 modelist[*nummodes].bpp = 16;
1657 q_snprintf (modelist[*nummodes].modedesc, MAX_DESC, "%d x %d (user mode)", width, height);
1658 Cvar_SetValueQuick (&vid_mode, *nummodes);
1659 (*nummodes)++;
1660 }
1661 else
1662 {
1663 Con_SafePrintf ("ignoring invalid -width and/or -height arguments\n");
1664 }
1665
1666 if (!vid_conscale)
1667 Cvar_SetValueQuick (&vid_config_consize, width);
1668
1669 // This will display a bigger hud and readable fonts at high
1670 // resolutions. The fonts will be somewhat distorted, though
1671 i = COM_CheckParm("-conwidth");
1672 if (i != 0 && i < com_argc-1)
1673 i = atoi(com_argv[i + 1]);
1674 else i = vid_config_consize.integer;
1675 if (i < MIN_WIDTH) i = MIN_WIDTH;
1676 else if (i > width) i = width;
1677 Cvar_SetValueQuick(&vid_config_consize, i);
1678 if (vid_config_consize.integer != width)
1679 vid_conscale = true;
1680
1681 if (COM_CheckParm("-paltex"))
1682 Cvar_SetQuick (&vid_config_gl8bit, "1");
1683
1684 vid.maxwarpwidth = WARP_WIDTH;
1685 vid.maxwarpheight = WARP_HEIGHT;
1686 vid.colormap = host_colormap;
1687 vid.fullbright = 256 - LittleLong (*((int *)vid.colormap + 2048));
1688
1689 temp = scr_disabled_for_loading;
1690 scr_disabled_for_loading = true;
1691 //set the mode
1692 if (!VID_SetMode (vid_mode.integer))
1693 Sys_Error ("Couldn't set video mode");
1694 ClearAllStates ();
1695
1696 GL_SetupLightmapFmt();
1697 GL_Init ();
1698 VID_InitGamma();
1699 VID_Init8bitPalette();
1700
1701 // lock the early-read cvars until Host_Init is finished
1702 for (i = 0; i < (int)num_readvars; i++)
1703 Cvar_LockVar (read_vars[i]);
1704
1705 vid_initialized = true;
1706 scr_disabled_for_loading = temp;
1707 vid.recalc_refdef = 1;
1708
1709 Con_SafePrintf ("Video initialized.\n");
1710
1711 vid_menudrawfn = VID_MenuDraw;
1712 vid_menukeyfn = VID_MenuKey;
1713
1714 // if (COM_CheckParm("-fullsbar"))
1715 // fullsbardraw = true;
1716 }
1717
1718
VID_Shutdown(void)1719 void VID_Shutdown (void)
1720 {
1721 VID_KillContext();
1722 #ifdef REFGL_MINIGL
1723 MGLTerm();
1724 #ifdef __CLIB2__
1725 if (GfxBase) {
1726 CloseLibrary((struct Library *)GfxBase);
1727 GfxBase = NULL;
1728 }
1729 #endif
1730 #endif
1731 #ifdef REFGL_AMESA
1732 if (CyberGfxBase) {
1733 CloseLibrary(CyberGfxBase);
1734 CyberGfxBase = NULL;
1735 }
1736 #ifdef __CLIB2__
1737 if (GfxBase) {
1738 CloseLibrary((struct Library *)GfxBase);
1739 GfxBase = NULL;
1740 }
1741 #endif
1742 #endif
1743 }
1744
1745
VID_KillContext(void)1746 static void VID_KillContext (void)
1747 {
1748 #if defined(__AROS__) && defined(AROS_USE_GLA)
1749 if (context)
1750 {
1751 glADestroyContext(context);
1752 context = NULL;
1753 }
1754 #elif defined(__AROS__)
1755 if (context)
1756 {
1757 AROSMesaDestroyContext(context);
1758 context = NULL;
1759 }
1760 #elif defined __MORPHOS__
1761 if (contextinit)
1762 {
1763 if (screen && !(TinyGLBase->lib_Version == 0 && TinyGLBase->lib_Revision < 4))
1764 glADestroyContextScreen();
1765 else
1766 glADestroyContextWindowed();
1767 contextinit = false;
1768 }
1769 if (__tglContext)
1770 {
1771 GLClose(__tglContext);
1772 __tglContext = NULL;
1773 }
1774 #elif defined(__AMIGA__) && defined(REFGL_MINIGL)
1775 if (mini_CurrentContext)
1776 {
1777 mglDeleteContext();
1778 window = NULL;
1779 screen = NULL;
1780 mini_CurrentContext = NULL;
1781 }
1782 #elif defined(__AMIGA__) && defined(REFGL_AMESA)
1783 if (context)
1784 {
1785 AmigaMesaDestroyContext(context);
1786 context = NULL;
1787 }
1788 #endif
1789
1790 #ifndef REFGL_MINIGL
1791 if (window)
1792 {
1793 CloseWindow(window);
1794 window = NULL;
1795 }
1796
1797 if (screen)
1798 {
1799 CloseScreen(screen);
1800 screen = NULL;
1801 }
1802 #endif
1803 }
1804
1805
1806 /*
1807 ================
1808 VID_ToggleFullscreen
1809 Handles switching between fullscreen/windowed modes
1810 and brings the mouse to a proper state afterwards
1811 ================
1812 */
1813 extern qboolean menu_disabled_mouse;
VID_ToggleFullscreen(void)1814 void VID_ToggleFullscreen (void)
1815 {
1816 // implement this
1817 }
1818
1819
1820 #ifndef H2W /* unused in hexenworld */
D_ShowLoadingSize(void)1821 void D_ShowLoadingSize (void)
1822 {
1823 #if defined(DRAW_PROGRESSBARS)
1824 int cur_perc;
1825 static int prev_perc;
1826
1827 if (!vid_initialized)
1828 return;
1829
1830 cur_perc = loading_stage * 100;
1831 if (total_loading_size)
1832 cur_perc += current_loading_size * 100 / total_loading_size;
1833 if (cur_perc == prev_perc)
1834 return;
1835 prev_perc = cur_perc;
1836
1837 glDrawBuffer_fp (GL_FRONT);
1838
1839 SCR_DrawLoading();
1840
1841 glFlush_fp();
1842
1843 glDrawBuffer_fp (GL_BACK);
1844 #endif /* DRAW_PROGRESSBARS */
1845 }
1846 #endif
1847
1848
1849 //========================================================
1850 // Video menu stuff
1851 //========================================================
1852
1853 static int vid_menunum;
1854 static int vid_cursor;
1855 static qboolean want_fstoggle, need_apply;
1856 static qboolean vid_menu_firsttime = true;
1857
1858 enum {
1859 VID_FULLSCREEN, // make sure the fullscreen entry (0)
1860 VID_RESOLUTION, // is lower than resolution entry (1)
1861 VID_MULTISAMPLE,
1862 VID_MULTITEXTURE,
1863 VID_NPOT,
1864 VID_PALTEX,
1865 VID_BLANKLINE, // spacer line
1866 VID_RESET,
1867 VID_APPLY,
1868 VID_ITEMS
1869 };
1870
M_DrawYesNo(int x,int y,int on,int white)1871 static void M_DrawYesNo (int x, int y, int on, int white)
1872 {
1873 if (on)
1874 {
1875 if (white)
1876 M_PrintWhite (x, y, "yes");
1877 else
1878 M_Print (x, y, "yes");
1879 }
1880 else
1881 {
1882 if (white)
1883 M_PrintWhite (x, y, "no");
1884 else
1885 M_Print (x, y, "no");
1886 }
1887 }
1888
1889 /*
1890 ================
1891 VID_MenuDraw
1892 ================
1893 */
VID_MenuDraw(void)1894 static void VID_MenuDraw (void)
1895 {
1896 ScrollTitle("gfx/menu/title7.lmp");
1897
1898 if (vid_menu_firsttime)
1899 { // settings for entering the menu first time
1900 vid_menunum = vid_modenum;
1901 vid_menu_fs = (modestate != MS_WINDOWED);
1902 vid_cursor = (num_fmodes) ? 0 : VID_RESOLUTION;
1903 vid_menu_firsttime = false;
1904 }
1905
1906 want_fstoggle = ( ((modestate == MS_WINDOWED) && vid_menu_fs) || ((modestate != MS_WINDOWED) && !vid_menu_fs) );
1907
1908 need_apply = (vid_menunum != vid_modenum) || want_fstoggle ||
1909 (have_mtex && (gl_mtexable != !!gl_multitexture.integer)) ||
1910 (have_NPOT && (gl_tex_NPOT != !!gl_texture_NPOT.integer)) ||
1911 (have8bit && (is8bit != !!vid_config_gl8bit.integer));
1912
1913 M_Print (76, 92 + 8*VID_FULLSCREEN, "Fullscreen: ");
1914 M_DrawYesNo (76+12*8, 92 + 8*VID_FULLSCREEN, vid_menu_fs, !want_fstoggle);
1915
1916 M_Print (76, 92 + 8*VID_RESOLUTION, "Resolution: ");
1917 if (vid_menunum == vid_modenum)
1918 M_PrintWhite (76+12*8, 92 + 8*VID_RESOLUTION, modelist[vid_menunum].modedesc);
1919 else
1920 M_Print (76+12*8, 92 + 8*VID_RESOLUTION, modelist[vid_menunum].modedesc);
1921
1922 M_Print (76, 92 + 8*VID_MULTISAMPLE, "Antialiasing :");
1923 M_PrintWhite (76+16*8, 92 + 8*VID_MULTISAMPLE, "Not found");
1924
1925 M_Print (76, 92 + 8*VID_MULTITEXTURE, "Multitexturing:");
1926 if (have_mtex)
1927 M_DrawYesNo (76+16*8, 92 + 8*VID_MULTITEXTURE, gl_multitexture.integer, (gl_mtexable == !!gl_multitexture.integer));
1928 else
1929 M_PrintWhite (76+16*8, 92 + 8*VID_MULTITEXTURE, "Not found");
1930
1931 M_Print (76, 92 + 8*VID_NPOT, "NPOT textures :");
1932 if (have_NPOT)
1933 M_DrawYesNo (76+16*8, 92 + 8*VID_NPOT, gl_texture_NPOT.integer, (gl_tex_NPOT == !!gl_texture_NPOT.integer));
1934 else
1935 M_PrintWhite (76+16*8, 92 + 8*VID_NPOT, "Not found");
1936
1937 M_Print (76, 92 + 8*VID_PALTEX, "8 bit textures:");
1938 if (have8bit)
1939 M_DrawYesNo (76+16*8, 92 + 8*VID_PALTEX, vid_config_gl8bit.integer, (is8bit == !!vid_config_gl8bit.integer));
1940 else
1941 M_PrintWhite (76+16*8, 92 + 8*VID_PALTEX, "Not found");
1942
1943 if (need_apply)
1944 {
1945 M_Print (76, 92 + 8*VID_RESET, "RESET CHANGES");
1946 M_Print (76, 92 + 8*VID_APPLY, "APPLY CHANGES");
1947 }
1948
1949 M_DrawCharacter (64, 92 + vid_cursor*8, 12+((int)(realtime*4)&1));
1950 }
1951
1952 /*
1953 ================
1954 VID_MenuKey
1955 ================
1956 */
VID_MenuKey(int key)1957 static void VID_MenuKey (int key)
1958 {
1959 switch (key)
1960 {
1961 case K_ESCAPE:
1962 vid_cursor = (num_fmodes) ? 0 : VID_RESOLUTION;
1963 M_Menu_Options_f ();
1964 break;
1965
1966 case K_UPARROW:
1967 S_LocalSound ("raven/menu1.wav");
1968 vid_cursor--;
1969 if (vid_cursor < 0)
1970 {
1971 vid_cursor = (need_apply) ? VID_ITEMS-1 : VID_BLANKLINE-1;
1972 }
1973 else if (vid_cursor == VID_BLANKLINE)
1974 {
1975 vid_cursor--;
1976 }
1977 break;
1978
1979 case K_DOWNARROW:
1980 S_LocalSound ("raven/menu1.wav");
1981 vid_cursor++;
1982 if (vid_cursor >= VID_ITEMS)
1983 {
1984 vid_cursor = (num_fmodes) ? 0 : VID_RESOLUTION;
1985 break;
1986 }
1987 if (vid_cursor >= VID_BLANKLINE)
1988 {
1989 if (need_apply)
1990 {
1991 if (vid_cursor == VID_BLANKLINE)
1992 vid_cursor++;
1993 }
1994 else
1995 {
1996 vid_cursor = (num_fmodes) ? 0 : VID_RESOLUTION;
1997 }
1998 }
1999 break;
2000
2001 case K_ENTER:
2002 switch (vid_cursor)
2003 {
2004 case VID_RESET:
2005 vid_menu_fs = (modestate != MS_WINDOWED);
2006 vid_menunum = vid_modenum;
2007 Cvar_SetValueQuick (&vid_config_gl8bit, is8bit);
2008 vid_cursor = (num_fmodes) ? 0 : VID_RESOLUTION;
2009 break;
2010 case VID_APPLY:
2011 if (need_apply)
2012 {
2013 Cvar_SetValueQuick(&vid_mode, vid_menunum);
2014 Cvar_SetValueQuick(&vid_config_fscr, vid_menu_fs);
2015 VID_Restart_f();
2016 }
2017 vid_cursor = (num_fmodes) ? 0 : VID_RESOLUTION;
2018 break;
2019 }
2020 return;
2021
2022 case K_LEFTARROW:
2023 switch (vid_cursor)
2024 {
2025 case VID_FULLSCREEN:
2026 vid_menu_fs = !vid_menu_fs;
2027 if (fs_toggle_works)
2028 VID_ToggleFullscreen();
2029 break;
2030 case VID_RESOLUTION:
2031 S_LocalSound ("raven/menu1.wav");
2032 vid_menunum--;
2033 if (vid_menunum < 0)
2034 vid_menunum = 0;
2035 break;
2036 case VID_MULTISAMPLE:
2037 break;
2038 case VID_MULTITEXTURE:
2039 if (have_mtex)
2040 Cvar_SetQuick (&gl_multitexture, gl_multitexture.integer ? "0" : "1");
2041 break;
2042 case VID_NPOT:
2043 if (have_NPOT)
2044 Cvar_SetQuick (&gl_texture_NPOT, gl_texture_NPOT.integer ? "0" : "1");
2045 break;
2046 case VID_PALTEX:
2047 if (have8bit)
2048 Cvar_SetQuick (&vid_config_gl8bit, vid_config_gl8bit.integer ? "0" : "1");
2049 break;
2050 }
2051 return;
2052
2053 case K_RIGHTARROW:
2054 switch (vid_cursor)
2055 {
2056 case VID_FULLSCREEN:
2057 vid_menu_fs = !vid_menu_fs;
2058 if (fs_toggle_works)
2059 VID_ToggleFullscreen();
2060 break;
2061 case VID_RESOLUTION:
2062 S_LocalSound ("raven/menu1.wav");
2063 vid_menunum++;
2064 if (vid_menunum >= *nummodes)
2065 vid_menunum = *nummodes - 1;
2066 break;
2067 case VID_MULTISAMPLE:
2068 break;
2069 case VID_MULTITEXTURE:
2070 if (have_mtex)
2071 Cvar_SetQuick (&gl_multitexture, gl_multitexture.integer ? "0" : "1");
2072 break;
2073 case VID_NPOT:
2074 if (have_NPOT)
2075 Cvar_SetQuick (&gl_texture_NPOT, gl_texture_NPOT.integer ? "0" : "1");
2076 break;
2077 case VID_PALTEX:
2078 if (have8bit)
2079 Cvar_SetQuick (&vid_config_gl8bit, vid_config_gl8bit.integer ? "0" : "1");
2080 break;
2081 }
2082 return;
2083
2084 default:
2085 break;
2086 }
2087 }
2088
2089