diff options
| author | Travis Bradshaw <travis.bradshaw@idsoftware.com> | 2012-01-31 14:32:09 -0600 |
|---|---|---|
| committer | Travis Bradshaw <travis.bradshaw@idsoftware.com> | 2012-01-31 14:32:09 -0600 |
| commit | 0023db327bc1db00068284b70e1db45857aeee35 (patch) | |
| tree | 01dd8366d20bd674741cfe8ceb069d82a2e33973 /WinQuake/vid_dos.c | |
| download | quake-pum-0023db327bc1db00068284b70e1db45857aeee35.tar.gz | |
The Quake sources as originally release under the GPL license on December 21, 1999
Diffstat (limited to 'WinQuake/vid_dos.c')
| -rw-r--r-- | WinQuake/vid_dos.c | 778 |
1 files changed, 778 insertions, 0 deletions
diff --git a/WinQuake/vid_dos.c b/WinQuake/vid_dos.c new file mode 100644 index 0000000..bf4293f --- /dev/null +++ b/WinQuake/vid_dos.c @@ -0,0 +1,778 @@ +/* +Copyright (C) 1996-1997 Id Software, Inc. + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + +See the GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +*/ +// +// vid_dos.c: DOS-specific video routines +// + +#include <unistd.h> +#include <stdlib.h> +#include <stdio.h> +#include <string.h> +#include <dos.h> +#include <dpmi.h> +#include <go32.h> + +#include "quakedef.h" +#include "d_local.h" +#include "dosisms.h" +#include "vid_dos.h" + +int vid_modenum; +vmode_t *pcurrentmode = NULL; +int vid_testingmode, vid_realmode; +double vid_testendtime; + +cvar_t vid_mode = {"vid_mode","0", false}; +cvar_t vid_wait = {"vid_wait","0"}; +cvar_t vid_nopageflip = {"vid_nopageflip","0", true}; +cvar_t _vid_wait_override = {"_vid_wait_override", "0", true}; +cvar_t _vid_default_mode = {"_vid_default_mode","0", true}; +cvar_t _vid_default_mode_win = {"_vid_default_mode_win","1", true}; +cvar_t vid_config_x = {"vid_config_x","800", true}; +cvar_t vid_config_y = {"vid_config_y","600", true}; +cvar_t vid_stretch_by_2 = {"vid_stretch_by_2","1", true}; +cvar_t _windowed_mouse = {"_windowed_mouse","0", true}; +cvar_t vid_fullscreen_mode = {"vid_fullscreen_mode","3", true}; +cvar_t vid_windowed_mode = {"vid_windowed_mode","0", true}; +cvar_t block_switch = {"block_switch","0", true}; +cvar_t vid_window_x = {"vid_window_x", "0", true}; +cvar_t vid_window_y = {"vid_window_y", "0", true}; + +int d_con_indirect = 0; + +int numvidmodes; +vmode_t *pvidmodes; + +static int firstupdate = 1; + +extern regs_t regs; + +void VID_TestMode_f (void); +void VID_NumModes_f (void); +void VID_DescribeCurrentMode_f (void); +void VID_DescribeMode_f (void); +void VID_DescribeModes_f (void); + +byte vid_current_palette[768]; // save for mode changes + + +static qboolean nomodecheck = false; + +unsigned short d_8to16table[256]; // not used in 8 bpp mode +unsigned d_8to24table[256]; // not used in 8 bpp mode + +void VID_MenuDraw (void); +void VID_MenuKey (int key); + + +/* +================ +VID_Init +================ +*/ +void VID_Init (unsigned char *palette) +{ + Cvar_RegisterVariable (&vid_mode); + Cvar_RegisterVariable (&vid_wait); + Cvar_RegisterVariable (&vid_nopageflip); + Cvar_RegisterVariable (&_vid_wait_override); + Cvar_RegisterVariable (&_vid_default_mode); + Cvar_RegisterVariable (&_vid_default_mode_win); + Cvar_RegisterVariable (&vid_config_x); + Cvar_RegisterVariable (&vid_config_y); + Cvar_RegisterVariable (&vid_stretch_by_2); + Cvar_RegisterVariable (&_windowed_mouse); + Cvar_RegisterVariable (&vid_fullscreen_mode); + Cvar_RegisterVariable (&vid_windowed_mode); + Cvar_RegisterVariable (&block_switch); + + Cmd_AddCommand ("vid_testmode", VID_TestMode_f); + Cmd_AddCommand ("vid_nummodes", VID_NumModes_f); + Cmd_AddCommand ("vid_describecurrentmode", VID_DescribeCurrentMode_f); + Cmd_AddCommand ("vid_describemode", VID_DescribeMode_f); + Cmd_AddCommand ("vid_describemodes", VID_DescribeModes_f); + +// set up the mode list; note that later inits link in their modes ahead of +// earlier ones, so the standard VGA modes are always first in the list. This +// is important because mode 0 must always be VGA mode 0x13 + if (!COM_CheckParm ("-stdvid")) + VID_InitExtra (); + VGA_Init (); + + vid_testingmode = 0; + + vid_modenum = vid_mode.value; + + VID_SetMode (vid_modenum, palette); + + vid_realmode = vid_modenum; + + vid_menudrawfn = VID_MenuDraw; + vid_menukeyfn = VID_MenuKey; +} + + +/* +================= +VID_GetModePtr +================= +*/ +vmode_t *VID_GetModePtr (int modenum) +{ + vmode_t *pv; + + pv = pvidmodes; + if (!pv) + Sys_Error ("VID_GetModePtr: empty vid mode list"); + + while (modenum--) + { + pv = pv->pnext; + if (!pv) + Sys_Error ("VID_GetModePtr: corrupt vid mode list"); + } + + return pv; +} + +/* +================ +VID_NumModes +================ +*/ +int VID_NumModes () +{ + return (numvidmodes); +} + + +/* +================ +VID_ModeInfo +================ +*/ +char *VID_ModeInfo (int modenum, char **ppheader) +{ + static char *badmodestr = "Bad mode number"; + vmode_t *pv; + + pv = VID_GetModePtr (modenum); + + if (!pv) + { + if (ppheader) + *ppheader = NULL; + return badmodestr; + } + else + { + if (ppheader) + *ppheader = pv->header; + return pv->name; + } +} + + +/* +================ +VID_SetMode +================ +*/ +int VID_SetMode (int modenum, unsigned char *palette) +{ + int stat; + vmode_t *pnewmode, *poldmode; + + if ((modenum >= numvidmodes) || (modenum < 0)) + { + Cvar_SetValue ("vid_mode", (float)vid_modenum); + + nomodecheck = true; + Con_Printf ("No such video mode: %d\n", modenum); + nomodecheck = false; + + if (pcurrentmode == NULL) + { + modenum = 0; // mode hasn't been set yet, so initialize to base + // mode since they gave us an invalid initial mode + } + else + { + return 0; + } + } + + pnewmode = VID_GetModePtr (modenum); + + if (pnewmode == pcurrentmode) + return 1; // already in the desired mode + +// initialize the new mode + poldmode = pcurrentmode; + pcurrentmode = pnewmode; + + vid.width = pcurrentmode->width; + vid.height = pcurrentmode->height; + vid.aspect = pcurrentmode->aspect; + vid.rowbytes = pcurrentmode->rowbytes; + + stat = (*pcurrentmode->setmode) (&vid, pcurrentmode); + + if (stat < 1) + { + if (stat == 0) + { + // real, hard failure that requires resetting the mode + if (!VID_SetMode (vid_modenum, palette)) // restore prior mode + Sys_Error ("VID_SetMode: Unable to set any mode, probably " + "because there's not enough memory available"); + Con_Printf ("Failed to set mode %d\n", modenum); + return 0; + } + else if (stat == -1) + { + // not enough memory; just put things back the way they were + pcurrentmode = poldmode; + vid.width = pcurrentmode->width; + vid.height = pcurrentmode->height; + vid.aspect = pcurrentmode->aspect; + vid.rowbytes = pcurrentmode->rowbytes; + return 0; + } + else + { + Sys_Error ("VID_SetMode: invalid setmode return code %d"); + } + } + + (*pcurrentmode->setpalette) (&vid, pcurrentmode, palette); + + vid_modenum = modenum; + Cvar_SetValue ("vid_mode", (float)vid_modenum); + + nomodecheck = true; + Con_Printf ("%s\n", VID_ModeInfo (vid_modenum, NULL)); + nomodecheck = false; + + vid.recalc_refdef = 1; + + return 1; +} + + +/* +================ +VID_SetPalette +================ +*/ +void VID_SetPalette (unsigned char *palette) +{ + if (palette != vid_current_palette) + Q_memcpy(vid_current_palette, palette, 768); + (*pcurrentmode->setpalette)(&vid, pcurrentmode, vid_current_palette); +} + + +/* +================ +VID_ShiftPalette +================ +*/ +void VID_ShiftPalette (unsigned char *palette) +{ + + VID_SetPalette (palette); +} + + +/* +================ +VID_Shutdown +================ +*/ +void VID_Shutdown (void) +{ + + regs.h.ah = 0; + regs.h.al = 0x3; + dos_int86(0x10); + + vid_testingmode = 0; +} + + +/* +================ +VID_Update +================ +*/ +void VID_Update (vrect_t *rects) +{ + if (firstupdate && _vid_default_mode.value) + { + if(_vid_default_mode.value >= numvidmodes) + Cvar_SetValue ("_vid_default_mode", 0); + + firstupdate = 0; + Cvar_SetValue ("vid_mode", _vid_default_mode.value); + } + + (*pcurrentmode->swapbuffers)(&vid, pcurrentmode, rects); + + if (!nomodecheck) + { + if (vid_testingmode) + { + if (realtime >= vid_testendtime) + { + VID_SetMode (vid_realmode, vid_current_palette); + vid_testingmode = 0; + } + } + else + { + if (vid_mode.value != vid_realmode) + { + VID_SetMode ((int)vid_mode.value, vid_current_palette); + Cvar_SetValue ("vid_mode", (float)vid_modenum); + // so if mode set fails, we don't keep on + // trying to set that mode + vid_realmode = vid_modenum; + } + } + } +} + + +/* +================= +VID_NumModes_f +================= +*/ +void VID_NumModes_f (void) +{ + int nummodes; + + nummodes = VID_NumModes (); + if (nummodes == 1) + Con_Printf ("%d video mode is available\n", VID_NumModes ()); + else + Con_Printf ("%d video modes are available\n", VID_NumModes ()); +} + + +/* +================= +VID_DescribeCurrentMode_f +================= +*/ +void VID_DescribeCurrentMode_f (void) +{ + Con_Printf ("%s\n", VID_ModeInfo (vid_modenum, NULL)); +} + + +/* +================= +VID_DescribeMode_f +================= +*/ +void VID_DescribeMode_f (void) +{ + int modenum; + + modenum = Q_atoi (Cmd_Argv(1)); + + Con_Printf ("%s\n", VID_ModeInfo (modenum, NULL)); +} + + +/* +================= +VID_DescribeModes_f +================= +*/ +void VID_DescribeModes_f (void) +{ + int i, nummodes; + char *pinfo, *pheader; + vmode_t *pv; + qboolean na; + + na = false; + + nummodes = VID_NumModes (); + for (i=0 ; i<nummodes ; i++) + { + pv = VID_GetModePtr (i); + pinfo = VID_ModeInfo (i, &pheader); + if (pheader) + Con_Printf ("\n%s\n", pheader); + + if (VGA_CheckAdequateMem (pv->width, pv->height, pv->rowbytes, + (pv->numpages == 1) || vid_nopageflip.value)) + { + Con_Printf ("%2d: %s\n", i, pinfo); + } + else + { + Con_Printf ("**: %s\n", pinfo); + na = true; + } + } + + if (na) + { + Con_Printf ("\n[**: not enough system RAM for mode]\n"); + } +} + + +/* +================= +VID_GetModeDescription +================= +*/ +char *VID_GetModeDescription (int mode) +{ + char *pinfo, *pheader; + vmode_t *pv; + + pv = VID_GetModePtr (mode); + pinfo = VID_ModeInfo (mode, &pheader); + + if (VGA_CheckAdequateMem (pv->width, pv->height, pv->rowbytes, + (pv->numpages == 1) || vid_nopageflip.value)) + { + return pinfo; + } + else + { + return NULL; + } +} + + +/* +================= +VID_TestMode_f +================= +*/ +void VID_TestMode_f (void) +{ + int modenum; + double testduration; + + if (!vid_testingmode) + { + modenum = Q_atoi (Cmd_Argv(1)); + + if (VID_SetMode (modenum, vid_current_palette)) + { + vid_testingmode = 1; + testduration = Q_atof (Cmd_Argv(2)); + if (testduration == 0) + testduration = 5.0; + vid_testendtime = realtime + testduration; + } + } +} + + +/* +================ +D_BeginDirectRect +================ +*/ +void D_BeginDirectRect (int x, int y, byte *pbitmap, int width, int height) +{ + + if (!vid.direct || !pcurrentmode) + return; + + if ((width > 24) || (height > 24) || (width < 1) || (height < 1)) + return; + + if (width & 0x03) + return; + + (*pcurrentmode->begindirectrect) (&vid, pcurrentmode, x, y, pbitmap, width, + height); +} + + +/* +================ +D_EndDirectRect +================ +*/ +void D_EndDirectRect (int x, int y, int width, int height) +{ + + if (!vid.direct || !pcurrentmode) + return; + + if ((width > 24) || (height > 24) || (width < 1) || (height < 1)) + return; + + if ((width & 0x03) || (height & 0x03)) + return; + + (*pcurrentmode->enddirectrect) (&vid, pcurrentmode, x, y, width, height); +} + + +//=========================================================================== + +extern void M_Menu_Options_f (void); +extern void M_Print (int cx, int cy, char *str); +extern void M_PrintWhite (int cx, int cy, char *str); +extern void M_DrawCharacter (int cx, int line, int num); +extern void M_DrawTransPic (int x, int y, qpic_t *pic); +extern void M_DrawPic (int x, int y, qpic_t *pic); + +static int vid_line, vid_wmodes, vid_column_size; + +typedef struct +{ + int modenum; + char *desc; + int iscur; +} modedesc_t; + +#define MAX_COLUMN_SIZE 11 + +#define MAX_MODEDESCS (MAX_COLUMN_SIZE*3) + +static modedesc_t modedescs[MAX_MODEDESCS]; + +/* +================ +VID_MenuDraw +================ +*/ +void VID_MenuDraw (void) +{ + qpic_t *p; + char *ptr; + int nummodes, i, j, column, row, dup; + char temp[100]; + + vid_wmodes = 0; + nummodes = VID_NumModes (); + + p = Draw_CachePic ("gfx/vidmodes.lmp"); + M_DrawPic ( (320-p->width)/2, 4, p); + + for (i=0 ; i<nummodes ; i++) + { + if (vid_wmodes < MAX_MODEDESCS) + { + if (i != 1) + { + ptr = VID_GetModeDescription (i); + + if (ptr) + { + dup = 0; + + for (j=0 ; j<vid_wmodes ; j++) + { + if (!strcmp (modedescs[j].desc, ptr)) + { + if (modedescs[j].modenum != 0) + { + modedescs[j].modenum = i; + dup = 1; + + if (i == vid_modenum) + modedescs[j].iscur = 1; + } + else + { + dup = 1; + } + + break; + } + } + + if (!dup) + { + modedescs[vid_wmodes].modenum = i; + modedescs[vid_wmodes].desc = ptr; + modedescs[vid_wmodes].iscur = 0; + + if (i == vid_modenum) + modedescs[vid_wmodes].iscur = 1; + + vid_wmodes++; + } + } + } + } + } + + vid_column_size = (vid_wmodes + 2) / 3; + + column = 16; + row = 36; + + for (i=0 ; i<vid_wmodes ; i++) + { + if (modedescs[i].iscur) + M_PrintWhite (column, row, modedescs[i].desc); + else + M_Print (column, row, modedescs[i].desc); + + row += 8; + + if ((i % vid_column_size) == (vid_column_size - 1)) + { + column += 13*8; + row = 36; + } + } + +// line cursor + if (vid_testingmode) + { + sprintf (temp, "TESTING %s", + modedescs[vid_line].desc); + M_Print (13*8, 36 + MAX_COLUMN_SIZE * 8 + 8*4, temp); + M_Print (9*8, 36 + MAX_COLUMN_SIZE * 8 + 8*6, + "Please wait 5 seconds..."); + } + else + { + M_Print (9*8, 36 + MAX_COLUMN_SIZE * 8 + 8, + "Press Enter to set mode"); + M_Print (6*8, 36 + MAX_COLUMN_SIZE * 8 + 8*3, + "T to test mode for 5 seconds"); + ptr = VID_GetModeDescription (vid_modenum); + sprintf (temp, "D to make %s the default", ptr); + M_Print (6*8, 36 + MAX_COLUMN_SIZE * 8 + 8*5, temp); + ptr = VID_GetModeDescription ((int)_vid_default_mode.value); + + if (ptr) + { + sprintf (temp, "Current default is %s", ptr); + M_Print (7*8, 36 + MAX_COLUMN_SIZE * 8 + 8*6, temp); + } + + M_Print (15*8, 36 + MAX_COLUMN_SIZE * 8 + 8*8, + "Esc to exit"); + + row = 36 + (vid_line % vid_column_size) * 8; + column = 8 + (vid_line / vid_column_size) * 13*8; + + M_DrawCharacter (column, row, 12+((int)(realtime*4)&1)); + } +} + + +/* +================ +VID_MenuKey +================ +*/ +void VID_MenuKey (int key) +{ + if (vid_testingmode) + return; + + switch (key) + { + case K_ESCAPE: + S_LocalSound ("misc/menu1.wav"); + M_Menu_Options_f (); + break; + + case K_UPARROW: + S_LocalSound ("misc/menu1.wav"); + vid_line--; + + if (vid_line < 0) + vid_line = vid_wmodes - 1; + break; + + case K_DOWNARROW: + S_LocalSound ("misc/menu1.wav"); + vid_line++; + + if (vid_line >= vid_wmodes) + vid_line = 0; + break; + + case K_LEFTARROW: + S_LocalSound ("misc/menu1.wav"); + vid_line -= vid_column_size; + + if (vid_line < 0) + { + vid_line += ((vid_wmodes + (vid_column_size - 1)) / + vid_column_size) * vid_column_size; + + while (vid_line >= vid_wmodes) + vid_line -= vid_column_size; + } + break; + + case K_RIGHTARROW: + S_LocalSound ("misc/menu1.wav"); + vid_line += vid_column_size; + + if (vid_line >= vid_wmodes) + { + vid_line -= ((vid_wmodes + (vid_column_size - 1)) / + vid_column_size) * vid_column_size; + + while (vid_line < 0) + vid_line += vid_column_size; + } + break; + + case K_ENTER: + S_LocalSound ("misc/menu1.wav"); + VID_SetMode (modedescs[vid_line].modenum, vid_current_palette); + break; + + case 'T': + case 't': + S_LocalSound ("misc/menu1.wav"); + if (VID_SetMode (modedescs[vid_line].modenum, vid_current_palette)) + { + vid_testingmode = 1; + vid_testendtime = realtime + 5.0; + } + break; + + case 'D': + case 'd': + S_LocalSound ("misc/menu1.wav"); + firstupdate = 0; + Cvar_SetValue ("_vid_default_mode", vid_modenum); + break; + + default: + break; + } +} + |
