yquake2remaster/src/backends/generic/vid.c

355 lines
8 KiB
C
Raw Normal View History

2009-03-05 09:03:26 +00:00
/*
2010-10-18 14:56:30 +00:00
* 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.
*
2012-08-02 12:00:04 +00:00
* This implementation works for Windows and unixoid systems, but
* other platforms may need an own implementation!
*
2010-10-18 14:56:30 +00:00
* =======================================================================
*/
2009-03-05 09:03:26 +00:00
#include <assert.h>
#include <errno.h>
2012-08-01 11:58:10 +00:00
#include "../../client/header/client.h"
2012-08-01 14:53:40 +00:00
#include "header/input.h"
2009-03-05 09:03:26 +00:00
2010-10-18 14:56:30 +00:00
/* Structure containing functions exported from refresh DLL */
refexport_t re;
2009-03-05 09:03:26 +00:00
2010-10-18 14:56:30 +00:00
/* Console variables that we need to access from this module */
2012-06-08 11:01:56 +00:00
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;
2009-03-05 09:03:26 +00:00
2010-10-18 14:56:30 +00:00
/* Global variables used internally by this module */
viddef_t viddef; /* global video state; used by other modules */
qboolean reflib_active = 0;
2009-03-05 09:03:26 +00:00
2012-06-08 11:01:56 +00:00
#define VID_NUM_MODES (sizeof(vid_modes) / sizeof(vid_modes[0]))
2009-03-05 09:03:26 +00:00
2012-06-08 11:01:56 +00:00
void Do_Key_Event(int key, qboolean down);
// Input state
in_state_t in_state;
2009-03-05 09:03:26 +00:00
2010-10-18 14:56:30 +00:00
#define MAXPRINTMSG 4096
2009-03-05 09:03:26 +00:00
2010-10-18 14:56:30 +00:00
void
2012-06-08 11:01:56 +00:00
VID_Printf(int print_level, char *fmt, ...)
2009-03-05 09:03:26 +00:00
{
2010-10-18 14:56:30 +00:00
va_list argptr;
2012-06-08 11:01:56 +00:00
char msg[MAXPRINTMSG];
2010-10-18 14:56:30 +00:00
2012-06-08 11:01:56 +00:00
va_start(argptr, fmt);
vsnprintf(msg, MAXPRINTMSG, fmt, argptr);
va_end(argptr);
2010-10-18 14:56:30 +00:00
2012-06-08 11:01:56 +00:00
if (print_level == PRINT_ALL)
2010-10-18 14:56:30 +00:00
{
2012-06-08 11:01:56 +00:00
Com_Printf("%s", msg);
2010-10-18 14:56:30 +00:00
}
2009-03-05 09:03:26 +00:00
else
2010-10-18 14:56:30 +00:00
{
2012-06-08 11:01:56 +00:00
Com_DPrintf("%s", msg);
2010-10-18 14:56:30 +00:00
}
2009-03-05 09:03:26 +00:00
}
2010-10-18 14:56:30 +00:00
void
2012-06-08 11:01:56 +00:00
VID_Error(int err_level, char *fmt, ...)
2009-03-05 09:03:26 +00:00
{
2010-10-18 14:56:30 +00:00
va_list argptr;
2012-06-08 11:01:56 +00:00
char msg[MAXPRINTMSG];
2009-03-05 09:03:26 +00:00
2012-06-08 11:01:56 +00:00
va_start(argptr, fmt);
vsnprintf(msg, MAXPRINTMSG, fmt, argptr);
va_end(argptr);
2010-10-18 14:56:30 +00:00
2012-06-08 11:01:56 +00:00
Com_Error(err_level, "%s", msg);
2010-10-18 14:56:30 +00:00
}
2009-03-05 09:03:26 +00:00
/*
* 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.
2010-10-18 14:56:30 +00:00
*/
void
2012-06-08 11:01:56 +00:00
VID_Restart_f(void)
2009-03-05 09:03:26 +00:00
{
vid_fullscreen->modified = true;
2009-03-05 09:03:26 +00:00
}
typedef struct vidmode_s
{
const char *description;
2010-10-18 14:56:30 +00:00
int width, height;
int mode;
2009-03-05 09:03:26 +00:00
} vidmode_t;
/* This must be the same as in videomenu.c! */
2010-10-18 14:56:30 +00:00
vidmode_t vid_modes[] = {
2012-06-08 11:01:56 +00:00
{"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},
2012-06-08 11:01:56 +00:00
{"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},
2009-03-05 09:03:26 +00:00
};
2010-10-18 14:56:30 +00:00
qboolean
2012-06-08 11:01:56 +00:00
VID_GetModeInfo(int *width, int *height, int mode)
2009-03-05 09:03:26 +00:00
{
2012-06-08 11:01:56 +00:00
if ((mode < 0) || (mode >= VID_NUM_MODES))
2010-10-18 14:56:30 +00:00
{
2012-06-08 11:01:56 +00:00
return false;
2010-10-18 14:56:30 +00:00
}
2009-03-05 09:03:26 +00:00
2012-06-08 11:01:56 +00:00
*width = vid_modes[mode].width;
*height = vid_modes[mode].height;
2009-03-05 09:03:26 +00:00
2012-06-08 11:01:56 +00:00
return true;
2009-03-05 09:03:26 +00:00
}
2010-10-18 14:56:30 +00:00
void
2012-06-08 11:01:56 +00:00
VID_NewWindow(int width, int height)
2009-03-05 09:03:26 +00:00
{
2012-06-08 11:01:56 +00:00
viddef.width = width;
2009-03-05 09:03:26 +00:00
viddef.height = height;
}
2010-10-18 14:56:30 +00:00
void
2012-06-08 11:01:56 +00:00
VID_FreeReflib(void)
2009-03-05 09:03:26 +00:00
{
/*if (reflib_library)
2010-10-18 14:56:30 +00:00
{
2012-06-08 11:01:56 +00:00
if (IN_Close_fp)
2010-10-18 14:56:30 +00:00
{
2010-10-19 08:25:47 +00:00
IN_Close_fp();
2010-10-18 14:56:30 +00:00
}
2012-06-08 11:01:56 +00:00
if (IN_BackendShutdown_fp)
2010-10-18 14:56:30 +00:00
{
2010-10-19 08:25:47 +00:00
IN_BackendShutdown_fp();
2010-10-18 14:56:30 +00:00
}
}*/
2010-10-18 14:56:30 +00:00
// Shut down the input backend
IN_Close();
IN_BackendShutdown();
2010-10-18 14:56:30 +00:00
// Get rid of refexport function pointers
2012-06-08 11:01:56 +00:00
memset(&re, 0, sizeof(re));
// Declare the refresher as inactive
2012-06-08 11:01:56 +00:00
reflib_active = false;
2009-03-05 09:03:26 +00:00
}
2010-10-18 14:56:30 +00:00
qboolean
//VID_LoadRefresh(char *name)
VID_LoadRefresh(void)
2009-03-05 09:03:26 +00:00
{
refimport_t ri; // Refresh imported functions
2010-10-18 14:56:30 +00:00
2012-06-08 11:01:56 +00:00
if (reflib_active)
2009-03-05 09:03:26 +00:00
{
/*if (IN_Close_fp)
2010-10-18 14:56:30 +00:00
{
2010-10-19 08:25:47 +00:00
IN_Close_fp();
2010-10-18 14:56:30 +00:00
}
2012-06-08 11:01:56 +00:00
if (IN_BackendShutdown_fp)
2010-10-18 14:56:30 +00:00
{
2010-10-19 08:25:47 +00:00
IN_BackendShutdown_fp();
}*/
2010-10-18 14:56:30 +00:00
2009-03-05 09:03:26 +00:00
re.Shutdown();
2010-10-18 14:56:30 +00:00
VID_FreeReflib();
2009-03-05 09:03:26 +00:00
}
2012-06-08 11:01:56 +00:00
Com_Printf("----- refresher initialization -----\n");
2009-03-05 09:03:26 +00:00
// Fill in client functions for the refresher
2009-03-05 09:03:26 +00:00
ri.Cmd_AddCommand = Cmd_AddCommand;
ri.Cmd_RemoveCommand = Cmd_RemoveCommand;
ri.Cmd_Argc = Cmd_Argc;
ri.Cmd_Argv = Cmd_Argv;
ri.Cmd_ExecuteText = Cbuf_ExecuteText;
ri.Con_Printf = VID_Printf;
ri.Sys_Error = VID_Error;
ri.Sys_Mkdir = Sys_Mkdir;
ri.Sys_LoadLibrary = Sys_LoadLibrary;
ri.Sys_FreeLibrary = Sys_FreeLibrary;
ri.Sys_GetProcAddress = Sys_GetProcAddress;
2009-03-05 09:03:26 +00:00
ri.FS_LoadFile = FS_LoadFile;
ri.FS_FreeFile = FS_FreeFile;
ri.FS_Gamedir = FS_Gamedir;
ri.Cvar_Get = Cvar_Get;
ri.Cvar_Set = Cvar_Set;
ri.Cvar_SetValue = Cvar_SetValue;
ri.Vid_GetModeInfo = VID_GetModeInfo;
ri.Vid_MenuInit = VID_MenuInit;
ri.Vid_NewWindow = VID_NewWindow;
// Get refresher API
re = R_GetRefAPI(ri);
2009-03-05 09:03:26 +00:00
/* Init IN (Mouse) */
in_state.IN_CenterView_fp = IN_CenterView;
in_state.Key_Event_fp = Do_Key_Event;
in_state.viewangles = cl.viewangles;
in_state.in_strafe_state = &in_strafe.state;
in_state.in_speed_state = &in_speed.state;
// Initiate the input backend
IN_BackendInit (&in_state);
2009-03-05 09:03:26 +00:00
2012-06-08 11:01:56 +00:00
if (re.Init(0, 0) == -1)
2009-03-05 09:03:26 +00:00
{
re.Shutdown();
2010-10-18 14:56:30 +00:00
VID_FreeReflib();
2012-06-08 11:01:56 +00:00
return false;
2009-03-05 09:03:26 +00:00
}
// Initiate keyboard at the input backend
IN_KeyboardInit (Do_Key_Event);
2009-03-05 09:03:26 +00:00
Key_ClearStates();
2012-06-08 11:01:56 +00:00
Com_Printf("------------------------------------\n\n");
2009-03-05 09:03:26 +00:00
reflib_active = true;
2012-06-08 11:01:56 +00:00
return true;
2009-03-05 09:03:26 +00:00
}
/*
2010-10-18 14:56:30 +00:00
* 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
2010-10-18 14:56:30 +00:00
* and/or video mode to match.
*/
void
2012-06-08 11:01:56 +00:00
VID_CheckChanges(void)
2009-03-05 09:03:26 +00:00
{
if (vid_fullscreen->modified)
2009-03-05 09:03:26 +00:00
{
S_StopAllSounds();
2010-10-18 14:56:30 +00:00
/* refresh has changed */
2009-03-05 09:03:26 +00:00
vid_fullscreen->modified = true;
cl.refresh_prepped = false;
cl.cinematicpalette_active = false;
2009-03-05 09:03:26 +00:00
cls.disable_screen = true;
// Proceed to reboot the refresher
VID_LoadRefresh();
2009-03-05 09:03:26 +00:00
cls.disable_screen = false;
}
}
2010-10-18 14:56:30 +00:00
void
2012-06-08 11:01:56 +00:00
VID_Init(void)
2009-03-05 09:03:26 +00:00
{
/* Create the video variables so we know how to start the graphics drivers */
2012-06-08 11:01:56 +00:00
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);
2009-03-05 09:03:26 +00:00
/* Add some console commands that we want to handle */
2012-06-08 11:01:56 +00:00
Cmd_AddCommand("vid_restart", VID_Restart_f);
2009-03-05 09:03:26 +00:00
/* Start the graphics mode and load refresh DLL */
VID_CheckChanges();
}
2010-10-18 14:56:30 +00:00
void
2012-06-08 11:01:56 +00:00
VID_Shutdown(void)
2009-03-05 09:03:26 +00:00
{
2012-06-08 11:01:56 +00:00
if (reflib_active)
2009-03-05 09:03:26 +00:00
{
/*if (IN_Close_fp)
2010-10-18 14:56:30 +00:00
{
2010-10-19 08:25:47 +00:00
IN_Close_fp();
2010-10-18 14:56:30 +00:00
}
2012-06-08 11:01:56 +00:00
if (IN_BackendShutdown_fp)
2010-10-18 14:56:30 +00:00
{
2010-10-19 08:25:47 +00:00
IN_BackendShutdown_fp();
}*/
2010-10-18 14:56:30 +00:00
re.Shutdown();
VID_FreeReflib();
2009-03-05 09:03:26 +00:00
}
}
2010-10-18 14:56:30 +00:00
/* INPUT */
2010-10-18 14:56:30 +00:00
void
2012-06-08 11:01:56 +00:00
IN_Shutdown(void)
2009-03-05 09:03:26 +00:00
{
IN_BackendShutdown();
2009-03-05 09:03:26 +00:00
}
2010-10-18 14:56:30 +00:00
void
2012-06-08 11:01:56 +00:00
IN_Commands(void)
2009-03-05 09:03:26 +00:00
{
IN_BackendMouseButtons();
2009-03-05 09:03:26 +00:00
}
2010-10-18 14:56:30 +00:00
void
2012-06-08 11:01:56 +00:00
IN_Move(usercmd_t *cmd)
2009-03-05 09:03:26 +00:00
{
IN_BackendMove (cmd);
2009-03-05 09:03:26 +00:00
}
2010-10-18 14:56:30 +00:00
void
2012-06-08 11:01:56 +00:00
Do_Key_Event(int key, qboolean down)
2009-03-05 09:03:26 +00:00
{
2012-06-08 11:01:56 +00:00
Key_Event(key, down, Sys_Milliseconds());
2009-03-05 09:03:26 +00:00
}
2012-06-08 11:01:56 +00:00