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