Subversion Repositories Kolibri OS

Rev

Blame | Last modification | View Log | RSS feed

  1. /*
  2. Copyright (C) 1996-1997 Id Software, Inc.
  3.  
  4. This program is free software; you can redistribute it and/or
  5. modify it under the terms of the GNU General Public License
  6. as published by the Free Software Foundation; either version 2
  7. of the License, or (at your option) any later version.
  8.  
  9. This program is distributed in the hope that it will be useful,
  10. but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  
  12.  
  13. See the GNU General Public License for more details.
  14.  
  15. You should have received a copy of the GNU General Public License
  16. along with this program; if not, write to the Free Software
  17. Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
  18.  
  19. */
  20. //
  21. // vid_dos.c: DOS-specific video routines
  22. //
  23.  
  24. #include <unistd.h>
  25. #include <stdlib.h>
  26. #include <stdio.h>
  27. #include <string.h>
  28. #include <dos.h>
  29. #include <dpmi.h>
  30. #include <go32.h>
  31.  
  32. #include "quakedef.h"
  33. #include "d_local.h"
  34. #include "dosisms.h"
  35. #include "vid_dos.h"
  36.  
  37. int                     vid_modenum;
  38. vmode_t         *pcurrentmode = NULL;
  39. int                     vid_testingmode, vid_realmode;
  40. double          vid_testendtime;
  41.  
  42. cvar_t          vid_mode = {"vid_mode","0", false};
  43. cvar_t          vid_wait = {"vid_wait","0"};
  44. cvar_t          vid_nopageflip = {"vid_nopageflip","0", true};
  45. cvar_t          _vid_wait_override = {"_vid_wait_override", "0", true};
  46. cvar_t          _vid_default_mode = {"_vid_default_mode","0", true};
  47. cvar_t          _vid_default_mode_win = {"_vid_default_mode_win","1", true};
  48. cvar_t          vid_config_x = {"vid_config_x","800", true};
  49. cvar_t          vid_config_y = {"vid_config_y","600", true};
  50. cvar_t          vid_stretch_by_2 = {"vid_stretch_by_2","1", true};
  51. cvar_t          _windowed_mouse = {"_windowed_mouse","0", true};
  52. cvar_t          vid_fullscreen_mode = {"vid_fullscreen_mode","3", true};
  53. cvar_t          vid_windowed_mode = {"vid_windowed_mode","0", true};
  54. cvar_t          block_switch = {"block_switch","0", true};
  55. cvar_t          vid_window_x = {"vid_window_x", "0", true};
  56. cvar_t          vid_window_y = {"vid_window_y", "0", true};
  57.  
  58. int     d_con_indirect = 0;
  59.  
  60. int             numvidmodes;
  61. vmode_t *pvidmodes;
  62.  
  63. static int      firstupdate = 1;
  64.  
  65. extern regs_t regs;
  66.  
  67. void VID_TestMode_f (void);
  68. void VID_NumModes_f (void);
  69. void VID_DescribeCurrentMode_f (void);
  70. void VID_DescribeMode_f (void);
  71. void VID_DescribeModes_f (void);
  72.  
  73. byte    vid_current_palette[768];       // save for mode changes
  74.  
  75.  
  76. static qboolean nomodecheck = false;
  77.  
  78. unsigned short  d_8to16table[256];      // not used in 8 bpp mode
  79. unsigned                d_8to24table[256];      // not used in 8 bpp mode
  80.  
  81. void VID_MenuDraw (void);
  82. void VID_MenuKey (int key);
  83.  
  84.  
  85. /*
  86. ================
  87. VID_Init
  88. ================
  89. */
  90. void    VID_Init (unsigned char *palette)
  91. {
  92.         Cvar_RegisterVariable (&vid_mode);
  93.         Cvar_RegisterVariable (&vid_wait);
  94.         Cvar_RegisterVariable (&vid_nopageflip);
  95.         Cvar_RegisterVariable (&_vid_wait_override);
  96.         Cvar_RegisterVariable (&_vid_default_mode);
  97.         Cvar_RegisterVariable (&_vid_default_mode_win);
  98.         Cvar_RegisterVariable (&vid_config_x);
  99.         Cvar_RegisterVariable (&vid_config_y);
  100.         Cvar_RegisterVariable (&vid_stretch_by_2);
  101.         Cvar_RegisterVariable (&_windowed_mouse);
  102.         Cvar_RegisterVariable (&vid_fullscreen_mode);
  103.         Cvar_RegisterVariable (&vid_windowed_mode);
  104.         Cvar_RegisterVariable (&block_switch);
  105.  
  106.         Cmd_AddCommand ("vid_testmode", VID_TestMode_f);
  107.         Cmd_AddCommand ("vid_nummodes", VID_NumModes_f);
  108.         Cmd_AddCommand ("vid_describecurrentmode", VID_DescribeCurrentMode_f);
  109.         Cmd_AddCommand ("vid_describemode", VID_DescribeMode_f);
  110.         Cmd_AddCommand ("vid_describemodes", VID_DescribeModes_f);
  111.  
  112. // set up the mode list; note that later inits link in their modes ahead of
  113. // earlier ones, so the standard VGA modes are always first in the list. This
  114. // is important because mode 0 must always be VGA mode 0x13
  115.         if (!COM_CheckParm ("-stdvid"))
  116.                 VID_InitExtra ();
  117.         VGA_Init ();
  118.  
  119.         vid_testingmode = 0;
  120.  
  121.         vid_modenum = vid_mode.value;
  122.  
  123.         VID_SetMode (vid_modenum, palette);
  124.  
  125.         vid_realmode = vid_modenum;
  126.        
  127.         vid_menudrawfn = VID_MenuDraw;
  128.         vid_menukeyfn = VID_MenuKey;
  129. }
  130.  
  131.  
  132. /*
  133. =================
  134. VID_GetModePtr
  135. =================
  136. */
  137. vmode_t *VID_GetModePtr (int modenum)
  138. {
  139.         vmode_t *pv;
  140.  
  141.         pv = pvidmodes;
  142.         if (!pv)
  143.                 Sys_Error ("VID_GetModePtr: empty vid mode list");
  144.  
  145.         while (modenum--)
  146.         {
  147.                 pv = pv->pnext;
  148.                 if (!pv)
  149.                         Sys_Error ("VID_GetModePtr: corrupt vid mode list");
  150.         }
  151.  
  152.         return pv;
  153. }
  154.  
  155. /*
  156. ================
  157. VID_NumModes
  158. ================
  159. */
  160. int VID_NumModes ()
  161. {
  162.         return (numvidmodes);
  163. }
  164.  
  165.  
  166. /*
  167. ================
  168. VID_ModeInfo
  169. ================
  170. */
  171. char *VID_ModeInfo (int modenum, char **ppheader)
  172. {
  173.         static char     *badmodestr = "Bad mode number";
  174.         vmode_t         *pv;
  175.  
  176.         pv = VID_GetModePtr (modenum);
  177.  
  178.         if (!pv)
  179.         {
  180.                 if (ppheader)
  181.                         *ppheader = NULL;
  182.                 return badmodestr;
  183.         }
  184.         else
  185.         {
  186.                 if (ppheader)
  187.                         *ppheader = pv->header;
  188.                 return pv->name;
  189.         }
  190. }
  191.  
  192.  
  193. /*
  194. ================
  195. VID_SetMode
  196. ================
  197. */
  198. int VID_SetMode (int modenum, unsigned char *palette)
  199. {
  200.         int             stat;
  201.         vmode_t *pnewmode, *poldmode;
  202.  
  203.         if ((modenum >= numvidmodes) || (modenum < 0))
  204.         {
  205.                 Cvar_SetValue ("vid_mode", (float)vid_modenum);
  206.  
  207.                 nomodecheck = true;
  208.                 Con_Printf ("No such video mode: %d\n", modenum);
  209.                 nomodecheck = false;
  210.  
  211.                 if (pcurrentmode == NULL)
  212.                 {
  213.                         modenum = 0;    // mode hasn't been set yet, so initialize to base
  214.                                                         //  mode since they gave us an invalid initial mode
  215.                 }
  216.                 else
  217.                 {
  218.                         return 0;
  219.                 }
  220.         }
  221.  
  222.         pnewmode = VID_GetModePtr (modenum);
  223.  
  224.         if (pnewmode == pcurrentmode)
  225.                 return 1;       // already in the desired mode
  226.  
  227. // initialize the new mode
  228.         poldmode = pcurrentmode;
  229.         pcurrentmode = pnewmode;
  230.  
  231.         vid.width = pcurrentmode->width;
  232.         vid.height = pcurrentmode->height;
  233.         vid.aspect = pcurrentmode->aspect;
  234.         vid.rowbytes = pcurrentmode->rowbytes;
  235.  
  236.         stat = (*pcurrentmode->setmode) (&vid, pcurrentmode);
  237.  
  238.         if (stat < 1)
  239.         {
  240.                 if (stat == 0)
  241.                 {
  242.                 // real, hard failure that requires resetting the mode
  243.                         if (!VID_SetMode (vid_modenum, palette))        // restore prior mode
  244.                                 Sys_Error ("VID_SetMode: Unable to set any mode, probably "
  245.                                                    "because there's not enough memory available");
  246.                         Con_Printf ("Failed to set mode %d\n", modenum);
  247.                         return 0;
  248.                 }
  249.                 else if (stat == -1)
  250.                 {
  251.                 // not enough memory; just put things back the way they were
  252.                         pcurrentmode = poldmode;
  253.                         vid.width = pcurrentmode->width;
  254.                         vid.height = pcurrentmode->height;
  255.                         vid.aspect = pcurrentmode->aspect;
  256.                         vid.rowbytes = pcurrentmode->rowbytes;
  257.                         return 0;
  258.                 }
  259.                 else
  260.                 {
  261.                         Sys_Error ("VID_SetMode: invalid setmode return code %d");
  262.                 }
  263.         }
  264.  
  265.         (*pcurrentmode->setpalette) (&vid, pcurrentmode, palette);
  266.  
  267.         vid_modenum = modenum;
  268.         Cvar_SetValue ("vid_mode", (float)vid_modenum);
  269.  
  270.         nomodecheck = true;
  271.         Con_Printf ("%s\n", VID_ModeInfo (vid_modenum, NULL));
  272.         nomodecheck = false;
  273.  
  274.         vid.recalc_refdef = 1;
  275.  
  276.         return 1;
  277. }
  278.  
  279.  
  280. /*
  281. ================
  282. VID_SetPalette
  283. ================
  284. */
  285. void    VID_SetPalette (unsigned char *palette)
  286. {
  287.         if (palette != vid_current_palette)
  288.                 Q_memcpy(vid_current_palette, palette, 768);
  289.         (*pcurrentmode->setpalette)(&vid, pcurrentmode, vid_current_palette);
  290. }
  291.  
  292.  
  293. /*
  294. ================
  295. VID_ShiftPalette
  296. ================
  297. */
  298. void    VID_ShiftPalette (unsigned char *palette)
  299. {
  300.  
  301.         VID_SetPalette (palette);
  302. }
  303.  
  304.  
  305. /*
  306. ================
  307. VID_Shutdown
  308. ================
  309. */
  310. void VID_Shutdown (void)
  311. {
  312.  
  313.         regs.h.ah = 0;
  314.         regs.h.al = 0x3;
  315.         dos_int86(0x10);
  316.  
  317.         vid_testingmode = 0;
  318. }
  319.  
  320.  
  321. /*
  322. ================
  323. VID_Update
  324. ================
  325. */
  326. void    VID_Update (vrect_t *rects)
  327. {
  328.         if (firstupdate && _vid_default_mode.value)
  329.         {
  330.                 if(_vid_default_mode.value >= numvidmodes)
  331.                         Cvar_SetValue ("_vid_default_mode", 0);
  332.  
  333.                 firstupdate = 0;
  334.                 Cvar_SetValue ("vid_mode", _vid_default_mode.value);
  335.         }
  336.  
  337.         (*pcurrentmode->swapbuffers)(&vid, pcurrentmode, rects);
  338.  
  339.         if (!nomodecheck)
  340.         {
  341.                 if (vid_testingmode)
  342.                 {
  343.                         if (realtime >= vid_testendtime)
  344.                         {
  345.                                 VID_SetMode (vid_realmode, vid_current_palette);
  346.                                 vid_testingmode = 0;
  347.                         }
  348.                 }
  349.                 else
  350.                 {
  351.                         if (vid_mode.value != vid_realmode)
  352.                         {
  353.                                 VID_SetMode ((int)vid_mode.value, vid_current_palette);
  354.                                 Cvar_SetValue ("vid_mode", (float)vid_modenum);
  355.                                                                         // so if mode set fails, we don't keep on
  356.                                                                         //  trying to set that mode
  357.                                 vid_realmode = vid_modenum;
  358.                         }
  359.                 }
  360.         }
  361. }
  362.  
  363.  
  364. /*
  365. =================
  366. VID_NumModes_f
  367. =================
  368. */
  369. void VID_NumModes_f (void)
  370. {
  371.         int             nummodes;
  372.  
  373.         nummodes = VID_NumModes ();
  374.         if (nummodes == 1)
  375.                 Con_Printf ("%d video mode is available\n", VID_NumModes ());
  376.         else
  377.                 Con_Printf ("%d video modes are available\n", VID_NumModes ());
  378. }
  379.  
  380.  
  381. /*
  382. =================
  383. VID_DescribeCurrentMode_f
  384. =================
  385. */
  386. void VID_DescribeCurrentMode_f (void)
  387. {
  388.         Con_Printf ("%s\n", VID_ModeInfo (vid_modenum, NULL));
  389. }
  390.  
  391.  
  392. /*
  393. =================
  394. VID_DescribeMode_f
  395. =================
  396. */
  397. void VID_DescribeMode_f (void)
  398. {
  399.         int             modenum;
  400.        
  401.         modenum = Q_atoi (Cmd_Argv(1));
  402.  
  403.         Con_Printf ("%s\n", VID_ModeInfo (modenum, NULL));
  404. }
  405.  
  406.  
  407. /*
  408. =================
  409. VID_DescribeModes_f
  410. =================
  411. */
  412. void VID_DescribeModes_f (void)
  413. {
  414.         int                     i, nummodes;
  415.         char            *pinfo, *pheader;
  416.         vmode_t         *pv;
  417.         qboolean        na;
  418.  
  419.         na = false;
  420.  
  421.         nummodes = VID_NumModes ();
  422.         for (i=0 ; i<nummodes ; i++)
  423.         {
  424.                 pv = VID_GetModePtr (i);
  425.                 pinfo = VID_ModeInfo (i, &pheader);
  426.                 if (pheader)
  427.                         Con_Printf ("\n%s\n", pheader);
  428.  
  429.                 if (VGA_CheckAdequateMem (pv->width, pv->height, pv->rowbytes,
  430.                         (pv->numpages == 1) || vid_nopageflip.value))
  431.                 {
  432.                         Con_Printf ("%2d: %s\n", i, pinfo);
  433.                 }
  434.                 else
  435.                 {
  436.                         Con_Printf ("**: %s\n", pinfo);
  437.                         na = true;
  438.                 }
  439.         }
  440.  
  441.         if (na)
  442.         {
  443.                 Con_Printf ("\n[**: not enough system RAM for mode]\n");
  444.         }
  445. }
  446.  
  447.  
  448. /*
  449. =================
  450. VID_GetModeDescription
  451. =================
  452. */
  453. char *VID_GetModeDescription (int mode)
  454. {
  455.         char            *pinfo, *pheader;
  456.         vmode_t         *pv;
  457.  
  458.         pv = VID_GetModePtr (mode);
  459.         pinfo = VID_ModeInfo (mode, &pheader);
  460.  
  461.         if (VGA_CheckAdequateMem (pv->width, pv->height, pv->rowbytes,
  462.                 (pv->numpages == 1) || vid_nopageflip.value))
  463.         {
  464.                 return pinfo;
  465.         }
  466.         else
  467.         {
  468.                 return NULL;
  469.         }
  470. }
  471.  
  472.  
  473. /*
  474. =================
  475. VID_TestMode_f
  476. =================
  477. */
  478. void VID_TestMode_f (void)
  479. {
  480.         int             modenum;
  481.         double  testduration;
  482.  
  483.         if (!vid_testingmode)
  484.         {
  485.                 modenum = Q_atoi (Cmd_Argv(1));
  486.  
  487.                 if (VID_SetMode (modenum, vid_current_palette))
  488.                 {
  489.                         vid_testingmode = 1;
  490.                         testduration = Q_atof (Cmd_Argv(2));
  491.                         if (testduration == 0)
  492.                                 testduration = 5.0;
  493.                         vid_testendtime = realtime + testduration;
  494.                 }
  495.         }
  496. }
  497.  
  498.  
  499. /*
  500. ================
  501. D_BeginDirectRect
  502. ================
  503. */
  504. void D_BeginDirectRect (int x, int y, byte *pbitmap, int width, int height)
  505. {
  506.  
  507.         if (!vid.direct || !pcurrentmode)
  508.                 return;
  509.  
  510.         if ((width > 24) || (height > 24) || (width < 1) || (height < 1))
  511.                 return;
  512.  
  513.         if (width & 0x03)
  514.                 return;
  515.  
  516.         (*pcurrentmode->begindirectrect) (&vid, pcurrentmode, x, y, pbitmap, width,
  517.                                                                           height);
  518. }
  519.  
  520.  
  521. /*
  522. ================
  523. D_EndDirectRect
  524. ================
  525. */
  526. void D_EndDirectRect (int x, int y, int width, int height)
  527. {
  528.  
  529.         if (!vid.direct || !pcurrentmode)
  530.                 return;
  531.  
  532.         if ((width > 24) || (height > 24) || (width < 1) || (height < 1))
  533.                 return;
  534.  
  535.         if ((width & 0x03) || (height & 0x03))
  536.                 return;
  537.  
  538.         (*pcurrentmode->enddirectrect) (&vid, pcurrentmode, x, y, width, height);
  539. }
  540.  
  541.  
  542. //===========================================================================
  543.  
  544. extern void M_Menu_Options_f (void);
  545. extern void M_Print (int cx, int cy, char *str);
  546. extern void M_PrintWhite (int cx, int cy, char *str);
  547. extern void M_DrawCharacter (int cx, int line, int num);
  548. extern void M_DrawTransPic (int x, int y, qpic_t *pic);
  549. extern void M_DrawPic (int x, int y, qpic_t *pic);
  550.  
  551. static int      vid_line, vid_wmodes, vid_column_size;
  552.  
  553. typedef struct
  554. {
  555.         int             modenum;
  556.         char    *desc;
  557.         int             iscur;
  558. } modedesc_t;
  559.  
  560. #define MAX_COLUMN_SIZE 11
  561.  
  562. #define MAX_MODEDESCS   (MAX_COLUMN_SIZE*3)
  563.  
  564. static modedesc_t       modedescs[MAX_MODEDESCS];
  565.  
  566. /*
  567. ================
  568. VID_MenuDraw
  569. ================
  570. */
  571. void VID_MenuDraw (void)
  572. {
  573.         qpic_t          *p;
  574.         char            *ptr;
  575.         int                     nummodes, i, j, column, row, dup;
  576.         char            temp[100];
  577.  
  578.         vid_wmodes = 0;
  579.         nummodes = VID_NumModes ();
  580.        
  581.         p = Draw_CachePic ("gfx/vidmodes.lmp");
  582.         M_DrawPic ( (320-p->width)/2, 4, p);
  583.  
  584.         for (i=0 ; i<nummodes ; i++)
  585.         {
  586.                 if (vid_wmodes < MAX_MODEDESCS)
  587.                 {
  588.                         if (i != 1)
  589.                         {
  590.                                 ptr = VID_GetModeDescription (i);
  591.  
  592.                                 if (ptr)
  593.                                 {
  594.                                         dup = 0;
  595.  
  596.                                         for (j=0 ; j<vid_wmodes ; j++)
  597.                                         {
  598.                                                 if (!strcmp (modedescs[j].desc, ptr))
  599.                                                 {
  600.                                                         if (modedescs[j].modenum != 0)
  601.                                                         {
  602.                                                                 modedescs[j].modenum = i;
  603.                                                                 dup = 1;
  604.  
  605.                                                                 if (i == vid_modenum)
  606.                                                                         modedescs[j].iscur = 1;
  607.                                                         }
  608.                                                         else
  609.                                                         {
  610.                                                                 dup = 1;
  611.                                                         }
  612.  
  613.                                                         break;
  614.                                                 }
  615.                                         }
  616.  
  617.                                         if (!dup)
  618.                                         {
  619.                                                 modedescs[vid_wmodes].modenum = i;
  620.                                                 modedescs[vid_wmodes].desc = ptr;
  621.                                                 modedescs[vid_wmodes].iscur = 0;
  622.  
  623.                                                 if (i == vid_modenum)
  624.                                                         modedescs[vid_wmodes].iscur = 1;
  625.  
  626.                                                 vid_wmodes++;
  627.                                         }
  628.                                 }
  629.                         }
  630.                 }
  631.         }
  632.  
  633.         vid_column_size = (vid_wmodes + 2) / 3;
  634.  
  635.         column = 16;
  636.         row = 36;
  637.  
  638.         for (i=0 ; i<vid_wmodes ; i++)
  639.         {
  640.                 if (modedescs[i].iscur)
  641.                         M_PrintWhite (column, row, modedescs[i].desc);
  642.                 else
  643.                         M_Print (column, row, modedescs[i].desc);
  644.  
  645.                 row += 8;
  646.  
  647.                 if ((i % vid_column_size) == (vid_column_size - 1))
  648.                 {
  649.                         column += 13*8;
  650.                         row = 36;
  651.                 }
  652.         }
  653.  
  654. // line cursor
  655.         if (vid_testingmode)
  656.         {
  657.                 sprintf (temp, "TESTING %s",
  658.                                 modedescs[vid_line].desc);
  659.                 M_Print (13*8, 36 + MAX_COLUMN_SIZE * 8 + 8*4, temp);
  660.                 M_Print (9*8, 36 + MAX_COLUMN_SIZE * 8 + 8*6,
  661.                                 "Please wait 5 seconds...");
  662.         }
  663.         else
  664.         {
  665.                 M_Print (9*8, 36 + MAX_COLUMN_SIZE * 8 + 8,
  666.                                 "Press Enter to set mode");
  667.                 M_Print (6*8, 36 + MAX_COLUMN_SIZE * 8 + 8*3,
  668.                                 "T to test mode for 5 seconds");
  669.                 ptr = VID_GetModeDescription (vid_modenum);
  670.                 sprintf (temp, "D to make %s the default", ptr);
  671.                 M_Print (6*8, 36 + MAX_COLUMN_SIZE * 8 + 8*5, temp);
  672.                 ptr = VID_GetModeDescription ((int)_vid_default_mode.value);
  673.  
  674.                 if (ptr)
  675.                 {
  676.                         sprintf (temp, "Current default is %s", ptr);
  677.                         M_Print (7*8, 36 + MAX_COLUMN_SIZE * 8 + 8*6, temp);
  678.                 }
  679.  
  680.                 M_Print (15*8, 36 + MAX_COLUMN_SIZE * 8 + 8*8,
  681.                                 "Esc to exit");
  682.  
  683.                 row = 36 + (vid_line % vid_column_size) * 8;
  684.                 column = 8 + (vid_line / vid_column_size) * 13*8;
  685.  
  686.                 M_DrawCharacter (column, row, 12+((int)(realtime*4)&1));
  687.         }
  688. }
  689.  
  690.  
  691. /*
  692. ================
  693. VID_MenuKey
  694. ================
  695. */
  696. void VID_MenuKey (int key)
  697. {
  698.         if (vid_testingmode)
  699.                 return;
  700.  
  701.         switch (key)
  702.         {
  703.         case K_ESCAPE:
  704.                 S_LocalSound ("misc/menu1.wav");
  705.                 M_Menu_Options_f ();
  706.                 break;
  707.  
  708.         case K_UPARROW:
  709.                 S_LocalSound ("misc/menu1.wav");
  710.                 vid_line--;
  711.  
  712.                 if (vid_line < 0)
  713.                         vid_line = vid_wmodes - 1;
  714.                 break;
  715.  
  716.         case K_DOWNARROW:
  717.                 S_LocalSound ("misc/menu1.wav");
  718.                 vid_line++;
  719.  
  720.                 if (vid_line >= vid_wmodes)
  721.                         vid_line = 0;
  722.                 break;
  723.  
  724.         case K_LEFTARROW:
  725.                 S_LocalSound ("misc/menu1.wav");
  726.                 vid_line -= vid_column_size;
  727.  
  728.                 if (vid_line < 0)
  729.                 {
  730.                         vid_line += ((vid_wmodes + (vid_column_size - 1)) /
  731.                                         vid_column_size) * vid_column_size;
  732.  
  733.                         while (vid_line >= vid_wmodes)
  734.                                 vid_line -= vid_column_size;
  735.                 }
  736.                 break;
  737.  
  738.         case K_RIGHTARROW:
  739.                 S_LocalSound ("misc/menu1.wav");
  740.                 vid_line += vid_column_size;
  741.  
  742.                 if (vid_line >= vid_wmodes)
  743.                 {
  744.                         vid_line -= ((vid_wmodes + (vid_column_size - 1)) /
  745.                                         vid_column_size) * vid_column_size;
  746.  
  747.                         while (vid_line < 0)
  748.                                 vid_line += vid_column_size;
  749.                 }
  750.                 break;
  751.  
  752.         case K_ENTER:
  753.                 S_LocalSound ("misc/menu1.wav");
  754.                 VID_SetMode (modedescs[vid_line].modenum, vid_current_palette);
  755.                 break;
  756.  
  757.         case 'T':
  758.         case 't':
  759.                 S_LocalSound ("misc/menu1.wav");
  760.                 if (VID_SetMode (modedescs[vid_line].modenum, vid_current_palette))
  761.                 {
  762.                         vid_testingmode = 1;
  763.                         vid_testendtime = realtime + 5.0;
  764.                 }
  765.                 break;
  766.  
  767.         case 'D':
  768.         case 'd':
  769.                 S_LocalSound ("misc/menu1.wav");
  770.                 firstupdate = 0;
  771.                 Cvar_SetValue ("_vid_default_mode", vid_modenum);
  772.                 break;
  773.  
  774.         default:
  775.                 break;
  776.         }
  777. }
  778.  
  779.