diff --git a/libs/video/targets/vid_win.c b/libs/video/targets/vid_win.c index b8c35396e..9fde73bf5 100644 --- a/libs/video/targets/vid_win.c +++ b/libs/video/targets/vid_win.c @@ -29,80 +29,57 @@ #endif #include "winquake.h" +#include -#include "QF/cdaudio.h" #include "QF/cmd.h" -#include "QF/console.h" #include "QF/cvar.h" #include "QF/input.h" #include "QF/keys.h" #include "QF/qargs.h" -#include "QF/qendian.h" -#include "QF/quakefs.h" -#include "QF/screen.h" -#include "QF/sound.h" #include "QF/sys.h" #include "QF/va.h" #include "QF/vid.h" #include "QF/GL/funcs.h" #include "QF/GL/qf_vid.h" -#include "compat.h" +#include "d_iface.h" +#include "d_local.h" #include "in_win.h" #include "r_cvar.h" -#include "win32/resources/resource.h" -#include "sbar.h" +#include "r_shared.h" #include "vid_internal.h" -extern const char *gl_renderer; +// true if the ddraw driver started up OK +qboolean vid_usingddraw = false; -HWND mainwindow; -qboolean win_canalttab = false; -modestate_t modestate = MS_UNINIT; -RECT window_rect; -DEVMODE win_gdevmode; -int window_center_x, window_center_y, window_x, window_y, window_width, - window_height; +// compatibility +HWND mainwindow = NULL; +qboolean win_canalttab = false; + +// main application window +HWND hWndWinQuake = NULL; +HDC maindc; + +byte gammatable[256]; + +//FIXME?int yeahimconsoled; static void *libgl_handle; -static HGLRC (GLAPIENTRY *qfwglCreateContext) (HDC); -static BOOL (GLAPIENTRY *qfwglDeleteContext) (HGLRC); -static HGLRC (GLAPIENTRY *qfwglGetCurrentContext) (void); -static HDC (GLAPIENTRY *qfwglGetCurrentDC) (void); -static BOOL (GLAPIENTRY *qfwglMakeCurrent) (HDC, HGLRC); +static HGLRC (GLAPIENTRY * qfwglCreateContext) (HDC); +static BOOL (GLAPIENTRY * qfwglDeleteContext) (HGLRC); +static HGLRC (GLAPIENTRY * qfwglGetCurrentContext) (void); +static HDC (GLAPIENTRY * qfwglGetCurrentDC) (void); +static BOOL (GLAPIENTRY * qfwglMakeCurrent) (HDC, HGLRC); -#define MAX_MODE_LIST 30 -#define VID_ROW_SIZE 3 -#define WARP_WIDTH 320 -#define WARP_HEIGHT 200 -#define MAXWIDTH 10000 -#define MAXHEIGHT 10000 -#define BASEWIDTH 320 -#define BASEHEIGHT 200 - -#define MODE_WINDOWED 0 -#define NO_MODE (MODE_WINDOWED - 1) -#define MODE_FULLSCREEN_DEFAULT (MODE_WINDOWED + 1) - -static int windowed_mouse; - -static HICON hIcon; -static RECT WindowRect; -static DWORD WindowStyle; - -static qboolean fullsbardraw = true; - -static HDC maindc; - - -static void GL_Init (void); -static void * (WINAPI *glGetProcAddress) (const char *symbol) = NULL; +static void *(WINAPI * glGetProcAddress) (const char *symbol) = NULL; +static void (*choose_visual) (void); +static void (*create_context) (void); static void * QFGL_GetProcAddress (void *handle, const char *name) { - void *glfunc = NULL; + void *glfunc = NULL; if (glGetProcAddress) glfunc = glGetProcAddress (name); @@ -114,7 +91,7 @@ QFGL_GetProcAddress (void *handle, const char *name) static void * QFGL_ProcAddress (const char *name, qboolean crit) { - void *glfunc = NULL; + void *glfunc = NULL; Sys_MaskPrintf (SYS_VID, "DEBUG: Finding symbol %s ... ", name); @@ -132,219 +109,6 @@ QFGL_ProcAddress (const char *name, qboolean crit) return NULL; } -//==================================== - -static void -CenterWindow (HWND hWndCenter, int width, int height, BOOL lefttopjustify) -{ - int CenterX, CenterY; - - CenterX = (GetSystemMetrics (SM_CXSCREEN) - width) / 2; - CenterY = (GetSystemMetrics (SM_CYSCREEN) - height) / 2; - if (CenterX > CenterY * 2) - CenterX >>= 1; // dual screens - CenterX = (CenterX < 0) ? 0 : CenterX; - CenterY = (CenterY < 0) ? 0 : CenterY; - SetWindowPos (hWndCenter, NULL, CenterX, CenterY, 0, 0, - SWP_NOSIZE | SWP_NOZORDER | SWP_SHOWWINDOW | SWP_DRAWFRAME); -} - -static qboolean -VID_SetWindowedMode ( void ) -{ - HDC hdc; - int width, height; - RECT rect; - - WindowStyle = WS_OVERLAPPED | WS_BORDER | WS_CAPTION | WS_SYSMENU | - WS_MINIMIZEBOX | WS_CLIPSIBLINGS | WS_CLIPCHILDREN; - - rect = WindowRect; - AdjustWindowRect (&rect, WindowStyle, FALSE); - - width = rect.right - rect.left; - height = rect.bottom - rect.top; - - // Create the window - mainwindow = CreateWindow ("QuakeForge", PACKAGE_NAME, - WindowStyle, rect.left, rect.top, width, height, - NULL, NULL, global_hInstance, NULL); - - if (!mainwindow) - Sys_Error ("Couldn't create DIB window (%lx)", GetLastError ()); - - // Center and show the window - CenterWindow (mainwindow, WindowRect.right - WindowRect.left, - WindowRect.bottom - WindowRect.top, false); - - ShowWindow (mainwindow, SW_SHOWDEFAULT); - UpdateWindow (mainwindow); - - modestate = MS_WINDOWED; - - // 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); - - viddef.numpages = 2; - - if(hIcon) { - SendMessage (mainwindow, WM_SETICON, (WPARAM) TRUE, (LPARAM) hIcon); - SendMessage (mainwindow, WM_SETICON, (WPARAM) FALSE, (LPARAM) hIcon); - } - - return true; -} - -static qboolean -VID_SetFullDIBMode ( void ) -{ - HDC hdc; - int width, height; - RECT rect; - - if (ChangeDisplaySettings (&win_gdevmode, CDS_FULLSCREEN) - != DISP_CHANGE_SUCCESSFUL) - Sys_Error ("Couldn't set fullscreen DIB mode (%lx)", GetLastError()); - - // FIXME: some drivers have broken FS popup window handling until I find a - // way around it, or find some other cause for it this is a way to avoid it - if (COM_CheckParm ("-brokenpopup")) - WindowStyle = 0; - else - WindowStyle = WS_POPUP | WS_CLIPSIBLINGS | WS_CLIPCHILDREN; - - rect = WindowRect; - AdjustWindowRect (&rect, WindowStyle, FALSE); - - width = rect.right - rect.left; - height = rect.bottom - rect.top; - - // Create the DIB window - mainwindow = CreateWindow ("QuakeForge", "GLQuakeWorld", WindowStyle, - rect.left, rect.top, width, height, NULL, NULL, - global_hInstance, NULL); - - if (!mainwindow) - Sys_Error ("Couldn't create DIB window (%lx)",GetLastError()); - - 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); - - viddef.numpages = 2; - - // needed because we're not getting WM_MOVE messages fullscreen on NT - window_x = 0; - window_y = 0; - - if (hIcon) { - SendMessage (mainwindow, WM_SETICON, (WPARAM) TRUE, (LPARAM) hIcon); - SendMessage (mainwindow, WM_SETICON, (WPARAM) FALSE, (LPARAM) hIcon); - } - - return true; -} - -static int -VID_SetMode (unsigned char *palette) -{ - qboolean stat = 0; - MSG msg; - - // so Con_Printfs don't mess us up by forcing vid and snd updates - CDAudio_Pause (); - - WindowRect.top = WindowRect.left = 0; - - WindowRect.right = viddef.width; - WindowRect.bottom = viddef.height; - - window_width = viddef.width; - window_height = viddef.height; - - // Set either the fullscreen or windowed mode - if (!vid_fullscreen->int_val) { - stat = VID_SetWindowedMode (); - } else { - stat = VID_SetFullDIBMode (); - } - - VID_UpdateWindowStatus (window_x, window_y); - - CDAudio_Resume (); - - if (!stat) { - Sys_Error ("Couldn't set video mode"); - } - - // 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 - SetForegroundWindow (mainwindow); - viddef.set_palette (palette); - - while (PeekMessage (&msg, NULL, 0, 0, PM_REMOVE)) { - TranslateMessage (&msg); - DispatchMessage (&msg); - } - - Sleep (100); - - 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 (); - - Sys_Printf ("Video mode %ix%i initialized.\n", - viddef.width, viddef.height); - - viddef.set_palette (palette); - - viddef.recalc_refdef = 1; - - return true; -} - -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 (); -} - -static void -GL_Init (void) -{ - GL_Init_Common (); - if (strnicmp (gl_renderer, "PowerVR", 7) == 0) - fullsbardraw = true; -} - static void GL_EndRendering (void) { @@ -352,92 +116,20 @@ GL_EndRendering (void) qfglFinish (); SwapBuffers (maindc); } - // handle the mouse state when windowed if that's changed if (!vid_fullscreen->int_val) { if (!in_grab->int_val) { - if (windowed_mouse) { - IN_DeactivateMouse (); - IN_ShowMouse (); - windowed_mouse = false; - } +//FIXME if (windowed_mouse) { +//FIXME IN_DeactivateMouse (); +//FIXME IN_ShowMouse (); +//FIXME windowed_mouse = false; +//FIXME } } else { - windowed_mouse = true; +//FIXME windowed_mouse = true; } } } -void -VID_Shutdown (void) -{ - HGLRC hRC; - HDC hDC; - int i; - GLuint temp[8192]; - -#ifdef SPLASH_SCREEN - if(hwnd_dialog) - DestroyWindow (hwnd_dialog); -#endif - - if (viddef.initialized) { - win_canalttab = false; - hRC = qfwglGetCurrentContext (); - hDC = qfwglGetCurrentDC (); - - qfwglMakeCurrent (NULL, NULL); - - // LordHavoc: free textures before closing (may help NVIDIA) - for (i = 0; i < 8192; i++) - temp[i] = i + 1; - qfglDeleteTextures (8192, temp); - - if (hRC) - qfwglDeleteContext (hRC); - - if (hDC && mainwindow) - ReleaseDC (mainwindow, hDC); - - if (vid_fullscreen->int_val) - ChangeDisplaySettings (NULL, 0); - - if (maindc && mainwindow) - ReleaseDC (mainwindow, maindc); - - AppActivate (false, false); - } -} - -//========================================================================== - -static BOOL -bSetupPixelFormat (HDC hDC) -{ - PIXELFORMATDESCRIPTOR pfd ; - int pixelformat; - - memset (&pfd, 0, sizeof(PIXELFORMATDESCRIPTOR)); - pfd.nSize = sizeof(PIXELFORMATDESCRIPTOR); - pfd.nVersion = 1; - pfd.dwFlags = PFD_DOUBLEBUFFER | PFD_SUPPORT_OPENGL | PFD_DRAW_TO_WINDOW; - pfd.iPixelType = PFD_TYPE_RGBA; - - pfd.cColorBits = win_gdevmode.dmBitsPerPel ; - - pfd.cDepthBits = 32; - pfd.iLayerType = PFD_MAIN_PLANE; - - if ((pixelformat = ChoosePixelFormat (hDC, &pfd)) == 0) { - MessageBox (NULL, "ChoosePixelFormat failed", "Error", MB_OK); - return FALSE; - } - - if (SetPixelFormat (hDC, pixelformat, &pfd) == FALSE) { - MessageBox (NULL, "SetPixelFormat failed", "Error", MB_OK); - return FALSE; - } - return TRUE; -} static void wgl_load_gl (void) @@ -447,7 +139,8 @@ wgl_load_gl (void) if (!(libgl_handle = LoadLibrary (gl_driver->string))) Sys_Error ("Couldn't load OpenGL library %s!", gl_driver->string); - glGetProcAddress =(void*)GetProcAddress(libgl_handle, "wglGetProcAddress"); + glGetProcAddress = + (void *) GetProcAddress (libgl_handle, "wglGetProcAddress"); qfwglCreateContext = QFGL_ProcAddress ("wglCreateContext", true); qfwglDeleteContext = QFGL_ProcAddress ("wglDeleteContext", true); @@ -456,142 +149,1945 @@ wgl_load_gl (void) qfwglMakeCurrent = QFGL_ProcAddress ("wglMakeCurrent", true); } -void -VID_Init (byte *palette, byte *colormap) + +/* +============================================================================= + + DIRECTDRAW VIDEO DRIVER + +============================================================================= +*/ + +LPDIRECTDRAW dd_Object = NULL; +HINSTANCE hInstDDraw = NULL; + +LPDIRECTDRAWSURFACE dd_FrontBuffer = NULL; +LPDIRECTDRAWSURFACE dd_BackBuffer = NULL; + +LPDIRECTDRAWCLIPPER dd_Clipper = NULL; + +typedef HRESULT (WINAPI * DIRECTDRAWCREATEPROC) (GUID FAR *, + LPDIRECTDRAW FAR *, + IUnknown FAR *); +DIRECTDRAWCREATEPROC QDirectDrawCreate = NULL; + +unsigned ddpal[256]; + +byte *vidbuf = NULL; + + +int dd_window_width = 640; +int dd_window_height = 480; +RECT SrcRect; +RECT DstRect; + +static void +DD_UpdateRects (int width, int height) { - BOOL stat; - WORD bpp, vid_mode; - HDC hdc; - HGLRC baseRC; - DWORD lasterror; - WNDCLASS wc; + POINT p; - R_LoadModule (wgl_load_gl, 0); //FIXME VID_SetPalette + p.x = 0; + p.y = 0; - vid_fullscreen = Cvar_Get ("vid_fullscreen", "0", CVAR_ROM | CVAR_ARCHIVE, - NULL, "Run WGL client at fullscreen"); - - memset (&win_gdevmode, 0, sizeof (win_gdevmode)); - - hIcon = LoadIcon (global_hInstance, MAKEINTRESOURCE (IDI_ICON1)); + // first we need to figure out where on the primary surface our window + // lives + ClientToScreen (hWndWinQuake, &p); + GetClientRect (hWndWinQuake, &DstRect); + OffsetRect (&DstRect, p.x, p.y); + SetRect (&SrcRect, 0, 0, width, height); +} - // Register the frame class - wc.style = 0; +static void +VID_CreateDDrawDriver (int width, int height, byte *palette, void **buffer, + int *rowbytes) +{ + HRESULT hr; + DDSURFACEDESC ddsd; + + vid_usingddraw = false; + dd_window_width = width; + dd_window_height = height; + + vidbuf = (byte *) malloc (width * height); + buffer[0] = vidbuf; + rowbytes[0] = width; + + if (!(hInstDDraw = LoadLibrary ("ddraw.dll"))) + return; + if (!(QDirectDrawCreate = + (DIRECTDRAWCREATEPROC) GetProcAddress (hInstDDraw, + "DirectDrawCreate"))) + return; + + if (FAILED (hr = QDirectDrawCreate (NULL, &dd_Object, NULL))) + return; + if (FAILED (hr = dd_Object->lpVtbl->SetCooperativeLevel (dd_Object, + hWndWinQuake, + DDSCL_NORMAL))) + return; + + // the primary surface in windowed mode is the full screen + memset (&ddsd, 0, sizeof (ddsd)); + ddsd.dwSize = sizeof (ddsd); + ddsd.dwFlags = DDSD_CAPS; + ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE | DDSCAPS_VIDEOMEMORY; + + // ...and create it + if (FAILED (hr = dd_Object->lpVtbl->CreateSurface (dd_Object, &ddsd, + &dd_FrontBuffer, NULL))) + return; + + // not using a clipper will slow things down and switch aero off + if (FAILED (hr = IDirectDraw_CreateClipper (dd_Object, 0, &dd_Clipper, + NULL))) + return; + if (FAILED (hr = IDirectDrawClipper_SetHWnd (dd_Clipper, 0, hWndWinQuake))) + return; + if (FAILED (hr = IDirectDrawSurface_SetClipper (dd_FrontBuffer, + dd_Clipper))) + return; + + // the secondary surface is an offscreen surface that is the currect + // dimensions + // this will be blitted to the correct location on the primary surface + // (which is the full screen) during our draw op + memset (&ddsd, 0, sizeof (ddsd)); + ddsd.dwSize = sizeof (ddsd); + ddsd.dwFlags = DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH; + ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | DDSCAPS_VIDEOMEMORY; + ddsd.dwWidth = width; + ddsd.dwHeight = height; + + if (FAILED (hr = IDirectDraw_CreateSurface (dd_Object, &ddsd, + &dd_BackBuffer, NULL))) + return; + + // direct draw is working now + vid_usingddraw = true; + + // create a palette + VID_InitGamma (palette); + viddef.set_palette (palette); + + // create initial rects + DD_UpdateRects (dd_window_width, dd_window_height); +} + + +/* +===================================================================== + + GDI VIDEO DRIVER + +===================================================================== +*/ + +// common bitmap definition +typedef struct dibinfo { + BITMAPINFOHEADER header; + RGBQUAD acolors[256]; +} dibinfo_t; + + +static HGDIOBJ previously_selected_GDI_obj = NULL; +HBITMAP hDIBSection; +byte *pDIBBase = NULL; +HDC hdcDIBSection = NULL; +HDC hdcGDI = NULL; + + +static void +VID_CreateGDIDriver (int width, int height, byte *palette, void **buffer, + int *rowbytes) +{ + dibinfo_t dibheader; + BITMAPINFO *pbmiDIB = (BITMAPINFO *) & dibheader; + int i; + + hdcGDI = GetDC (hWndWinQuake); + memset (&dibheader, 0, sizeof (dibheader)); + + // fill in the bitmap info + pbmiDIB->bmiHeader.biSize = sizeof (BITMAPINFOHEADER); + pbmiDIB->bmiHeader.biWidth = width; + pbmiDIB->bmiHeader.biHeight = height; + pbmiDIB->bmiHeader.biPlanes = 1; + pbmiDIB->bmiHeader.biCompression = BI_RGB; + pbmiDIB->bmiHeader.biSizeImage = 0; + pbmiDIB->bmiHeader.biXPelsPerMeter = 0; + pbmiDIB->bmiHeader.biYPelsPerMeter = 0; + pbmiDIB->bmiHeader.biClrUsed = 256; + pbmiDIB->bmiHeader.biClrImportant = 256; + pbmiDIB->bmiHeader.biBitCount = 8; + + // fill in the palette + for (i = 0; i < 256; i++) { + // d_8to24table isn't filled in yet so this is just for testing + dibheader.acolors[i].rgbRed = palette[i * 3]; + dibheader.acolors[i].rgbGreen = palette[i * 3 + 1]; + dibheader.acolors[i].rgbBlue = palette[i * 3 + 2]; + } + + // create the DIB section + hDIBSection = CreateDIBSection (hdcGDI, + pbmiDIB, + DIB_RGB_COLORS, + (void **) &pDIBBase, NULL, 0); + + // set video buffers + if (pbmiDIB->bmiHeader.biHeight > 0) { + // bottom up + buffer[0] = pDIBBase + (height - 1) * width; + rowbytes[0] = -width; + } else { + // top down + buffer[0] = pDIBBase; + rowbytes[0] = width; + } + + // clear the buffer + memset (pDIBBase, 0xff, width * height); + + if ((hdcDIBSection = CreateCompatibleDC (hdcGDI)) == NULL) + Sys_Error ("DIB_Init() - CreateCompatibleDC failed\n"); + + if ((previously_selected_GDI_obj = + SelectObject (hdcDIBSection, hDIBSection)) == NULL) + Sys_Error ("DIB_Init() - SelectObject failed\n"); + + // create a palette + VID_InitGamma (palette); + viddef.set_palette (palette); +} + + +static void +VID_UnloadAllDrivers (void) +{ + // shut down ddraw + if (vidbuf) { + free (vidbuf); + vidbuf = NULL; + } + + if (dd_Clipper) { + IDirectDrawClipper_Release (dd_Clipper); + dd_Clipper = NULL; + } + + if (dd_FrontBuffer) { + IDirectDrawSurface_Release (dd_FrontBuffer); + dd_FrontBuffer = NULL; + } + + if (dd_BackBuffer) { + IDirectDrawSurface_Release (dd_BackBuffer); + dd_BackBuffer = NULL; + } + + if (dd_Object) { + IDirectDraw_Release (dd_Object); + dd_Object = NULL; + } + + if (hInstDDraw) { + FreeLibrary (hInstDDraw); + hInstDDraw = NULL; + } + + QDirectDrawCreate = NULL; + + // shut down gdi + if (hdcDIBSection) { + SelectObject (hdcDIBSection, previously_selected_GDI_obj); + DeleteDC (hdcDIBSection); + hdcDIBSection = NULL; + } + + if (hDIBSection) { + DeleteObject (hDIBSection); + hDIBSection = NULL; + pDIBBase = NULL; + } + + if (hdcGDI) { + // if hdcGDI exists then hWndWinQuake must also be valid + ReleaseDC (hWndWinQuake, hdcGDI); + hdcGDI = NULL; + } + // not using ddraw now + vid_usingddraw = false; +} + + + +// compatibility +qboolean DDActive; + +// not used any more +void +VID_LockBuffer (void) +{ +} + +void +VID_UnlockBuffer (void) +{ +} + +//static int VID_ForceUnlockedAndReturnState (void) {return 0;} +void +VID_ForceLockState (int lk) +{ +} + + +#define MAX_MODE_LIST 36 +#define VID_ROW_SIZE 3 + +extern qboolean Minimized; + +HWND WINAPI InitializeWindow (HINSTANCE hInstance, int nCmdShow); + +int DIBWidth, DIBHeight; +RECT WindowRect; +DWORD WindowStyle, ExWindowStyle; + +int window_center_x, window_center_y, window_width, window_height; +RECT window_rect; + +DEVMODE win_gdevmode; +static qboolean startwindowed = 0, windowed_mode_set; +static int firstupdate = 1; +static qboolean vid_initialized = false, vid_palettized; +static int vid_fulldib_on_focus_mode; +static qboolean force_minimized, in_mode_set, force_mode_set; +static int windowed_mouse; +static qboolean palette_changed, vid_mode_set, hide_window; +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) + +cvar_t *vid_ddraw; + +// Note that 0 is MODE_WINDOWED +cvar_t *vid_mode; + +// Note that 0 is MODE_WINDOWED +cvar_t *_vid_default_mode; + +// Note that 3 is MODE_FULLSCREEN_DEFAULT +cvar_t *_vid_default_mode_win; +cvar_t *vid_wait; +cvar_t *vid_nopageflip; +cvar_t *_vid_wait_override; +cvar_t *vid_config_x; +cvar_t *vid_config_y; +cvar_t *vid_stretch_by_2; +cvar_t *_windowed_mouse; +cvar_t *vid_fullscreen_mode; +cvar_t *vid_windowed_mode; +cvar_t *block_switch; +cvar_t *vid_window_x; +cvar_t *vid_window_y; + + +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; + +byte vid_curpal[256 * 3]; + +unsigned short d_8to16table[256]; + +int mode; + +typedef struct { + modestate_t type; + int width; + int height; + int modenum; + int fullscreen; + 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); + +// video commands +int VID_NumModes (void); +vmode_t *VID_GetModePtr (int modenum); +void VID_TestMode_f (void); +void VID_ForceMode_f (void); +void VID_Minimize_f (void); +void VID_Fullscreen_f (void); +void VID_Windowed_f (void); +void VID_DescribeModes_f (void); +void VID_DescribeMode_f (void); +void VID_NumModes_f (void); +void VID_DescribeCurrentMode_f (void); +char *VID_GetExtModeDescription (int mode); +char *VID_GetModeDescription (int mode); +char *VID_GetModeDescription2 (int mode); +char *VID_GetModeDescriptionMemCheck (int mode); +void VID_CheckModedescFixup (int mode); + + +/* +================ +VID_RememberWindowPos +================ +*/ +static void __attribute__ ((used)) + VID_RememberWindowPos (void) +{ + RECT rect; + + if (GetWindowRect (hWndWinQuake, &rect)) { + if ((rect.left < GetSystemMetrics (SM_CXSCREEN)) && + (rect.top < GetSystemMetrics (SM_CYSCREEN)) && + (rect.right > 0) && (rect.bottom > 0)) { + Cvar_SetValue (vid_window_x, (float) rect.left); + Cvar_SetValue (vid_window_y, (float) rect.top); + } + } +} + + +/* +================ +VID_CheckWindowXY +================ +*/ +static void +VID_CheckWindowXY (void) +{ + if (((int) vid_window_x->value > (GetSystemMetrics (SM_CXSCREEN) - 160)) || + ((int) vid_window_y->value > (GetSystemMetrics (SM_CYSCREEN) - 120)) || + ((int) vid_window_x->value < 0) || ((int) vid_window_y->value < 0)) { + Cvar_SetValue (vid_window_x, 0.0); + Cvar_SetValue (vid_window_y, 0.0); + } +} + + +/* +================ +VID_UpdateWindowStatus +================ +*/ +void +VID_UpdateWindowStatus (int window_x, int window_y) +{ + window_rect.left = window_x; + window_rect.top = window_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 (); +} + + +/* +================ +ClearAllStates +================ +*/ +static void +ClearAllStates (void) +{ + int i; + + // send an up event for each key, to make sure the server clears them all + for (i = 0; i < 256; i++) { + Key_Event (i, 0, false); + } + + Key_ClearStates (); + IN_ClearStates (); +} + + +/* +================ +VID_CheckAdequateMem +================ +*/ +static qboolean +VID_CheckAdequateMem (int width, int height) +{ + // there will always be enough ;) + return true; +} + + +static void +VID_InitModes (HINSTANCE hInstance) +{ + WNDCLASS wc; + HDC hdc; + +//FIXME hIcon = LoadIcon (hInstance, MAKEINTRESOURCE (IDI_ICON2)); + + /* Register the frame class */ + wc.style = CS_OWNDC; wc.lpfnWndProc = (WNDPROC) MainWndProc; wc.cbClsExtra = 0; wc.cbWndExtra = 0; - wc.hInstance = global_hInstance; + wc.hInstance = hInstance; wc.hIcon = 0; wc.hCursor = LoadCursor (NULL, IDC_ARROW); wc.hbrBackground = NULL; wc.lpszMenuName = 0; - wc.lpszClassName = "QuakeForge"; + wc.lpszClassName = "WinQuake"; if (!RegisterClass (&wc)) - Sys_Error ("Couldn't register window class (%lx)", GetLastError ()); + Sys_Error ("Couldn't register window class"); - VID_GetWindowSize (640, 480); + modelist[0].type = MS_WINDOWED; + modelist[0].width = 320; + modelist[0].height = 240; + strcpy (modelist[0].modedesc, "320x240"); + modelist[0].modenum = MODE_WINDOWED; + modelist[0].fullscreen = 0; - if (!vid_fullscreen->int_val) { - hdc = GetDC (NULL); + modelist[1].type = MS_WINDOWED; + modelist[1].width = 640; + modelist[1].height = 480; + strcpy (modelist[1].modedesc, "640x480"); + modelist[1].modenum = MODE_WINDOWED + 1; + modelist[1].fullscreen = 0; - if (GetDeviceCaps (hdc, RASTERCAPS) & RC_PALETTE) { - Sys_Error ("Can't run in non-RGB mode"); - } + modelist[2].type = MS_WINDOWED; + modelist[2].width = 800; + modelist[2].height = 600; + strcpy (modelist[2].modedesc, "800x600"); + modelist[2].modenum = MODE_WINDOWED + 2; + modelist[2].fullscreen = 0; - ReleaseDC (NULL, hdc); + // automatically stretch the default mode up if > 640x480 desktop + // resolution + hdc = GetDC (NULL); + + if ((GetDeviceCaps (hdc, HORZRES) > 800) + && !COM_CheckParm ("-noautostretch")) { + vid_default = MODE_WINDOWED + 2; + } else if ((GetDeviceCaps (hdc, HORZRES) > 640) + && !COM_CheckParm ("-noautostretch")) { + vid_default = MODE_WINDOWED + 1; } else { - if (COM_CheckParm ("-bpp")) { - bpp = atoi (com_argv[COM_CheckParm ("-bpp") + 1]); - } else { - bpp = 16; - } - vid_mode = 0; - do { - stat = EnumDisplaySettings (NULL, vid_mode, &win_gdevmode); + vid_default = MODE_WINDOWED; + } - if ((win_gdevmode.dmBitsPerPel == bpp) - && (win_gdevmode.dmPelsWidth == viddef.width) - && (win_gdevmode.dmPelsHeight == viddef.height)) { - win_gdevmode.dmFields = (DM_BITSPERPEL | DM_PELSWIDTH - | DM_PELSHEIGHT); + // always start at the lowest mode then switch to the higher one if + // selected + vid_default = MODE_WINDOWED; - if (ChangeDisplaySettings (&win_gdevmode, - CDS_TEST | CDS_FULLSCREEN) - == DISP_CHANGE_SUCCESSFUL) { - break; + windowed_default = vid_default; + ReleaseDC (NULL, hdc); + nummodes = 3; // reserve space for windowed mode +} + + +/* +================= +VID_GetDisplayModes +================= +*/ +static void +VID_GetDisplayModes (void) +{ + DEVMODE devmode; + int i, modenum, existingmode, originalnummodes, lowestres; + BOOL stat; + + // enumerate > 8 bpp modes + originalnummodes = nummodes; + modenum = 0; + lowestres = 99999; + + do { + stat = EnumDisplaySettings (NULL, modenum, &devmode); + + if ((devmode.dmPelsWidth <= MAXWIDTH) + && (devmode.dmPelsHeight <= MAXHEIGHT) + && (devmode.dmPelsWidth >= 320) + && (devmode.dmPelsHeight >= 240) + && (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].fullscreen = 1; + sprintf (modelist[nummodes].modedesc, "%dx%d", + (int) devmode.dmPelsWidth, + (int) devmode.dmPelsHeight); + + // see is the mode already there + // (same dimensions but different refresh rate) + 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 it's not add it to the list + if (!existingmode) { + if (modelist[nummodes].width < lowestres) + lowestres = modelist[nummodes].width; + + nummodes++; } } + } - vid_mode++; - } while (stat); - if (!stat) - Sys_Error ("Couldn't get requested resolution (%i, %i, %i)", - viddef.width, viddef.height, bpp); + modenum++; + } while (stat); + + if (nummodes != originalnummodes) + vid_default = MODE_FULLSCREEN_DEFAULT; + else + Sys_Printf ("No fullscreen DIB modes found\n"); +} + + +static void +VID_DestroyWindow (void) +{ + if (modestate == MS_FULLDIB) + ChangeDisplaySettings (NULL, CDS_FULLSCREEN); + + VID_UnloadAllDrivers (); +} + + +static qboolean +VID_SetWindowedMode (int modenum) +{ + 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 = true; } + VID_CheckModedescFixup (modenum); + VID_DestroyWindow (); + + WindowRect.top = WindowRect.left = 0; + WindowRect.right = modelist[modenum].width; + WindowRect.bottom = modelist[modenum].height; + DIBWidth = modelist[modenum].width; + DIBHeight = modelist[modenum].height; + + WindowStyle = WS_OVERLAPPEDWINDOW | WS_CAPTION | WS_SYSMENU | WS_SIZEBOX | + WS_MINIMIZEBOX | WS_MAXIMIZEBOX | WS_CLIPSIBLINGS | + WS_CLIPCHILDREN | WS_THICKFRAME; + + // WindowStyle = WS_OVERLAPPEDWINDOW|WS_VISIBLE; + 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) { + hWndWinQuake = CreateWindowEx (ExWindowStyle, + "WinQuake", + "WinQuake", + WindowStyle, + 0, 0, + WindowRect.right - WindowRect.left, + WindowRect.bottom - WindowRect.top, + NULL, NULL, global_hInstance, NULL); + + if (!hWndWinQuake) + Sys_Error ("Couldn't create DIB window"); + + // compatibility + mainwindow = hWndWinQuake; + + // done + vid_mode_set = true; + } else { + SetWindowLong (hWndWinQuake, GWL_STYLE, WindowStyle | WS_VISIBLE); + SetWindowLong (hWndWinQuake, GWL_EXSTYLE, ExWindowStyle); + } + + if (!SetWindowPos (hWndWinQuake, + 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 (hWndWinQuake, NULL, (int) vid_window_x->value, + (int) vid_window_y->value, 0, 0, + SWP_NOSIZE | SWP_NOZORDER | SWP_SHOWWINDOW | SWP_DRAWFRAME); + + if (force_minimized) + ShowWindow (hWndWinQuake, SW_MINIMIZE); + else + ShowWindow (hWndWinQuake, SW_SHOWDEFAULT); + + UpdateWindow (hWndWinQuake); + modestate = MS_WINDOWED; + vid_fulldib_on_focus_mode = 0; + + viddef.numpages = 1; + viddef.maxwarpwidth = WARP_WIDTH; viddef.maxwarpheight = WARP_HEIGHT; - viddef.colormap8 = colormap; - viddef.fullbright = 256 - viddef.colormap8[256 * VID_GRADES]; -#ifdef SPLASH_SCREEN - if(hwnd_dialog) - DestroyWindow (hwnd_dialog); + // viddef.maxlowwidth = LOW_WIDTH; + // viddef.maxlowheight = LOW_HEIGHT; + +// viddef.height = viddef.conheight = DIBHeight; +// viddef.width = viddef.conwidth = DIBWidth; + + viddef.height = viddef.conheight = DIBHeight; + viddef.width = viddef.conwidth = DIBWidth; +//FIXME? if (!yeahimconsoled){ +//FIXME? viddef.vconheight = DIBHeight; +//FIXME? viddef.vconwidth = DIBWidth; +//FIXME? } + SendMessage (hWndWinQuake, WM_SETICON, (WPARAM) TRUE, (LPARAM) hIcon); + SendMessage (hWndWinQuake, WM_SETICON, (WPARAM) FALSE, (LPARAM) hIcon); + + return true; +} + + +static qboolean +VID_SetFullDIBMode (int modenum) +{ + VID_DestroyWindow (); + + win_gdevmode.dmFields = DM_PELSWIDTH | DM_PELSHEIGHT; + win_gdevmode.dmPelsWidth = modelist[modenum].width; + win_gdevmode.dmPelsHeight = modelist[modenum].height; + win_gdevmode.dmSize = sizeof (win_gdevmode); + + if (ChangeDisplaySettings (&win_gdevmode, CDS_FULLSCREEN) != + DISP_CHANGE_SUCCESSFUL) + Sys_Error ("Couldn't set fullscreen DIB mode"); + + modestate = MS_FULLDIB; + vid_fulldib_on_focus_mode = modenum; + WindowRect.top = WindowRect.left = 0; + + WindowRect.right = modelist[modenum].width; + WindowRect.bottom = modelist[modenum].height; + + 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 (hWndWinQuake, GWL_STYLE, WindowStyle | WS_VISIBLE); + SetWindowLong (hWndWinQuake, GWL_EXSTYLE, ExWindowStyle); + + if (!SetWindowPos (hWndWinQuake, + 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 (hWndWinQuake, HWND_TOPMOST, 0, 0, 0, 0, + SWP_NOSIZE | SWP_SHOWWINDOW | SWP_DRAWFRAME); + ShowWindow (hWndWinQuake, SW_SHOWDEFAULT); + UpdateWindow (hWndWinQuake); + + viddef.numpages = 1; + viddef.maxwarpwidth = WARP_WIDTH; + viddef.maxwarpheight = WARP_HEIGHT; + + // viddef.maxlowwidth = LOW_WIDTH; + // viddef.maxlowheight = LOW_HEIGHT; + +#ifdef SCALED2D + viddef.height = viddef.conheight = DIBHeight; + viddef.width = viddef.conwidth = DIBWidth; + // viddef.vconwidth = 320; + // viddef.vconheight = 200; +//FIXME? if (!yeahimconsoled){ +//FIXME? viddef.vconheight = DIBHeight; +//FIXME? viddef.vconwidth = DIBWidth; +//FIXME? } +#else + viddef.height = viddef.conheight = DIBHeight; + viddef.width = viddef.conwidth = DIBWidth; #endif - VID_SetMode (palette); + return true; +} - maindc = GetDC (mainwindow); - bSetupPixelFormat (maindc); +static int VID_SetMode (int modenum, byte *palette); - baseRC = qfwglCreateContext (maindc); - if (!baseRC) { - lasterror=GetLastError(); - if (maindc && mainwindow) - ReleaseDC (mainwindow, maindc); - Sys_Error ("Could not initialize GL (wglCreateContext failed).\n\n" - "Make sure you are in 65535 color mode, and try running " - "with -window.\n" - "Error code: (%lx)", lasterror); +static 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"); } - if (!qfwglMakeCurrent (maindc, baseRC)) { - lasterror = GetLastError (); - if (baseRC) - qfwglDeleteContext (baseRC); - if (maindc && mainwindow) - ReleaseDC (mainwindow, maindc); - Sys_Error ("wglMakeCurrent failed (%lx)", lasterror); + inerror = false; +} + + +static void __attribute__ ((used)) + VID_SetDefaultMode (void) +{ + if (vid_initialized) + VID_SetMode (0, vid_curpal); + + IN_DeactivateMouse (); +} + + +static int +VID_SetMode (int modenum, byte *palette) +{ + int original_mode; // FIXME, 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, (float) modenum); + } else { + Cvar_SetValue (vid_mode, (float) vid_modenum); + return 0; + } } - GL_Init (); + if (!force_mode_set && (modenum == vid_modenum)) + return true; - VID_InitGamma (palette); - viddef.set_palette (viddef.palette); + // so Con_Printfs don't mess us up by forcing vid and snd updates +//FIXME? temp = scr_disabled_for_loading; +//FIXME? scr_disabled_for_loading = true; + in_mode_set = true; +//FIXME CDAudio_Pause (); +//FIXME S_ClearBuffer (); - viddef.initialized = true; + if (vid_modenum == NO_MODE) + original_mode = windowed_default; + else + original_mode = vid_modenum; - win_canalttab = true; + // Set either the fullscreen or windowed mode + if (modelist[modenum].type == MS_WINDOWED) { + if (_windowed_mouse->value) { + stat = VID_SetWindowedMode (modenum); + IN_ActivateMouse (); + IN_HideMouse (); + } else { + IN_DeactivateMouse (); + IN_ShowMouse (); + stat = VID_SetWindowedMode (modenum); + } + } else { + stat = VID_SetFullDIBMode (modenum); + IN_ActivateMouse (); + IN_HideMouse (); + } - if (COM_CheckParm ("-nofullsbar")) - fullsbardraw = false; + // shutdown any old driver that was active + VID_UnloadAllDrivers (); + + // 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. This also prevents a screen flash to while when + // switching drivers. it still flashes, but at least it's black now + hdc = GetDC (hWndWinQuake); + PatBlt (hdc, 0, 0, WindowRect.right, WindowRect.bottom, BLACKNESS); + ReleaseDC (hWndWinQuake, hdc); + + // create the new driver + vid_usingddraw = false; + + // attempt to create a direct draw driver + if (vid_ddraw->value) + VID_CreateDDrawDriver (DIBWidth, DIBHeight, palette, &viddef.buffer, + &viddef.rowbytes); + + // create a gdi driver if directdraw failed or if we preferred not to use + // it + if (!vid_usingddraw) { + // because directdraw may have been partially created we must shut it + // down again first + VID_UnloadAllDrivers (); + + // now create the gdi driver + VID_CreateGDIDriver (DIBWidth, DIBHeight, palette, &viddef.buffer, + &viddef.rowbytes); + } + // if ddraw failed to come up we disable the cvar too + if (vid_ddraw->value && !vid_usingddraw) + Cvar_Set (vid_ddraw, "0"); + + // set the rest of the buffers we need (why not just use one single buffer + // instead of all this crap? oh well, it's Quake...) + viddef.direct = (byte *) viddef.buffer; + viddef.conbuffer = viddef.buffer; + + // more crap for the console + viddef.conrowbytes = viddef.rowbytes; + + window_width = viddef.width; + window_height = viddef.height; + + + VID_UpdateWindowStatus (0, 0); // FIXME right numbers? +//FIXME CDAudio_Resume (); +//FIXME? scr_disabled_for_loading = temp; + + 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 (hWndWinQuake); + + hdc = GetDC (NULL); + + if (GetDeviceCaps (hdc, RASTERCAPS) & RC_PALETTE) + vid_palettized = true; + else + vid_palettized = false; + + viddef.set_palette (palette); + ReleaseDC (NULL, hdc); + vid_modenum = modenum; + Cvar_SetValue (vid_mode, (float) vid_modenum); + + VID_InitBuffers (); + + while (PeekMessage (&msg, NULL, 0, 0, PM_REMOVE)) { + TranslateMessage (&msg); + DispatchMessage (&msg); + } + + Sleep (100); + + if (!force_minimized) { + SetWindowPos (hWndWinQuake, HWND_TOP, 0, 0, 0, 0, + SWP_DRAWFRAME | SWP_NOMOVE | SWP_NOSIZE | SWP_SHOWWINDOW | + SWP_NOCOPYBITS); + + SetForegroundWindow (hWndWinQuake); + } + // fix the leftover Alt from any Alt-Tab or the like that switched us away + ClearAllStates (); + + Sys_Printf ("%s\n", VID_GetModeDescription (vid_modenum)); + + viddef.set_palette (palette); + + in_mode_set = false; + + viddef.recalc_refdef = 1; + +//FIXME SCR_StretchInit(); +//FIXME SCR_StretchRefresh(); +//FIXME SCR_CvarCheck(); + return true; +} + + +static void +VID_SetPalette (const byte *palette) +{ + int i; + const byte *pal = palette; + + if (!Minimized) { + if (vid_usingddraw) { + // incoming palette is 3 component + for (i = 0; i < 256; i++, pal += 3) { + PALETTEENTRY *p = (PALETTEENTRY *) & ddpal[i]; + + p->peRed = gammatable[pal[2]]; + p->peGreen = gammatable[pal[1]]; + p->peBlue = gammatable[pal[0]]; + p->peFlags = 255; + } + } else { + RGBQUAD colors[256]; + + if (hdcDIBSection) { + // incoming palette is 3 component + for (i = 0; i < 256; i++, pal += 3) { + PALETTEENTRY *p = (PALETTEENTRY *) & ddpal[i]; + + colors[i].rgbRed = gammatable[pal[0]]; + colors[i].rgbGreen = gammatable[pal[1]]; + colors[i].rgbBlue = gammatable[pal[2]]; + colors[i].rgbReserved = 0; + + p->peRed = gammatable[pal[2]]; + p->peGreen = gammatable[pal[1]]; + p->peBlue = gammatable[pal[0]]; + p->peFlags = 255; + } + + colors[0].rgbRed = 0; + colors[0].rgbGreen = 0; + colors[0].rgbBlue = 0; + colors[255].rgbRed = 0xff; + colors[255].rgbGreen = 0xff; + colors[255].rgbBlue = 0xff; + + if (SetDIBColorTable (hdcDIBSection, 0, 256, colors) == 0) { + Sys_Printf ("DIB_SetPalette() - SetDIBColorTable failed\n"); + } + } + } + } + + memcpy (vid_curpal, palette, sizeof (vid_curpal)); +} + + +#define CVAR_ORIGINAL CVAR_NONE // FIXME +void +VID_Init_Cvars (void) +{ + vid_ddraw = Cvar_Get ("vid_ddraw", "1", CVAR_ORIGINAL, 0, ""); + vid_mode = Cvar_Get ("vid_mode", "0", CVAR_ORIGINAL, 0, ""); + vid_wait = Cvar_Get ("vid_wait", "0", CVAR_ORIGINAL, 0, ""); + vid_nopageflip = + Cvar_Get ("vid_nopageflip", "0", CVAR_ARCHIVE | CVAR_ORIGINAL, 0, ""); + _vid_wait_override = + Cvar_Get ("_vid_wait_override", "0", CVAR_ARCHIVE | CVAR_ORIGINAL, 0, + ""); + _vid_default_mode = + Cvar_Get ("_vid_default_mode", "0", CVAR_ARCHIVE | CVAR_ORIGINAL, 0, + ""); + _vid_default_mode_win = + Cvar_Get ("_vid_default_mode_win", "3", CVAR_ARCHIVE | CVAR_ORIGINAL, 0, + ""); + vid_config_x = + Cvar_Get ("vid_config_x", "800", CVAR_ARCHIVE | CVAR_ORIGINAL, 0, ""); + vid_config_y = + Cvar_Get ("vid_config_y", "600", CVAR_ARCHIVE | CVAR_ORIGINAL, 0, ""); + vid_stretch_by_2 = + Cvar_Get ("vid_stretch_by_2", "1", CVAR_ARCHIVE | CVAR_ORIGINAL, 0, ""); + _windowed_mouse = + Cvar_Get ("_windowed_mouse", "0", CVAR_ARCHIVE | CVAR_ORIGINAL, 0, ""); + vid_fullscreen_mode = + Cvar_Get ("vid_fullscreen_mode", "3", CVAR_ARCHIVE | CVAR_ORIGINAL, 0, + ""); + vid_windowed_mode = + Cvar_Get ("vid_windowed_mode", "0", CVAR_ARCHIVE | CVAR_ORIGINAL, 0, + ""); + block_switch = + Cvar_Get ("block_switch", "0", CVAR_ARCHIVE | CVAR_ORIGINAL, 0, ""); + vid_window_x = + Cvar_Get ("vid_window_x", "0", CVAR_ARCHIVE | CVAR_ORIGINAL, 0, ""); + vid_window_y = + Cvar_Get ("vid_window_y", "0", CVAR_ARCHIVE | CVAR_ORIGINAL, 0, ""); +} + +static void +win_choose_visual (void) +{ +} + +static void +win_create_context (void) +{ } void -VID_Init_Cvars () +VID_Init (byte *palette, byte *colormap) { + choose_visual = win_choose_visual; + create_context = win_create_context; + + R_LoadModule (wgl_load_gl, VID_SetPalette); + + viddef.numpages = 1; + viddef.colormap8 = colormap; + viddef.fullbright = 256 - viddef.colormap8[256 * VID_GRADES]; + + VID_GetWindowSize (640, 480); + + VID_InitModes (global_hInstance); + VID_GetDisplayModes (); + choose_visual (); + + create_context (); + VID_InitGamma (palette); + + viddef.maxwarpwidth = WARP_WIDTH; + viddef.maxwarpheight = WARP_HEIGHT; + + // viddef.maxlowwidth = LOW_WIDTH; + // viddef.maxlowheight = LOW_HEIGHT; + vid_testingmode = 0; + + // if (COM_CheckParm("-startwindowed")) + { + startwindowed = 1; + vid_default = windowed_default; + } + +//FIXME? if (hwnd_dialog) +//FIXME? DestroyWindow (hwnd_dialog); + + // 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; +//FIXME if (firsttime) S_Init (); + vid_initialized = true; + +//FIXME SCR_StretchInit(); + + force_mode_set = true; + VID_SetMode (vid_default, palette); + force_mode_set = false; + vid_realmode = vid_modenum; + viddef.set_palette (palette); + strcpy (badmode.modedesc, "Bad mode"); +} + +#if 0 +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, ""); +Cmd_AddCommand ("vid_forcemode", VID_ForceMode_f, ""); +Cmd_AddCommand ("vid_windowed", VID_Windowed_f, ""); +Cmd_AddCommand ("vid_fullscreen", VID_Fullscreen_f, ""); +Cmd_AddCommand ("vid_minimize", VID_Minimize_f, ""); +#endif + + +void +VID_Shutdown (void) +{ + if (vid_initialized) { + if (modestate == MS_FULLDIB) + ChangeDisplaySettings (NULL, CDS_FULLSCREEN); + + PostMessage (HWND_BROADCAST, WM_PALETTECHANGED, (WPARAM) hWndWinQuake, + (LPARAM) 0); + PostMessage (HWND_BROADCAST, WM_SYSCOLORCHANGE, (WPARAM) 0, (LPARAM) 0); + AppActivate (false, false); + + VID_DestroyWindow (); + +//FIXME? if (hwnd_dialog) DestroyWindow (hwnd_dialog); + if (hWndWinQuake) + DestroyWindow (hWndWinQuake); + + vid_testingmode = 0; + vid_initialized = 0; + } +} + + +/* +================ +FlipScreen +================ +*/ +static void +FlipScreen (vrect_t *rects) +{ + int numrects = 0; + + while (rects) { + if (vid_usingddraw) { + int x, y; + HRESULT hr = S_OK; + byte *src = NULL; + unsigned *dst = NULL; + + if (dd_BackBuffer) { + RECT TheRect; + RECT sRect, dRect; + DDSURFACEDESC ddsd; + + memset (&ddsd, 0, sizeof (ddsd)); + ddsd.dwSize = sizeof (DDSURFACEDESC); + + // lock the correct subrect + TheRect.left = rects->x; + TheRect.right = rects->x + rects->width; + TheRect.top = rects->y; + TheRect.bottom = rects->y + rects->height; + + if ((hr = + IDirectDrawSurface_Lock (dd_BackBuffer, &TheRect, &ddsd, + DDLOCK_WRITEONLY | + DDLOCK_SURFACEMEMORYPTR, + NULL)) == DDERR_WASSTILLDRAWING) + return; + + src = (byte *) vidbuf + rects->y * viddef.rowbytes + rects->x; + dst = (unsigned *) ddsd.lpSurface; + + // convert pitch to unsigned int addressable + ddsd.lPitch >>= 2; + + // because we created a 32 bit backbuffer we need to copy from + // the 8 bit memory buffer to it before flipping + if (!(rects->width & 15)) { + for (y = 0; y < rects->height; + y++, src += viddef.rowbytes, dst += ddsd.lPitch) { + byte *psrc = src; + unsigned *pdst = dst; + + for (x = 0; x < rects->width; + x += 16, psrc += 16, pdst += 16) { + pdst[0] = ddpal[psrc[0]]; + pdst[1] = ddpal[psrc[1]]; + pdst[2] = ddpal[psrc[2]]; + pdst[3] = ddpal[psrc[3]]; + + pdst[4] = ddpal[psrc[4]]; + pdst[5] = ddpal[psrc[5]]; + pdst[6] = ddpal[psrc[6]]; + pdst[7] = ddpal[psrc[7]]; + + pdst[8] = ddpal[psrc[8]]; + pdst[9] = ddpal[psrc[9]]; + pdst[10] = ddpal[psrc[10]]; + pdst[11] = ddpal[psrc[11]]; + + pdst[12] = ddpal[psrc[12]]; + pdst[13] = ddpal[psrc[13]]; + pdst[14] = ddpal[psrc[14]]; + pdst[15] = ddpal[psrc[15]]; + } + } + } else if (!(rects->width % 10)) { + for (y = 0; y < rects->height; + y++, src += viddef.rowbytes, dst += ddsd.lPitch) { + byte *psrc = src; + unsigned *pdst = dst; + + for (x = 0; x < rects->width; + x += 10, psrc += 10, pdst += 10) { + pdst[0] = ddpal[psrc[0]]; + pdst[1] = ddpal[psrc[1]]; + pdst[2] = ddpal[psrc[2]]; + pdst[3] = ddpal[psrc[3]]; + pdst[4] = ddpal[psrc[4]]; + + pdst[5] = ddpal[psrc[5]]; + pdst[6] = ddpal[psrc[6]]; + pdst[7] = ddpal[psrc[7]]; + pdst[8] = ddpal[psrc[8]]; + pdst[9] = ddpal[psrc[9]]; + } + } + } else if (!(rects->width & 7)) { + for (y = 0; y < rects->height; + y++, src += viddef.rowbytes, dst += ddsd.lPitch) { + byte *psrc = src; + unsigned *pdst = dst; + + for (x = 0; x < rects->width; + x += 8, psrc += 8, pdst += 8) { + pdst[0] = ddpal[psrc[0]]; + pdst[1] = ddpal[psrc[1]]; + pdst[2] = ddpal[psrc[2]]; + pdst[3] = ddpal[psrc[3]]; + + pdst[4] = ddpal[psrc[4]]; + pdst[5] = ddpal[psrc[5]]; + pdst[6] = ddpal[psrc[6]]; + pdst[7] = ddpal[psrc[7]]; + } + } + } else if (!(rects->width % 5)) { + for (y = 0; y < rects->height; + y++, src += viddef.rowbytes, dst += ddsd.lPitch) { + byte *psrc = src; + unsigned *pdst = dst; + + for (x = 0; x < rects->width; + x += 5, psrc += 5, pdst += 5) { + pdst[0] = ddpal[psrc[0]]; + pdst[1] = ddpal[psrc[1]]; + pdst[2] = ddpal[psrc[2]]; + pdst[3] = ddpal[psrc[3]]; + pdst[4] = ddpal[psrc[4]]; + } + } + } else if (!(rects->width & 3)) { + for (y = 0; y < rects->height; + y++, src += viddef.rowbytes, dst += ddsd.lPitch) { + byte *psrc = src; + unsigned *pdst = dst; + + for (x = 0; x < rects->width; + x += 4, psrc += 4, pdst += 4) { + pdst[0] = ddpal[psrc[0]]; + pdst[1] = ddpal[psrc[1]]; + pdst[2] = ddpal[psrc[2]]; + pdst[3] = ddpal[psrc[3]]; + } + } + } else { + for (y = 0; y < rects->height; + y++, src += viddef.rowbytes, dst += ddsd.lPitch) { + for (x = 0; x < rects->width; x++) { + dst[x] = ddpal[src[x]]; + } + } + } + + IDirectDrawSurface_Unlock (dd_BackBuffer, NULL); + + // correctly offset source + sRect.left = SrcRect.left + rects->x; + sRect.right = SrcRect.left + rects->x + rects->width; + sRect.top = SrcRect.top + rects->y; + sRect.bottom = SrcRect.top + rects->y + rects->height; + + // correctly offset dest + dRect.left = DstRect.left + rects->x; + dRect.right = DstRect.left + rects->x + rects->width; + dRect.top = DstRect.top + rects->y; + dRect.bottom = DstRect.top + rects->y + rects->height; + + // copy to front buffer + IDirectDrawSurface_Blt (dd_FrontBuffer, &dRect, dd_BackBuffer, + &sRect, 0, NULL); + } + } else if (hdcDIBSection) { + BitBlt (hdcGDI, rects->x, rects->y, + rects->x + rects->width, rects->y + rects->height, + hdcDIBSection, rects->x, rects->y, SRCCOPY); + } + + numrects++; + rects = rects->next; + } +} + + +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 (viddef.aspect > 1.5) { + reps = 2; + repshift = 1; + } else { + reps = 1; + repshift = 0; + } + + if (!viddef.direct) + return; + + for (i = 0; i < (height << repshift); i += reps) { + for (j = 0; j < reps; j++) { + memcpy (&backingbuf[(i + j) * 24], + viddef.direct + x + ((y << repshift) + i + + j) * viddef.rowbytes, width); + + memcpy (viddef.direct + x + + ((y << repshift) + i + j) * viddef.rowbytes, + &pbitmap[(i >> repshift) * width], width); + } + } + + rect.x = x; + rect.y = y; + rect.width = width; + rect.height = height << repshift; + rect.next = NULL; + + FlipScreen (&rect); +} + + +void +D_EndDirectRect (int x, int y, int width, int height) +{ + int i, j, reps, repshift; + vrect_t rect; + + if (!vid_initialized) + return; + + if (viddef.aspect > 1.5) { + reps = 2; + repshift = 1; + } else { + reps = 1; + repshift = 0; + } + + if (!viddef.direct) + return; + + for (i = 0; i < (height << repshift); i += reps) { + for (j = 0; j < reps; j++) { + memcpy (viddef.direct + x + + ((y << repshift) + i + j) * viddef.rowbytes, + &backingbuf[(i + j) * 24], width); + } + } + + rect.x = x; + rect.y = y; + rect.width = width; + rect.height = height << repshift; + rect.next = NULL; + + FlipScreen (&rect); +} + + +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 = viddef.width; + rect.height = viddef.height; + rect.next = NULL; + rects = ▭ + } + + if (firstupdate) { + if (modestate == MS_WINDOWED) { + GetWindowRect (hWndWinQuake, &trect); + + if ((trect.left != (int) vid_window_x->value) || + (trect.top != (int) vid_window_y->value)) { + if (COM_CheckParm ("-resetwinpos")) { + Cvar_SetValue (vid_window_x, 0.0); + Cvar_SetValue (vid_window_y, 0.0); + } + + VID_CheckWindowXY (); + SetWindowPos (hWndWinQuake, NULL, (int) vid_window_x->value, + (int) vid_window_y->value, 0, 0, + SWP_NOSIZE | SWP_NOZORDER | SWP_SHOWWINDOW | + SWP_DRAWFRAME); + } + } + + if ((_vid_default_mode_win->value != vid_default) && + (!startwindowed + || (_vid_default_mode_win->value < 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->value < 0) || + (_vid_default_mode_win->value >= nummodes)) { + Cvar_SetValue (_vid_default_mode_win, windowed_default); + } + + Cvar_SetValue (vid_mode, _vid_default_mode_win->value); + } + } + // We've drawn the frame; copy it to the screen + FlipScreen (rects); + + // check for a driver change + if ((vid_ddraw->value && !vid_usingddraw) + || (!vid_ddraw->value && vid_usingddraw)) { + // reset the mode + force_mode_set = true; + VID_SetMode ((int) vid_mode->value, vid_curpal); + force_mode_set = false; + + // store back + if (vid_usingddraw) + Sys_Printf ("loaded DirectDraw driver\n"); + else + Sys_Printf ("loaded GDI driver\n"); + } + + if (vid_testingmode) { + if (Sys_DoubleTime () >= vid_testendtime) { + VID_SetMode (vid_realmode, vid_curpal); + vid_testingmode = 0; + } + } else { + if ((int) vid_mode->value != vid_realmode) { + VID_SetMode ((int) vid_mode->value, vid_curpal); + 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; + } + } + + // handle the mouse state when windowed if that's changed + if (modestate == MS_WINDOWED) { + if ((int) _windowed_mouse->value != windowed_mouse) { + if (_windowed_mouse->value) { + IN_ActivateMouse (); + IN_HideMouse (); + } else { + IN_DeactivateMouse (); + IN_ShowMouse (); + } + + windowed_mouse = (int) _windowed_mouse->value; + } + } +} + + +//========================================================================== + + +/* +================ +VID_HandlePause +================ +*/ +static void __attribute__ ((used)) + VID_HandlePause (qboolean pause) +{ + if ((modestate == MS_WINDOWED) && _windowed_mouse->value) { + if (pause) { + IN_DeactivateMouse (); + IN_ShowMouse (); + } else { + IN_ActivateMouse (); + IN_HideMouse (); + } + } +} + + +/* +=================================================================== + +MAIN WINDOW + +=================================================================== +*/ + +typedef struct { + int modenum; + char *desc; + int iscur; + 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]; + +/* +================= +VID_NumModes +================= +*/ +int +VID_NumModes (void) +{ + return nummodes; +} + + +/* +================= +VID_GetModePtr +================= +*/ +vmode_t * +VID_GetModePtr (int modenum) +{ + if ((modenum >= 0) && (modenum < nummodes)) + return &modelist[modenum]; + else + return &badmode; +} + + +/* +================= +VID_CheckModedescFixup +================= +*/ +void +VID_CheckModedescFixup (int mode) +{ +} + + +/* +================= +VID_GetModeDescriptionMemCheck +================= +*/ +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; + } +} + + +/* +================= +VID_GetModeDescription +================= +*/ +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) { + sprintf (pinfo, "%s fullscreen", pv->modedesc); + } else if (modelist[mode].type == MS_FULLDIB) { + sprintf (pinfo, "%s fullscreen", pv->modedesc); + } else { + sprintf (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_FULLDIB) { + sprintf (pinfo, "%s fullscreen", pv->modedesc); + } else { + sprintf (pinfo, "%s windowed", pv->modedesc); + } + + return pinfo; +} + + +/* +================= +VID_DescribeCurrentMode_f +================= +*/ +void +VID_DescribeCurrentMode_f (void) +{ + Sys_Printf ("%s\n", VID_GetExtModeDescription (vid_modenum)); +} + + +/* +================= +VID_NumModes_f +================= +*/ +void +VID_NumModes_f (void) +{ + if (nummodes == 1) + Sys_Printf ("%d video mode is available\n", nummodes); + else + Sys_Printf ("%d video modes are available\n", nummodes); +} + + +/* +================= +VID_DescribeMode_f +================= +*/ +void +VID_DescribeMode_f (void) +{ + int modenum; + + modenum = atoi (Cmd_Argv (1)); + Sys_Printf ("%s\n", VID_GetExtModeDescription (modenum)); +} + + +/* +================= +VID_DescribeModes_f +================= +*/ +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)) { + Sys_Printf ("%2d: %s\n", i, pinfo); + } else { + Sys_Printf ("**: %s\n", pinfo); + na = true; + } + } + + if (na) { + Sys_Printf ("\n[**: not enough system RAM for mode]\n"); + } +} + + +/* +================= +VID_TestMode_f +================= +*/ +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 = Sys_DoubleTime () + testduration; + } + } +} + + +/* +================= +VID_Windowed_f +================= +*/ +void +VID_Windowed_f (void) +{ + VID_SetMode ((int) vid_windowed_mode->value, vid_curpal); +} + + +/* +================= +VID_Fullscreen_f +================= +*/ +void +VID_Fullscreen_f (void) +{ + VID_SetMode ((int) vid_fullscreen_mode->value, vid_curpal); +} + + +/* +================= +VID_Minimize_f +================= +*/ +void +VID_Minimize_f (void) +{ + // we only support minimizing windows; if you're fullscreen, + // switch to windowed first + if (modestate == MS_WINDOWED) + ShowWindow (hWndWinQuake, SW_MINIMIZE); +} + + + +/* +================= +VID_ForceMode_f +================= +*/ +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_SetCaption (const char *text) { if (text && *text) { - char *temp = strdup (text); + char *temp = strdup (text); - SetWindowText (mainwindow, - (LPSTR) va ("%s: %s", PACKAGE_STRING, temp)); + SetWindowText (mainwindow, (LPSTR) va ("%s: %s", PACKAGE_STRING, temp)); free (temp); } else { SetWindowText (mainwindow, (LPSTR) va ("%s", PACKAGE_STRING)); @@ -604,8 +2100,8 @@ static WORD currentgammaramps[3][256]; qboolean VID_SetGamma (double gamma) { - int i; - HDC hdc = GetDC (NULL); + int i; + HDC hdc = GetDC (NULL); for (i = 0; i < 256; i++) { currentgammaramps[2][i] = currentgammaramps[1][i] = @@ -617,27 +2113,11 @@ VID_SetGamma (double gamma) return i; } -void -VID_LockBuffer (void) -{ -} - -void -VID_UnlockBuffer (void) -{ -} - -void -VID_Update (vrect_t *rects) -{ - //FIXME sw -} - #if 0 static void VID_SaveGamma (void) { - HDC hdc = GetDC (NULL); + HDC hdc = GetDC (NULL); GetDeviceGammaRamp (hdc, &systemgammaramps[0][0]); ReleaseDC (NULL, hdc); @@ -646,7 +2126,7 @@ VID_SaveGamma (void) static void VID_RestoreGamma (void) { - HDC hdc = GetDC (NULL); + HDC hdc = GetDC (NULL); SetDeviceGammaRamp (hdc, &systemgammaramps[0][0]); ReleaseDC (NULL, hdc);