diff --git a/libs/video/targets/vid_mgl.c b/libs/video/targets/vid_mgl.c deleted file mode 100644 index 7fa3b84a0..000000000 --- a/libs/video/targets/vid_mgl.c +++ /dev/null @@ -1,2894 +0,0 @@ -/* - vid_mgl.c - - Win32 Scitech MGL video driver - - 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: - - Free Software Foundation, Inc. - 59 Temple Place - Suite 330 - Boston, MA 02111-1307, USA - -*/ -static const char rcsid[] = - "$Id$"; - -#ifdef HAVE_CONFIG_H -# include "config.h" -#endif - -#include - -#include "QF/cmd.h" -#include "QF/cdaudio.h" -#include "QF/console.h" -#include "QF/draw.h" -#include "QF/keys.h" -#include "QF/input.h" -#include "QF/qargs.h" -#include "QF/qendian.h" -#include "QF/screen.h" -#include "QF/sound.h" -#include "QF/sys.h" -#include "QF/va.h" -#include "QF/wad.h" - -#include "d_local.h" -#include "in_win.h" -#include "win32/resources/resource.h" -#include "winquake.h" - -#define MINIMUM_MEMORY 0x550000 - -#define MAX_MODE_LIST 30 -#define VID_ROW_SIZE 3 - -// Unused -int VGA_width, VGA_height, VGA_rowbytes, VGA_bufferrowbytes, - VGA_planar; -byte *VGA_pagebase; -// end Unused - -qboolean dibonly; - -HWND mainwindow; -HWND WINAPI InitializeWindow (HINSTANCE hInstance, int nCmdShow); - -int DIBWidth, DIBHeight; -/* DDActive is gone, merge into ActiveApp? -qboolean DDActive; -*/ -RECT WindowRect; -DWORD WindowStyle, ExWindowStyle; - -int window_center_x, window_center_y, window_x, window_y, window_width, - window_height; -RECT window_rect; - -static DEVMODE gdevmode; -static qboolean startwindowed = 0, windowed_mode_set = 0; -static int firstupdate = 1; -static qboolean vid_palettized; -static int lockcount; -static int vid_fulldib_on_focus_mode; -static qboolean force_minimized, in_mode_set, is_mode0x13, force_mode_set; -static int vid_stretched, windowed_mouse; -static qboolean palette_changed, syscolchg, vid_mode_set, hide_window, - pal_is_nostatic; -static HICON hIcon; - -#define MODE_WINDOWED 0 -#define MODE_SETTABLE_WINDOW 2 -#define NO_MODE (MODE_WINDOWED - 1) -#define MODE_FULLSCREEN_DEFAULT (MODE_WINDOWED + 3) - -// Note that 0 is MODE_WINDOWED -// Note that 3 is MODE_FULLSCREEN_DEFAULT -cvar_t *vid_mode; -cvar_t *_vid_default_mode_win; -cvar_t *vid_nopageflip; -cvar_t *vid_config_x; -cvar_t *vid_config_y; -cvar_t *vid_stretch_by_2; -cvar_t *vid_windowed_mode; -cvar_t *block_switch; -cvar_t *vid_window_x; -cvar_t *vid_window_y; - -typedef struct { - int width; - int height; -} lmode_t; - -lmode_t lowresmodes[] = { - {320, 200}, - {320, 240}, - {400, 300}, - {512, 384}, -}; - -int vid_modenum = NO_MODE; -int vid_testingmode, vid_realmode; -double vid_testendtime; -int vid_default = MODE_WINDOWED; -static int windowed_default; - -modestate_t modestate = MS_UNINIT; - -static byte *vid_surfcache; -static int vid_surfcachesize; -static int VID_highhunkmark; - -unsigned char vid_curpal[256 * 3]; - -int driver = grDETECT, mode; -qboolean useWinDirect = true, useDirectDraw = true; -MGLDC *mgldc = NULL, *memdc = NULL, *dibdc = NULL, *windc = NULL; - -typedef struct { - modestate_t type; - int width; - int height; - int modenum; - int mode13; - int stretched; - int dib; - int fullscreen; - int bpp; - int halfscreen; - char modedesc[13]; -} vmode_t; - -static vmode_t modelist[MAX_MODE_LIST]; -static int nummodes; - -int aPage; // Current active display page -int vPage; // Current visible display page -int waitVRT = true; // True to wait for retrace on flip - -static vmode_t badmode; - -static byte backingbuf[48 * 24]; - -void VID_MenuDraw (void); -void VID_MenuKey (int key); - -LONG WINAPI MainWndProc (HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam); -void AppActivate (BOOL fActive, BOOL minimize); - - -void -VID_RememberWindowPos (void) -{ - RECT rect; - - if (GetWindowRect (mainwindow, &rect)) { - if ((rect.left < GetSystemMetrics (SM_CXSCREEN)) && - (rect.top < GetSystemMetrics (SM_CYSCREEN)) && - (rect.right > 0) && (rect.bottom > 0)) { - Cvar_SetValue (vid_window_x, rect.left); - Cvar_SetValue (vid_window_y, rect.top); - } - } -} - -void -VID_CheckWindowXY (void) -{ - - if ((vid_window_x->int_val > (GetSystemMetrics (SM_CXSCREEN) - 160)) || - (vid_window_y->int_val > (GetSystemMetrics (SM_CYSCREEN) - 120)) || - (vid_window_x->int_val < 0) || (vid_window_y->int_val < 0)) { - Cvar_SetValue (vid_window_x, 0.0); - Cvar_SetValue (vid_window_y, 0.0); - } -} - -void -VID_UpdateWindowStatus (int w_x, int w_y) -{ - - window_rect.left = window_x = w_x; - window_rect.top = window_y = w_y; - window_rect.right = window_x + window_width; - window_rect.bottom = window_y + window_height; - window_center_x = (window_rect.left + window_rect.right) / 2; - window_center_y = (window_rect.top + window_rect.bottom) / 2; - - IN_UpdateClipCursor (); -} - -qboolean -VID_CheckAdequateMem (int width, int height) -{ - return true; -} - -qboolean -VID_AllocBuffers (int width, int height) -{ - int zbuffersize, cachesize; - - // Calculate the sizes we want first - - zbuffersize = width * height * sizeof (*d_pzbuffer); - cachesize = D_SurfaceCacheForRes (width, height); - - // Free the old z-buffer - if (d_pzbuffer) { - free (d_pzbuffer); - d_pzbuffer = NULL; - } - // Free the old surface cache - vid_surfcache = D_SurfaceCacheAddress (); - - if (vid_surfcache) { - D_FlushCaches (); - free (vid_surfcache); - vid_surfcache = NULL; - } - // Allocate the new z-buffer - d_pzbuffer = calloc (zbuffersize, 1); - if (!d_pzbuffer) { - Sys_Error ("Not enough memory for video mode"); - return false; - } - // Allocate the new surface cache; free the z-buffer if we fail - vid_surfcache = calloc (cachesize, 1); - if (!vid_surfcache) { - free (d_pzbuffer); - d_pzbuffer = NULL; - Sys_Error ("Not enough memory for video mode"); - return false; - } - vid_surfcachesize = cachesize; - - return true; -} - -void -initFatalError (void) -{ - MGL_exit (); - MGL_fatalError (MGL_errorMsg (MGL_result ())); - exit (EXIT_FAILURE); -} - -int -VID_Suspend (MGLDC * dc, int flags) -{ - - if (flags & MGL_DEACTIVATE) { - // FIXME: this doesn't currently work on NT - if (block_switch->int_val && !WinNT) { - return MGL_NO_DEACTIVATE; - } - - S_BlockSound (); - S_ClearBuffer (); - - IN_RestoreOriginalMouseState (); - CDAudio_Pause (); - - // keep WM_PAINT from trying to redraw - in_mode_set = true; - - block_drawing = true; // so we don't try to draw while - // switched away - } else if (flags & MGL_REACTIVATE) { - IN_SetQuakeMouseState (); - // fix leftover Alt from any Alt-Tab or the like that switched us away - IN_ClearStates (); - CDAudio_Resume (); - S_UnblockSound (); - - in_mode_set = false; - - vid.recalc_refdef = 1; - - block_drawing = false; - } - - return MGL_NO_SUSPEND_APP; -} - -void -registerAllDispDrivers (void) -{ - /* Event though these driver require WinDirect, we register * them so - that they will still be available even if DirectDraw * is present and - the user has disable the high performance * WinDirect modes. */ - MGL_registerDriver (MGL_VGA8NAME, VGA8_driver); -// MGL_registerDriver(MGL_VGAXNAME, VGAX_driver); - - // Register display drivers - if (useWinDirect) { -/* we don't want VESA 1.X drivers - MGL_registerDriver(MGL_SVGA8NAME, SVGA8_driver); -*/ - MGL_registerDriver (MGL_LINEAR8NAME, LINEAR8_driver); - - if (!COM_CheckParm ("-novbeaf")) - MGL_registerDriver (MGL_ACCEL8NAME, ACCEL8_driver); - } - - if (useDirectDraw) { - MGL_registerDriver (MGL_DDRAW8NAME, DDRAW8_driver); - } -} - -void -registerAllMemDrivers (void) -{ - // Register memory context drivers - MGL_registerDriver (MGL_PACKED8NAME, PACKED8_driver); -} - -void -VID_InitMGLFull (HINSTANCE hInstance) -{ - int i, xRes, yRes, bits, lowres, curmode, temp; - int lowstretchedres, stretchedmode = 0, lowstretched; - uchar *m; - -// FIXME: NT is checked for because MGL currently has a bug that causes it -// to try to use WinDirect modes even on NT - if (COM_CheckParm ("-nowindirect") || - COM_CheckParm ("-nowd") || COM_CheckParm ("-novesa") || WinNT) { - useWinDirect = false; - } - - if (COM_CheckParm ("-nodirectdraw") || COM_CheckParm ("-noddraw") - || COM_CheckParm ("-nodd")) - useDirectDraw = false; - - // Initialise the MGL - MGL_unregisterAllDrivers (); - registerAllDispDrivers (); - registerAllMemDrivers (); - MGL_detectGraph (&driver, &mode); - m = MGL_availableModes (); - - if (m[0] != 0xFF) { - lowres = lowstretchedres = 99999; - lowstretched = 0; - curmode = 0; - - // find the lowest-res mode, or a mode we can stretch up to and get - // lowest-res that way - for (i = 0; m[i] != 0xFF; i++) { - MGL_modeResolution (m[i], &xRes, &yRes, &bits); - - if ((bits == 8) && - (xRes <= MAXWIDTH) && - (yRes <= MAXHEIGHT) && (curmode < MAX_MODE_LIST)) { - if (m[i] == grVGA_320x200x256) - is_mode0x13 = true; - - if (!COM_CheckParm ("-noforcevga")) { - if (m[i] == grVGA_320x200x256) { - mode = i; - break; - } - } - - if (xRes < lowres) { - lowres = xRes; - mode = i; - } - - if ((xRes < lowstretchedres) && ((xRes >> 1) >= 320)) { - lowstretchedres = xRes >> 1; - stretchedmode = i; - } - } - - curmode++; - } - - // if there's a mode we can stretch by 2 up to, thereby effectively - // getting a lower-res mode than the lowest-res real but still at least - // 320x200, that will be our default mode - if (lowstretchedres < lowres) { - mode = stretchedmode; - lowres = lowstretchedres; - lowstretched = 1; - } - // build the mode list, leaving room for the low-res stretched mode, - // if any - nummodes++; // leave room for default mode - - for (i = 0; m[i] != 0xFF; i++) { - MGL_modeResolution (m[i], &xRes, &yRes, &bits); - - if ((bits == 8) && - (xRes <= MAXWIDTH) && - (yRes <= MAXHEIGHT) && (nummodes < MAX_MODE_LIST)) { - if (i == mode) { - if (lowstretched) { - stretchedmode = nummodes; - curmode = nummodes++; - } else { - curmode = MODE_FULLSCREEN_DEFAULT; - } - } else { - curmode = nummodes++; - } - - modelist[curmode].type = MS_FULLSCREEN; - modelist[curmode].width = xRes; - modelist[curmode].height = yRes; - snprintf (modelist[curmode].modedesc, - sizeof (modelist[curmode].modedesc), "%dx%d", xRes, - yRes); - - if (m[i] == grVGA_320x200x256) - modelist[curmode].mode13 = 1; - else - modelist[curmode].mode13 = 0; - - modelist[curmode].modenum = m[i]; - modelist[curmode].stretched = 0; - modelist[curmode].dib = 0; - modelist[curmode].fullscreen = 1; - modelist[curmode].halfscreen = 0; - modelist[curmode].bpp = 8; - } - } - - if (lowstretched) { - modelist[MODE_FULLSCREEN_DEFAULT] = modelist[stretchedmode]; - modelist[MODE_FULLSCREEN_DEFAULT].stretched = 1; - modelist[MODE_FULLSCREEN_DEFAULT].width >>= 1; - modelist[MODE_FULLSCREEN_DEFAULT].height >>= 1; - snprintf (modelist[MODE_FULLSCREEN_DEFAULT].modedesc, - sizeof (modelist[MODE_FULLSCREEN_DEFAULT].modedesc), - "%dx%d", modelist[MODE_FULLSCREEN_DEFAULT].width, - modelist[MODE_FULLSCREEN_DEFAULT].height); - } - - vid_default = MODE_FULLSCREEN_DEFAULT; - - temp = m[0]; - - if (!MGL_init (&driver, &temp, "")) { - initFatalError (); - } - } - - MGL_setSuspendAppCallback (VID_Suspend); -} - -/* - createDisplayDC - - Returns pointer to the MGL device context to use for the application - Initialises the MGL and creates an appropriate display device context to be - used by the GUI. This creates and apropriate device context depending on the - system being compile for, and should be the only place where system specific - code is required. -*/ -MGLDC * -createDisplayDC (int forcemem) -{ - MGLDC *dc; - pixel_format_t pf; - int npages; - - // Start the specified video mode - if (!MGL_changeDisplayMode (mode)) - initFatalError (); - - npages = MGL_availablePages (mode); - - if (npages > 3) - npages = 3; - - if (!COM_CheckParm ("-notriplebuf")) { - if (npages > 2) { - npages = 2; - } - } - - if ((dc = MGL_createDisplayDC (npages)) == NULL) - return NULL; - - if (!forcemem && (MGL_surfaceAccessType (dc)) == MGL_LINEAR_ACCESS - && (dc->mi.maxPage > 0)) { - MGL_makeCurrentDC (dc); - memdc = NULL; - } else { - // Set up for blitting from a memory buffer - memdc = MGL_createMemoryDC (MGL_sizex (dc) + 1, MGL_sizey (dc) + 1, 8, - &pf); - MGL_makeCurrentDC (memdc); - } - - // Enable page flipping even for even for blitted surfaces - if (forcemem) { - vid.numpages = 1; - } else { - vid.numpages = dc->mi.maxPage + 1; - - if (vid.numpages > 1) { - // Set up for page flipping - MGL_setActivePage (dc, aPage = 1); - MGL_setVisualPage (dc, vPage = 0, false); - } - - if (vid.numpages > 3) - vid.numpages = 3; - } - - if (vid.numpages == 2) - waitVRT = true; - else - waitVRT = false; - - return dc; -} - -void -VID_InitMGLDIB (HINSTANCE hInstance) -{ - WNDCLASS wc; - HDC hdc; - - hIcon = LoadIcon (hInstance, MAKEINTRESOURCE (IDI_ICON1)); - - // Register the frame class - wc.style = 0; - wc.lpfnWndProc = (WNDPROC) MainWndProc; - wc.cbClsExtra = 0; - wc.cbWndExtra = 0; - wc.hInstance = hInstance; - wc.hIcon = 0; - wc.hCursor = LoadCursor (NULL, IDC_ARROW); - wc.hbrBackground = NULL; - wc.lpszMenuName = 0; - wc.lpszClassName = "WinQuake"; - - if (!RegisterClass (&wc)) - Sys_Error ("Couldn't register window class"); - - // Find the size for the DIB window - // Initialise the MGL for windowed operation - MGL_setAppInstance (hInstance); - registerAllMemDrivers (); - MGL_initWindowed (""); - - modelist[0].type = MS_WINDOWED; - modelist[0].width = 320; - modelist[0].height = 240; - strcpy (modelist[0].modedesc, "320x240"); - modelist[0].mode13 = 0; - modelist[0].modenum = MODE_WINDOWED; - modelist[0].stretched = 0; - modelist[0].dib = 1; - modelist[0].fullscreen = 0; - modelist[0].halfscreen = 0; - modelist[0].bpp = 8; - - modelist[1].type = MS_WINDOWED; - modelist[1].width = 640; - modelist[1].height = 480; - strcpy (modelist[1].modedesc, "640x480"); - modelist[1].mode13 = 0; - modelist[1].modenum = MODE_WINDOWED + 1; - modelist[1].stretched = 1; - modelist[1].dib = 1; - modelist[1].fullscreen = 0; - modelist[1].halfscreen = 0; - modelist[1].bpp = 8; - - modelist[2].type = MS_WINDOWED; - modelist[2].width = 800; - modelist[2].height = 600; - strcpy (modelist[2].modedesc, "800x600"); - modelist[2].mode13 = 0; - modelist[2].modenum = MODE_WINDOWED + 2; - modelist[2].stretched = 1; - modelist[2].dib = 1; - modelist[2].fullscreen = 0; - modelist[2].halfscreen = 0; - modelist[2].bpp = 8; - - // automatically stretch default mode up if > 640x480 desktop resolution - hdc = GetDC (NULL); - - if ((GetDeviceCaps (hdc, HORZRES) > 640) - && !COM_CheckParm ("-noautostretch")) { - vid_default = MODE_WINDOWED + 1; - } else { - vid_default = MODE_WINDOWED; - } - - windowed_default = vid_default; - - ReleaseDC (NULL, hdc); - - nummodes = 3; // reserve space for windowed mode - - DDActive = 0; -} - -void -VID_InitFullDIB (HINSTANCE hInstance) -{ - DEVMODE devmode; - int i, j, modenum, existingmode, originalnummodes, lowestres; - int numlowresmodes, bpp, done; - int cstretch, istretch, mstretch = 0; - BOOL stat; - - // enumerate 8 bpp modes - originalnummodes = nummodes; - modenum = 0; - lowestres = 99999; - - do { - stat = EnumDisplaySettings (NULL, modenum, &devmode); - - if ((devmode.dmBitsPerPel == 8) && (devmode.dmPelsWidth <= MAXWIDTH) && - (devmode.dmPelsHeight <= MAXHEIGHT) && - (nummodes < MAX_MODE_LIST)) { - devmode.dmFields = DM_BITSPERPEL | DM_PELSWIDTH | DM_PELSHEIGHT; - - if (ChangeDisplaySettings (&devmode, CDS_TEST | CDS_FULLSCREEN) == - DISP_CHANGE_SUCCESSFUL) { - modelist[nummodes].type = MS_FULLDIB; - modelist[nummodes].width = devmode.dmPelsWidth; - modelist[nummodes].height = devmode.dmPelsHeight; - modelist[nummodes].modenum = 0; - modelist[nummodes].mode13 = 0; - modelist[nummodes].stretched = 0; - modelist[nummodes].halfscreen = 0; - modelist[nummodes].dib = 1; - modelist[nummodes].fullscreen = 1; - modelist[nummodes].bpp = devmode.dmBitsPerPel; - snprintf (modelist[nummodes].modedesc, - sizeof (modelist[nummodes].modedesc), "%ldx%ld", - devmode.dmPelsWidth, devmode.dmPelsHeight); - - // if the width is more than twice the height, reduce it by - // half because this - // is probably a dual-screen monitor - if (!COM_CheckParm ("-noadjustaspect")) { - if (modelist[nummodes].width > - (modelist[nummodes].height << 1)) { - modelist[nummodes].width >>= 1; - modelist[nummodes].halfscreen = 1; - snprintf (modelist[nummodes].modedesc, - sizeof (modelist[nummodes].modedesc), - "%dx%d", modelist[nummodes].width, - modelist[nummodes].height); - } - } - - for (i = originalnummodes, existingmode = 0; i < nummodes; - i++) { - if ((modelist[nummodes].width == modelist[i].width) && - (modelist[nummodes].height == modelist[i].height)) { - existingmode = 1; - break; - } - } - - if (!existingmode) { - if (modelist[nummodes].width < lowestres) - lowestres = modelist[nummodes].width; - - nummodes++; - } - } - } - - modenum++; - } while (stat); - -// see if any of them were actually settable; if so, this is our mode list, -// else enumerate all modes; our mode list is whichever ones are settable -// with > 8 bpp - if (nummodes == originalnummodes) { - modenum = 0; - lowestres = 99999; - - Con_Printf ("No 8-bpp fullscreen DIB modes found\n"); - - do { - stat = EnumDisplaySettings (NULL, modenum, &devmode); - - if ((((devmode.dmPelsWidth <= MAXWIDTH) && - (devmode.dmPelsHeight <= MAXHEIGHT)) || - (!COM_CheckParm ("-noadjustaspect") && - (devmode.dmPelsWidth <= (MAXWIDTH * 2)) && - (devmode.dmPelsWidth > (devmode.dmPelsHeight * 2)))) && - (nummodes < MAX_MODE_LIST) && (devmode.dmBitsPerPel > 8)) { - devmode.dmFields = DM_BITSPERPEL | DM_PELSWIDTH | - DM_PELSHEIGHT; - - if (ChangeDisplaySettings (&devmode, CDS_TEST | CDS_FULLSCREEN) - == DISP_CHANGE_SUCCESSFUL) { - modelist[nummodes].type = MS_FULLDIB; - modelist[nummodes].width = devmode.dmPelsWidth; - modelist[nummodes].height = devmode.dmPelsHeight; - modelist[nummodes].modenum = 0; - modelist[nummodes].mode13 = 0; - modelist[nummodes].stretched = 0; - modelist[nummodes].halfscreen = 0; - modelist[nummodes].dib = 1; - modelist[nummodes].fullscreen = 1; - modelist[nummodes].bpp = devmode.dmBitsPerPel; - snprintf (modelist[nummodes].modedesc, - sizeof (modelist[nummodes].modedesc), "%ldx%ld", - devmode.dmPelsWidth, devmode.dmPelsHeight); - - // if the width is more than twice the height, reduce it - // by half because this is probably a dual-screen monitor - if (!COM_CheckParm ("-noadjustaspect")) { - if (modelist[nummodes].width > - (modelist[nummodes].height * 2)) { - modelist[nummodes].width >>= 1; - modelist[nummodes].halfscreen = 1; - snprintf (modelist[nummodes].modedesc, - sizeof (modelist[nummodes].modedesc), - "%dx%d", modelist[nummodes].width, - modelist[nummodes].height); - } - } - - for (i = originalnummodes, existingmode = 0; i < nummodes; - i++) { - if ((modelist[nummodes].width == modelist[i].width) - && (modelist[nummodes].height == - modelist[i].height)) { - // pick the lowest available bpp - if (modelist[nummodes].bpp < modelist[i].bpp) - modelist[i] = modelist[nummodes]; - - existingmode = 1; - break; - } - } - - if (!existingmode) { - if (modelist[nummodes].width < lowestres) - lowestres = modelist[nummodes].width; - - nummodes++; - } - } - } - - modenum++; - } while (stat); - } - // see if there are any low-res modes that aren't being reported - numlowresmodes = sizeof (lowresmodes) / sizeof (lowresmodes[0]); - bpp = 8; - done = 0; - - // first make sure the driver doesn't just answer yes to all tests - devmode.dmBitsPerPel = 8; - devmode.dmPelsWidth = 42; - devmode.dmPelsHeight = 37; - devmode.dmFields = DM_BITSPERPEL | DM_PELSWIDTH | DM_PELSHEIGHT; - - if (ChangeDisplaySettings (&devmode, CDS_TEST | CDS_FULLSCREEN) == - DISP_CHANGE_SUCCESSFUL) { - done = 1; - } - - while (!done) { - for (j = 0; (j < numlowresmodes) && (nummodes < MAX_MODE_LIST); j++) { - devmode.dmBitsPerPel = bpp; - devmode.dmPelsWidth = lowresmodes[j].width; - devmode.dmPelsHeight = lowresmodes[j].height; - devmode.dmFields = DM_BITSPERPEL | DM_PELSWIDTH | DM_PELSHEIGHT; - - if (ChangeDisplaySettings (&devmode, CDS_TEST | CDS_FULLSCREEN) == - DISP_CHANGE_SUCCESSFUL) { - modelist[nummodes].type = MS_FULLDIB; - modelist[nummodes].width = devmode.dmPelsWidth; - modelist[nummodes].height = devmode.dmPelsHeight; - modelist[nummodes].modenum = 0; - modelist[nummodes].mode13 = 0; - modelist[nummodes].stretched = 0; - modelist[nummodes].halfscreen = 0; - modelist[nummodes].dib = 1; - modelist[nummodes].fullscreen = 1; - modelist[nummodes].bpp = devmode.dmBitsPerPel; - snprintf (modelist[nummodes].modedesc, - sizeof (modelist[nummodes].modedesc), "%ldx%ld", - devmode.dmPelsWidth, devmode.dmPelsHeight); - - // we only want the lowest-bpp version of each mode - for (i = originalnummodes, existingmode = 0; i < nummodes; - i++) { - if ((modelist[nummodes].width == modelist[i].width) && - (modelist[nummodes].height == modelist[i].height) && - (modelist[nummodes].bpp >= modelist[i].bpp)) { - existingmode = 1; - break; - } - } - - if (!existingmode) { - if (modelist[nummodes].width < lowestres) - lowestres = modelist[nummodes].width; - - nummodes++; - } - } - } - - switch (bpp) { - case 8: - bpp = 16; - break; - - case 16: - bpp = 32; - break; - - case 32: - done = 1; - break; - } - } - - // now add the lowest stretch-by-2 pseudo-modes between 320-wide - // (inclusive) and lowest real res (not inclusive) don't bother if we have - // a real VGA mode 0x13 mode - if (!is_mode0x13) { - for (i = originalnummodes, cstretch = 0; i < nummodes; i++) { - if (((modelist[i].width >> 1) < lowestres) && - ((modelist[i].width >> 1) >= 320)) { - lowestres = modelist[i].width >> 1; - cstretch = 1; - mstretch = i; - } - } - - if ((nummodes + cstretch) > MAX_MODE_LIST) - cstretch = MAX_MODE_LIST - nummodes; - - if (cstretch > 0) { - for (i = (nummodes - 1); i >= originalnummodes; i--) - modelist[i + cstretch] = modelist[i]; - - nummodes += cstretch; - istretch = originalnummodes; - - modelist[istretch] = modelist[mstretch]; - modelist[istretch].width >>= 1; - modelist[istretch].height >>= 1; - modelist[istretch].stretched = 1; - snprintf (modelist[istretch].modedesc, - sizeof (modelist[istretch].modedesc), "%dx%d", - modelist[istretch].width, modelist[istretch].height); - } - } - - if (nummodes != originalnummodes) - vid_default = MODE_FULLSCREEN_DEFAULT; - else - Con_Printf ("No fullscreen DIB modes found\n"); -} - -int -VID_NumModes (void) -{ - return nummodes; -} - -vmode_t * -VID_GetModePtr (int modenum) -{ - - if ((modenum >= 0) && (modenum < nummodes)) - return &modelist[modenum]; - else - return &badmode; -} - -void -VID_CheckModedescFixup (int mode) -{ - int x, y, stretch; - - if (mode == MODE_SETTABLE_WINDOW) { - modelist[mode].stretched = vid_stretch_by_2->int_val; - stretch = modelist[mode].stretched; - - Cvar_SetValue (vid_config_x, - max (vid_config_x->int_val, 320 << stretch)); - Cvar_SetValue (vid_config_y, - max (vid_config_y->int_val, 200 << stretch)); - - x = vid_config_x->int_val; - y = vid_config_y->int_val; - snprintf (modelist[mode].modedesc, sizeof (modelist[mode].modedesc), - "%dx%d", x, y); - modelist[mode].width = x; - modelist[mode].height = y; - } -} - -char * -VID_GetModeDescriptionMemCheck (int mode) -{ - char *pinfo; - vmode_t *pv; - - if ((mode < 0) || (mode >= nummodes)) - return NULL; - - VID_CheckModedescFixup (mode); - - pv = VID_GetModePtr (mode); - pinfo = pv->modedesc; - - if (VID_CheckAdequateMem (pv->width, pv->height)) { - return pinfo; - } else { - return NULL; - } -} - -char * -VID_GetModeDescription (int mode) -{ - char *pinfo; - vmode_t *pv; - - if ((mode < 0) || (mode >= nummodes)) - return NULL; - - VID_CheckModedescFixup (mode); - - pv = VID_GetModePtr (mode); - pinfo = pv->modedesc; - return pinfo; -} - -/* - VID_GetModeDescription2 - - Tacks on "windowed" or "fullscreen" -*/ -char * -VID_GetModeDescription2 (int mode) -{ - static char pinfo[40]; - vmode_t *pv; - - if ((mode < 0) || (mode >= nummodes)) - return NULL; - - VID_CheckModedescFixup (mode); - - pv = VID_GetModePtr (mode); - - if (modelist[mode].type == MS_FULLSCREEN) { - snprintf (pinfo, sizeof (pinfo), "%s fullscreen", pv->modedesc); - } else if (modelist[mode].type == MS_FULLDIB) { - snprintf (pinfo, sizeof (pinfo), "%s fullscreen", pv->modedesc); - } else { - snprintf (pinfo, sizeof (pinfo), "%s windowed", pv->modedesc); - } - - return pinfo; -} - -// KJB: Added this to return the mode driver name in description for console -char * -VID_GetExtModeDescription (int mode) -{ - static char pinfo[40]; - vmode_t *pv; - - if ((mode < 0) || (mode >= nummodes)) - return NULL; - - VID_CheckModedescFixup (mode); - - pv = VID_GetModePtr (mode); - if (modelist[mode].type == MS_FULLSCREEN) { - snprintf (pinfo, sizeof (pinfo), "%s fullscreen %s", pv->modedesc, - MGL_modeDriverName (pv->modenum)); - } else if (modelist[mode].type == MS_FULLDIB) { - snprintf (pinfo, sizeof (pinfo), "%s fullscreen DIB", pv->modedesc); - } else { - snprintf (pinfo, sizeof (pinfo), "%s windowed", pv->modedesc); - } - - return pinfo; -} - -void -DestroyDIBWindow (void) -{ - - if (modestate == MS_WINDOWED) { - // destroy the associated MGL DC's; the window gets reused - if (windc) - MGL_destroyDC (windc); - if (dibdc) - MGL_destroyDC (dibdc); - windc = dibdc = NULL; - } -} - -void -DestroyFullscreenWindow (void) -{ - if (modestate == MS_FULLSCREEN) { - // destroy the existing fullscreen mode and DC's - if (mgldc) - MGL_destroyDC (mgldc); - if (memdc) - MGL_destroyDC (memdc); - mgldc = memdc = NULL; - } -} - -void -DestroyFullDIBWindow (void) -{ - if (modestate == MS_FULLDIB) { - ChangeDisplaySettings (NULL, CDS_FULLSCREEN); - - // Destroy the fullscreen DIB window and associated MGL DC's - if (windc) - MGL_destroyDC (windc); - if (dibdc) - MGL_destroyDC (dibdc); - windc = dibdc = NULL; - } -} - -qboolean -VID_SetWindowedMode (int modenum) -{ - HDC hdc; - pixel_format_t pf; - qboolean stretched; - int lastmodestate; - - if (!windowed_mode_set) { - if (COM_CheckParm ("-resetwinpos")) { - Cvar_SetValue (vid_window_x, 0.0); - Cvar_SetValue (vid_window_y, 0.0); - } - - windowed_mode_set = 1; - } - - VID_CheckModedescFixup (modenum); - - DDActive = 0; - lastmodestate = modestate; - - DestroyFullscreenWindow (); - DestroyFullDIBWindow (); - - if (windc) - MGL_destroyDC (windc); - if (dibdc) - MGL_destroyDC (dibdc); - windc = dibdc = NULL; - - // KJB: Signal to the MGL that we are going back to windowed mode - if (!MGL_changeDisplayMode (grWINDOWED)) - initFatalError (); - - WindowRect.top = WindowRect.left = 0; - - WindowRect.right = modelist[modenum].width; - WindowRect.bottom = modelist[modenum].height; - stretched = modelist[modenum].stretched; - - DIBWidth = modelist[modenum].width; - DIBHeight = modelist[modenum].height; - - if (stretched) { - DIBWidth >>= 1; - DIBHeight >>= 1; - } - - WindowStyle = WS_OVERLAPPED | WS_BORDER | WS_CAPTION | WS_SYSMENU | - WS_MINIMIZEBOX | WS_MAXIMIZEBOX | WS_CLIPSIBLINGS | WS_CLIPCHILDREN; - ExWindowStyle = 0; - AdjustWindowRectEx (&WindowRect, WindowStyle, FALSE, 0); - - // the first time we're called to set the mode, create the window we'll use - // for the rest of the session - if (!vid_mode_set) { - mainwindow = CreateWindowEx (ExWindowStyle, "WinQuake", PROGRAM, - WindowStyle, 0, 0, - WindowRect.right - WindowRect.left, - WindowRect.bottom - WindowRect.top, - NULL, NULL, global_hInstance, NULL); - if (!mainwindow) - Sys_Error ("Couldn't create DIB window"); - - // tell MGL to use this window for fullscreen modes - MGL_registerFullScreenWindow (mainwindow); - - vid_mode_set = true; - } else { - SetWindowLong (mainwindow, GWL_STYLE, WindowStyle | WS_VISIBLE); - SetWindowLong (mainwindow, GWL_EXSTYLE, ExWindowStyle); - } - - if (!SetWindowPos (mainwindow, NULL, 0, 0, - WindowRect.right - WindowRect.left, - WindowRect.bottom - WindowRect.top, - SWP_NOCOPYBITS | SWP_NOZORDER | SWP_HIDEWINDOW)) { - Sys_Error ("Couldn't resize DIB window"); - } - - if (hide_window) - return true; - - // position and show the DIB window - VID_CheckWindowXY (); - SetWindowPos (mainwindow, NULL, vid_window_x->int_val, - vid_window_y->int_val, 0, 0, - SWP_NOSIZE | SWP_NOZORDER | SWP_SHOWWINDOW | SWP_DRAWFRAME); - - if (force_minimized) - ShowWindow (mainwindow, SW_MINIMIZE); - else - ShowWindow (mainwindow, SW_SHOWDEFAULT); - - UpdateWindow (mainwindow); - - modestate = MS_WINDOWED; - vid_fulldib_on_focus_mode = 0; - -// because we have set the background brush for the window to NULL -// (to avoid flickering when re-sizing the window on the desktop), -// we clear the window to black when created, otherwise it will be -// empty while Quake starts up. - hdc = GetDC (mainwindow); - PatBlt (hdc, 0, 0, WindowRect.right, WindowRect.bottom, BLACKNESS); - ReleaseDC (mainwindow, hdc); - - // Create the MGL window DC and the MGL memory DC - if ((windc = MGL_createWindowedDC (mainwindow)) == NULL) - MGL_fatalError ("Unable to create Windowed DC!"); - - if ((dibdc = MGL_createMemoryDC (DIBWidth, DIBHeight, 8, &pf)) == NULL) - MGL_fatalError ("Unable to create Memory DC!"); - - MGL_makeCurrentDC (dibdc); - - vid.buffer = vid.conbuffer = vid.direct = dibdc->surface; - vid.rowbytes = vid.conrowbytes = dibdc->mi.bytesPerLine; - vid.numpages = 1; - vid.maxwarpwidth = WARP_WIDTH; - vid.maxwarpheight = WARP_HEIGHT; - vid.height = vid.conheight = DIBHeight; - vid.width = vid.conwidth = DIBWidth; - vid.aspect = ((float) vid.height / (float) vid.width) * (320.0 / 240.0); - - vid_stretched = stretched; - - SendMessage (mainwindow, WM_SETICON, (WPARAM) TRUE, (LPARAM) hIcon); - SendMessage (mainwindow, WM_SETICON, (WPARAM) FALSE, (LPARAM) hIcon); - - return true; -} - -qboolean -VID_SetFullscreenMode (int modenum) -{ - - DDActive = 1; - - DestroyDIBWindow (); - DestroyFullDIBWindow (); - - mode = modelist[modenum].modenum; - - // Destroy old DC's, resetting back to fullscreen mode - if (mgldc) - MGL_destroyDC (mgldc); - if (memdc) - MGL_destroyDC (memdc); - mgldc = memdc = NULL; - - if ((mgldc = createDisplayDC (modelist[modenum].stretched || - vid_nopageflip->int_val)) == NULL) { - return false; - } - - modestate = MS_FULLSCREEN; - vid_fulldib_on_focus_mode = 0; - - vid.buffer = vid.conbuffer = vid.direct = NULL; - vid.maxwarpwidth = WARP_WIDTH; - vid.maxwarpheight = WARP_HEIGHT; - DIBHeight = vid.height = vid.conheight = modelist[modenum].height; - DIBWidth = vid.width = vid.conwidth = modelist[modenum].width; - vid.aspect = ((float) vid.height / (float) vid.width) * (320.0 / 240.0); - - vid_stretched = modelist[modenum].stretched; - - // needed because we're not getting WM_MOVE messages fullscreen on NT - window_x = 0; - window_y = 0; - - // set the large icon, so the Quake icon will show up in the taskbar - SendMessage (mainwindow, WM_SETICON, (WPARAM) 1, (LPARAM) hIcon); - SendMessage (mainwindow, WM_SETICON, (WPARAM) 0, (LPARAM) hIcon); - - // shouldn't be needed, but Kendall needs to let us get the activation - // message for this not to be needed on NT - AppActivate (true, false); - - return true; -} - -qboolean -VID_SetFullDIBMode (int modenum) -{ - HDC hdc; - pixel_format_t pf; - int lastmodestate; - - DDActive = 0; - - DestroyFullscreenWindow (); - DestroyDIBWindow (); - - if (windc) - MGL_destroyDC (windc); - if (dibdc) - MGL_destroyDC (dibdc); - windc = dibdc = NULL; - - // KJB: Signal to the MGL that we are going back to windowed mode - if (!MGL_changeDisplayMode (grWINDOWED)) - initFatalError (); - - gdevmode.dmFields = DM_BITSPERPEL | DM_PELSWIDTH | DM_PELSHEIGHT; - gdevmode.dmBitsPerPel = modelist[modenum].bpp; - gdevmode.dmPelsWidth = - modelist[modenum].width << modelist[modenum]. - stretched << modelist[modenum].halfscreen; - gdevmode.dmPelsHeight = - modelist[modenum].height << modelist[modenum].stretched; - gdevmode.dmSize = sizeof (gdevmode); - - if (ChangeDisplaySettings (&gdevmode, CDS_FULLSCREEN) != - DISP_CHANGE_SUCCESSFUL) Sys_Error ("Couldn't set fullscreen DIB mode"); - - lastmodestate = modestate; - modestate = MS_FULLDIB; - vid_fulldib_on_focus_mode = modenum; - - WindowRect.top = WindowRect.left = 0; - - hdc = GetDC (NULL); - - WindowRect.right = modelist[modenum].width << modelist[modenum].stretched; - WindowRect.bottom = modelist[modenum].height << - modelist[modenum].stretched; - - ReleaseDC (NULL, hdc); - - DIBWidth = modelist[modenum].width; - DIBHeight = modelist[modenum].height; - - WindowStyle = WS_POPUP | WS_SYSMENU | WS_CLIPSIBLINGS | WS_CLIPCHILDREN; - ExWindowStyle = 0; - AdjustWindowRectEx (&WindowRect, WindowStyle, FALSE, 0); - - SetWindowLong (mainwindow, GWL_STYLE, WindowStyle | WS_VISIBLE); - SetWindowLong (mainwindow, GWL_EXSTYLE, ExWindowStyle); - - if (!SetWindowPos (mainwindow, NULL, 0, 0, - WindowRect.right - WindowRect.left, - WindowRect.bottom - WindowRect.top, - SWP_NOCOPYBITS | SWP_NOZORDER)) { - Sys_Error ("Couldn't resize DIB window"); - } - // position and show the DIB window - SetWindowPos (mainwindow, HWND_TOPMOST, 0, 0, 0, 0, - SWP_NOSIZE | SWP_SHOWWINDOW | SWP_DRAWFRAME); - ShowWindow (mainwindow, SW_SHOWDEFAULT); - UpdateWindow (mainwindow); - - // Because we have set the background brush for the window to NULL - // (to avoid flickering when re-sizing the window on the desktop), we - // clear the window to black when created, otherwise it will be - // empty while Quake starts up. - hdc = GetDC (mainwindow); - PatBlt (hdc, 0, 0, WindowRect.right, WindowRect.bottom, BLACKNESS); - ReleaseDC (mainwindow, hdc); - - // Create the MGL window DC and the MGL memory DC - if ((windc = MGL_createWindowedDC (mainwindow)) == NULL) - MGL_fatalError ("Unable to create Fullscreen DIB DC!"); - - if ((dibdc = MGL_createMemoryDC (DIBWidth, DIBHeight, 8, &pf)) == NULL) - MGL_fatalError ("Unable to create Memory DC!"); - - MGL_makeCurrentDC (dibdc); - - vid.buffer = vid.conbuffer = vid.direct = dibdc->surface; - vid.rowbytes = vid.conrowbytes = dibdc->mi.bytesPerLine; - vid.numpages = 1; - vid.maxwarpwidth = WARP_WIDTH; - vid.maxwarpheight = WARP_HEIGHT; - vid.height = vid.conheight = DIBHeight; - vid.width = vid.conwidth = DIBWidth; - vid.aspect = ((float) vid.height / (float) vid.width) * (320.0 / 240.0); - - vid_stretched = modelist[modenum].stretched; - - // needed because we're not getting WM_MOVE messages fullscreen on NT - window_x = 0; - window_y = 0; - - return true; -} - -void -VID_RestoreOldMode (int original_mode) -{ - static qboolean inerror = false; - - if (inerror) - return; - - in_mode_set = false; - inerror = true; - - // make sure mode set happens (video mode changes) - vid_modenum = original_mode - 1; - - if (!VID_SetMode (original_mode, vid_curpal)) { - vid_modenum = MODE_WINDOWED - 1; - - if (!VID_SetMode (windowed_default, vid_curpal)) - Sys_Error ("Can't set any video mode"); - } - - inerror = false; -} - -void -VID_SetDefaultMode (void) -{ - - if (vid.initialized) - VID_SetMode (0, vid_curpal); - - IN_DeactivateMouse (); -} - -int -VID_SetMode (int modenum, unsigned char *palette) -{ - int original_mode, temp; - qboolean stat; - MSG msg; - HDC hdc; - - while ((modenum >= nummodes) || (modenum < 0)) { - if (vid_modenum == NO_MODE) { - if (modenum == vid_default) { - modenum = windowed_default; - } else { - modenum = vid_default; - } - - Cvar_SetValue (vid_mode, modenum); - } else { - Cvar_SetValue (vid_mode, vid_modenum); - return 0; - } - } - - if (!force_mode_set && (modenum == vid_modenum)) - return true; - - // so Con_Printfs don't mess us up by forcing vid and snd updates - in_mode_set = true; - - CDAudio_Pause (); - S_ClearBuffer (); - - if (vid_modenum == NO_MODE) - original_mode = windowed_default; - else - original_mode = vid_modenum; - - // Set either the fullscreen or windowed mode - if (modelist[modenum].type == MS_WINDOWED) { - if (in_grab->int_val && key_dest == key_game) { - stat = VID_SetWindowedMode (modenum); - IN_ActivateMouse (); - IN_HideMouse (); - } else { - IN_DeactivateMouse (); - IN_ShowMouse (); - stat = VID_SetWindowedMode (modenum); - } - } else if (modelist[modenum].type == MS_FULLDIB) { - stat = VID_SetFullDIBMode (modenum); - IN_ActivateMouse (); - IN_HideMouse (); - } else { - stat = VID_SetFullscreenMode (modenum); - IN_ActivateMouse (); - IN_HideMouse (); - } - - window_width = vid.width << vid_stretched; - window_height = vid.height << vid_stretched; - VID_UpdateWindowStatus (window_x, window_y); - - CDAudio_Resume (); - - if (!stat) { - VID_RestoreOldMode (original_mode); - return false; - } - - if (hide_window) - return true; - -// now we try to make sure we get the focus on the mode switch, because -// sometimes in some systems we don't. We grab the foreground, then -// finish setting up, pump all our messages, and sleep for a little while -// to let messages finish bouncing around the system, then we put -// ourselves at the top of the z order, then grab the foreground again, -// Who knows if it helps, but it probably doesn't hurt - if (!force_minimized) - SetForegroundWindow (mainwindow); - - hdc = GetDC (NULL); - - if (GetDeviceCaps (hdc, RASTERCAPS) & RC_PALETTE) - vid_palettized = true; - else - vid_palettized = false; - - VID_SetPalette (palette); - - ReleaseDC (NULL, hdc); - - vid_modenum = modenum; - Cvar_SetValue (vid_mode, vid_modenum); - - if (!VID_AllocBuffers (vid.width, vid.height)) { - // couldn't get memory for this mode; try to fall back to previous mode - VID_RestoreOldMode (original_mode); - return false; - } - - D_InitCaches (vid_surfcache, vid_surfcachesize); - - while (PeekMessage (&msg, NULL, 0, 0, PM_REMOVE)) { - TranslateMessage (&msg); - DispatchMessage (&msg); - } - - Sleep (100); - - if (!force_minimized) { - SetWindowPos (mainwindow, HWND_TOP, 0, 0, 0, 0, SWP_DRAWFRAME | - SWP_NOMOVE | SWP_NOSIZE | SWP_SHOWWINDOW | - SWP_NOCOPYBITS); - - SetForegroundWindow (mainwindow); - } - - // fix the leftover Alt from any Alt-Tab or the like that switched us away - IN_ClearStates (); - - Con_Printf ("Video mode %s initialized\n", - VID_GetModeDescription (vid_modenum)); - - VID_SetPalette (palette); - - in_mode_set = false; - vid.recalc_refdef = 1; - - return true; -} - -void -VID_LockBuffer (void) -{ - if (dibdc) - return; - - lockcount++; - - if (lockcount > 1) - return; - - MGL_beginDirectAccess (); - - if (memdc) { - // Update surface pointer for linear access modes - vid.buffer = vid.conbuffer = vid.direct = memdc->surface; - vid.rowbytes = vid.conrowbytes = memdc->mi.bytesPerLine; - } else if (mgldc) { - // Update surface pointer for linear access modes - vid.buffer = vid.conbuffer = vid.direct = mgldc->surface; - vid.rowbytes = vid.conrowbytes = mgldc->mi.bytesPerLine; - } - - if (r_dowarp) - d_viewbuffer = r_warpbuffer; - else - d_viewbuffer = (void *) (byte *) vid.buffer; - - if (r_dowarp) - screenwidth = WARP_WIDTH; - else - screenwidth = vid.rowbytes; -} - -void -VID_UnlockBuffer (void) -{ - if (dibdc) - return; - - lockcount--; - - if (lockcount > 0) - return; - - if (lockcount < 0) - Sys_Error ("Unbalanced unlock"); - - MGL_endDirectAccess (); - - // to turn up any unlocked accesses - vid.buffer = vid.conbuffer = vid.direct = d_viewbuffer = NULL; -} - -int -VID_ForceUnlockedAndReturnState (void) -{ - int lk; - - if (!lockcount) - return 0; - - lk = lockcount; - - if (dibdc) { - lockcount = 0; - } else { - lockcount = 1; - VID_UnlockBuffer (); - } - - return lk; -} - -void -VID_ForceLockState (int lk) -{ - if (!dibdc && lk) { - lockcount = 0; - VID_LockBuffer (); - } - - lockcount = lk; -} - -void -VID_SetPalette (unsigned char *palette) -{ - INT i; - palette_t pal[256]; - HDC hdc; - - if (!Minimized) { - palette_changed = true; - - // make sure we have the static colors if we're the active app - hdc = GetDC (NULL); - - if (vid_palettized && ActiveApp) { - if (GetSystemPaletteUse (hdc) == SYSPAL_STATIC) { - // switch to SYSPAL_NOSTATIC and remap the colors - SetSystemPaletteUse (hdc, SYSPAL_NOSTATIC); - syscolchg = true; - pal_is_nostatic = true; - } - } - - ReleaseDC (NULL, hdc); - - // Translate the palette values to an MGL palette array and - // set the values. - for (i = 0; i < 256; i++) { - pal[i].red = palette[i * 3]; - pal[i].green = palette[i * 3 + 1]; - pal[i].blue = palette[i * 3 + 2]; - } - - if (DDActive) { - if (!mgldc) - return; - - MGL_setPalette (mgldc, pal, 256, 0); - MGL_realizePalette (mgldc, 256, 0, false); - if (memdc) - MGL_setPalette (memdc, pal, 256, 0); - } else { - if (!windc) - return; - - MGL_setPalette (windc, pal, 256, 0); - MGL_realizePalette (windc, 256, 0, false); - if (dibdc) { - MGL_setPalette (dibdc, pal, 256, 0); - MGL_realizePalette (dibdc, 256, 0, false); - } - } - } - - memcpy (vid_curpal, palette, sizeof (vid_curpal)); - - if (syscolchg) { - PostMessage (HWND_BROADCAST, WM_SYSCOLORCHANGE, (WPARAM) 0, - (LPARAM) 0); - syscolchg = false; - } -} - -void -VID_DescribeCurrentMode_f (void) -{ - Con_Printf ("%s\n", VID_GetExtModeDescription (vid_modenum)); -} - -void -VID_NumModes_f (void) -{ - - if (nummodes == 1) - Con_Printf ("%d video mode is available\n", nummodes); - else - Con_Printf ("%d video modes are available\n", nummodes); -} - -void -VID_DescribeMode_f (void) -{ - int modenum; - - modenum = atoi (Cmd_Argv (1)); - - Con_Printf ("%s\n", VID_GetExtModeDescription (modenum)); -} - -void -VID_DescribeModes_f (void) -{ - int i, lnummodes; - char *pinfo; - qboolean na; - vmode_t *pv; - - na = false; - - lnummodes = VID_NumModes (); - - for (i = 0; i < lnummodes; i++) { - pv = VID_GetModePtr (i); - pinfo = VID_GetExtModeDescription (i); - - if (VID_CheckAdequateMem (pv->width, pv->height)) { - 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"); - } -} - -void -VID_TestMode_f (void) -{ - int modenum; - double testduration; - - if (!vid_testingmode) { - modenum = atoi (Cmd_Argv (1)); - - if (VID_SetMode (modenum, vid_curpal)) { - vid_testingmode = 1; - testduration = atof (Cmd_Argv (2)); - if (testduration == 0) - testduration = 5.0; - vid_testendtime = realtime + testduration; - } - } -} - -void -VID_Windowed_f (void) -{ - - VID_SetMode (vid_windowed_mode->int_val, vid_curpal); -} - -void -VID_Fullscreen_f (void) -{ - - VID_SetMode (vid_fullscreen_mode->int_val, vid_curpal); -} - -void -VID_Minimize_f (void) -{ - // we only support minimizing windows; if you're fullscreen, - // switch to windowed first - if (modestate == MS_WINDOWED) - ShowWindow (mainwindow, SW_MINIMIZE); -} - -void -VID_ForceMode_f (void) -{ - int modenum; - - if (!vid_testingmode) { - modenum = atoi (Cmd_Argv (1)); - - force_mode_set = 1; - VID_SetMode (modenum, vid_curpal); - force_mode_set = 0; - } -} - -void -VID_Init (unsigned char *palette) -{ - int i, bestmatch = 0, bestmatchmetric, t, dr, dg, db; - int basenummodes; - byte *ptmp; - - Cmd_AddCommand ("vid_testmode", VID_TestMode_f, "Switch to another video " - "mode temporarily for 5-seconds to test it.\n" - "(vid_testmode (mode))"); - Cmd_AddCommand ("vid_nummodes", VID_NumModes_f, "Reports the total number " - "of video modes available"); - Cmd_AddCommand ("vid_describecurrentmode", VID_DescribeCurrentMode_f, - "Report current video mode."); - Cmd_AddCommand ("vid_describemode", VID_DescribeMode_f, "Report " - "information on specified video mode, default is " - "current.\n(vid_describemode (mode))"); - Cmd_AddCommand ("vid_describemodes", VID_DescribeModes_f, "Report " - "information on all video modes."); - Cmd_AddCommand ("vid_forcemode", VID_ForceMode_f, "Force QuakeWorld to " - "use a certain video mode. (vid_forcemode (mode))"); - Cmd_AddCommand ("vid_windowed", VID_Windowed_f, "Switch to windowed mode"); - Cmd_AddCommand ("vid_fullscreen", VID_Fullscreen_f, "Switch to full " - "screen mode"); - Cmd_AddCommand ("vid_minimize", VID_Minimize_f, "Minimize windowed Quake"); - - if (COM_CheckParm ("-dibonly")) - dibonly = true; - - VID_InitMGLDIB (global_hInstance); - - basenummodes = nummodes; - - if (!dibonly) - VID_InitMGLFull (global_hInstance); - - // if there are no non-windowed modes, or only windowed and mode 0x13, - // then use fullscreen DIBs as well - if (((nummodes == basenummodes) || ((nummodes == (basenummodes + 1)) && - is_mode0x13)) && - !COM_CheckParm ("-nofulldib")) - { - VID_InitFullDIB (global_hInstance); - } - - vid.maxwarpwidth = WARP_WIDTH; - vid.maxwarpheight = WARP_HEIGHT; - vid.colormap8 = vid_colormap; - vid.fullbright = 256 - LittleLong (*((int *) vid.colormap8 + 2048)); - vid_testingmode = 0; - - // GDI doesn't let us remap palette index 0, so we'll remap color - // mappings from that black to another one - bestmatchmetric = 256 * 256 * 3; - - for (i = 1; i < 256; i++) { - dr = palette[0] - palette[i * 3]; - dg = palette[1] - palette[i * 3 + 1]; - db = palette[2] - palette[i * 3 + 2]; - - t = (dr * dr) + (dg * dg) + (db * db); - - if (t < bestmatchmetric) { - bestmatchmetric = t; - bestmatch = i; - - if (t == 0) - break; - } - } - - for (i = 0, ptmp = vid.colormap8; i < (1 << (VID_CBITS + 8)); - i++, ptmp++) { - if (*ptmp == 0) - *ptmp = bestmatch; - } - - if (COM_CheckParm ("-startwindowed") || COM_CheckParm ("-window")) { - startwindowed = 1; - vid_default = windowed_default; - } -#ifdef SPLASH_SCREEN - if (hwnd_dialog) - DestroyWindow (hwnd_dialog); -#endif - -// FIXME: remove dead comment and S_Init -// sound initialization has to go here, preceded by a windowed mode set, -// so there's a window for DirectSound to work with but we're not yet -// fullscreen so the "hardware already in use" dialog is visible if it -// gets displayed - - // keep the window minimized until we're ready for the first real mode set - hide_window = true; - VID_SetMode (MODE_WINDOWED, palette); - hide_window = false; -// S_Init (); - - vid.initialized = true; - - force_mode_set = true; - VID_SetMode (vid_default, palette); - force_mode_set = false; - - vid_realmode = vid_modenum; - - VID_SetPalette (palette); - - vid_menudrawfn = VID_MenuDraw; - vid_menukeyfn = VID_MenuKey; - - strcpy (badmode.modedesc, "Bad mode"); -} - -void -VID_Init_Cvars () -{ - vid_mode = Cvar_Get ("vid_mode", "0", CVAR_NONE, NULL, "Set the video " - "mode"); - vid_nopageflip = Cvar_Get ("vid_nopageflip", "0", CVAR_ARCHIVE, NULL, - "Toggles the use of page flipping"); - _vid_default_mode_win = Cvar_Get ("_vid_default_mode_win", "3", - CVAR_ARCHIVE, NULL, "Default windowed " - "video mode"); - vid_config_x = Cvar_Get ("vid_config_x", "800", CVAR_ARCHIVE, NULL, - "Maximum x-axis screen size"); - vid_config_y = Cvar_Get ("vid_config_y", "600", CVAR_ARCHIVE, NULL, - "Maximum y-axis screen size"); - vid_stretch_by_2 = Cvar_Get ("vid_stretch_by_2", "1", CVAR_ARCHIVE, NULL, - "Stretch the pixles by a two fold to acheive " - "proper view"); - in_grab = Cvar_Get ("in_grab", "0", CVAR_ARCHIVE, NULL, - "Have quake grab the mouse from X when you " - "play"); - vid_fullscreen_mode = Cvar_Get ("vid_fullscreen_mode", "3", CVAR_ARCHIVE, - NULL, "Set the full screen video mode."); - vid_windowed_mode = Cvar_Get ("vid_windowed_mode", "0", CVAR_ARCHIVE, NULL, - "Set the windowed video mode"); - block_switch = Cvar_Get ("block_switch", "0", CVAR_ARCHIVE, NULL, "If " - "set, won't allow you to task switch while " - "playing"); - vid_window_x = Cvar_Get ("vid_window_x", "0", CVAR_ARCHIVE, NULL, "The " - "x-axis location of the window, if windowed"); - vid_window_y = Cvar_Get ("vid_window_y", "0", CVAR_ARCHIVE, NULL, "The " - "y-axis location of the window, if windowed"); -} - -void -VID_Shutdown (void) -{ -#ifdef SPLASH_SCREEN - if (hwnd_dialog) - DestroyWindow (hwnd_dialog); -#endif - - if (vid.initialized) { - if (modestate == MS_FULLDIB) - ChangeDisplaySettings (NULL, CDS_FULLSCREEN); - - PostMessage (HWND_BROADCAST, WM_PALETTECHANGED, (WPARAM) mainwindow, - (LPARAM) 0); - PostMessage (HWND_BROADCAST, WM_SYSCOLORCHANGE, (WPARAM) 0, - (LPARAM) 0); - - AppActivate (false, false); - DestroyDIBWindow (); - DestroyFullscreenWindow (); - DestroyFullDIBWindow (); - - if (mainwindow) - DestroyWindow (mainwindow); - - MGL_exit (); - - vid_testingmode = 0; - vid.initialized = 0; - } -} - -void -FlipScreen (vrect_t *rects) -{ - // Flip the surfaces - if (DDActive) { - if (mgldc) { - if (memdc) { - while (rects) { - if (vid_stretched) { - MGL_stretchBltCoord (mgldc, memdc, rects->x, - rects->y, rects->x + rects->width, - rects->y + rects->height, - rects->x << 1, rects->y << 1, - (rects->x + rects->width) << 1, - (rects->y + rects->height) << 1); - } else { - MGL_bitBltCoord (mgldc, memdc, rects->x, rects->y, - (rects->x + rects->width), - (rects->y + rects->height), - rects->x, rects->y, MGL_REPLACE_MODE); - } - - rects = rects->pnext; - } - } - - if (vid.numpages > 1) { - // We have a flipping surface, so do a hard page flip - aPage = (aPage + 1) % vid.numpages; - vPage = (vPage + 1) % vid.numpages; - MGL_setActivePage (mgldc, aPage); - MGL_setVisualPage (mgldc, vPage, waitVRT); - } - } - } else { - HDC hdcScreen; - - hdcScreen = GetDC (mainwindow); - - if (windc && dibdc) { - MGL_setWinDC (windc, hdcScreen); - - while (rects) { - if (vid_stretched) { - MGL_stretchBltCoord (windc, dibdc, rects->x, rects->y, - rects->x + rects->width, - rects->y + rects->height, - rects->x << 1, rects->y << 1, - (rects->x + rects->width) << 1, - (rects->y + rects->height) << 1); - } else { - MGL_bitBltCoord (windc, dibdc, rects->x, rects->y, - rects->x + rects->width, - rects->y + rects->height, rects->x, - rects->y, MGL_REPLACE_MODE); - } - - rects = rects->pnext; - } - } - - ReleaseDC (mainwindow, hdcScreen); - } -} - -void -VID_Update (vrect_t *rects) -{ - vrect_t rect; - RECT trect; - - if (!vid_palettized && palette_changed) { - palette_changed = false; - rect.x = 0; - rect.y = 0; - rect.width = vid.width; - rect.height = vid.height; - rect.pnext = NULL; - rects = ▭ - } - - if (firstupdate) { - if (modestate == MS_WINDOWED) { - GetWindowRect (mainwindow, &trect); - - if ((trect.left != vid_window_x->int_val) || - (trect.top != vid_window_y->int_val)) { - if (COM_CheckParm ("-resetwinpos")) { - Cvar_SetValue (vid_window_x, 0.0); - Cvar_SetValue (vid_window_y, 0.0); - } - - VID_CheckWindowXY (); - SetWindowPos (mainwindow, NULL, vid_window_x->int_val, - vid_window_y->int_val, 0, 0, SWP_NOSIZE | - SWP_NOZORDER | SWP_SHOWWINDOW | SWP_DRAWFRAME); - } - } - - if ((_vid_default_mode_win->int_val != vid_default) && - (!startwindowed || (_vid_default_mode_win->int_val < - MODE_FULLSCREEN_DEFAULT))) { - firstupdate = 0; - - if (COM_CheckParm ("-resetwinpos")) { - Cvar_SetValue (vid_window_x, 0.0); - Cvar_SetValue (vid_window_y, 0.0); - } - - if ((_vid_default_mode_win->int_val < 0) || - (_vid_default_mode_win->int_val >= nummodes)) { - Cvar_SetValue (_vid_default_mode_win, windowed_default); - } - - Cvar_SetValue (vid_mode, _vid_default_mode_win->int_val); - } - } - // We've drawn the frame; copy it to the screen - FlipScreen (rects); - - if (vid_testingmode) { - if (realtime >= vid_testendtime) { - VID_SetMode (vid_realmode, vid_curpal); - vid_testingmode = 0; - } - } else { - if (vid_mode->int_val != vid_realmode) { - VID_SetMode (vid_mode->int_val, vid_curpal); - Cvar_SetValue (vid_mode, vid_modenum); - // so if mode set fails, we don't keep on trying to set that mode - vid_realmode = vid_modenum; - } - } - - // handle the mouse state when windowed if that's changed - if (modestate == MS_WINDOWED) { - if (!in_grab->int_val) { - if (windowed_mouse) { - IN_DeactivateMouse (); - IN_ShowMouse (); - } - windowed_mouse = false; - } else { - windowed_mouse = true; - if (key_dest == key_game && !mouseactive && ActiveApp) { - IN_ActivateMouse (); - IN_HideMouse (); - } else if (mouseactive && key_dest != key_game) { - IN_DeactivateMouse (); - IN_ShowMouse (); - } - } - } -} - -void -D_BeginDirectRect (int x, int y, byte * pbitmap, int width, int height) -{ - int i, j, reps, repshift; - vrect_t rect; - - if (!vid.initialized) - return; - - if (vid.aspect > 1.5) { - reps = 2; - repshift = 1; - } else { - reps = 1; - repshift = 0; - } - - if (vid.numpages == 1) { - VID_LockBuffer (); - - if (!vid.direct) - Sys_Error ("NULL vid.direct pointer"); - - for (i = 0; i < (height << repshift); i += reps) { - for (j = 0; j < reps; j++) { - memcpy (&backingbuf[(i + j) * 24], - vid.direct + x + ((y << repshift) + i + - j) * vid.rowbytes, width); - memcpy (vid.direct + x + - ((y << repshift) + i + j) * vid.rowbytes, - &pbitmap[(i >> repshift) * width], width); - } - } - - VID_UnlockBuffer (); - - rect.x = x; - rect.y = y; - rect.width = width; - rect.height = height << repshift; - rect.pnext = NULL; - - FlipScreen (&rect); - } else { - // unlock if locked - if (lockcount > 0) - MGL_endDirectAccess (); - - // set the active page to the displayed page - MGL_setActivePage (mgldc, vPage); - - // lock the screen - MGL_beginDirectAccess (); - - // save from and draw to screen - for (i = 0; i < (height << repshift); i += reps) { - for (j = 0; j < reps; j++) { - memcpy (&backingbuf[(i + j) * 24], - (byte *) mgldc->surface + x + - ((y << repshift) + i + j) * mgldc->mi.bytesPerLine, - width); - memcpy ((byte *) mgldc->surface + x + - ((y << repshift) + i + j) * mgldc->mi.bytesPerLine, - &pbitmap[(i >> repshift) * width], width); - } - } - - // unlock the screen - MGL_endDirectAccess (); - - // restore the original active page - MGL_setActivePage (mgldc, aPage); - - // relock the screen if it was locked - if (lockcount > 0) - MGL_beginDirectAccess (); - } -} - -void -D_EndDirectRect (int x, int y, int width, int height) -{ - int i, j, reps, repshift; - vrect_t rect; - - if (!vid.initialized) - return; - - if (vid.aspect > 1.5) { - reps = 2; - repshift = 1; - } else { - reps = 1; - repshift = 0; - } - - if (vid.numpages == 1) { - VID_LockBuffer (); - - if (!vid.direct) - Sys_Error ("NULL vid.direct pointer"); - - for (i = 0; i < (height << repshift); i += reps) { - for (j = 0; j < reps; j++) { - memcpy (vid.direct + x + - ((y << repshift) + i + j) * vid.rowbytes, - &backingbuf[(i + j) * 24], width); - } - } - - VID_UnlockBuffer (); - - rect.x = x; - rect.y = y; - rect.width = width; - rect.height = height << repshift; - rect.pnext = NULL; - - FlipScreen (&rect); - } else { - // unlock if locked - if (lockcount > 0) - MGL_endDirectAccess (); - - // set the active page to the displayed page - MGL_setActivePage (mgldc, vPage); - - // lock the screen - MGL_beginDirectAccess (); - - // restore to the screen - for (i = 0; i < (height << repshift); i += reps) { - for (j = 0; j < reps; j++) { - memcpy ((byte *) mgldc->surface + x + - ((y << repshift) + i + j) * mgldc->mi.bytesPerLine, - &backingbuf[(i + j) * 24], width); - } - } - - // unlock the screen - MGL_endDirectAccess (); - - // restore the original active page - MGL_setActivePage (mgldc, aPage); - - // relock the screen if it was locked - if (lockcount > 0) - MGL_beginDirectAccess (); - } -} - -//============================================================================= - -/* - AppActivate - - fActive - True if app is activating - If the application is activating, then swap the system into SYSPAL_NOSTATIC - mode so that our palettes will display correctly. -*/ -void -AppActivate (BOOL fActive, BOOL minimize) -{ - HDC hdc; - int i, t; - static BOOL sound_active; - - ActiveApp = fActive; - - // messy, but it seems to work - if (vid_fulldib_on_focus_mode) { - Minimized = minimize; - - if (Minimized) - ActiveApp = false; - } - - MGL_appActivate (windc, ActiveApp); - - if (vid.initialized) { - // yield the palette if we're losing the focus - hdc = GetDC (NULL); - - if (GetDeviceCaps (hdc, RASTERCAPS) & RC_PALETTE) { - if (ActiveApp) { - if ((modestate == MS_WINDOWED) || (modestate == MS_FULLDIB)) { - if (GetSystemPaletteUse (hdc) == SYSPAL_STATIC) { - // switch to SYSPAL_NOSTATIC and remap the colors - SetSystemPaletteUse (hdc, SYSPAL_NOSTATIC); - syscolchg = true; - pal_is_nostatic = true; - } - } - } else if (pal_is_nostatic) { - if (GetSystemPaletteUse (hdc) == SYSPAL_NOSTATIC) { - // switch back to SYSPAL_STATIC and the old mapping - SetSystemPaletteUse (hdc, SYSPAL_STATIC); - syscolchg = true; - } - - pal_is_nostatic = false; - } - } - - if (!Minimized) - VID_SetPalette (vid_curpal); - - scr_fullupdate = 0; - - ReleaseDC (NULL, hdc); - } - // enable/disable sound on focus gain/loss - if (!ActiveApp && sound_active) { - S_BlockSound (); - S_ClearBuffer (); - sound_active = false; - } else if (ActiveApp && !sound_active) { - S_UnblockSound (); - S_ClearBuffer (); - sound_active = true; - } - // minimize/restore fulldib windows/mouse-capture normal windows on demand - if (!in_mode_set) { - if (ActiveApp) { - if (vid_fulldib_on_focus_mode) { - if (vid.initialized) { - VID_SetMode (vid_fulldib_on_focus_mode, vid_curpal); - - t = in_mode_set; - in_mode_set = true; - AppActivate (true, false); - in_mode_set = t; - } - - IN_ActivateMouse (); - IN_HideMouse (); - } - else if ((modestate == MS_WINDOWED) && in_grab->int_val - && key_dest == key_game) { - IN_ActivateMouse (); - IN_HideMouse (); - } - } - - if (!ActiveApp) { - if (modestate == MS_FULLDIB) { - if (vid.initialized) { - force_minimized = true; - i = vid_fulldib_on_focus_mode; - VID_SetMode (windowed_default, vid_curpal); - vid_fulldib_on_focus_mode = i; - force_minimized = false; - - // we never seem to get WM_ACTIVATE inactive from this - // mode set, so we'll do it manually - t = in_mode_set; - in_mode_set = true; - AppActivate (false, true); - in_mode_set = t; - } - - IN_DeactivateMouse (); - IN_ShowMouse (); - } else if ((modestate == MS_WINDOWED) && in_grab->int_val - /* && mouseactive */ ) { - IN_DeactivateMouse (); - IN_ShowMouse (); - } - } - } -} - -void -VID_HandlePause (qboolean pause) -{ -#if 0 - if ((modestate == MS_WINDOWED) && in_grab->int_val) { - if (pause) { - IN_DeactivateMouse (); - IN_ShowMouse (); - } else { - IN_ActivateMouse (); - IN_HideMouse (); - } - } -#endif -} - -// MAIN WINDOW ================================================================ - -LONG CDAudio_MessageHandler (HWND hWnd, UINT uMsg, WPARAM wParam, - LPARAM lParam); - -/* main window procedure */ -LONG WINAPI -MainWndProc (HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) -{ - LONG lRet = 0; - int fActive, fMinimized, temp; - int key, unicode; - HDC hdc; - PAINTSTRUCT ps; - extern unsigned int uiWheelMessage; - - if (uMsg == uiWheelMessage) { - uMsg = WM_MOUSEWHEEL; - wParam <<= 16; - } - - switch (uMsg) { - case WM_CREATE: - break; - - case WM_MOVE: - VID_UpdateWindowStatus ((int) LOWORD (lParam), - (int) HIWORD (lParam)); - if ((modestate == MS_WINDOWED) && !in_mode_set && !Minimized) - VID_RememberWindowPos (); - break; - - case WM_KEYDOWN: - case WM_SYSKEYDOWN: - if (!in_mode_set) { - MapKey (lParam, 1, &key, &unicode); - Key_Event (key, unicode, true); - } - break; - - case WM_KEYUP: - case WM_SYSKEYUP: - if (!in_mode_set) { - MapKey (lParam, 0, &key, &unicode); - Key_Event (key, unicode, false); - } - break; - - case WM_SYSCHAR: - // keep Alt-Space from happening - break; - - // this is complicated because Win32 seems to pack multiple mouse - // events into one update sometimes, so always check all states and - // look for events - case WM_LBUTTONDOWN: - case WM_LBUTTONUP: - case WM_RBUTTONDOWN: - case WM_RBUTTONUP: - case WM_MBUTTONDOWN: - case WM_MBUTTONUP: - case WM_MOUSEMOVE: - if (!in_mode_set) { - temp = 0; - - if (wParam & MK_LBUTTON) - temp |= 1; - if (wParam & MK_RBUTTON) - temp |= 2; - if (wParam & MK_MBUTTON) - temp |= 4; - IN_MouseEvent (temp); - } - break; - - // JACK: This is the mouse wheel with the Intellimouse - // Its delta is either positive or neg, and we generate the proper - // Event. - case WM_MOUSEWHEEL: - if ((short) HIWORD (wParam) > 0) { - Key_Event (QFK_MWHEELUP, -1, true); - Key_Event (QFK_MWHEELUP, -1, false); - } else { - Key_Event (QFK_MWHEELDOWN, -1, true); - Key_Event (QFK_MWHEELDOWN, -1, false); - } - break; - - case WM_SIZE: - Minimized = false; - - if (!(wParam & SIZE_RESTORED)) { - if (wParam & SIZE_MINIMIZED) - Minimized = true; - } - break; - - case WM_CLOSE: - // this causes Close in the right-click task bar menu not to work, - // but right now bad things happen if Close is handled in that case - // (garbage and a crash on Win95) - if (!in_mode_set) { - if (MessageBox - (mainwindow, "Are you sure you want to quit?", - "Confirm Exit", - MB_YESNO | MB_SETFOREGROUND | MB_ICONQUESTION) == IDYES) { - Sys_Quit (); - } - } - break; - - case WM_ACTIVATE: - fActive = LOWORD (wParam); - fMinimized = (BOOL) HIWORD (wParam); - AppActivate (!(fActive == WA_INACTIVE), fMinimized); - // fix leftover Alt from any Alt-Tab or the like that switched us - // away - IN_ClearStates (); - - if (!in_mode_set) { - if (windc) - MGL_activatePalette (windc, true); - - VID_SetPalette (vid_curpal); - } - break; - - case MM_MCINOTIFY: -// FIXME lRet = CDAudio_MessageHandler (hWnd, uMsg, wParam, lParam); - break; - - default: - // pass all unhandled messages to DefWindowProc - lRet = DefWindowProc (hWnd, uMsg, wParam, lParam); - break; - - case WM_SYSCOMMAND: - // Check for maximize being hit - switch (wParam & ~0x0F) { - case SC_MAXIMIZE: - // if minimized, bring up as a window before going - // fullscreen, so MGL will have the right state to restore - if (Minimized) { - force_mode_set = true; - VID_SetMode (vid_modenum, vid_curpal); - force_mode_set = false; - } - - VID_SetMode (vid_fullscreen_mode->int_val, vid_curpal); - break; - - case SC_SCREENSAVE: - case SC_MONITORPOWER: - if (modestate != MS_WINDOWED) { - // don't call DefWindowProc() because we don't want - // to start the screen saver fullscreen - break; - } - - // fall through windowed and allow the screen saver to start - default: - if (!in_mode_set) { - S_BlockSound (); - S_ClearBuffer (); - } - - lRet = DefWindowProc (hWnd, uMsg, wParam, lParam); - - if (!in_mode_set) { - S_UnblockSound (); - } - } - break; - - case WM_PAINT: - hdc = BeginPaint (hWnd, &ps); - - if (!in_mode_set && host_initialized) - SCR_UpdateWholeScreen (); - - EndPaint (hWnd, &ps); - break; - - // KJB: Added these new palette functions - case WM_PALETTECHANGED: - if ((HWND) wParam == hWnd) - break; - - // Fall through to WM_QUERYNEWPALETTE - case WM_QUERYNEWPALETTE: - hdc = GetDC (NULL); - - if (GetDeviceCaps (hdc, RASTERCAPS) & RC_PALETTE) - vid_palettized = true; - else - vid_palettized = false; - - ReleaseDC (NULL, hdc); - - scr_fullupdate = 0; - - if (vid.initialized && !in_mode_set && windc - && MGL_activatePalette (windc, false) && !Minimized) { - VID_SetPalette (vid_curpal); - InvalidateRect (mainwindow, NULL, false); - - // specifically required if WM_QUERYNEWPALETTE realizes a new - // palette - lRet = TRUE; - } - break; - - case WM_DISPLAYCHANGE: - if (!in_mode_set && (modestate == MS_WINDOWED) - && !vid_fulldib_on_focus_mode) { - force_mode_set = true; - VID_SetMode (vid_modenum, vid_curpal); - force_mode_set = false; - } - break; - } - - return lRet; // return 0 if handled message, 1 if not -} - - -static int vid_line, vid_wmodes; - -typedef struct { - int modenum; - char *desc; - int iscur; - int ismode13; - int width; -} modedesc_t; - -#define MAX_COLUMN_SIZE 5 -#define MODE_AREA_HEIGHT (MAX_COLUMN_SIZE + 6) -#define MAX_MODEDESCS (MAX_COLUMN_SIZE*3) - -static modedesc_t modedescs[MAX_MODEDESCS]; - -void -VID_MenuDraw (void) -{ - qpic_t *p; - char *ptr; - int lnummodes, i, j, k, column, row, dup, dupmode = 0; - char temp[100]; - vmode_t *pv; - modedesc_t tmodedesc; - - p = Draw_CachePic ("gfx/vidmodes.lmp", true); - M_DrawPic ((320 - p->width) / 2, 4, p); - - for (i = 0; i < 3; i++) { - ptr = VID_GetModeDescriptionMemCheck (i); - modedescs[i].modenum = modelist[i].modenum; - modedescs[i].desc = ptr; - modedescs[i].ismode13 = 0; - modedescs[i].iscur = 0; - - if (vid_modenum == i) - modedescs[i].iscur = 1; - } - - vid_wmodes = 3; - lnummodes = VID_NumModes (); - - for (i = 3; i < lnummodes; i++) { - ptr = VID_GetModeDescriptionMemCheck (i); - pv = VID_GetModePtr (i); - - // we only have room for 15 fullscreen modes, so don't allow - // 360-wide modes, because if there are 5 320-wide modes and - // 5 360-wide modes, we'll run out of space - if (ptr && ((pv->width != 360) || COM_CheckParm ("-allow360"))) { - dup = 0; - - for (j = 3; j < vid_wmodes; j++) { - if (!strcmp (modedescs[j].desc, ptr)) { - dup = 1; - dupmode = j; - break; - } - } - - if (dup || (vid_wmodes < MAX_MODEDESCS)) { - if (!dup || !modedescs[dupmode].ismode13 - || COM_CheckParm ("-noforcevga")) { - if (dup) { - k = dupmode; - } else { - k = vid_wmodes; - } - - modedescs[k].modenum = i; - modedescs[k].desc = ptr; - modedescs[k].ismode13 = pv->mode13; - modedescs[k].iscur = 0; - modedescs[k].width = pv->width; - - if (i == vid_modenum) - modedescs[k].iscur = 1; - - if (!dup) - vid_wmodes++; - } - } - } - } - - // sort the modes on width (to handle picking up oddball dibonly modes - // after all the others) - for (i = 3; i < (vid_wmodes - 1); i++) { - for (j = (i + 1); j < vid_wmodes; j++) { - if (modedescs[i].width > modedescs[j].width) { - tmodedesc = modedescs[i]; - modedescs[i] = modedescs[j]; - modedescs[j] = tmodedesc; - } - } - } - - M_Print (13 * 8, 36, "Windowed Modes"); - - column = 16; - row = 36 + 2 * 8; - - for (i = 0; i < 3; i++) { - if (modedescs[i].iscur) - M_PrintWhite (column, row, modedescs[i].desc); - else - M_Print (column, row, modedescs[i].desc); - - column += 13 * 8; - } - - if (vid_wmodes > 3) { - M_Print (12 * 8, 36 + 4 * 8, "Fullscreen Modes"); - - column = 16; - row = 36 + 6 * 8; - - for (i = 3; i < vid_wmodes; i++) { - if (modedescs[i].iscur) - M_PrintWhite (column, row, modedescs[i].desc); - else - M_Print (column, row, modedescs[i].desc); - - column += 13 * 8; - - if (((i - 3) % VID_ROW_SIZE) == (VID_ROW_SIZE - 1)) { - column = 16; - row += 8; - } - } - } - // line cursor - if (vid_testingmode) { - snprintf (temp, sizeof (temp), "TESTING %s", modedescs[vid_line].desc); - M_Print (13 * 8, 36 + MODE_AREA_HEIGHT * 8 + 8 * 4, temp); - M_Print (9 * 8, 36 + MODE_AREA_HEIGHT * 8 + 8 * 6, - "Please wait 5 seconds..."); - } else { - M_Print (9 * 8, 36 + MODE_AREA_HEIGHT * 8 + 8, - "Press Enter to set mode"); - M_Print (6 * 8, 36 + MODE_AREA_HEIGHT * 8 + 8 * 3, - "T to test mode for 5 seconds"); - ptr = VID_GetModeDescription2 (vid_modenum); - - if (ptr) { - snprintf (temp, sizeof (temp), "D to set default: %s", ptr); - M_Print (2 * 8, 36 + MODE_AREA_HEIGHT * 8 + 8 * 5, temp); - } - - ptr = VID_GetModeDescription2 (_vid_default_mode_win->int_val); - - if (ptr) { - snprintf (temp, sizeof (temp), "Current default: %s", ptr); - M_Print (3 * 8, 36 + MODE_AREA_HEIGHT * 8 + 8 * 6, temp); - } - - M_Print (15 * 8, 36 + MODE_AREA_HEIGHT * 8 + 8 * 8, "Esc to exit"); - - row = 36 + 2 * 8 + (vid_line / VID_ROW_SIZE) * 8; - column = 8 + (vid_line % VID_ROW_SIZE) * 13 * 8; - - if (vid_line >= 3) - row += 3 * 8; - - M_DrawCharacter (column, row, 12 + ((int) (realtime * 4) & 1)); - } -} - -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_LEFTARROW: - S_LocalSound ("misc/menu1.wav"); - vid_line = ((vid_line / VID_ROW_SIZE) * VID_ROW_SIZE) + - ((vid_line + 2) % VID_ROW_SIZE); - - if (vid_line >= vid_wmodes) - vid_line = vid_wmodes - 1; - break; - - case K_RIGHTARROW: - S_LocalSound ("misc/menu1.wav"); - vid_line = ((vid_line / VID_ROW_SIZE) * VID_ROW_SIZE) + - ((vid_line + 4) % VID_ROW_SIZE); - - if (vid_line >= vid_wmodes) - vid_line = (vid_line / VID_ROW_SIZE) * VID_ROW_SIZE; - break; - - case K_UPARROW: - S_LocalSound ("misc/menu1.wav"); - vid_line -= VID_ROW_SIZE; - - if (vid_line < 0) { - vid_line += ((vid_wmodes + (VID_ROW_SIZE - 1)) / - VID_ROW_SIZE) * VID_ROW_SIZE; - - while (vid_line >= vid_wmodes) - vid_line -= VID_ROW_SIZE; - } - break; - - case K_DOWNARROW: - S_LocalSound ("misc/menu1.wav"); - vid_line += VID_ROW_SIZE; - - if (vid_line >= vid_wmodes) { - vid_line -= ((vid_wmodes + (VID_ROW_SIZE - 1)) / - VID_ROW_SIZE) * VID_ROW_SIZE; - - while (vid_line < 0) - vid_line += VID_ROW_SIZE; - } - break; - - case K_ENTER: - S_LocalSound ("misc/menu1.wav"); - VID_SetMode (modedescs[vid_line].modenum, vid_curpal); - break; - - case 'T': - case 't': - S_LocalSound ("misc/menu1.wav"); - // have to set this before setting the mode because WM_PAINT - // happens during the mode set and does a VID_Update, which - // checks vid_testingmode - vid_testingmode = 1; - vid_testendtime = realtime + 5.0; - - if (!VID_SetMode (modedescs[vid_line].modenum, vid_curpal)) { - vid_testingmode = 0; - } - break; - - case 'D': - case 'd': - S_LocalSound ("misc/menu1.wav"); - firstupdate = 0; - Cvar_SetValue (_vid_default_mode_win, vid_modenum); - break; - - default: - break; - } -} - -void -VID_SetCaption (const char *text) -{ - if (text && *text) { - char *temp = strdup (text); - - SetWindowText (mainwindow, (LPSTR) va ("%s %s: %s", PROGRAM, VERSION, - text)); - free (temp); - } else { - SetWindowText (mainwindow, (LPSTR) va ("%s %s", PROGRAM, VERSION)); - } -}