1 /*
2 * vid_cgx.c -- CyberGraphX video driver for AmigaOS & variants.
3 * Select window size and mode and init CGX in SOFTWARE mode.
4 * $Id: vid_cgx.c 5981 2017-09-25 18:50:30Z sezero $
5 *
6 * Copyright (C) 1996-1997 Id Software, Inc.
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 #include <intuition/intuition.h>
28 #include <intuition/intuitionbase.h>
29 #include <cybergraphx/cybergraphics.h>
30 #include <exec/execbase.h>
31
32 #include <proto/exec.h>
33 #include <proto/intuition.h>
34 #include <proto/graphics.h>
35 #include <proto/cybergraphics.h>
36
37 #include <SDI/SDI_compiler.h> /* IPTR */
38
39 /* WriteLUTPixelArray not included in vbcc_target_m68k-amigaos.lha */
40 #if defined(__VBCC__) && defined(__M68K__) && !defined(WriteLUTPixelArray)
41 ULONG __WriteLUTPixelArray(__reg("a6") void *, __reg("a0") APTR srcRect, __reg("d0") UWORD SrcX, __reg("d1") UWORD SrcY, __reg("d2") UWORD SrcMod, __reg("a1") struct RastPort * a1arg, __reg("a2") APTR a2arg, __reg("d3") UWORD DestX, __reg("d4") UWORD DestY, __reg("d5") UWORD SizeX, __reg("d6") UWORD SizeY, __reg("d7") UBYTE CTFormat)="\tjsr\t-198(a6)";
42 #define WriteLUTPixelArray(srcRect, SrcX, SrcY, SrcMod, a1arg, a2arg, DestX, DestY, SizeX, SizeY, CTFormat) __WriteLUTPixelArray(CyberGfxBase, (srcRect), (SrcX), (SrcY), (SrcMod), (a1arg), (a2arg), (DestX), (DestY), (SizeX), (SizeY), (CTFormat))
43 #endif
44
45 #include "quakedef.h"
46 #include "d_local.h"
47 #include "cfgfile.h"
48 #include "bgmusic.h"
49 #include "cdaudio.h"
50
51 #define MIN_WIDTH 320
52 #define MIN_HEIGHT 240
53 #define MAX_DESC 33
54
55 /* - CGX ----------------------------------- */
56
57 struct Window *window = NULL; /* used by in_amiga.c */
58 static struct Screen *screen = NULL;
59 static unsigned char ppal[256 * 4];
60 static pixel_t *buffer = NULL;
61 static byte *directbitmap = NULL;
62 #ifdef __CLIB2__
63 struct GfxBase *GfxBase = NULL;
64 #endif
65 #ifdef PLATFORM_AMIGAOS3
66 struct Library *CyberGfxBase = NULL;
67 #ifdef USE_C2P
68 static qboolean use_c2p = false;
69 static int currentBitMap;
70 static struct ScreenBuffer *sbuf[2];
71
72 #define C2P_BITMAP
73
74 #ifdef C2P_BITMAP
75 typedef void (*c2p_write_bm_func)(REG(d0, WORD chunkyx), REG(d1, WORD chunkyy), REG(d2, WORD offsx), REG(d3, WORD offsy), REG(a0, APTR chunkyscreen), REG(a1, struct BitMap *bitmap));
76 static c2p_write_bm_func c2p_write_bm;
77 #else
78 typedef void (*c2p_init_func)(REG(d0, WORD chunkyx), REG(d1, WORD chunkyy), REG(d3, WORD scroffsy), REG(d5, LONG bplsize));
79 typedef void (*c2p_write_func)(REG(a0, APTR c2pscreen), REG(a1, APTR bitplanes));
80 static c2p_init_func c2p_init;
81 static c2p_write_func c2p_write;
82 #endif
83
84 ASM_LINKAGE_BEGIN
85 extern void c2p1x1_8_c5_030_smcinit(REG(d0, WORD chunkyx), REG(d1, WORD chunkyy), REG(d3, WORD scroffsy), REG(d5, LONG bplsize));
86 extern void c2p1x1_8_c5_030(REG(a0, APTR c2pscreen), REG(a1, APTR bitplanes));
87 extern void c2p1x1_8_c5_040_init(REG(d0, WORD chunkyx), REG(d1, WORD chunkyy), REG(d3, WORD scroffsy), REG(d5, LONG bplsize));
88 extern void c2p1x1_8_c5_040(REG(a0, APTR c2pscreen), REG(a1, APTR bitplanes));
89 extern void c2p1x1_8_c5_bm(REG(d0, WORD chunkyx), REG(d1, WORD chunkyy), REG(d2, WORD offsx), REG(d3, WORD offsy), REG(a0, APTR chunkyscreen), REG(a1, struct BitMap *bitmap));
90 extern void c2p1x1_8_c5_bm_040(REG(d0, WORD chunkyx), REG(d1, WORD chunkyy), REG(d2, WORD offsx), REG(d3, WORD offsy), REG(a0, APTR chunkyscreen), REG(a1, struct BitMap *bitmap));
91 ASM_LINKAGE_END
92 #endif /* USE_C2P */
93 #endif /* PLATFORM_AMIGAOS3 */
94
95 /* ----------------------------------------- */
96
97 static unsigned char vid_curpal[256*3]; /* save for mode changes */
98
99 unsigned short d_8to16table[256];
100 unsigned int d_8to24table[256];
101
102 byte globalcolormap[VID_GRADES*256], lastglobalcolor = 0;
103 byte *lastsourcecolormap = NULL;
104
105 qboolean in_mode_set;
106 static int enable_mouse;
107 static qboolean palette_changed;
108
109 static int num_fmodes;
110 static int num_wmodes;
111 static int *nummodes;
112
113 static qboolean vid_menu_fs;
114 //static qboolean fs_toggle_works = false;
115
116 viddef_t vid; // global video state
117 // cvar vid_mode must be set before calling VID_SetMode, VID_ChangeVideoMode or VID_Restart_f
118 static cvar_t vid_mode = {"vid_mode", "0", CVAR_NONE};
119 static cvar_t vid_config_glx = {"vid_config_glx", "640", CVAR_ARCHIVE};
120 static cvar_t vid_config_gly = {"vid_config_gly", "480", CVAR_ARCHIVE};
121 static cvar_t vid_config_swx = {"vid_config_swx", "320", CVAR_ARCHIVE};
122 static cvar_t vid_config_swy = {"vid_config_swy", "240", CVAR_ARCHIVE};
123 #ifdef PLATFORM_AMIGAOS3
124 static cvar_t vid_config_fscr= {"vid_config_fscr", "1", CVAR_ARCHIVE};
125 #else
126 static cvar_t vid_config_fscr= {"vid_config_fscr", "0", CVAR_ARCHIVE};
127 #endif
128 static cvar_t vid_config_mon = {"vid_config_mon", "0", CVAR_ARCHIVE};
129
130 static cvar_t vid_showload = {"vid_showload", "1", CVAR_NONE};
131
132 cvar_t _enable_mouse = {"_enable_mouse", "1", CVAR_ARCHIVE};
133
134 static int vid_default = -1; // modenum of 320x240 as a safe default
135 static int vid_modenum = -1; // current video mode, set after mode setting succeeds
136 static int vid_maxwidth = 640, vid_maxheight = 480;
137 modestate_t modestate = MS_UNINIT;
138
139 static byte *vid_surfcache;
140 static int vid_surfcachesize;
141 static int VID_highhunkmark;
142
143 typedef struct {
144 modestate_t type;
145 int width;
146 int height;
147 int modenum;
148 int fullscreen;
149 int bpp;
150 /* int halfscreen;*/
151 ULONG modeid;
152 #ifdef PLATFORM_AMIGAOS3
153 qboolean noadapt;
154 #endif
155 char modedesc[MAX_DESC];
156 } vmode_t;
157
158 typedef struct {
159 int width;
160 int height;
161 } stdmode_t;
162
163 #define RES_640X480 3
164 static const stdmode_t std_modes[] = {
165 // NOTE: keep this list in order
166 {320, 240}, // 0
167 {400, 300}, // 1
168 {512, 384}, // 2
169 {640, 480}, // 3 == RES_640X480, this is our default, below
170 // this is the lowresmodes region.
171 // either do not change its order,
172 // or change the above define, too
173 {800, 600}, // 4, RES_640X480 + 1
174 {1024, 768} // 5, RES_640X480 + 2
175 };
176
177 #define MAX_MODE_LIST 64
178 #define MAX_STDMODES (sizeof(std_modes) / sizeof(std_modes[0]))
179 #define NUM_LOWRESMODES (RES_640X480)
180 static vmode_t fmodelist[MAX_MODE_LIST+1]; // list of enumerated fullscreen modes
181 static vmode_t wmodelist[MAX_STDMODES +1]; // list of standart 4:3 windowed modes
182 static vmode_t *modelist; // modelist in use, points to one of the above lists
183
184 static qboolean VID_SetMode (int modenum, const unsigned char *palette);
185
186 static void VID_MenuDraw (void);
187 static void VID_MenuKey (int key);
188
189 // window manager stuff
190 #if defined(H2W)
191 # define WM_TITLEBAR_TEXT "HexenWorld"
192 #else
193 # define WM_TITLEBAR_TEXT "Hexen II"
194 #endif
195
196 //====================================
197
198 /*
199 ================
200 ClearAllStates
201 ================
202 */
ClearAllStates(void)203 static void ClearAllStates (void)
204 {
205 Key_ClearStates ();
206 IN_ClearStates ();
207 }
208
209
210 /*
211 ================
212 VID_AllocBuffers
213 ================
214 */
VID_AllocBuffers(int width,int height)215 static qboolean VID_AllocBuffers (int width, int height)
216 {
217 int tsize, tbuffersize;
218
219 tbuffersize = width * height * sizeof (*d_pzbuffer);
220
221 tsize = D_SurfaceCacheForRes (width, height);
222
223 tbuffersize += tsize;
224
225 // see if there's enough memory, allowing for the normal mode 0x13 pixel,
226 // z, and surface buffers
227 //if ((host_parms->memsize - tbuffersize + SURFCACHE_SIZE_AT_320X200 +
228 // 0x10000 * 3) < MINIMUM_MEMORY)
229 // Pa3PyX: using hopefully better estimation now
230 // if total memory < needed surface cache + (minimum operational memory
231 // less surface cache for 320x200 and typical hunk state after init)
232 if (host_parms->memsize < tbuffersize + 0x180000 + 0xC00000)
233 {
234 Con_SafePrintf ("Not enough memory for video mode\n");
235 return false; // not enough memory for mode
236 }
237
238 vid_surfcachesize = tsize;
239
240 if (d_pzbuffer)
241 {
242 D_FlushCaches ();
243 Hunk_FreeToHighMark (VID_highhunkmark);
244 d_pzbuffer = NULL;
245 }
246
247 VID_highhunkmark = Hunk_HighMark ();
248
249 d_pzbuffer = (short *) Hunk_HighAllocName (tbuffersize, "video");
250
251 vid_surfcache = (byte *)d_pzbuffer +
252 width * height * sizeof (*d_pzbuffer);
253
254 return true;
255 }
256
257 /*
258 ================
259 VID_CheckAdequateMem
260 ================
261 */
VID_CheckAdequateMem(int width,int height)262 static qboolean VID_CheckAdequateMem (int width, int height)
263 {
264 int tbuffersize;
265
266 tbuffersize = width * height * sizeof (*d_pzbuffer);
267
268 tbuffersize += D_SurfaceCacheForRes (width, height);
269
270 // see if there's enough memory, allowing for the normal mode 0x13 pixel,
271 // z, and surface buffers
272 //if ((host_parms->memsize - tbuffersize + SURFCACHE_SIZE_AT_320X200 +
273 // 0x10000 * 3) < MINIMUM_MEMORY)
274 // Pa3PyX: using hopefully better estimation now
275 // Experimentation: the heap should have at least 12.0 megs
276 // remaining (after init) after setting video mode, otherwise
277 // it's Hunk_Alloc failures and cache thrashes upon level load
278 if (host_parms->memsize < tbuffersize + 0x180000 + 0xC00000)
279 {
280 return false; // not enough memory for mode
281 }
282
283 return true;
284 }
285
286 //------------------------------------
sort_modes(const void * arg1,const void * arg2)287 static int sort_modes (const void *arg1, const void *arg2)
288 {
289 const vmode_t *a1, *a2;
290 a1 = (const vmode_t *) arg1;
291 a2 = (const vmode_t *) arg2;
292
293 if (a1->width == a2->width)
294 return a1->height - a2->height; // lowres-to-highres
295 // return a2->height - a1->height; // highres-to-lowres
296 else
297 return a1->width - a2->width; // lowres-to-highres
298 // return a2->width - a1->width; // highres-to-lowres
299 }
300
VID_PrepareModes(void)301 static void VID_PrepareModes (void)
302 {
303 qboolean have_mem;
304 ULONG id;
305 unsigned int i;
306 APTR handle;
307 struct DimensionInfo diminfo;
308 #ifdef PLATFORM_AMIGAOS3
309 ULONG monitorid;
310 struct DisplayInfo dispinfo;
311 struct NameInfo nameinfo;
312 #endif
313
314 num_fmodes = 0;
315 num_wmodes = 0;
316
317 // standard 4:3 windowed modes
318 for (i = 0; i < (int)MAX_STDMODES; i++)
319 {
320 have_mem = VID_CheckAdequateMem(std_modes[i].width, std_modes[i].height);
321 if (!have_mem)
322 break;
323 wmodelist[num_wmodes].width = std_modes[i].width;
324 wmodelist[num_wmodes].height = std_modes[i].height;
325 wmodelist[num_wmodes].fullscreen = 0;
326 wmodelist[num_wmodes].bpp = 8;
327 wmodelist[num_wmodes].modeid = INVALID_ID;
328 #ifdef PLATFORM_AMIGAOS3
329 wmodelist[num_wmodes].noadapt = false;
330 #endif
331 q_snprintf (wmodelist[num_wmodes].modedesc, MAX_DESC,
332 "%d x %d", std_modes[i].width, std_modes[i].height);
333 num_wmodes++;
334 }
335
336 // fullscreen modes
337 id = INVALID_ID;
338 while((id = NextDisplayInfo(id)) != INVALID_ID)
339 {
340 #ifdef PLATFORM_AMIGAOS3
341 //if (!IsCyberModeID(id)) continue;
342 monitorid = id & MONITOR_ID_MASK;
343 if (monitorid == DEFAULT_MONITOR_ID || monitorid == A2024_MONITOR_ID)
344 continue;
345 #endif
346
347 handle = FindDisplayInfo(id);
348 if (!handle)
349 continue;
350
351 #ifdef PLATFORM_AMIGAOS3
352 if (!GetDisplayInfoData(handle, (UBYTE *)&dispinfo, sizeof(dispinfo), DTAG_DISP, 0))
353 continue;
354 // this is a good way to filter out HAM, EHB, DPF modes
355 if (!GetDisplayInfoData(handle, (UBYTE *)&nameinfo, sizeof(nameinfo), DTAG_NAME, 0))
356 continue;
357 //Con_SafePrintf ("modeid %08x name %s\n", id, nameinfo.Name);
358 #endif
359
360 if (!GetDisplayInfoData(handle, (UBYTE *)&diminfo, sizeof(diminfo), DTAG_DIMS, 0))
361 continue;
362
363 #ifdef __AROS__
364 if (diminfo.MaxDepth != 24 || diminfo.Nominal.MaxX + 1 < MIN_WIDTH) continue;
365 #else
366 if (diminfo.MaxDepth != 8 || diminfo.Nominal.MaxX + 1 < MIN_WIDTH) continue;
367 #endif
368
369 fmodelist[num_fmodes].width = diminfo.Nominal.MaxX + 1;
370 fmodelist[num_fmodes].height = diminfo.Nominal.MaxY + 1;
371 #ifdef PLATFORM_AMIGAOS3
372 // round down PAL resolutions to the nearest multiple of 240
373 if (fmodelist[num_fmodes].height % 256 == 0)
374 fmodelist[num_fmodes].height -= fmodelist[num_fmodes].height % MIN_HEIGHT;
375 #endif
376 fmodelist[num_fmodes].fullscreen = 1;
377 fmodelist[num_fmodes].bpp = 8; // diminfo.MaxDepth
378 fmodelist[num_fmodes].modeid = id;
379 q_snprintf (fmodelist[num_fmodes].modedesc, MAX_DESC, "%d x %d", (fmodelist[num_fmodes].width), (fmodelist[num_fmodes].height));
380 #ifdef PLATFORM_AMIGAOS3
381 if (dispinfo.PropertyFlags & DIPF_IS_LACE)
382 q_strlcat(fmodelist[num_fmodes].modedesc, "i", MAX_DESC);
383 if (monitorid == PAL_MONITOR_ID)
384 q_strlcat(fmodelist[num_fmodes].modedesc, " PAL", MAX_DESC);
385 else if (monitorid == NTSC_MONITOR_ID)
386 q_strlcat(fmodelist[num_fmodes].modedesc, " NTSC", MAX_DESC);
387 else if (monitorid == DBLPAL_MONITOR_ID)
388 q_strlcat(fmodelist[num_fmodes].modedesc, " DblPAL", MAX_DESC);
389 else if (monitorid == DBLNTSC_MONITOR_ID)
390 q_strlcat(fmodelist[num_fmodes].modedesc, " DblNTSC", MAX_DESC);
391 else if (monitorid == EURO36_MONITOR_ID)
392 q_strlcat(fmodelist[num_fmodes].modedesc, " Euro36", MAX_DESC);
393 else if (monitorid == EURO72_MONITOR_ID)
394 q_strlcat(fmodelist[num_fmodes].modedesc, " Euro72", MAX_DESC);
395 else if (monitorid == SUPER72_MONITOR_ID)
396 q_strlcat(fmodelist[num_fmodes].modedesc, " Super72", MAX_DESC);
397 else if (monitorid == VGA_MONITOR_ID)
398 q_strlcat(fmodelist[num_fmodes].modedesc, " VGA", MAX_DESC);
399 else
400 q_strlcat(fmodelist[num_fmodes].modedesc, " RTG", MAX_DESC);
401
402 fmodelist[num_fmodes].noadapt = (!CyberGfxBase || !IsCyberModeID(id));
403 #endif
404 //Con_SafePrintf ("fmodelist[%d].modedesc = %s maxdepth %d id %08x\n", num_fmodes, fmodelist[num_fmodes].modedesc, diminfo.MaxDepth, id);
405
406 if (++num_fmodes == MAX_MODE_LIST)
407 break;
408 }
409
410 if (num_fmodes == 0)
411 {
412 Con_SafePrintf ("No fullscreen video modes available\n");
413 if (num_wmodes > RES_640X480)
414 num_wmodes = RES_640X480 + 1;
415 modelist = wmodelist;
416 nummodes = &num_wmodes;
417 vid_default = 0;
418 Cvar_SetValueQuick (&vid_config_swx, modelist[vid_default].width);
419 Cvar_SetValueQuick (&vid_config_swy, modelist[vid_default].height);
420 return;
421 }
422
423 if (num_fmodes > 1)
424 qsort(fmodelist, num_fmodes, sizeof(vmode_t), sort_modes);
425 nummodes = &num_fmodes;
426 modelist = fmodelist;
427
428 /*vid_maxwidth = fmodelist[num_fmodes-1].width;
429 vid_maxheight = fmodelist[num_fmodes-1].height;*/
430 if ((screen = LockPubScreen(NULL)))
431 {
432 vid_maxwidth = screen->Width;
433 vid_maxheight = screen->Height;
434 UnlockPubScreen(NULL, screen);
435 screen = NULL;
436 }
437
438 // see if we have 320x240 among the available modes
439 for (i = 0; i < num_fmodes; i++)
440 {
441 if (fmodelist[i].width == 320 && fmodelist[i].height == 240)
442 {
443 vid_default = i;
444 break;
445 }
446 }
447
448 if (vid_default < 0)
449 {
450 // 320x240 not found among the supported dimensions
451 // set default to the lowest resolution reported
452 vid_default = 0;
453 }
454
455 // limit the windowed (standard) modes list to desktop dimensions
456 for (i = 0; i < num_wmodes; i++)
457 {
458 if (wmodelist[i].width > vid_maxwidth || wmodelist[i].height > vid_maxheight)
459 break;
460 }
461 if (i < num_wmodes)
462 num_wmodes = i;
463
464 Cvar_SetValueQuick (&vid_config_swx, modelist[vid_default].width);
465 Cvar_SetValueQuick (&vid_config_swy, modelist[vid_default].height);
466 }
467
VID_ListModes_f(void)468 static void VID_ListModes_f (void)
469 {
470 int i;
471
472 Con_Printf ("Maximum allowed mode: %d x %d\n", vid_maxwidth, vid_maxheight);
473 Con_Printf ("Windowed modes enabled:\n");
474 for (i = 0; i < num_wmodes; i++)
475 Con_Printf ("%2d: %d x %d\n", i, wmodelist[i].width, wmodelist[i].height);
476 Con_Printf ("Fullscreen modes enumerated:");
477 if (num_fmodes)
478 {
479 Con_Printf ("\n");
480 for (i = 0; i < num_fmodes; i++)
481 Con_Printf ("%2d: %d x %d\n", i, fmodelist[i].width, fmodelist[i].height);
482 }
483 else
484 {
485 Con_Printf (" None\n");
486 }
487 }
488
VID_NumModes_f(void)489 static void VID_NumModes_f (void)
490 {
491 Con_Printf ("%d video modes in current list\n", *nummodes);
492 }
493
494 //====================================
495
496
VID_DestroyWindow(void)497 static void VID_DestroyWindow (void)
498 {
499 if (window)
500 {
501 CloseWindow(window);
502 window = NULL;
503 }
504
505 if (buffer)
506 {
507 free(buffer);
508 buffer = NULL;
509 }
510
511 /*if (pointermem)
512 {
513 FreeVec(pointermem);
514 pointermem = NULL;
515 }*/
516
517 #if defined(PLATFORM_AMIGAOS3) && defined(USE_C2P)
518 use_c2p = false;
519
520 if (sbuf[0])
521 {
522 FreeScreenBuffer(screen, sbuf[0]);
523 sbuf[0] = NULL;
524 }
525
526 if (sbuf[1])
527 {
528 FreeScreenBuffer(screen, sbuf[1]);
529 sbuf[1] = NULL;
530 }
531 #endif
532
533 if (screen)
534 {
535 CloseScreen(screen);
536 screen = NULL;
537 }
538 }
539
VID_SetMode(int modenum,const unsigned char * palette)540 static qboolean VID_SetMode (int modenum, const unsigned char *palette)
541 {
542 ULONG flags;
543 qboolean eightbit = false;
544
545 in_mode_set = true;
546
547 VID_DestroyWindow ();
548
549 if (!vid_config_fscr.integer && (screen = LockPubScreen(NULL)))
550 {
551 eightbit = (GetBitMapAttr(screen->RastPort.BitMap, BMA_DEPTH) <= 8);
552 UnlockPubScreen(NULL, screen);
553 screen = NULL;
554
555 if (eightbit)
556 {
557 struct EasyStruct es;
558
559 es.es_StructSize = sizeof(es);
560 es.es_Flags = 0;
561 es.es_Title = (STRPTR) ENGINE_NAME;
562 es.es_TextFormat = (STRPTR) "Windowed mode requires 15 bit or higher color depth screen\nFalling back to fullscreen.";
563 es.es_GadgetFormat = (STRPTR) "OK";
564
565 EasyRequest(0, &es, 0, 0);
566
567 Cvar_SetQuick (&vid_config_fscr, "1");
568 }
569 }
570
571 flags = WFLG_ACTIVATE | WFLG_RMBTRAP;
572
573 if (vid_config_fscr.integer)
574 {
575 ULONG ModeID;
576 #if defined(PLATFORM_AMIGAOS3) && defined(USE_C2P)
577 struct BitMap *bm;
578 #endif
579
580 /*ModeID = BestCModeIDTags(
581 CYBRBIDTG_Depth, 8,
582 CYBRBIDTG_NominalWidth, modelist[modenum].width,
583 CYBRBIDTG_NominalHeight, modelist[modenum].height,
584 TAG_DONE);*/
585 ModeID = modelist[modenum].modeid;
586
587 screen = OpenScreenTags(0,
588 ModeID != INVALID_ID ? SA_DisplayID : TAG_IGNORE, ModeID,
589 SA_Width, modelist[modenum].width,
590 SA_Height, modelist[modenum].height,
591 SA_Depth, 8,
592 SA_Quiet, TRUE,
593 TAG_DONE);
594
595 #if defined(PLATFORM_AMIGAOS3) && defined(USE_C2P)
596 currentBitMap = 0;
597 bm = screen->RastPort.BitMap;
598
599 if ((GetBitMapAttr(bm, BMA_FLAGS) & BMF_STANDARD) && (modelist[modenum].width % 32) == 0)
600 {
601 if ((sbuf[0] = AllocScreenBuffer(screen, 0, SB_SCREEN_BITMAP)) && (sbuf[1] = AllocScreenBuffer(screen, 0, 0)))
602 {
603 use_c2p = true;
604 #ifndef C2P_BITMAP
605 c2p_init(modelist[modenum].width, modelist[modenum].height, 0, bm->BytesPerRow*bm->Rows);
606 #endif
607 // this fixes some RTG modes which would otherwise display garbage on the 1st buffer swap
608 //VID_Update(NULL);
609 }
610 }
611 #endif
612 }
613
614 if (screen)
615 {
616 flags |= WFLG_BACKDROP | WFLG_BORDERLESS;
617 }
618 else
619 {
620 if (eightbit) /* shouldn't happen, but.. */
621 Sys_Error("failed OpenScreen ()");
622 Cvar_SetQuick (&vid_config_fscr, "0");
623 flags |= WFLG_DRAGBAR | WFLG_DEPTHGADGET | WFLG_CLOSEGADGET;
624 }
625
626 window = OpenWindowTags(0,
627 WA_InnerWidth, modelist[modenum].width,
628 WA_InnerHeight, modelist[modenum].height,
629 WA_Title, (IPTR)WM_TITLEBAR_TEXT,
630 WA_Flags, flags,
631 screen ? WA_CustomScreen : TAG_IGNORE, (IPTR)screen,
632 WA_IDCMP, IDCMP_CLOSEWINDOW | IDCMP_ACTIVEWINDOW | IDCMP_INACTIVEWINDOW,
633 TAG_DONE);
634
635 if (window)
636 {
637 /*pointermem = AllocVec(256, MEMF_ANY | MEMF_CLEAR);
638 if (pointermem) {*/
639 vid.height = vid.conheight = modelist[modenum].height;
640 vid.rowbytes = vid.conrowbytes = vid.width = vid.conwidth = modelist[modenum].width;
641 buffer = (pixel_t *) malloc(vid.width * vid.height);
642
643 if (buffer)
644 {
645 vid.buffer = vid.direct = vid.conbuffer = buffer;
646 vid.numpages = 1;
647 vid.aspect = ((float)vid.height / (float)vid.width) * (320.0 / 240.0);
648
649 if (VID_AllocBuffers (vid.width, vid.height))
650 {
651 D_InitCaches (vid_surfcache, vid_surfcachesize);
652
653 // real success. set vid_modenum properly.
654 vid_modenum = modenum;
655 modestate = (screen) ? MS_FULLDIB : MS_WINDOWED;
656 Cvar_SetValueQuick (&vid_config_swx, modelist[vid_modenum].width);
657 Cvar_SetValueQuick (&vid_config_swy, modelist[vid_modenum].height);
658 if (screen)
659 Cvar_SetValueQuick (&vid_config_mon, (float)(modelist[vid_modenum].modeid & MONITOR_ID_MASK));
660
661 //IN_HideMouse ();
662
663 ClearAllStates();
664
665 VID_SetPalette (palette);
666
667 Con_SafePrintf ("Video Mode: %ux%ux%d\n", vid.width, vid.height, modelist[modenum].bpp);
668
669 #ifdef PLATFORM_AMIGAOS3
670 vid.noadapt = modelist[modenum].noadapt;
671 #endif
672 in_mode_set = false;
673 vid.recalc_refdef = 1;
674
675 return true;
676 }
677 free(buffer);
678 buffer = NULL;
679 }
680 /* FreeVec(pointermem);
681 pointermem = NULL;
682 }*/
683 CloseWindow(window);
684 window = NULL;
685 }
686
687 if (screen)
688 {
689 CloseScreen(screen);
690 screen = NULL;
691 }
692
693 in_mode_set = false;
694 return false;
695 }
696
697
VID_ChangeVideoMode(int newmode)698 static void VID_ChangeVideoMode (int newmode)
699 {
700 int temp;
701
702 temp = scr_disabled_for_loading;
703 scr_disabled_for_loading = true;
704 CDAudio_Pause ();
705 BGM_Pause ();
706 S_ClearBuffer ();
707
708 if (!VID_SetMode (newmode, vid_curpal))
709 {
710 if (vid_modenum == newmode)
711 Sys_Error ("Couldn't set video mode");
712
713 // failed setting mode, probably due to insufficient
714 // memory. go back to previous mode.
715 Cvar_SetValueQuick (&vid_mode, vid_modenum);
716 if (!VID_SetMode (vid_modenum, vid_curpal))
717 Sys_Error ("Couldn't set video mode");
718 }
719
720 CDAudio_Resume ();
721 BGM_Resume ();
722 scr_disabled_for_loading = temp;
723 }
724
VID_Restart_f(void)725 static void VID_Restart_f (void)
726 {
727 if (vid_mode.integer < 0 || vid_mode.integer >= *nummodes)
728 {
729 Con_Printf ("Bad video mode %d\n", vid_mode.integer);
730 Cvar_SetValueQuick (&vid_mode, vid_modenum);
731 return;
732 }
733
734 Con_Printf ("Re-initializing video:\n");
735 VID_ChangeVideoMode (vid_mode.integer);
736 }
737
VID_LockBuffer(void)738 void VID_LockBuffer(void)
739 {
740 }
741
VID_UnlockBuffer(void)742 void VID_UnlockBuffer(void)
743 {
744 }
745
746
VID_SetPalette(const unsigned char * palette)747 void VID_SetPalette(const unsigned char *palette)
748 {
749 const unsigned char *p;
750 unsigned char *pp;
751 int i;
752
753 palette_changed = true;
754
755 if (palette != vid_curpal)
756 memcpy(vid_curpal, palette, sizeof(vid_curpal));
757
758 if (screen)
759 {
760 ULONG spal[1 + (256 * 3) + 1];
761 ULONG *sp = spal;
762
763 *sp++ = 256 << 16;
764
765 for (i = 0, p = palette; i < 256; i++)
766 {
767 *sp++ = ((ULONG) *p++) << 24;
768 *sp++ = ((ULONG) *p++) << 24;
769 *sp++ = ((ULONG) *p++) << 24;
770 }
771
772 *sp = 0;
773
774 LoadRGB32(&screen->ViewPort, spal);
775 }
776
777 for (i = 0, p = palette, pp = ppal; i < 256; i++)
778 {
779 if (host_bigendian)
780 {
781 *pp++ = 0;
782 *pp++ = *p++;
783 *pp++ = *p++;
784 *pp++ = *p++;
785 }
786 else
787 {
788 *pp++ = p[2];
789 *pp++ = p[1];
790 *pp++ = p[0];
791 *pp++ = 0;
792 p += 3;
793 }
794 }
795 }
796
VID_ShiftPalette(const unsigned char * palette)797 void VID_ShiftPalette(const unsigned char *palette)
798 {
799 VID_SetPalette(palette);
800 }
801
VID_Init(const unsigned char * palette)802 void VID_Init (const unsigned char *palette)
803 {
804 int width, height, i, temp, monitor;
805 const char *read_vars[] = {
806 "vid_config_fscr",
807 "vid_config_mon",
808 "vid_config_swx",
809 "vid_config_swy" };
810 #define num_readvars ( sizeof(read_vars)/sizeof(read_vars[0]) )
811
812 #ifdef __CLIB2__
813 GfxBase = (struct GfxBase *)OpenLibrary("graphics.library", 0);
814 if (!GfxBase)
815 Sys_Error ("Cannot open graphics.library!");
816 #endif
817
818 #ifdef PLATFORM_AMIGAOS3
819 CyberGfxBase = OpenLibrary("cybergraphics.library", 0);
820 /*if (!CyberGfxBase)
821 Sys_Error ("Cannot open cybergraphics.library!");*/
822
823 #ifdef USE_C2P
824 if (SysBase->AttnFlags & AFF_68040)
825 {
826 #ifdef C2P_BITMAP
827 c2p_write_bm = c2p1x1_8_c5_bm_040;
828 #else
829 c2p_init = c2p1x1_8_c5_040_init;
830 c2p_write = c2p1x1_8_c5_040;
831 #endif
832 }
833 else
834 {
835 #ifdef C2P_BITMAP
836 c2p_write_bm = c2p1x1_8_c5_bm;
837 #else
838 c2p_init = c2p1x1_8_c5_030_smcinit;
839 c2p_write = c2p1x1_8_c5_030;
840 #endif
841 }
842 #endif
843 #endif
844
845 temp = scr_disabled_for_loading;
846 scr_disabled_for_loading = true;
847
848 Cvar_RegisterVariable (&vid_config_fscr);
849 Cvar_RegisterVariable (&vid_config_mon);
850 Cvar_RegisterVariable (&vid_config_swy);
851 Cvar_RegisterVariable (&vid_config_swx);
852 Cvar_RegisterVariable (&vid_config_gly);
853 Cvar_RegisterVariable (&vid_config_glx);
854 Cvar_RegisterVariable (&vid_mode);
855 Cvar_RegisterVariable (&_enable_mouse);
856 Cvar_RegisterVariable (&vid_showload);
857
858 Cmd_AddCommand ("vid_listmodes", VID_ListModes_f);
859 Cmd_AddCommand ("vid_nummodes", VID_NumModes_f);
860 Cmd_AddCommand ("vid_restart", VID_Restart_f);
861
862
863 // prepare the modelists, find the actual modenum for vid_default
864 VID_PrepareModes();
865 //VID_ListModes_f();
866
867 // set vid_mode to our safe default first
868 Cvar_SetValueQuick (&vid_mode, vid_default);
869
870 // perform an early read of config.cfg
871 CFG_ReadCvars (read_vars, num_readvars);
872
873 // windowed mode is default
874 // see if the user wants fullscreen
875 if (COM_CheckParm("-fullscreen") || COM_CheckParm("-f"))
876 {
877 Cvar_SetQuick (&vid_config_fscr, "1");
878 }
879 else if (COM_CheckParm("-window") || COM_CheckParm("-w"))
880 {
881 Cvar_SetQuick (&vid_config_fscr, "0");
882 }
883
884 if (vid_config_fscr.integer && !num_fmodes) // FIXME: see below, as well
885 Sys_Error ("No fullscreen modes available at this color depth");
886
887 width = vid_config_swx.integer;
888 height = vid_config_swy.integer;
889 monitor = vid_config_mon.integer;
890
891 // user is always right ...
892 i = COM_CheckParm("-width");
893 if (i && i < com_argc-1)
894 { // FIXME: this part doesn't know about a disaster case
895 // like we aren't reported any fullscreen modes.
896 width = atoi(com_argv[i+1]);
897
898 i = COM_CheckParm("-height");
899 if (i && i < com_argc-1)
900 height = atoi(com_argv[i+1]);
901 else // proceed with 4/3 ratio
902 height = 3 * width / 4;
903 }
904
905 // pick the appropriate list
906 if (vid_config_fscr.integer)
907 {
908 modelist = fmodelist;
909 nummodes = &num_fmodes;
910 }
911 else
912 {
913 modelist = wmodelist;
914 nummodes = &num_wmodes;
915 }
916
917 // user requested a mode either from the config or from the
918 // command line
919 // scan existing modes to see if this is already available
920 // if not, add this as the last "valid" video mode and set
921 // vid_mode to it only if it doesn't go beyond vid_maxwidth
922 i = 0;
923 if (vid_config_fscr.integer)
924 {
925 while (i < *nummodes)
926 {
927 if (modelist[i].width == width && modelist[i].height == height && (modelist[i].modeid & MONITOR_ID_MASK) == monitor)
928 break;
929 i++;
930 }
931 }
932 if (i == 0 || i == *nummodes)
933 {
934 i = 0;
935 while (i < *nummodes)
936 {
937 if (modelist[i].width == width && modelist[i].height == height)
938 break;
939 i++;
940 }
941 }
942 if (i < *nummodes)
943 {
944 Cvar_SetValueQuick (&vid_mode, i);
945 }
946 else if ( (width <= vid_maxwidth && width >= MIN_WIDTH &&
947 height <= vid_maxheight && height >= MIN_HEIGHT) ||
948 COM_CheckParm("-force") )
949 {
950 modelist[*nummodes].width = width;
951 modelist[*nummodes].height = height;
952 modelist[*nummodes].fullscreen = 1;
953 modelist[*nummodes].bpp = 8;
954 modelist[*nummodes].modeid = INVALID_ID;
955 #ifdef PLATFORM_AMIGAOS3
956 modelist[*nummodes].noadapt = false;
957 #endif
958 q_snprintf (modelist[*nummodes].modedesc, MAX_DESC, "%d x %d (user mode)", width, height);
959 Cvar_SetValueQuick (&vid_mode, *nummodes);
960 (*nummodes)++;
961 }
962 else
963 {
964 Con_SafePrintf ("ignoring invalid -width and/or -height arguments\n");
965 }
966
967 vid.maxwarpwidth = WARP_WIDTH;
968 vid.maxwarpheight = WARP_HEIGHT;
969 vid.colormap = host_colormap;
970 vid.fullbright = 256 - LittleLong (*((int *)vid.colormap + 2048));
971
972 if (!VID_SetMode (vid_mode.integer, palette))
973 {
974 if (vid_mode.integer == vid_default)
975 Sys_Error ("Couldn't set video mode");
976
977 // just one more try before dying
978 Con_SafePrintf ("Couldn't set video mode %d\n"
979 "Trying the default mode\n", vid_mode.integer);
980 //Cvar_SetQuick (&vid_config_fscr, "0");
981 Cvar_SetValueQuick (&vid_mode, vid_default);
982 if (!VID_SetMode (vid_default, palette))
983 Sys_Error ("Couldn't set video mode");
984 }
985
986 // lock the early-read cvars until Host_Init is finished
987 for (i = 0; i < (int)num_readvars; i++)
988 Cvar_LockVar (read_vars[i]);
989
990 scr_disabled_for_loading = temp;
991
992 vid_menudrawfn = VID_MenuDraw;
993 vid_menukeyfn = VID_MenuKey;
994 }
995
996
VID_Shutdown(void)997 void VID_Shutdown (void)
998 {
999 VID_DestroyWindow ();
1000
1001 #ifdef PLATFORM_AMIGAOS3
1002 if (CyberGfxBase) {
1003 CloseLibrary(CyberGfxBase);
1004 CyberGfxBase = NULL;
1005 }
1006 #endif
1007 #ifdef __CLIB2__
1008 if (GfxBase) {
1009 CloseLibrary((struct Library *)GfxBase);
1010 GfxBase = NULL;
1011 }
1012 #endif
1013 }
1014
1015
FlipScreen(vrect_t * rects)1016 static void FlipScreen (vrect_t *rects)
1017 {
1018 #ifdef USE_C2P
1019 if (use_c2p)
1020 {
1021 currentBitMap ^= 1;
1022 #ifdef C2P_BITMAP
1023 c2p_write_bm(vid.width, vid.height, 0, 0, vid.buffer, sbuf[currentBitMap]->sb_BitMap);
1024 #else
1025 c2p_write(vid.buffer, sbuf[currentBitMap]->sb_BitMap->Planes[0]);
1026 #endif
1027 ChangeScreenBuffer(screen, sbuf[currentBitMap]);
1028 return;
1029 }
1030 #endif
1031
1032 while (rects)
1033 {
1034 #ifdef PLATFORM_AMIGAOS3
1035 if (!CyberGfxBase)
1036 {
1037 WriteChunkyPixels(window->RPort,
1038 rects->x,
1039 rects->y,
1040 rects->width,
1041 rects->height,
1042 vid.buffer,
1043 vid.rowbytes);
1044 }
1045 else
1046 #endif
1047 if (screen)
1048 {
1049 WritePixelArray(vid.buffer,
1050 rects->x,
1051 rects->y,
1052 vid.rowbytes,
1053 window->RPort,
1054 rects->x,
1055 rects->y,
1056 rects->width,
1057 rects->height,
1058 RECTFMT_LUT8);
1059 }
1060 else
1061 {
1062 WriteLUTPixelArray(vid.buffer,
1063 rects->x,
1064 rects->y,
1065 vid.rowbytes,
1066 window->RPort, ppal,
1067 window->BorderLeft + rects->x,
1068 window->BorderTop + rects->y,
1069 rects->width,
1070 rects->height,
1071 CTABFMT_XRGB8);
1072 }
1073
1074 rects = rects->pnext;
1075 }
1076 }
1077
VID_Update(vrect_t * rects)1078 void VID_Update(vrect_t *rects)
1079 {
1080 vrect_t rect;
1081
1082 if (palette_changed)
1083 {
1084 palette_changed = false;
1085 rect.x = 0;
1086 rect.y = 0;
1087 rect.width = vid.width;
1088 rect.height = vid.height;
1089 rect.pnext = NULL;
1090 rects = ▭
1091 }
1092
1093 // We've drawn the frame; copy it to the screen
1094 FlipScreen (rects);
1095
1096 // handle the mouse state when windowed if that's changed
1097 if (_enable_mouse.integer != enable_mouse /*&& modestate == MS_WINDOWED*/)
1098 {
1099 if (_enable_mouse.integer)
1100 IN_ActivateMouse ();
1101 else IN_DeactivateMouse ();
1102
1103 enable_mouse = _enable_mouse.integer;
1104 }
1105 }
1106
1107
1108 /*
1109 ================
1110 D_BeginDirectRect
1111 ================
1112 */
D_BeginDirectRect(int x,int y,byte * pbitmap,int width,int height)1113 void D_BeginDirectRect (int x, int y, byte *pbitmap, int width, int height)
1114 {
1115 directbitmap = pbitmap;
1116 }
1117
1118 /*
1119 ================
1120 D_EndDirectRect
1121 ================
1122 */
D_EndDirectRect(int x,int y,int width,int height)1123 void D_EndDirectRect (int x, int y, int width, int height)
1124 {
1125 if (!window || !directbitmap)
1126 return;
1127
1128 if (x < 0)
1129 x = vid.width + x - 1;
1130
1131 if (screen)
1132 {
1133 WritePixelArray(directbitmap, 0, 0, width, window->RPort, x, y, width, height, RECTFMT_LUT8);
1134 }
1135 else
1136 {
1137 WriteLUTPixelArray(directbitmap, 0, 0, width, window->RPort, ppal, window->BorderLeft + x, window->BorderTop + y, width, height, CTABFMT_XRGB8);
1138 }
1139
1140 directbitmap = NULL;
1141 }
1142
1143 #ifndef H2W
1144 // unused in hexenworld
D_ShowLoadingSize(void)1145 void D_ShowLoadingSize (void)
1146 {
1147 #if defined(DRAW_PROGRESSBARS)
1148 #error NOT IMPLEMENTED
1149 #endif
1150 }
1151 #endif
1152
1153
1154 //==========================================================================
1155
1156 /*
1157 ================
1158 VID_HandlePause
1159 ================
1160 */
VID_HandlePause(qboolean paused)1161 void VID_HandlePause (qboolean paused)
1162 {
1163 if (_enable_mouse.integer /*&& (modestate == MS_WINDOWED)*/)
1164 {
1165 // for consistency, don't show pointer - S.A
1166 if (paused)
1167 {
1168 IN_DeactivateMouse ();
1169 //SetPointer(window, pointermem, 16, 16, 0, 0);
1170 }
1171 else
1172 {
1173 IN_ActivateMouse ();
1174 //ClearPointer(window);
1175 }
1176 }
1177 }
1178
1179
1180 /*
1181 ================
1182 VID_ToggleFullscreen
1183 Handles switching between fullscreen/windowed modes
1184 and brings the mouse to a proper state afterwards
1185 ================
1186 */
1187 //extern qboolean menu_disabled_mouse;
VID_ToggleFullscreen(void)1188 void VID_ToggleFullscreen(void)
1189 {
1190 // implement this...
1191 }
1192
1193
1194 //========================================================
1195 // Video menu stuff
1196 //========================================================
1197
1198 static int vid_menunum;
1199 static int vid_cursor;
1200 static vmode_t *vid_menulist; // this changes when vid_menu_fs changes
1201 static qboolean want_fstoggle, need_apply;
1202 static qboolean vid_menu_firsttime = true;
1203
1204 enum {
1205 VID_FULLSCREEN, // make sure the fullscreen entry (0)
1206 VID_RESOLUTION, // is lower than resolution entry (1)
1207 VID_BLANKLINE, // spacer line
1208 VID_RESET,
1209 VID_APPLY,
1210 VID_ITEMS
1211 };
1212
M_DrawYesNo(int x,int y,int on,int white)1213 static void M_DrawYesNo (int x, int y, int on, int white)
1214 {
1215 if (on)
1216 {
1217 if (white)
1218 M_PrintWhite (x, y, "yes");
1219 else
1220 M_Print (x, y, "yes");
1221 }
1222 else
1223 {
1224 if (white)
1225 M_PrintWhite (x, y, "no");
1226 else
1227 M_Print (x, y, "no");
1228 }
1229 }
1230
1231 /*
1232 ================
1233 VID_MenuDraw
1234 ================
1235 */
VID_MenuDraw(void)1236 static void VID_MenuDraw (void)
1237 {
1238 ScrollTitle("gfx/menu/title7.lmp");
1239
1240 if (vid_menu_firsttime)
1241 { // settings for entering the menu first time
1242 vid_menunum = vid_modenum;
1243 vid_menu_fs = (modestate != MS_WINDOWED);
1244 vid_menulist = (modestate == MS_WINDOWED) ? wmodelist : fmodelist;
1245 vid_cursor = (num_fmodes) ? 0 : VID_RESOLUTION;
1246 vid_menu_firsttime = false;
1247 }
1248
1249 want_fstoggle = ( ((modestate == MS_WINDOWED) && vid_menu_fs) || ((modestate != MS_WINDOWED) && !vid_menu_fs) );
1250
1251 need_apply = (vid_menunum != vid_modenum) || want_fstoggle;
1252
1253 M_Print (76, 92 + 8*VID_FULLSCREEN, "Fullscreen: ");
1254 M_DrawYesNo (76+12*8, 92 + 8*VID_FULLSCREEN, vid_menu_fs, !want_fstoggle);
1255
1256 M_Print (76, 92 + 8*VID_RESOLUTION, "Resolution: ");
1257 if (vid_menunum == vid_modenum)
1258 M_PrintWhite (76+12*8, 92 + 8*VID_RESOLUTION, vid_menulist[vid_menunum].modedesc);
1259 else
1260 M_Print (76+12*8, 92 + 8*VID_RESOLUTION, vid_menulist[vid_menunum].modedesc);
1261
1262 if (need_apply)
1263 {
1264 M_Print (76, 92 + 8*VID_RESET, "RESET CHANGES");
1265 M_Print (76, 92 + 8*VID_APPLY, "APPLY CHANGES");
1266 }
1267
1268 M_DrawCharacter (64, 92 + vid_cursor*8, 12+((int)(realtime*4)&1));
1269 }
1270
match_windowed_fullscr_modes(void)1271 static int match_windowed_fullscr_modes (void)
1272 {
1273 int l;
1274 vmode_t *tmplist;
1275 int *tmpcount;
1276
1277 // choose the new mode
1278 tmplist = (vid_menu_fs) ? fmodelist : wmodelist;
1279 tmpcount = (vid_menu_fs) ? &num_fmodes : &num_wmodes;
1280 for (l = 0; l < *tmpcount; l++)
1281 {
1282 if (tmplist[l].width == vid_menulist[vid_menunum].width &&
1283 tmplist[l].height == vid_menulist[vid_menunum].height)
1284 {
1285 return l;
1286 }
1287 }
1288 return 0;
1289 }
1290
1291 /*
1292 ================
1293 VID_MenuKey
1294 ================
1295 */
VID_MenuKey(int key)1296 static void VID_MenuKey (int key)
1297 {
1298 int *tmpnum;
1299
1300 switch (key)
1301 {
1302 case K_ESCAPE:
1303 vid_cursor = (num_fmodes) ? 0 : VID_RESOLUTION;
1304 M_Menu_Options_f ();
1305 return;
1306
1307 case K_ENTER:
1308 switch (vid_cursor)
1309 {
1310 case VID_RESET:
1311 vid_menu_fs = (modestate != MS_WINDOWED);
1312 vid_menunum = vid_modenum;
1313 vid_menulist = (modestate == MS_WINDOWED) ? wmodelist : fmodelist;
1314 vid_cursor = (num_fmodes) ? 0 : VID_RESOLUTION;
1315 break;
1316 case VID_APPLY:
1317 if (need_apply)
1318 {
1319 Cvar_SetValueQuick(&vid_mode, vid_menunum);
1320 Cvar_SetValueQuick(&vid_config_fscr, vid_menu_fs);
1321 modelist = (vid_menu_fs) ? fmodelist : wmodelist;
1322 nummodes = (vid_menu_fs) ? &num_fmodes : &num_wmodes;
1323 VID_Restart_f();
1324 }
1325 vid_cursor = (num_fmodes) ? 0 : VID_RESOLUTION;
1326 break;
1327 }
1328 return;
1329
1330 case K_LEFTARROW:
1331 switch (vid_cursor)
1332 {
1333 case VID_FULLSCREEN:
1334 vid_menu_fs = !vid_menu_fs;
1335 vid_menunum = match_windowed_fullscr_modes();
1336 vid_menulist = (vid_menu_fs) ? fmodelist : wmodelist;
1337 /*if (fs_toggle_works)
1338 VID_ToggleFullscreen();*/
1339 break;
1340 case VID_RESOLUTION:
1341 S_LocalSound ("raven/menu1.wav");
1342 vid_menunum--;
1343 if (vid_menunum < 0)
1344 vid_menunum = 0;
1345 break;
1346 }
1347 return;
1348
1349 case K_RIGHTARROW:
1350 switch (vid_cursor)
1351 {
1352 case VID_FULLSCREEN:
1353 vid_menu_fs = !vid_menu_fs;
1354 vid_menunum = match_windowed_fullscr_modes();
1355 vid_menulist = (vid_menu_fs) ? fmodelist : wmodelist;
1356 /*if (fs_toggle_works)
1357 VID_ToggleFullscreen();*/
1358 break;
1359 case VID_RESOLUTION:
1360 S_LocalSound ("raven/menu1.wav");
1361 tmpnum = (vid_menu_fs) ? &num_fmodes : &num_wmodes;
1362 vid_menunum++;
1363 /*if (vid_menunum >= *nummodes)
1364 vid_menunum = *nummodes - 1;*/
1365 if (vid_menunum >= *tmpnum)
1366 vid_menunum--;
1367 break;
1368 }
1369 return;
1370
1371 case K_UPARROW:
1372 S_LocalSound ("raven/menu1.wav");
1373 vid_cursor--;
1374 if (vid_cursor < 0)
1375 {
1376 vid_cursor = (need_apply) ? VID_ITEMS-1 : VID_BLANKLINE-1;
1377 }
1378 else if (vid_cursor == VID_BLANKLINE)
1379 {
1380 vid_cursor--;
1381 }
1382 break;
1383
1384 case K_DOWNARROW:
1385 S_LocalSound ("raven/menu1.wav");
1386 vid_cursor++;
1387 if (vid_cursor >= VID_ITEMS)
1388 {
1389 vid_cursor = (num_fmodes) ? 0 : VID_RESOLUTION;
1390 break;
1391 }
1392 if (vid_cursor >= VID_BLANKLINE)
1393 {
1394 if (need_apply)
1395 {
1396 if (vid_cursor == VID_BLANKLINE)
1397 vid_cursor++;
1398 }
1399 else
1400 {
1401 vid_cursor = (num_fmodes) ? 0 : VID_RESOLUTION;
1402 }
1403 }
1404 break;
1405
1406 default:
1407 return;
1408 }
1409 }
1410
1411