2010-02-15 23:26:55 +00:00
/*
Copyright ( C ) 1996 - 2001 Id Software , Inc .
Copyright ( C ) 2002 - 2009 John Fitzgibbons and others
Copyright ( C ) 2007 - 2008 Kristian Duske
2014-09-22 08:55:46 +00:00
Copyright ( C ) 2010 - 2014 QuakeSpasm developers
2010-02-15 23:26:55 +00:00
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 .
*/
// screen.c -- master for refresh, status bar, console, chat, notify, etc
# include "quakedef.h"
/*
background clear
rendering
turtle / net / ram icons
sbar
centerprint / slow centerprint
notify lines
intermission / finale overlay
loading plaque
console
menu
required background clears
required update regions
syncronous draw mode or async
One off screen buffer , with updates either copied or xblited
Need to double buffer ?
async draw will require the refresh area to be cleared , because it will be
xblited , but sync draw can just ignore it .
sync
draw
CenterPrint ( )
SlowPrint ( )
Screen_Update ( ) ;
Con_Printf ( ) ;
net
turn off messages option
the refresh is allways rendered , unless the console is full screen
console is :
notify lines
half
full
*/
int glx , gly , glwidth , glheight ;
float scr_con_current ;
float scr_conlines ; // lines of console to display
//johnfitz -- new cvars
2011-12-28 22:01:33 +00:00
cvar_t scr_menuscale = { " scr_menuscale " , " 1 " , CVAR_ARCHIVE } ;
cvar_t scr_sbarscale = { " scr_sbarscale " , " 1 " , CVAR_ARCHIVE } ;
2012-09-04 18:38:13 +00:00
cvar_t scr_sbaralpha = { " scr_sbaralpha " , " 0.75 " , CVAR_ARCHIVE } ;
2011-12-28 22:01:33 +00:00
cvar_t scr_conwidth = { " scr_conwidth " , " 0 " , CVAR_ARCHIVE } ;
cvar_t scr_conscale = { " scr_conscale " , " 1 " , CVAR_ARCHIVE } ;
cvar_t scr_crosshairscale = { " scr_crosshairscale " , " 1 " , CVAR_ARCHIVE } ;
cvar_t scr_showfps = { " scr_showfps " , " 0 " , CVAR_NONE } ;
cvar_t scr_clock = { " scr_clock " , " 0 " , CVAR_NONE } ;
2010-02-15 23:26:55 +00:00
//johnfitz
2011-12-28 22:01:33 +00:00
cvar_t scr_viewsize = { " viewsize " , " 100 " , CVAR_ARCHIVE } ;
cvar_t scr_fov = { " fov " , " 90 " , CVAR_NONE } ; // 10 - 170
2013-01-31 20:03:23 +00:00
cvar_t scr_fov_adapt = { " fov_adapt " , " 1 " , CVAR_ARCHIVE } ;
2011-12-28 22:01:33 +00:00
cvar_t scr_conspeed = { " scr_conspeed " , " 500 " , CVAR_ARCHIVE } ;
cvar_t scr_centertime = { " scr_centertime " , " 2 " , CVAR_NONE } ;
cvar_t scr_showram = { " showram " , " 1 " , CVAR_NONE } ;
cvar_t scr_showturtle = { " showturtle " , " 0 " , CVAR_NONE } ;
cvar_t scr_showpause = { " showpause " , " 1 " , CVAR_NONE } ;
cvar_t scr_printspeed = { " scr_printspeed " , " 8 " , CVAR_NONE } ;
cvar_t gl_triplebuffer = { " gl_triplebuffer " , " 1 " , CVAR_ARCHIVE } ;
2010-02-15 23:26:55 +00:00
extern cvar_t crosshair ;
qboolean scr_initialized ; // ready to draw
qpic_t * scr_ram ;
qpic_t * scr_net ;
qpic_t * scr_turtle ;
int clearconsole ;
int clearnotify ;
vrect_t scr_vrect ;
qboolean scr_disabled_for_loading ;
qboolean scr_drawloading ;
float scr_disabled_time ;
int scr_tileclear_updates = 0 ; //johnfitz
void SCR_ScreenShot_f ( void ) ;
/*
= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
CENTER PRINTING
= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
*/
char scr_centerstring [ 1024 ] ;
float scr_centertime_start ; // for slow victory printing
float scr_centertime_off ;
int scr_center_lines ;
int scr_erase_lines ;
int scr_erase_center ;
2017-09-17 02:12:53 +00:00
# define CPRINT_TYPEWRITER (1u<<0)
# define CPRINT_PERSIST (1u<<1)
# define CPRINT_TALIGN (1u<<2)
unsigned int scr_centerprint_flags ;
2010-02-15 23:26:55 +00:00
/*
= = = = = = = = = = = = = =
SCR_CenterPrint
Called for important messages that should stay in the center of the screen
for a few moments
= = = = = = = = = = = = = =
*/
2010-08-29 02:22:55 +00:00
void SCR_CenterPrint ( const char * str ) //update centerprint data
2010-02-15 23:26:55 +00:00
{
2017-09-17 02:12:53 +00:00
unsigned int flags = 0 ;
if ( * str ! = ' / ' & & cl . intermission )
flags | = CPRINT_TYPEWRITER | CPRINT_PERSIST | CPRINT_TALIGN ;
//check for centerprint prefixes/flags
while ( * str = = ' / ' )
{
if ( str [ 1 ] = = ' . ' )
{ //no more
str + = 2 ;
break ;
}
else if ( str [ 1 ] = = ' P ' )
flags | = CPRINT_PERSIST ;
else if ( str [ 1 ] = = ' W ' ) //typewriter
flags ^ = CPRINT_TYPEWRITER ;
else if ( str [ 1 ] = = ' S ' ) //typewriter
flags ^ = CPRINT_PERSIST ;
else if ( str [ 1 ] = = ' M ' ) //masked background
;
else if ( str [ 1 ] = = ' O ' ) //obituary print (lower half)
;
else if ( str [ 1 ] = = ' B ' ) //bottom-align
;
else if ( str [ 1 ] = = ' B ' ) //top-align
;
else if ( str [ 1 ] = = ' L ' ) //left-align
;
else if ( str [ 1 ] = = ' R ' ) //right-align
;
else if ( str [ 1 ] = = ' F ' ) //alternative 'finale' control
{
str + = 2 ;
if ( ! cl . intermission )
cl . completed_time = cl . time ;
switch ( * str + + )
{
case 0 :
str - - ;
break ;
case ' R ' : //remove intermission (no other method to do this)
cl . intermission = 0 ;
break ;
case ' I ' : //regular intermission
case ' S ' : //show scoreboard
cl . intermission = 1 ;
break ;
case ' F ' : //like svc_finale
cl . intermission = 2 ;
break ;
default :
break ; //any other flag you want
}
vid . recalc_refdef = true ;
continue ;
}
else if ( str [ 1 ] = = ' I ' ) //title image
{
const char * e ;
str + = 2 ;
e = strchr ( str , ' : ' ) ;
if ( ! e )
e = strchr ( str , ' ' ) ; //probably an error
if ( ! e )
e = str + strlen ( str ) - 1 ; //error
str = e + 1 ;
continue ;
}
else
break ;
str + = 2 ;
}
2010-02-15 23:26:55 +00:00
strncpy ( scr_centerstring , str , sizeof ( scr_centerstring ) - 1 ) ;
2017-09-17 02:12:53 +00:00
scr_centertime_off = ( flags & CPRINT_PERSIST ) ? 999999 : scr_centertime . value ;
2010-02-15 23:26:55 +00:00
scr_centertime_start = cl . time ;
2017-09-17 02:12:53 +00:00
if ( * scr_centerstring & & ! ( flags & CPRINT_PERSIST ) )
Con_LogCenterPrint ( scr_centerstring ) ;
2010-02-15 23:26:55 +00:00
// count the number of lines for centering
scr_center_lines = 1 ;
2012-01-13 19:10:52 +00:00
str = scr_centerstring ;
2010-02-15 23:26:55 +00:00
while ( * str )
{
if ( * str = = ' \n ' )
scr_center_lines + + ;
str + + ;
}
}
void SCR_DrawCenterString ( void ) //actually do the drawing
{
char * start ;
int l ;
int j ;
int x , y ;
int remaining ;
GL_SetCanvas ( CANVAS_MENU ) ; //johnfitz
// the finale prints the characters one at a time
if ( cl . intermission )
remaining = scr_printspeed . value * ( cl . time - scr_centertime_start ) ;
else
remaining = 9999 ;
scr_erase_center = 0 ;
start = scr_centerstring ;
if ( scr_center_lines < = 4 )
y = 200 * 0.35 ; //johnfitz -- 320x200 coordinate system
else
y = 48 ;
2014-06-29 01:22:35 +00:00
if ( crosshair . value )
y - = 8 ;
2010-02-15 23:26:55 +00:00
do
{
// scan the width of the line
for ( l = 0 ; l < 40 ; l + + )
if ( start [ l ] = = ' \n ' | | ! start [ l ] )
break ;
x = ( 320 - l * 8 ) / 2 ; //johnfitz -- 320x200 coordinate system
for ( j = 0 ; j < l ; j + + , x + = 8 )
{
Draw_Character ( x , y , start [ j ] ) ; //johnfitz -- stretch overlays
if ( ! remaining - - )
return ;
}
y + = 8 ;
while ( * start & & * start ! = ' \n ' )
start + + ;
if ( ! * start )
break ;
start + + ; // skip the \n
} while ( 1 ) ;
}
void SCR_CheckDrawCenterString ( void )
{
if ( scr_center_lines > scr_erase_lines )
scr_erase_lines = scr_center_lines ;
scr_centertime_off - = host_frametime ;
if ( scr_centertime_off < = 0 & & ! cl . intermission )
return ;
if ( key_dest ! = key_game )
return ;
if ( cl . paused ) //johnfitz -- don't show centerprint during a pause
return ;
SCR_DrawCenterString ( ) ;
}
//=============================================================================
2012-10-31 07:30:36 +00:00
/*
= = = = = = = = = = = = = = = = = = = =
AdaptFovx
2013-03-02 18:52:22 +00:00
Adapt a 4 : 3 horizontal FOV to the current screen size using the " Hor+ " scaling :
2.0 * atan ( width / height * 3.0 / 4.0 * tan ( fov_x / 2.0 ) )
2012-10-31 07:30:36 +00:00
= = = = = = = = = = = = = = = = = = = =
*/
2013-03-02 18:52:22 +00:00
float AdaptFovx ( float fov_x , float width , float height )
2012-10-31 07:30:36 +00:00
{
2013-03-02 18:52:22 +00:00
float a , x ;
2017-09-17 02:12:53 +00:00
if ( cl . statsf [ STAT_VIEWZOOM ] )
fov_x * = cl . statsf [ STAT_VIEWZOOM ] / 255.0 ;
if ( fov_x < 1 )
fov_x = 1 ;
if ( fov_x > 179 )
fov_x = 179 ;
2013-03-02 18:52:22 +00:00
if ( ! scr_fov_adapt . value )
return fov_x ;
if ( ( x = height / width ) = = 0.75 )
return fov_x ;
a = atan ( 0.75 / x * tan ( fov_x / 360 * M_PI ) ) ;
a = a * 360 / M_PI ;
return a ;
2012-10-31 07:30:36 +00:00
}
2010-02-15 23:26:55 +00:00
/*
= = = = = = = = = = = = = = = = = = = =
CalcFovy
= = = = = = = = = = = = = = = = = = = =
*/
float CalcFovy ( float fov_x , float width , float height )
{
2013-03-02 18:52:22 +00:00
float a , x ;
2010-02-15 23:26:55 +00:00
2013-03-02 18:52:22 +00:00
if ( fov_x < 1 | | fov_x > 179 )
Sys_Error ( " Bad fov: %f " , fov_x ) ;
2010-02-15 23:26:55 +00:00
2013-03-02 18:52:22 +00:00
x = width / tan ( fov_x / 360 * M_PI ) ;
a = atan ( height / x ) ;
a = a * 360 / M_PI ;
return a ;
2010-02-15 23:26:55 +00:00
}
/*
= = = = = = = = = = = = = = = = =
SCR_CalcRefdef
Must be called whenever vid changes
Internal use only
= = = = = = = = = = = = = = = = =
*/
static void SCR_CalcRefdef ( void )
{
float size , scale ; //johnfitz -- scale
chase.c, cl_input.c, cl_parse.c, client.h, common.c, common.h, console.h,
cvar.h, draw.h, gl_draw.c, gl_fog.c, gl_mesh.c, gl_model.c, gl_model.h,
gl_rmain.c, gl_rmisc.c, gl_screen.c, gl_sky.c, gl_texmgr.c, glquake.h,
host.c, keys.c, keys.h, main.c, menu.c, menu.h, pr_cmds.c, quakedef.h,
r_alias.c, r_brush.c, r_part.c, r_sprite.c, r_world.c, sbar.c, sbar.h,
screen.h, snd_dma.c, snd_mem.c, snd_mix.c, sv_main.c, sys_sdl.c, vid.h,
view.h, world.c, world.h: Loads of warning fixes about missing function
prototypes, missing parens around &, missing braces leading to ambiguous
else statements and unused and uninitialized variables. There are still a
couple of unitialised variables here and there, but not much. The warnings
about strict aliasing violations need taking care of.
git-svn-id: svn://svn.code.sf.net/p/quakespasm/code/trunk/quakespasm@21 af15c1b1-3010-417e-b628-4374ebc0bcbd
2010-02-16 12:01:07 +00:00
2010-02-15 23:26:55 +00:00
// force the status bar to redraw
Sbar_Changed ( ) ;
scr_tileclear_updates = 0 ; //johnfitz
// bound viewsize
if ( scr_viewsize . value < 30 )
2011-12-29 21:21:11 +00:00
Cvar_SetQuick ( & scr_viewsize , " 30 " ) ;
2010-02-15 23:26:55 +00:00
if ( scr_viewsize . value > 120 )
2011-12-29 21:21:11 +00:00
Cvar_SetQuick ( & scr_viewsize , " 120 " ) ;
2010-02-15 23:26:55 +00:00
// bound fov
if ( scr_fov . value < 10 )
2011-12-29 21:21:11 +00:00
Cvar_SetQuick ( & scr_fov , " 10 " ) ;
2010-02-15 23:26:55 +00:00
if ( scr_fov . value > 170 )
2011-12-29 21:21:11 +00:00
Cvar_SetQuick ( & scr_fov , " 170 " ) ;
2010-02-15 23:26:55 +00:00
2011-12-28 22:40:15 +00:00
vid . recalc_refdef = 0 ;
2010-02-15 23:26:55 +00:00
//johnfitz -- rewrote this section
size = scr_viewsize . value ;
scale = CLAMP ( 1.0 , scr_sbarscale . value , ( float ) glwidth / 320.0 ) ;
2018-05-01 00:35:14 +00:00
if ( size > = 120 | | cl . intermission | | ( scr_sbaralpha . value < 1 | | cl . qcvm . extfuncs . CSQC_DrawHud ) ) //johnfitz -- scr_sbaralpha.value. Spike -- simple csqc assumes fullscreen video the same way.
2010-02-15 23:26:55 +00:00
sb_lines = 0 ;
else if ( size > = 110 )
sb_lines = 24 * scale ;
else
sb_lines = 48 * scale ;
2014-06-22 05:50:39 +00:00
size = q_min ( scr_viewsize . value , 100 ) / 100 ;
2010-02-15 23:26:55 +00:00
//johnfitz
//johnfitz -- rewrote this section
2014-06-22 05:50:39 +00:00
r_refdef . vrect . width = q_max ( glwidth * size , 96 ) ; //no smaller than 96, for icons
r_refdef . vrect . height = q_min ( glheight * size , glheight - sb_lines ) ; //make room for sbar
2010-02-15 23:26:55 +00:00
r_refdef . vrect . x = ( glwidth - r_refdef . vrect . width ) / 2 ;
r_refdef . vrect . y = ( glheight - sb_lines - r_refdef . vrect . height ) / 2 ;
//johnfitz
2013-10-12 16:20:38 +00:00
r_refdef . fov_x = AdaptFovx ( scr_fov . value , vid . width , vid . height ) ;
2010-02-15 23:26:55 +00:00
r_refdef . fov_y = CalcFovy ( r_refdef . fov_x , r_refdef . vrect . width , r_refdef . vrect . height ) ;
scr_vrect = r_refdef . vrect ;
}
/*
= = = = = = = = = = = = = = = = =
SCR_SizeUp_f
Keybinding command
= = = = = = = = = = = = = = = = =
*/
void SCR_SizeUp_f ( void )
{
2011-12-29 21:21:11 +00:00
Cvar_SetValueQuick ( & scr_viewsize , scr_viewsize . value + 10 ) ;
2010-02-15 23:26:55 +00:00
}
/*
= = = = = = = = = = = = = = = = =
SCR_SizeDown_f
Keybinding command
= = = = = = = = = = = = = = = = =
*/
void SCR_SizeDown_f ( void )
{
2011-12-29 21:21:11 +00:00
Cvar_SetValueQuick ( & scr_viewsize , scr_viewsize . value - 10 ) ;
2011-12-28 22:40:15 +00:00
}
static void SCR_Callback_refdef ( cvar_t * var )
{
2010-02-15 23:26:55 +00:00
vid . recalc_refdef = 1 ;
}
/*
= = = = = = = = = = = = = = = = = =
SCR_Conwidth_f - - johnfitz - - called when scr_conwidth or scr_conscale changes
= = = = = = = = = = = = = = = = = =
*/
2011-12-24 14:04:01 +00:00
void SCR_Conwidth_f ( cvar_t * var )
2010-02-15 23:26:55 +00:00
{
2011-12-28 22:40:15 +00:00
vid . recalc_refdef = 1 ;
2010-02-15 23:26:55 +00:00
vid . conwidth = ( scr_conwidth . value > 0 ) ? ( int ) scr_conwidth . value : ( scr_conscale . value > 0 ) ? ( int ) ( vid . width / scr_conscale . value ) : vid . width ;
vid . conwidth = CLAMP ( 320 , vid . conwidth , vid . width ) ;
vid . conwidth & = 0xFFFFFFF8 ;
vid . conheight = vid . conwidth * vid . height / vid . width ;
}
//============================================================================
/*
= = = = = = = = = = = = = = = = = =
SCR_LoadPics - - johnfitz
= = = = = = = = = = = = = = = = = =
*/
void SCR_LoadPics ( void )
{
scr_ram = Draw_PicFromWad ( " ram " ) ;
scr_net = Draw_PicFromWad ( " net " ) ;
scr_turtle = Draw_PicFromWad ( " turtle " ) ;
}
2014-10-11 19:11:40 +00:00
2010-02-15 23:26:55 +00:00
/*
= = = = = = = = = = = = = = = = = =
SCR_Init
= = = = = = = = = = = = = = = = = =
*/
void SCR_Init ( void )
{
//johnfitz -- new cvars
2011-12-28 22:01:33 +00:00
Cvar_RegisterVariable ( & scr_menuscale ) ;
Cvar_RegisterVariable ( & scr_sbarscale ) ;
2012-09-10 06:55:29 +00:00
Cvar_SetCallback ( & scr_sbaralpha , SCR_Callback_refdef ) ;
2011-12-28 22:01:33 +00:00
Cvar_RegisterVariable ( & scr_sbaralpha ) ;
Cvar_SetCallback ( & scr_conwidth , & SCR_Conwidth_f ) ;
Cvar_SetCallback ( & scr_conscale , & SCR_Conwidth_f ) ;
2011-12-28 22:40:15 +00:00
Cvar_RegisterVariable ( & scr_conwidth ) ;
Cvar_RegisterVariable ( & scr_conscale ) ;
2011-12-28 22:01:33 +00:00
Cvar_RegisterVariable ( & scr_crosshairscale ) ;
Cvar_RegisterVariable ( & scr_showfps ) ;
Cvar_RegisterVariable ( & scr_clock ) ;
2010-02-15 23:26:55 +00:00
//johnfitz
2011-12-28 22:40:15 +00:00
Cvar_SetCallback ( & scr_fov , SCR_Callback_refdef ) ;
2013-01-31 20:03:23 +00:00
Cvar_SetCallback ( & scr_fov_adapt , SCR_Callback_refdef ) ;
2011-12-28 22:40:15 +00:00
Cvar_SetCallback ( & scr_viewsize , SCR_Callback_refdef ) ;
2011-12-28 22:01:33 +00:00
Cvar_RegisterVariable ( & scr_fov ) ;
2013-01-31 20:03:23 +00:00
Cvar_RegisterVariable ( & scr_fov_adapt ) ;
2011-12-28 22:01:33 +00:00
Cvar_RegisterVariable ( & scr_viewsize ) ;
Cvar_RegisterVariable ( & scr_conspeed ) ;
Cvar_RegisterVariable ( & scr_showram ) ;
Cvar_RegisterVariable ( & scr_showturtle ) ;
Cvar_RegisterVariable ( & scr_showpause ) ;
Cvar_RegisterVariable ( & scr_centertime ) ;
Cvar_RegisterVariable ( & scr_printspeed ) ;
Cvar_RegisterVariable ( & gl_triplebuffer ) ;
2010-02-15 23:26:55 +00:00
Cmd_AddCommand ( " screenshot " , SCR_ScreenShot_f ) ;
Cmd_AddCommand ( " sizeup " , SCR_SizeUp_f ) ;
Cmd_AddCommand ( " sizedown " , SCR_SizeDown_f ) ;
SCR_LoadPics ( ) ; //johnfitz
scr_initialized = true ;
}
//============================================================================
/*
= = = = = = = = = = = = = =
SCR_DrawFPS - - johnfitz
= = = = = = = = = = = = = =
*/
void SCR_DrawFPS ( void )
{
2012-01-20 17:11:24 +00:00
static double oldtime = 0 ;
static double lastfps = 0 ;
static int oldframecount = 0 ;
double elapsed_time ;
int frames ;
2010-02-15 23:26:55 +00:00
2012-01-20 17:11:24 +00:00
elapsed_time = realtime - oldtime ;
2010-02-15 23:26:55 +00:00
frames = r_framecount - oldframecount ;
2012-01-20 17:11:24 +00:00
if ( elapsed_time < 0 | | frames < 0 )
2010-02-15 23:26:55 +00:00
{
oldtime = realtime ;
oldframecount = r_framecount ;
return ;
}
2012-01-20 17:11:24 +00:00
// update value every 3/4 second
if ( elapsed_time > 0.75 )
2010-02-15 23:26:55 +00:00
{
2012-01-20 17:11:24 +00:00
lastfps = frames / elapsed_time ;
2010-02-15 23:26:55 +00:00
oldtime = realtime ;
oldframecount = r_framecount ;
}
2012-01-20 17:11:24 +00:00
if ( scr_showfps . value )
2010-02-15 23:26:55 +00:00
{
2012-01-20 17:11:24 +00:00
char st [ 16 ] ;
int x , y ;
sprintf ( st , " %4.0f fps " , lastfps ) ;
x = 320 - ( strlen ( st ) < < 3 ) ;
2010-02-15 23:26:55 +00:00
y = 200 - 8 ;
if ( scr_clock . value ) y - = 8 ; //make room for clock
GL_SetCanvas ( CANVAS_BOTTOMRIGHT ) ;
2012-01-20 17:11:24 +00:00
Draw_String ( x , y , st ) ;
2010-02-15 23:26:55 +00:00
scr_tileclear_updates = 0 ;
}
}
/*
= = = = = = = = = = = = = =
SCR_DrawClock - - johnfitz
= = = = = = = = = = = = = =
*/
void SCR_DrawClock ( void )
{
2011-12-27 10:50:42 +00:00
char str [ 12 ] ;
2010-02-15 23:26:55 +00:00
if ( scr_clock . value = = 1 )
{
int minutes , seconds ;
minutes = cl . time / 60 ;
seconds = ( ( int ) cl . time ) % 60 ;
sprintf ( str , " %i:%i%i " , minutes , seconds / 10 , seconds % 10 ) ;
}
else
return ;
//draw it
GL_SetCanvas ( CANVAS_BOTTOMRIGHT ) ;
Draw_String ( 320 - ( strlen ( str ) < < 3 ) , 200 - 8 , str ) ;
scr_tileclear_updates = 0 ;
}
/*
= = = = = = = = = = = = = =
SCR_DrawDevStats
= = = = = = = = = = = = = =
*/
void SCR_DrawDevStats ( void )
{
char str [ 40 ] ;
int y = 25 - 9 ; //9=number of lines to print
int x = 0 ; //margin
if ( ! devstats . value )
return ;
GL_SetCanvas ( CANVAS_BOTTOMLEFT ) ;
Draw_Fill ( x , y * 8 , 19 * 8 , 9 * 8 , 0 , 0.5 ) ; //dark rectangle
sprintf ( str , " devstats |Curr Peak " ) ;
Draw_String ( x , ( y + + ) * 8 - x , str ) ;
sprintf ( str , " ---------+--------- " ) ;
Draw_String ( x , ( y + + ) * 8 - x , str ) ;
sprintf ( str , " Edicts |%4i %4i " , dev_stats . edicts , dev_peakstats . edicts ) ;
Draw_String ( x , ( y + + ) * 8 - x , str ) ;
sprintf ( str , " Packet |%4i %4i " , dev_stats . packetsize , dev_peakstats . packetsize ) ;
Draw_String ( x , ( y + + ) * 8 - x , str ) ;
sprintf ( str , " Visedicts|%4i %4i " , dev_stats . visedicts , dev_peakstats . visedicts ) ;
Draw_String ( x , ( y + + ) * 8 - x , str ) ;
sprintf ( str , " Efrags |%4i %4i " , dev_stats . efrags , dev_peakstats . efrags ) ;
Draw_String ( x , ( y + + ) * 8 - x , str ) ;
sprintf ( str , " Dlights |%4i %4i " , dev_stats . dlights , dev_peakstats . dlights ) ;
Draw_String ( x , ( y + + ) * 8 - x , str ) ;
sprintf ( str , " Beams |%4i %4i " , dev_stats . beams , dev_peakstats . beams ) ;
Draw_String ( x , ( y + + ) * 8 - x , str ) ;
sprintf ( str , " Tempents |%4i %4i " , dev_stats . tempents , dev_peakstats . tempents ) ;
Draw_String ( x , ( y + + ) * 8 - x , str ) ;
}
/*
= = = = = = = = = = = = = =
SCR_DrawRam
= = = = = = = = = = = = = =
*/
void SCR_DrawRam ( void )
{
if ( ! scr_showram . value )
return ;
if ( ! r_cache_thrash )
return ;
GL_SetCanvas ( CANVAS_DEFAULT ) ; //johnfitz
Draw_Pic ( scr_vrect . x + 32 , scr_vrect . y , scr_ram ) ;
}
/*
= = = = = = = = = = = = = =
SCR_DrawTurtle
= = = = = = = = = = = = = =
*/
void SCR_DrawTurtle ( void )
{
static int count ;
if ( ! scr_showturtle . value )
return ;
if ( host_frametime < 0.1 )
{
count = 0 ;
return ;
}
count + + ;
if ( count < 3 )
return ;
GL_SetCanvas ( CANVAS_DEFAULT ) ; //johnfitz
Draw_Pic ( scr_vrect . x , scr_vrect . y , scr_turtle ) ;
}
/*
= = = = = = = = = = = = = =
SCR_DrawNet
= = = = = = = = = = = = = =
*/
void SCR_DrawNet ( void )
{
if ( realtime - cl . last_received_message < 0.3 )
return ;
if ( cls . demoplayback )
return ;
GL_SetCanvas ( CANVAS_DEFAULT ) ; //johnfitz
Draw_Pic ( scr_vrect . x + 64 , scr_vrect . y , scr_net ) ;
}
/*
= = = = = = = = = = = = = =
DrawPause
= = = = = = = = = = = = = =
*/
void SCR_DrawPause ( void )
{
qpic_t * pic ;
if ( ! cl . paused )
return ;
if ( ! scr_showpause . value ) // turn off for screenshots
return ;
GL_SetCanvas ( CANVAS_MENU ) ; //johnfitz
pic = Draw_CachePic ( " gfx/pause.lmp " ) ;
Draw_Pic ( ( 320 - pic - > width ) / 2 , ( 240 - 48 - pic - > height ) / 2 , pic ) ; //johnfitz -- stretched menus
scr_tileclear_updates = 0 ; //johnfitz
}
/*
= = = = = = = = = = = = = =
SCR_DrawLoading
= = = = = = = = = = = = = =
*/
void SCR_DrawLoading ( void )
{
qpic_t * pic ;
if ( ! scr_drawloading )
return ;
GL_SetCanvas ( CANVAS_MENU ) ; //johnfitz
pic = Draw_CachePic ( " gfx/loading.lmp " ) ;
Draw_Pic ( ( 320 - pic - > width ) / 2 , ( 240 - 48 - pic - > height ) / 2 , pic ) ; //johnfitz -- stretched menus
scr_tileclear_updates = 0 ; //johnfitz
}
/*
= = = = = = = = = = = = = =
SCR_DrawCrosshair - - johnfitz
= = = = = = = = = = = = = =
*/
void SCR_DrawCrosshair ( void )
{
if ( ! crosshair . value )
return ;
GL_SetCanvas ( CANVAS_CROSSHAIR ) ;
Draw_Character ( - 4 , - 4 , ' + ' ) ; //0,0 is center of viewport
}
//=============================================================================
/*
= = = = = = = = = = = = = = = = = =
SCR_SetUpToDrawConsole
= = = = = = = = = = = = = = = = = =
*/
void SCR_SetUpToDrawConsole ( void )
{
//johnfitz -- let's hack away the problem of slow console when host_timescale is <0
extern cvar_t host_timescale ;
float timescale ;
//johnfitz
Con_CheckResize ( ) ;
if ( scr_drawloading )
return ; // never a console with loading plaque
// decide on the height of the console
con_forcedup = ! cl . worldmodel | | cls . signon ! = SIGNONS ;
if ( con_forcedup )
{
scr_conlines = glheight ; //full screen //johnfitz -- glheight instead of vid.height
scr_con_current = scr_conlines ;
}
else if ( key_dest = = key_console )
scr_conlines = glheight / 2 ; //half screen //johnfitz -- glheight instead of vid.height
else
scr_conlines = 0 ; //none visible
timescale = ( host_timescale . value > 0 ) ? host_timescale . value : 1 ; //johnfitz -- timescale
if ( scr_conlines < scr_con_current )
{
2014-09-08 06:25:59 +00:00
// ericw -- (glheight/600.0) factor makes conspeed resolution independent, using 800x600 as a baseline
scr_con_current - = scr_conspeed . value * ( glheight / 600.0 ) * host_frametime / timescale ; //johnfitz -- timescale
2010-02-15 23:26:55 +00:00
if ( scr_conlines > scr_con_current )
scr_con_current = scr_conlines ;
}
else if ( scr_conlines > scr_con_current )
{
2014-09-08 06:25:59 +00:00
// ericw -- (glheight/600.0)
scr_con_current + = scr_conspeed . value * ( glheight / 600.0 ) * host_frametime / timescale ; //johnfitz -- timescale
2010-02-15 23:26:55 +00:00
if ( scr_conlines < scr_con_current )
scr_con_current = scr_conlines ;
}
if ( clearconsole + + < vid . numpages )
Sbar_Changed ( ) ;
if ( ! con_forcedup & & scr_con_current )
scr_tileclear_updates = 0 ; //johnfitz
}
/*
= = = = = = = = = = = = = = = = = =
SCR_DrawConsole
= = = = = = = = = = = = = = = = = =
*/
void SCR_DrawConsole ( void )
{
if ( scr_con_current )
{
Con_DrawConsole ( scr_con_current , true ) ;
clearconsole = 0 ;
}
else
{
if ( key_dest = = key_game | | key_dest = = key_message )
Con_DrawNotify ( ) ; // only draw notify in game
}
}
/*
= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
2014-10-11 19:11:40 +00:00
SCREEN SHOTS
2010-02-15 23:26:55 +00:00
= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
*/
2017-08-08 05:07:56 +00:00
static void SCR_ScreenShot_Usage ( void )
{
Con_Printf ( " usage: screenshot <format> <quality> \n " ) ;
Con_Printf ( " format must be \" png \" or \" tga \" or \" jpg \" \n " ) ;
Con_Printf ( " quality must be 1-100 \n " ) ;
return ;
}
2010-02-15 23:26:55 +00:00
/*
= = = = = = = = = = = = = = = = = =
SCR_ScreenShot_f - - johnfitz - - rewritten to use Image_WriteTGA
= = = = = = = = = = = = = = = = = =
*/
void SCR_ScreenShot_f ( void )
{
byte * buffer ;
2017-08-08 05:07:56 +00:00
char ext [ 4 ] ;
char imagename [ 16 ] ; //johnfitz -- was [80]
2010-02-15 23:26:55 +00:00
char checkname [ MAX_OSPATH ] ;
2017-08-08 05:07:56 +00:00
int i , quality ;
qboolean ok ;
Q_strncpy ( ext , " png " , sizeof ( ext ) ) ;
2010-02-15 23:26:55 +00:00
2017-08-08 05:07:56 +00:00
if ( Cmd_Argc ( ) > = 2 )
{
const char * requested_ext = Cmd_Argv ( 1 ) ;
if ( ! q_strcasecmp ( " png " , requested_ext )
| | ! q_strcasecmp ( " tga " , requested_ext )
| | ! q_strcasecmp ( " jpg " , requested_ext ) )
Q_strncpy ( ext , requested_ext , sizeof ( ext ) ) ;
else
{
SCR_ScreenShot_Usage ( ) ;
return ;
}
}
// read quality as the 3rd param (only used for JPG)
quality = 90 ;
if ( Cmd_Argc ( ) > = 3 )
quality = Q_atoi ( Cmd_Argv ( 2 ) ) ;
if ( quality < 1 | | quality > 100 )
{
SCR_ScreenShot_Usage ( ) ;
return ;
}
2010-02-15 23:26:55 +00:00
// find a file name to save it to
for ( i = 0 ; i < 10000 ; i + + )
{
2017-08-08 05:07:56 +00:00
q_snprintf ( imagename , sizeof ( imagename ) , " spasm%04i.%s " , i , ext ) ; // "fitz%04i.tga"
q_snprintf ( checkname , sizeof ( checkname ) , " %s/%s " , com_gamedir , imagename ) ;
2010-02-15 23:26:55 +00:00
if ( Sys_FileTime ( checkname ) = = - 1 )
break ; // file doesn't exist
}
if ( i = = 10000 )
{
Con_Printf ( " SCR_ScreenShot_f: Couldn't find an unused filename \n " ) ;
return ;
2014-04-28 08:12:42 +00:00
}
2010-02-15 23:26:55 +00:00
//get data
2014-04-28 08:12:42 +00:00
if ( ! ( buffer = ( byte * ) malloc ( glwidth * glheight * 3 ) ) )
{
Con_Printf ( " SCR_ScreenShot_f: Couldn't allocate memory \n " ) ;
return ;
}
2014-04-28 20:10:34 +00:00
2014-04-28 08:12:42 +00:00
glPixelStorei ( GL_PACK_ALIGNMENT , 1 ) ; /* for widths that aren't a multiple of 4 */
2010-02-15 23:26:55 +00:00
glReadPixels ( glx , gly , glwidth , glheight , GL_RGB , GL_UNSIGNED_BYTE , buffer ) ;
// now write the file
2017-08-08 05:07:56 +00:00
if ( ! q_strncasecmp ( ext , " png " , sizeof ( ext ) ) )
ok = Image_WritePNG ( imagename , buffer , glwidth , glheight , 24 , false ) ;
else if ( ! q_strncasecmp ( ext , " tga " , sizeof ( ext ) ) )
ok = Image_WriteTGA ( imagename , buffer , glwidth , glheight , 24 , false ) ;
else if ( ! q_strncasecmp ( ext , " jpg " , sizeof ( ext ) ) )
ok = Image_WriteJPG ( imagename , buffer , glwidth , glheight , 24 , quality , false ) ;
else
ok = false ;
if ( ok )
Con_Printf ( " Wrote %s \n " , imagename ) ;
2010-02-15 23:26:55 +00:00
else
2017-08-08 05:07:56 +00:00
Con_Printf ( " SCR_ScreenShot_f: Couldn't create %s \n " , imagename ) ;
2010-02-15 23:26:55 +00:00
free ( buffer ) ;
}
//=============================================================================
/*
= = = = = = = = = = = = = = =
SCR_BeginLoadingPlaque
= = = = = = = = = = = = = = = =
*/
void SCR_BeginLoadingPlaque ( void )
{
S_StopAllSounds ( true ) ;
if ( cls . state ! = ca_connected )
return ;
if ( cls . signon ! = SIGNONS )
return ;
// redraw with no console and the loading plaque
Con_ClearNotify ( ) ;
scr_centertime_off = 0 ;
scr_con_current = 0 ;
scr_drawloading = true ;
Sbar_Changed ( ) ;
SCR_UpdateScreen ( ) ;
scr_drawloading = false ;
scr_disabled_for_loading = true ;
scr_disabled_time = realtime ;
}
/*
= = = = = = = = = = = = = = =
SCR_EndLoadingPlaque
= = = = = = = = = = = = = = = =
*/
void SCR_EndLoadingPlaque ( void )
{
scr_disabled_for_loading = false ;
Con_ClearNotify ( ) ;
}
//=============================================================================
2010-08-29 02:22:55 +00:00
const char * scr_notifystring ;
2010-02-15 23:26:55 +00:00
qboolean scr_drawdialog ;
void SCR_DrawNotifyString ( void )
{
2010-08-29 02:22:55 +00:00
const char * start ;
2010-02-15 23:26:55 +00:00
int l ;
int j ;
int x , y ;
GL_SetCanvas ( CANVAS_MENU ) ; //johnfitz
start = scr_notifystring ;
y = 200 * 0.35 ; //johnfitz -- stretched overlays
do
{
// scan the width of the line
for ( l = 0 ; l < 40 ; l + + )
if ( start [ l ] = = ' \n ' | | ! start [ l ] )
break ;
x = ( 320 - l * 8 ) / 2 ; //johnfitz -- stretched overlays
for ( j = 0 ; j < l ; j + + , x + = 8 )
Draw_Character ( x , y , start [ j ] ) ;
y + = 8 ;
while ( * start & & * start ! = ' \n ' )
start + + ;
if ( ! * start )
break ;
start + + ; // skip the \n
} while ( 1 ) ;
}
/*
= = = = = = = = = = = = = = = = = =
SCR_ModalMessage
Displays a text string in the center of the screen and waits for a Y or N
keypress .
= = = = = = = = = = = = = = = = = =
*/
2010-08-29 02:22:55 +00:00
int SCR_ModalMessage ( const char * text , float timeout ) //johnfitz -- timeout
2010-02-15 23:26:55 +00:00
{
double time1 , time2 ; //johnfitz -- timeout
2014-10-02 19:00:42 +00:00
int lastkey , lastchar ;
2010-02-15 23:26:55 +00:00
if ( cls . state = = ca_dedicated )
return true ;
scr_notifystring = text ;
// draw a fresh screen
scr_drawdialog = true ;
SCR_UpdateScreen ( ) ;
scr_drawdialog = false ;
S_ClearBuffer ( ) ; // so dma doesn't loop current sound
2011-12-12 16:01:01 +00:00
time1 = Sys_DoubleTime ( ) + timeout ; //johnfitz -- timeout
2010-02-15 23:26:55 +00:00
time2 = 0.0f ; //johnfitz -- timeout
2014-10-02 19:00:42 +00:00
Key_BeginInputGrab ( ) ;
2010-02-15 23:26:55 +00:00
do
{
Sys_SendKeyEvents ( ) ;
2014-10-02 19:00:42 +00:00
Key_GetGrabbedInput ( & lastkey , & lastchar ) ;
Sys_Sleep ( 16 ) ;
2012-09-04 18:29:01 +00:00
if ( timeout ) time2 = Sys_DoubleTime ( ) ; //johnfitz -- zero timeout means wait forever.
2014-10-02 19:00:42 +00:00
} while ( lastchar ! = ' y ' & & lastchar ! = ' Y ' & &
2014-10-11 19:11:40 +00:00
lastchar ! = ' n ' & & lastchar ! = ' N ' & &
lastkey ! = K_ESCAPE & &
2016-03-01 21:58:08 +00:00
lastkey ! = K_ABUTTON & &
lastkey ! = K_BBUTTON & &
2014-10-11 19:11:40 +00:00
time2 < = time1 ) ;
2014-10-02 19:00:42 +00:00
Key_EndInputGrab ( ) ;
2012-01-19 19:09:23 +00:00
2010-02-15 23:26:55 +00:00
// SCR_UpdateScreen (); //johnfitz -- commented out
//johnfitz -- timeout
if ( time2 > time1 )
return false ;
//johnfitz
2016-03-01 21:58:08 +00:00
return ( lastchar = = ' y ' | | lastchar = = ' Y ' | | lastkey = = K_ABUTTON ) ;
2010-02-15 23:26:55 +00:00
}
//=============================================================================
//johnfitz -- deleted SCR_BringDownConsole
/*
= = = = = = = = = = = = = = = = = =
2014-10-11 19:11:40 +00:00
SCR_TileClear
johnfitz - - modified to use glwidth / glheight instead of vid . width / vid . height
also fixed the dimentions of right and top panels
also added scr_tileclear_updates
2010-02-15 23:26:55 +00:00
= = = = = = = = = = = = = = = = = =
*/
void SCR_TileClear ( void )
{
2015-06-15 21:17:45 +00:00
//ericw -- added check for glsl gamma. TODO: remove this ugly optimization?
if ( scr_tileclear_updates > = vid . numpages & & ! gl_clear . value & & ! ( gl_glsl_gamma_able & & vid_gamma . value ! = 1 ) )
2010-02-15 23:26:55 +00:00
return ;
scr_tileclear_updates + + ;
if ( r_refdef . vrect . x > 0 )
{
// left
Draw_TileClear ( 0 ,
0 ,
r_refdef . vrect . x ,
glheight - sb_lines ) ;
// right
Draw_TileClear ( r_refdef . vrect . x + r_refdef . vrect . width ,
0 ,
glwidth - r_refdef . vrect . x - r_refdef . vrect . width ,
glheight - sb_lines ) ;
}
if ( r_refdef . vrect . y > 0 )
{
// top
Draw_TileClear ( r_refdef . vrect . x ,
0 ,
r_refdef . vrect . width ,
r_refdef . vrect . y ) ;
// bottom
Draw_TileClear ( r_refdef . vrect . x ,
r_refdef . vrect . y + r_refdef . vrect . height ,
r_refdef . vrect . width ,
glheight - r_refdef . vrect . y - r_refdef . vrect . height - sb_lines ) ;
}
}
/*
= = = = = = = = = = = = = = = = = =
SCR_UpdateScreen
This is called every frame , and can also be called explicitly to flush
text to the screen .
WARNING : be very careful calling this from elsewhere , because the refresh
needs almost the entire 256 k of stack space !
= = = = = = = = = = = = = = = = = =
*/
void SCR_UpdateScreen ( void )
{
2012-01-20 17:11:24 +00:00
vid . numpages = ( gl_triplebuffer . value ) ? 3 : 2 ;
2010-02-15 23:26:55 +00:00
if ( scr_disabled_for_loading )
{
if ( realtime - scr_disabled_time > 60 )
{
scr_disabled_for_loading = false ;
Con_Printf ( " load failed. \n " ) ;
}
else
return ;
}
if ( ! scr_initialized | | ! con_initialized )
return ; // not initialized yet
GL_BeginRendering ( & glx , & gly , & glwidth , & glheight ) ;
//
// determine size of refresh window
//
if ( vid . recalc_refdef )
SCR_CalcRefdef ( ) ;
//
// do 3D refresh drawing, and then update the screen
//
SCR_SetUpToDrawConsole ( ) ;
V_RenderView ( ) ;
GL_Set2D ( ) ;
//FIXME: only call this when needed
SCR_TileClear ( ) ;
if ( scr_drawdialog ) //new game confirm
{
2013-03-02 09:34:18 +00:00
if ( con_forcedup )
Draw_ConsoleBackground ( ) ;
else
Sbar_Draw ( ) ;
2010-02-15 23:26:55 +00:00
Draw_FadeScreen ( ) ;
SCR_DrawNotifyString ( ) ;
}
else if ( scr_drawloading ) //loading
{
SCR_DrawLoading ( ) ;
Sbar_Draw ( ) ;
}
else if ( cl . intermission = = 1 & & key_dest = = key_game ) //end of level
{
Sbar_IntermissionOverlay ( ) ;
}
else if ( cl . intermission = = 2 & & key_dest = = key_game ) //end of episode
{
Sbar_FinaleOverlay ( ) ;
SCR_CheckDrawCenterString ( ) ;
}
else
{
SCR_DrawCrosshair ( ) ; //johnfitz
SCR_DrawRam ( ) ;
SCR_DrawNet ( ) ;
SCR_DrawTurtle ( ) ;
SCR_DrawPause ( ) ;
SCR_CheckDrawCenterString ( ) ;
Sbar_Draw ( ) ;
SCR_DrawDevStats ( ) ; //johnfitz
SCR_DrawFPS ( ) ; //johnfitz
SCR_DrawClock ( ) ; //johnfitz
SCR_DrawConsole ( ) ;
M_Draw ( ) ;
}
V_UpdateBlend ( ) ; //johnfitz -- V_UpdatePalette cleaned up and renamed
2015-01-26 20:18:45 +00:00
GLSLGamma_GammaCorrect ( ) ;
2010-02-15 23:26:55 +00:00
GL_EndRendering ( ) ;
}