2014-06-01 17:55:23 +00:00
/*
* This file is part of the DXX - Rebirth project < http : //www.dxx-rebirth.com/>.
* It is copyright by its individual contributors , as recorded in the
* project ' s Git history . See COPYING . txt at the top level for license
* terms and a link to the Git history .
*/
2006-03-20 17:12:09 +00:00
/*
*
* SDL video functions .
*
*/
2015-04-19 04:18:49 +00:00
# include <algorithm>
2006-03-20 17:12:09 +00:00
# include <stdlib.h>
# include <string.h>
2006-08-30 18:12:04 +00:00
# include <limits.h>
2008-03-20 23:23:46 +00:00
# include <math.h>
2013-06-30 02:22:56 +00:00
# include <SDL.h>
2006-03-20 17:12:09 +00:00
# include "gr.h"
# include "grdef.h"
# include "palette.h"
2015-07-25 23:10:45 +00:00
# include "game.h"
# include "console.h"
2006-03-20 17:12:09 +00:00
# include "u_mem.h"
2012-07-07 18:35:06 +00:00
# include "dxxerror.h"
2006-12-26 03:42:13 +00:00
# include "vers_id.h"
2008-02-24 14:41:27 +00:00
# include "gamefont.h"
2008-04-19 19:11:32 +00:00
# include "args.h"
2008-04-06 20:23:28 +00:00
# include "config.h"
2013-01-06 21:03:57 +00:00
# include "palette.h"
2006-03-20 17:12:09 +00:00
2014-11-30 22:09:19 +00:00
# include "compiler-make_unique.h"
2015-04-19 04:18:49 +00:00
using std : : min ;
2015-03-22 18:49:21 +00:00
static int sdl_video_flags = SDL_SWSURFACE | SDL_HWPALETTE | SDL_DOUBLEBUF ;
2010-01-29 21:53:17 +00:00
SDL_Surface * screen , * canvas ;
2015-03-22 18:49:21 +00:00
static int gr_installed ;
2006-03-20 17:12:09 +00:00
2008-03-20 23:23:46 +00:00
void gr_flip ( )
2006-03-20 17:12:09 +00:00
{
2010-01-29 21:53:17 +00:00
SDL_Rect src , dest ;
dest . x = src . x = dest . y = src . y = 0 ;
dest . w = src . w = canvas - > w ;
dest . h = src . h = canvas - > h ;
2010-06-24 09:29:11 +00:00
2010-01-29 21:53:17 +00:00
SDL_BlitSurface ( canvas , & src , screen , & dest ) ;
2008-02-24 14:41:27 +00:00
SDL_Flip ( screen ) ;
2006-03-20 17:12:09 +00:00
}
2010-06-24 09:29:11 +00:00
// returns possible (fullscreen) resolutions if any.
2015-05-14 02:23:13 +00:00
uint_fast32_t gr_list_modes ( array < screen_mode , 50 > & gsmodes )
2010-06-24 09:29:11 +00:00
{
SDL_Rect * * modes ;
2014-09-26 02:42:13 +00:00
int modesnum = 0 ;
2010-06-24 09:29:11 +00:00
int sdl_check_flags = sdl_video_flags ;
sdl_check_flags | = SDL_FULLSCREEN ; // always use Fullscreen as lead.
modes = SDL_ListModes ( NULL , sdl_check_flags ) ;
if ( modes = = ( SDL_Rect * * ) 0 ) // check if we get any modes - if not, return 0
return 0 ;
if ( modes = = ( SDL_Rect * * ) - 1 )
{
return 0 ; // can obviously use any resolution... strange!
}
else
{
2014-09-26 02:42:13 +00:00
for ( int i = 0 ; modes [ i ] ; + + i )
2010-06-24 09:29:11 +00:00
{
2010-07-25 00:49:33 +00:00
if ( modes [ i ] - > w > 0xFFF0 | | modes [ i ] - > h > 0xFFF0 // resolutions saved in 32bits. so skip bigger ones (unrealistic in 2010) (kreatordxx - made 0xFFF0 to kill warning)
2010-06-24 09:29:11 +00:00
| | modes [ i ] - > w < 320 | | modes [ i ] - > h < 200 ) // also skip everything smaller than 320x200
continue ;
2015-05-14 02:23:13 +00:00
gsmodes [ modesnum ] . width = modes [ i ] - > w ;
gsmodes [ modesnum ] . height = modes [ i ] - > h ;
2010-06-24 09:29:11 +00:00
modesnum + + ;
2015-05-14 02:23:13 +00:00
if ( modesnum > = gsmodes . size ( ) ) // that really seems to be enough big boy.
2010-06-24 09:29:11 +00:00
break ;
}
return modesnum ;
}
}
2015-05-14 02:23:13 +00:00
int gr_set_mode ( screen_mode mode )
2006-03-20 17:12:09 +00:00
{
2008-04-19 19:11:32 +00:00
screen = NULL ;
2013-03-03 01:03:33 +00:00
SDL_WM_SetCaption ( DESCENT_VERSION , DXX_SDL_WINDOW_CAPTION ) ;
SDL_WM_SetIcon ( SDL_LoadBMP ( DXX_SDL_WINDOW_ICON_BITMAP ) , NULL ) ;
2006-03-20 17:12:09 +00:00
2015-03-22 18:49:21 +00:00
const auto sdl_video_flags = : : sdl_video_flags ;
2015-05-14 02:23:13 +00:00
if ( SDL_VideoModeOK ( SM_W ( mode ) , SM_H ( mode ) , GameArg . DbgBpp , sdl_video_flags ) )
2006-03-20 17:12:09 +00:00
{
2008-04-19 19:11:32 +00:00
}
else
{
2015-05-14 02:23:13 +00:00
con_printf ( CON_URGENT , " Cannot set %hux%hu. Fallback to 640x480 " , SM_W ( mode ) , SM_H ( mode ) ) ;
mode . width = 640 ;
mode . height = 480 ;
Game_screen_mode = mode ;
2006-03-20 17:12:09 +00:00
}
2015-05-14 02:23:13 +00:00
const unsigned w = SM_W ( mode ) , h = SM_H ( mode ) ;
screen = SDL_SetVideoMode ( w , h , GameArg . DbgBpp , sdl_video_flags ) ;
2006-03-20 17:12:09 +00:00
2008-04-19 19:11:32 +00:00
if ( screen = = NULL )
{
2010-01-29 21:53:17 +00:00
Error ( " Could not set %dx%dx%d video mode \n " , w , h , GameArg . DbgBpp ) ;
exit ( 1 ) ;
}
canvas = SDL_CreateRGBSurface ( sdl_video_flags , w , h , 8 , 0 , 0 , 0 , 0 ) ;
if ( canvas = = NULL )
{
Error ( " Could not create canvas surface \n " ) ;
2008-04-19 19:11:32 +00:00
exit ( 1 ) ;
}
2006-03-20 17:12:09 +00:00
2014-07-04 03:47:03 +00:00
* grd_curscreen = { } ;
2015-03-22 18:49:21 +00:00
grd_curscreen - > set_screen_width_height ( w , h ) ;
grd_curscreen - > sc_aspect = fixdiv ( grd_curscreen - > get_screen_width ( ) * GameCfg . AspectX , grd_curscreen - > get_screen_height ( ) * GameCfg . AspectY ) ;
2015-01-17 18:31:40 +00:00
gr_init_canvas ( grd_curscreen - > sc_canvas , reinterpret_cast < unsigned char * > ( canvas - > pixels ) , BM_LINEAR , w , h ) ;
2012-03-24 06:43:45 +00:00
window_update_canvases ( ) ;
2006-03-20 17:12:09 +00:00
gr_set_current_canvas ( NULL ) ;
SDL_ShowCursor ( 0 ) ;
2008-02-24 14:41:27 +00:00
gamefont_choose_game_font ( w , h ) ;
2008-03-20 23:23:46 +00:00
gr_palette_load ( gr_palette ) ;
2008-04-06 20:23:28 +00:00
gr_remap_color_fonts ( ) ;
gr_remap_mono_fonts ( ) ;
2008-02-24 14:41:27 +00:00
2006-03-20 17:12:09 +00:00
return 0 ;
}
2008-04-19 19:11:32 +00:00
int gr_check_fullscreen ( void )
{
2006-03-20 17:12:09 +00:00
return ( sdl_video_flags & SDL_FULLSCREEN ) ? 1 : 0 ;
}
2015-03-22 18:49:21 +00:00
void gr_toggle_fullscreen ( )
2008-04-19 19:11:32 +00:00
{
2015-03-22 18:49:21 +00:00
const auto sdl_video_flags = ( : : sdl_video_flags ^ = SDL_FULLSCREEN ) ;
const int WindowMode = ! ( sdl_video_flags & SDL_FULLSCREEN ) ;
2008-04-06 20:23:28 +00:00
gr_remap_color_fonts ( ) ;
gr_remap_mono_fonts ( ) ;
2006-03-20 17:12:09 +00:00
SDL_WM_ToggleFullScreen ( screen ) ;
2015-03-22 18:49:21 +00:00
GameCfg . WindowMode = WindowMode ;
2006-03-20 17:12:09 +00:00
}
2008-04-22 08:29:29 +00:00
void gr_set_attributes ( void )
{
}
2015-05-14 02:23:13 +00:00
int gr_init ( )
2006-03-20 17:12:09 +00:00
{
2009-11-17 14:27:39 +00:00
// Only do this function once!
2006-03-20 17:12:09 +00:00
if ( gr_installed = = 1 )
return - 1 ;
if ( SDL_Init ( SDL_INIT_VIDEO ) < 0 )
{
Error ( " SDL library video initialisation failed: %s. " , SDL_GetError ( ) ) ;
}
2008-04-19 19:11:32 +00:00
2014-11-30 22:09:19 +00:00
grd_curscreen = make_unique < grs_screen , grs_screen > ( { } ) ;
2006-03-20 17:12:09 +00:00
2008-04-06 20:23:28 +00:00
if ( ! GameCfg . WindowMode & & ! GameArg . SysWindow )
2008-04-19 19:11:32 +00:00
sdl_video_flags | = SDL_FULLSCREEN ;
2007-07-15 21:22:07 +00:00
2011-02-10 14:30:08 +00:00
if ( GameArg . SysNoBorders )
sdl_video_flags | = SDL_NOFRAME ;
2007-07-23 18:13:49 +00:00
if ( GameArg . DbgSdlHWSurface )
2008-04-19 19:11:32 +00:00
sdl_video_flags | = SDL_HWSURFACE ;
2006-03-20 17:12:09 +00:00
2008-10-28 17:04:35 +00:00
if ( GameArg . DbgSdlASyncBlit )
sdl_video_flags | = SDL_ASYNCBLIT ;
2007-02-09 12:38:21 +00:00
// Set the mode.
2006-03-20 17:12:09 +00:00
grd_curscreen - > sc_canvas . cv_color = 0 ;
2011-02-23 16:46:39 +00:00
grd_curscreen - > sc_canvas . cv_fade_level = GR_FADE_OFF ;
grd_curscreen - > sc_canvas . cv_blend_func = GR_BLEND_NORMAL ;
2006-03-20 17:12:09 +00:00
grd_curscreen - > sc_canvas . cv_drawmode = 0 ;
grd_curscreen - > sc_canvas . cv_font = NULL ;
grd_curscreen - > sc_canvas . cv_font_fg_color = 0 ;
grd_curscreen - > sc_canvas . cv_font_bg_color = 0 ;
gr_set_current_canvas ( & grd_curscreen - > sc_canvas ) ;
gr_installed = 1 ;
return 0 ;
}
void gr_close ( )
{
if ( gr_installed = = 1 )
{
gr_installed = 0 ;
2014-11-30 22:09:19 +00:00
grd_curscreen . reset ( ) ;
2008-04-19 19:11:32 +00:00
SDL_ShowCursor ( 1 ) ;
2010-01-29 21:53:17 +00:00
SDL_FreeSurface ( canvas ) ;
2006-03-20 17:12:09 +00:00
}
}
// Palette functions follow.
static int last_r = 0 , last_g = 0 , last_b = 0 ;
2008-04-19 19:11:32 +00:00
void gr_palette_step_up ( int r , int g , int b )
{
2013-01-06 21:03:57 +00:00
palette_array_t & p = gr_palette ;
2008-04-19 19:11:32 +00:00
int temp ;
SDL_Palette * palette ;
2015-04-19 04:18:49 +00:00
array < SDL_Color , 256 > colors ;
2010-06-24 09:29:11 +00:00
2008-04-19 19:11:32 +00:00
if ( ( r = = last_r ) & & ( g = = last_g ) & & ( b = = last_b ) )
return ;
last_r = r ;
last_g = g ;
last_b = b ;
2006-03-20 17:12:09 +00:00
2010-01-29 21:53:17 +00:00
palette = canvas - > format - > palette ;
2006-03-20 17:12:09 +00:00
2008-04-19 19:11:32 +00:00
if ( palette = = NULL )
return ; // Display is not palettised
2006-03-20 17:12:09 +00:00
2014-09-26 02:42:13 +00:00
for ( int i = 0 ; i < 256 ; i + + )
2008-04-19 19:11:32 +00:00
{
2013-01-06 21:11:53 +00:00
temp = ( int ) ( p [ i ] . r ) + r + gr_palette_gamma ;
2008-04-19 19:11:32 +00:00
if ( temp < 0 )
temp = 0 ;
else if ( temp > 63 )
temp = 63 ;
colors [ i ] . r = temp * 4 ;
2013-01-06 21:11:53 +00:00
temp = ( int ) ( p [ i ] . g ) + g + gr_palette_gamma ;
2008-04-19 19:11:32 +00:00
if ( temp < 0 )
temp = 0 ;
else if ( temp > 63 )
temp = 63 ;
colors [ i ] . g = temp * 4 ;
2013-01-06 21:11:53 +00:00
temp = ( int ) ( p [ i ] . b ) + b + gr_palette_gamma ;
2008-04-19 19:11:32 +00:00
if ( temp < 0 )
temp = 0 ;
else if ( temp > 63 )
temp = 63 ;
colors [ i ] . b = temp * 4 ;
}
2015-04-19 04:18:49 +00:00
SDL_SetColors ( canvas , colors . data ( ) , 0 , colors . size ( ) ) ;
2006-03-20 17:12:09 +00:00
}
2013-01-06 21:03:57 +00:00
void gr_palette_load ( palette_array_t & pal )
2006-03-20 17:12:09 +00:00
{
2008-04-19 19:11:32 +00:00
SDL_Palette * palette ;
2015-04-19 04:18:49 +00:00
array < SDL_Color , 256 > colors ;
array < uint8_t , 64 > gamma ;
2008-04-19 19:11:32 +00:00
2013-01-06 21:11:53 +00:00
if ( pal ! = gr_current_pal )
2010-01-29 21:53:17 +00:00
SDL_FillRect ( canvas , NULL , SDL_MapRGB ( canvas - > format , 0 , 0 , 0 ) ) ;
2008-04-19 19:11:32 +00:00
2013-12-17 22:14:43 +00:00
copy_bound_palette ( gr_current_pal , pal ) ;
2009-11-17 14:27:39 +00:00
2010-01-29 21:53:17 +00:00
if ( canvas = = NULL )
2008-04-19 19:11:32 +00:00
return ;
2010-01-29 21:53:17 +00:00
palette = canvas - > format - > palette ;
2009-11-17 14:27:39 +00:00
2008-04-19 19:11:32 +00:00
if ( palette = = NULL )
return ; // Display is not palettised
2009-11-17 14:27:39 +00:00
2014-09-26 02:42:13 +00:00
for ( int i = 0 ; i < 64 ; i + + )
2008-04-19 19:11:32 +00:00
gamma [ i ] = ( int ) ( ( pow ( ( ( double ) ( 14 ) / ( double ) ( 32 ) ) , 1.0 ) * i ) + 0.5 ) ;
2009-11-17 14:27:39 +00:00
2014-11-11 04:21:57 +00:00
for ( int i = 0 , j = 0 ; j < 256 ; j + + )
2008-04-19 19:11:32 +00:00
{
int c ;
2013-01-06 21:11:53 +00:00
c = gr_find_closest_color ( gamma [ gr_palette [ j ] . r ] , gamma [ gr_palette [ j ] . g ] , gamma [ gr_palette [ j ] . b ] ) ;
2014-08-20 02:15:23 +00:00
gr_fade_table [ 14 ] [ j ] = c ;
2013-01-06 21:11:53 +00:00
colors [ j ] . r = ( min ( gr_current_pal [ i ] . r + gr_palette_gamma , 63 ) ) * 4 ;
colors [ j ] . g = ( min ( gr_current_pal [ i ] . g + gr_palette_gamma , 63 ) ) * 4 ;
colors [ j ] . b = ( min ( gr_current_pal [ i ] . b + gr_palette_gamma , 63 ) ) * 4 ;
i + + ;
2008-04-19 19:11:32 +00:00
}
2009-11-17 14:27:39 +00:00
2015-04-19 04:18:49 +00:00
SDL_SetColors ( canvas , colors . data ( ) , 0 , colors . size ( ) ) ;
2008-04-19 19:11:32 +00:00
init_computed_colors ( ) ;
2008-04-06 20:23:28 +00:00
gr_remap_color_fonts ( ) ;
gr_remap_mono_fonts ( ) ;
2006-03-20 17:12:09 +00:00
}
2013-01-06 21:03:57 +00:00
void gr_palette_read ( palette_array_t & pal )
2006-03-20 17:12:09 +00:00
{
2008-04-19 19:11:32 +00:00
SDL_Palette * palette ;
2013-01-06 21:11:53 +00:00
unsigned i ;
2009-11-17 14:27:39 +00:00
2010-01-29 21:53:17 +00:00
palette = canvas - > format - > palette ;
2009-11-17 14:27:39 +00:00
2008-04-19 19:11:32 +00:00
if ( palette = = NULL )
return ; // Display is not palettised
2006-03-20 17:12:09 +00:00
2013-01-06 21:11:53 +00:00
for ( i = 0 ; i < 256 ; i + + )
2008-04-19 19:11:32 +00:00
{
2013-01-06 21:11:53 +00:00
pal [ i ] . r = palette - > colors [ i ] . r / 4 ;
pal [ i ] . g = palette - > colors [ i ] . g / 4 ;
pal [ i ] . b = palette - > colors [ i ] . b / 4 ;
2008-04-19 19:11:32 +00:00
}
2006-03-20 17:12:09 +00:00
}