2
0
mirror of https://github.com/FWGS/xash3d-fwgs synced 2024-11-24 10:50:58 +01:00
xash3d-fwgs/engine/client/vid_common.c

235 lines
5.9 KiB
C

/*
vid_common.c - common vid component
Copyright (C) 2018 a1batross, Uncle Mike
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 3 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.
*/
#include "common.h"
#include "client.h"
#include "mod_local.h"
#include "input.h"
#include "vid_common.h"
#include "platform/platform.h"
static CVAR_DEFINE( window_width, "width", "0", FCVAR_RENDERINFO|FCVAR_VIDRESTART, "screen width" );
static CVAR_DEFINE( window_height, "height", "0", FCVAR_RENDERINFO|FCVAR_VIDRESTART, "screen height" );
static CVAR_DEFINE( vid_brightness, "brightness", "0.0", FCVAR_ARCHIVE, "brightness factor" );
static CVAR_DEFINE( vid_gamma, "gamma", "2.5", FCVAR_ARCHIVE, "gamma amount" );
static CVAR_DEFINE_AUTO( vid_mode, "0", FCVAR_RENDERINFO, "current video mode index (used only for storage)" );
static CVAR_DEFINE_AUTO( vid_rotate, "0", FCVAR_RENDERINFO|FCVAR_VIDRESTART, "screen rotation (0-3)" );
static CVAR_DEFINE_AUTO( vid_scale, "1.0", FCVAR_RENDERINFO|FCVAR_VIDRESTART, "pixel scale" );
CVAR_DEFINE_AUTO( vid_highdpi, "1", FCVAR_RENDERINFO|FCVAR_VIDRESTART, "enable High-DPI mode" );
CVAR_DEFINE( vid_fullscreen, "fullscreen", "0", FCVAR_RENDERINFO|FCVAR_VIDRESTART, "enable fullscreen mode" );
CVAR_DEFINE( window_xpos, "_window_xpos", "-1", FCVAR_RENDERINFO, "window position by horizontal" );
CVAR_DEFINE( window_ypos, "_window_ypos", "-1", FCVAR_RENDERINFO, "window position by vertical" );
glwstate_t glw_state;
/*
=================
VID_StartupGamma
=================
*/
void VID_StartupGamma( void )
{
BuildGammaTable( vid_gamma.value, vid_brightness.value );
Con_Reportf( "VID_StartupGamma: gamma %g brightness %g\n", vid_gamma.value, vid_brightness.value );
ClearBits( vid_brightness.flags, FCVAR_CHANGED );
ClearBits( vid_gamma.flags, FCVAR_CHANGED );
}
/*
=================
VID_InitDefaultResolution
=================
*/
void VID_InitDefaultResolution( void )
{
// we need to have something valid here
// until video subsystem initialized
refState.width = 640;
refState.height = 480;
}
/*
=================
R_SaveVideoMode
=================
*/
void R_SaveVideoMode( int w, int h, int render_w, int render_h )
{
if( !w || !h || !render_w || !render_h )
{
host.renderinfo_changed = false;
return;
}
host.window_center_x = w / 2;
host.window_center_y = h / 2;
Cvar_SetValue( "width", w );
Cvar_SetValue( "height", h );
// immediately drop changed state or we may trigger
// video subsystem to reapply settings
host.renderinfo_changed = false;
if( refState.width == render_w && refState.height == render_h )
return;
refState.width = render_w;
refState.height = render_h;
// check for 4:3 or 5:4
if( render_w * 3 != render_h * 4 && render_w * 4 != render_h * 5 )
refState.wideScreen = true;
else refState.wideScreen = false;
SCR_VidInit(); // tell client.dll that vid_mode has changed
}
/*
=================
VID_GetModeString
=================
*/
const char *VID_GetModeString( int vid_mode )
{
vidmode_t *vidmode;
if( vid_mode < 0 || vid_mode > R_MaxVideoModes() )
return NULL;
if( !( vidmode = R_GetVideoMode( vid_mode ) ) )
return NULL;
return vidmode->desc;
}
/*
==================
VID_CheckChanges
check vid modes and fullscreen
==================
*/
void VID_CheckChanges( void )
{
if( FBitSet( cl_allow_levelshots.flags, FCVAR_CHANGED ))
{
//GL_FreeTexture( cls.loadingBar );
SCR_RegisterTextures(); // reload 'lambda' image
ClearBits( cl_allow_levelshots.flags, FCVAR_CHANGED );
}
if( host.renderinfo_changed )
{
if( VID_SetMode( ))
{
SCR_VidInit(); // tell the client.dll what vid_mode has changed
}
else
{
Sys_Error( "Can't re-initialize video subsystem\n" );
}
host.renderinfo_changed = false;
}
}
/*
===============
VID_SetDisplayTransform
notify ref dll about screen transformations
===============
*/
void VID_SetDisplayTransform( int *render_w, int *render_h )
{
uint rotate = vid_rotate.value;
if( ref.dllFuncs.R_SetDisplayTransform( rotate, 0, 0, vid_scale.value, vid_scale.value ))
{
if( rotate & 1 )
{
int swap = *render_w;
*render_w = *render_h;
*render_h = swap;
}
*render_h /= vid_scale.value;
*render_w /= vid_scale.value;
}
else
{
Con_Printf( S_WARN "failed to setup screen transform\n" );
}
}
static void VID_Mode_f( void )
{
int w, h;
switch( Cmd_Argc() )
{
case 2:
{
vidmode_t *vidmode;
vidmode = R_GetVideoMode( Q_atoi( Cmd_Argv( 1 )) );
if( !vidmode )
{
Con_Print( S_ERROR "unable to set mode, backend returned null" );
return;
}
w = vidmode->width;
h = vidmode->height;
break;
}
case 3:
{
w = Q_atoi( Cmd_Argv( 1 ));
h = Q_atoi( Cmd_Argv( 2 ));
break;
}
default:
Msg( S_USAGE "vid_mode <modenum>|<width height>\n" );
return;
}
R_ChangeDisplaySettings( w, h, !!vid_fullscreen.value );
}
void VID_Init( void )
{
// system screen width and height (don't suppose for change from console at all)
Cvar_RegisterVariable( &window_width );
Cvar_RegisterVariable( &window_height );
Cvar_RegisterVariable( &vid_mode );
Cvar_RegisterVariable( &vid_highdpi );
Cvar_RegisterVariable( &vid_rotate );
Cvar_RegisterVariable( &vid_scale );
Cvar_RegisterVariable( &vid_fullscreen );
Cvar_RegisterVariable( &vid_brightness );
Cvar_RegisterVariable( &vid_gamma );
Cvar_RegisterVariable( &window_xpos );
Cvar_RegisterVariable( &window_ypos );
// a1ba: planned to be named vid_mode for compability
// but supported mode list is filled by backends, so numbers are not portable any more
Cmd_AddRestrictedCommand( "vid_setmode", VID_Mode_f, "display video mode" );
R_Init(); // init renderer
}