yquake2remaster/src/backends/generic/vid.c
Yamagi Burmeister aff37eda16 Make sure that no key is being marked down
It's apparently not enough to clear key repeats, we'll need to clear
the down states too. Without this Alt stays pressed after toggeling
fullscreen trhough Alt-Enter.
2015-03-30 21:22:55 +02:00

235 lines
6.1 KiB
C

/*
* Copyright (C) 1997-2001 Id Software, Inc.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or (at
* your option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
*
* See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
* 02111-1307, USA.
*
* =======================================================================
*
* This is the "heart" of the id Tech 2 refresh engine. This file
* implements the main window in which Quake II is running. The window
* itself is created by the SDL backend, but here the refresh module is
* loaded, initialized and it's interaction with the operating system
* implemented. This code is also the interconnect between the input
* system (the mouse) and the keyboard system, both are here tied
* together with the refresher. The direct interaction between the
* refresher and those subsystems are the main cause for the very
* acurate and precise input controls of the id Tech 2.
*
* This implementation works for Windows and unixoid systems, but
* other platforms may need an own implementation!
*
* =======================================================================
*/
#include <assert.h>
#include <errno.h>
#include "../../client/header/client.h"
#include "../../client/header/keyboard.h"
typedef struct vidmode_s
{
const char *description;
int width, height;
int mode;
} vidmode_t;
/* This must be the same as in videomenu.c! */
vidmode_t vid_modes[] = {
{"Mode 0: 320x240", 320, 240, 0},
{"Mode 1: 400x300", 400, 300, 1},
{"Mode 2: 512x384", 512, 384, 2},
{"Mode 3: 640x400", 640, 400, 3},
{"Mode 4: 640x480", 640, 480, 4},
{"Mode 5: 800x500", 800, 500, 5},
{"Mode 6: 800x600", 800, 600, 6},
{"Mode 7: 960x720", 960, 720, 7},
{"Mode 8: 1024x480", 1024, 480, 8},
{"Mode 9: 1024x640", 1024, 640, 9},
{"Mode 10: 1024x768", 1024, 768, 10},
{"Mode 11: 1152x768", 1152, 768, 11},
{"Mode 12: 1152x864", 1152, 864, 12},
{"Mode 13: 1280x800", 1280, 800, 13},
{"Mode 14: 1280x854", 1280, 854, 14},
{"Mode 15: 1280x960", 1280, 960, 15},
{"Mode 16: 1280x1024", 1280, 1024, 16},
{"Mode 17: 1366x768", 1366, 768, 17},
{"Mode 18: 1440x900", 1440, 900, 18},
{"Mode 19: 1600x1200", 1600, 1200, 19},
{"Mode 20: 1680x1050", 1680, 1050, 20},
{"Mode 21: 1920x1080", 1920, 1080, 21},
{"Mode 22: 1920x1200", 1920, 1200, 22},
{"Mode 23: 2048x1536", 2048, 1536, 23},
};
/* Console variables that we need to access from this module */
cvar_t *vid_gamma;
cvar_t *vid_xpos; /* X coordinate of window position */
cvar_t *vid_ypos; /* Y coordinate of window position */
cvar_t *vid_fullscreen;
/* Global variables used internally by this module */
viddef_t viddef; /* global video state; used by other modules */
qboolean ref_active = false; /* Is the refresher being used? */
#define VID_NUM_MODES (sizeof(vid_modes) / sizeof(vid_modes[0]))
#define MAXPRINTMSG 4096
void
VID_Printf(int print_level, char *fmt, ...)
{
va_list argptr;
char msg[MAXPRINTMSG];
va_start(argptr, fmt);
vsnprintf(msg, MAXPRINTMSG, fmt, argptr);
va_end(argptr);
if (print_level == PRINT_ALL)
{
Com_Printf("%s", msg);
}
else
{
Com_DPrintf("%s", msg);
}
}
void
VID_Error(int err_level, char *fmt, ...)
{
va_list argptr;
char msg[MAXPRINTMSG];
va_start(argptr, fmt);
vsnprintf(msg, MAXPRINTMSG, fmt, argptr);
va_end(argptr);
Com_Error(err_level, "%s", msg);
}
/*
* Console command to re-start the video mode and refresh. We do this
* simply by setting the modified flag for the vid_fullscreen variable, which will
* cause the entire video mode and refreshto be reset on the next frame.
*/
void
VID_Restart_f(void)
{
vid_fullscreen->modified = true;
}
qboolean
VID_GetModeInfo(int *width, int *height, int mode)
{
if ((mode < 0) || (mode >= VID_NUM_MODES))
{
return false;
}
*width = vid_modes[mode].width;
*height = vid_modes[mode].height;
return true;
}
void
VID_NewWindow(int width, int height)
{
viddef.width = width;
viddef.height = height;
}
qboolean
VID_LoadRefresh(void)
{
// If the refresher is already active
// we'll shut it down
VID_Shutdown();
// Log it!
Com_Printf("----- refresher initialization -----\n");
// Declare the refresher as active
ref_active = true;
// Initiate the refresher
if (R_Init(0, 0) == -1)
{
VID_Shutdown(); // Isn't that just too bad? :(
return false;
}
/* Ensure that all key states are cleared */
Key_MarkAllUp();
Com_Printf("------------------------------------\n\n");
return true;
}
/*
* This function gets called once just before drawing each frame, and
* it's sole purpose in life is to check to see if any of the video mode
* parameters have changed, and if they have to update the refresh
* and/or video mode to match.
*/
void
VID_CheckChanges(void)
{
if (vid_fullscreen->modified)
{
S_StopAllSounds();
/* refresh has changed */
cl.refresh_prepped = false;
cl.cinematicpalette_active = false;
cls.disable_screen = true;
// Proceed to reboot the refresher
VID_LoadRefresh();
cls.disable_screen = false;
}
}
void
VID_Init(void)
{
/* Create the video variables so we know how to start the graphics drivers */
vid_xpos = Cvar_Get("vid_xpos", "3", CVAR_ARCHIVE);
vid_ypos = Cvar_Get("vid_ypos", "22", CVAR_ARCHIVE);
vid_fullscreen = Cvar_Get("vid_fullscreen", "0", CVAR_ARCHIVE);
vid_gamma = Cvar_Get("vid_gamma", "1", CVAR_ARCHIVE);
/* Add some console commands that we want to handle */
Cmd_AddCommand("vid_restart", VID_Restart_f);
/* Start the graphics mode and load refresh DLL */
VID_CheckChanges();
}
void
VID_Shutdown(void)
{
if (ref_active)
{
/* Shut down the renderer */
R_Shutdown();
}
// Declare the refresher as inactive
ref_active = false;
}