2006-03-20 17:12:09 +00:00
/*
*
* SDL video functions .
*
*/
# 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"
# 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"
2006-03-20 17:12:09 +00:00
2008-02-24 14:41:27 +00:00
int sdl_video_flags = SDL_SWSURFACE | SDL_HWPALETTE | SDL_DOUBLEBUF ;
2010-01-29 21:53:17 +00:00
SDL_Surface * screen , * canvas ;
2006-03-20 17:12:09 +00:00
int gr_installed = 0 ;
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
}
2007-03-21 11:32:33 +00:00
// Set the buffer to draw to. 0 is front, 1 is back
// With SDL, can't use it without resetting the video mode
void gr_set_draw_buffer ( int buf )
{
buf = buf ;
}
2010-06-24 09:29:11 +00:00
// returns possible (fullscreen) resolutions if any.
int gr_list_modes ( u_int32_t gsmodes [ ] )
{
SDL_Rect * * modes ;
int i = 0 , modesnum = 0 ;
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
{
for ( i = 0 ; modes [ i ] ; + + i )
{
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 ;
gsmodes [ modesnum ] = SM ( modes [ i ] - > w , modes [ i ] - > h ) ;
modesnum + + ;
if ( modesnum > = 50 ) // that really seems to be enough big boy.
break ;
}
return modesnum ;
}
}
2009-11-17 14:27:39 +00:00
int gr_check_mode ( u_int32_t mode )
{
unsigned int w , h ;
w = SM_W ( mode ) ;
h = SM_H ( mode ) ;
2010-01-29 21:53:17 +00:00
return SDL_VideoModeOK ( w , h , GameArg . DbgBpp , sdl_video_flags ) ;
2009-11-17 14:27:39 +00:00
}
2006-03-20 17:12:09 +00:00
int gr_set_mode ( u_int32_t mode )
{
2006-10-08 23:19:46 +00:00
unsigned int w , h ;
2007-07-15 15:23:45 +00:00
2006-03-20 17:12:09 +00:00
if ( mode < = 0 )
return 0 ;
w = SM_W ( mode ) ;
h = SM_H ( mode ) ;
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
2010-01-29 21:53:17 +00:00
if ( SDL_VideoModeOK ( w , h , GameArg . DbgBpp , sdl_video_flags ) )
2006-03-20 17:12:09 +00:00
{
2010-01-29 21:53:17 +00:00
screen = SDL_SetVideoMode ( w , h , GameArg . DbgBpp , sdl_video_flags ) ;
2008-04-19 19:11:32 +00:00
}
else
{
con_printf ( CON_URGENT , " Cannot set %ix%i. Fallback to 640x480 \n " , w , h ) ;
w = 640 ;
h = 480 ;
Game_screen_mode = mode = SM ( w , h ) ;
2010-01-29 21:53:17 +00:00
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
2009-11-17 14:27:39 +00:00
memset ( grd_curscreen , 0 , sizeof ( grs_screen ) ) ;
2006-03-20 17:12:09 +00:00
grd_curscreen - > sc_mode = mode ;
grd_curscreen - > sc_w = w ;
grd_curscreen - > sc_h = h ;
2008-04-06 20:23:28 +00:00
grd_curscreen - > sc_aspect = fixdiv ( grd_curscreen - > sc_w * GameCfg . AspectX , grd_curscreen - > sc_h * GameCfg . AspectY ) ;
2012-11-11 22:12:51 +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 ;
}
2008-04-19 19:11:32 +00:00
int gr_toggle_fullscreen ( void )
{
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_video_flags ^ = SDL_FULLSCREEN ;
SDL_WM_ToggleFullScreen ( screen ) ;
2008-10-19 12:53:30 +00:00
GameCfg . WindowMode = ( sdl_video_flags & SDL_FULLSCREEN ) ? 0 : 1 ;
2006-03-20 17:12:09 +00:00
return ( sdl_video_flags & SDL_FULLSCREEN ) ? 1 : 0 ;
}
2008-04-22 08:29:29 +00:00
void gr_set_attributes ( void )
{
}
2007-02-09 12:38:21 +00:00
int gr_init ( int mode )
2006-03-20 17:12:09 +00:00
{
2007-02-19 14:02:28 +00:00
int retcode ;
2008-04-19 19:11:32 +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
2013-07-13 02:31:27 +00:00
CALLOC ( grd_curscreen , grs_screen , 1 ) ;
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.
if ( ( retcode = gr_set_mode ( mode ) ) )
return retcode ;
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 ;
d_free ( grd_curscreen ) ;
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 )
{
int i ;
ubyte * p = gr_palette ;
int temp ;
SDL_Palette * palette ;
SDL_Color colors [ 256 ] ;
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
2008-04-19 19:11:32 +00:00
for ( i = 0 ; i < 256 ; i + + )
{
temp = ( int ) ( * p + + ) + r + gr_palette_gamma ;
if ( temp < 0 )
temp = 0 ;
else if ( temp > 63 )
temp = 63 ;
colors [ i ] . r = temp * 4 ;
temp = ( int ) ( * p + + ) + g + gr_palette_gamma ;
if ( temp < 0 )
temp = 0 ;
else if ( temp > 63 )
temp = 63 ;
colors [ i ] . g = temp * 4 ;
temp = ( int ) ( * p + + ) + b + gr_palette_gamma ;
if ( temp < 0 )
temp = 0 ;
else if ( temp > 63 )
temp = 63 ;
colors [ i ] . b = temp * 4 ;
}
2010-01-29 21:53:17 +00:00
SDL_SetColors ( canvas , colors , 0 , 256 ) ;
2006-03-20 17:12:09 +00:00
}
# undef min
static inline int min ( int x , int y ) { return x < y ? x : y ; }
2010-06-24 09:29:11 +00:00
void gr_palette_load ( ubyte * pal )
2006-03-20 17:12:09 +00:00
{
2008-04-19 19:11:32 +00:00
int i , j ;
SDL_Palette * palette ;
SDL_Color colors [ 256 ] ;
ubyte gamma [ 64 ] ;
if ( memcmp ( pal , gr_current_pal , 768 ) )
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
for ( i = 0 ; i < 768 ; i + + )
{
gr_current_pal [ i ] = pal [ i ] ;
if ( gr_current_pal [ i ] > 63 )
gr_current_pal [ i ] = 63 ;
}
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
2008-04-19 19:11:32 +00:00
for ( i = 0 ; i < 64 ; i + + )
gamma [ i ] = ( int ) ( ( pow ( ( ( double ) ( 14 ) / ( double ) ( 32 ) ) , 1.0 ) * i ) + 0.5 ) ;
2009-11-17 14:27:39 +00:00
2008-04-19 19:11:32 +00:00
for ( i = 0 , j = 0 ; j < 256 ; j + + )
{
int c ;
c = gr_find_closest_color ( gamma [ gr_palette [ j * 3 ] ] , gamma [ gr_palette [ j * 3 + 1 ] ] , gamma [ gr_palette [ j * 3 + 2 ] ] ) ;
gr_fade_table [ 14 * 256 + j ] = c ;
colors [ j ] . r = ( min ( gr_current_pal [ i + + ] + gr_palette_gamma , 63 ) ) * 4 ;
colors [ j ] . g = ( min ( gr_current_pal [ i + + ] + gr_palette_gamma , 63 ) ) * 4 ;
colors [ j ] . b = ( min ( gr_current_pal [ i + + ] + gr_palette_gamma , 63 ) ) * 4 ;
}
2009-11-17 14:27:39 +00:00
2010-01-29 21:53:17 +00:00
SDL_SetColors ( canvas , colors , 0 , 256 ) ;
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
}
void gr_palette_read ( ubyte * pal )
{
2008-04-19 19:11:32 +00:00
SDL_Palette * palette ;
int i , j ;
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
2008-04-19 19:11:32 +00:00
for ( i = 0 , j = 0 ; i < 256 ; i + + )
{
pal [ j + + ] = palette - > colors [ i ] . r / 4 ;
pal [ j + + ] = palette - > colors [ i ] . g / 4 ;
pal [ j + + ] = palette - > colors [ i ] . b / 4 ;
}
2006-03-20 17:12:09 +00:00
}