Use screen_mode for screen resolution

This commit is contained in:
Kp 2015-05-14 02:23:13 +00:00
parent e592f3a0bb
commit 0ece005dfa
10 changed files with 163 additions and 111 deletions

View file

@ -780,6 +780,26 @@ constexpr A a(){return {};}
'''
if not self.Cxx11Compile(context, text=f, msg='for C++11 constexpr'):
raise SCons.Errors.StopError("C++ compiler does not support constexpr.")
@_custom_test
def check_constexpr_union_constructor(self,context):
# https://gcc.gnu.org/bugzilla/show_bug.cgi?id=56583
# <=gcc-4.7.x ICE on constexpr union constructors with anonymous
# substructure.
# Works fine without the substructure.
# Works fine in >=gcc-4.8 regardless of substructure.
f = '''
union U {
struct {
int a;
};
constexpr U(int b) :
a(b)
{
}
};
U a{640};
'''
self.Cxx11Compile(context, text=f, msg='whether compiler supports constexpr union constructors', successflags={'CPPDEFINES' : ['DXX_HAVE_CONSTEXPR_UNION_CONSTRUCTOR']})
@_implicit_test
def check_pch(self,context):
for how in [{'CXXFLAGS' : ['-x', 'c++-header']}]:

View file

@ -85,11 +85,6 @@ struct grs_point
#define BM_OGL 5
#endif /* def OGL */
#define SM(w,h) ((((u_int32_t)w)<<16)+(((u_int32_t)h)&0xFFFF))
#define SM_W(m) (m>>16)
#define SM_H(m) (m&0xFFFF)
#define SM_ORIGINAL 0
#define BM_FLAG_TRANSPARENT 1
#define BM_FLAG_SUPER_TRANSPARENT 2
#define BM_FLAG_NO_LIGHTING 4
@ -166,36 +161,71 @@ struct grs_canvas : prohibit_void_ptr<grs_canvas>
// canvas. Saves the current VGA state and screen mode.
#ifdef __cplusplus
union screen_mode
{
private:
uint32_t wh;
public:
struct {
uint16_t width, height;
};
bool operator==(const screen_mode &rhs)
{
return wh == rhs.wh;
}
bool operator!=(const screen_mode &rhs)
{
return !(*this == rhs);
}
screen_mode() = default;
#ifdef DXX_HAVE_CONSTEXPR_UNION_CONSTRUCTOR
constexpr
#endif
screen_mode(uint16_t &&w, uint16_t &&h) :
width(w), height(h)
{
}
};
static inline uint16_t SM_W(const screen_mode &s)
{
return s.width;
}
static inline uint16_t SM_H(const screen_mode &s)
{
return s.height;
}
uint_fast32_t gr_list_modes(array<screen_mode, 50> &modes);
int gr_set_mode(screen_mode mode);
class grs_screen : prohibit_void_ptr<grs_screen>
{ // This is a video screen
unsigned short sc_w, sc_h; // Actual Width and Height
screen_mode sc_mode;
public:
grs_canvas sc_canvas; // Represents the entire screen
fix sc_aspect; //aspect ratio (w/h) for this screen
uint_fast32_t get_screen_width() const
uint16_t get_screen_width() const
{
return sc_w;
return SM_W(sc_mode);
}
uint_fast32_t get_screen_height() const
uint16_t get_screen_height() const
{
return sc_h;
return SM_H(sc_mode);
}
uint_fast32_t get_screen_width_height() const
screen_mode get_screen_mode() const
{
return SM(get_screen_width(), get_screen_height());
return sc_mode;
}
void set_screen_width_height(uint16_t w, uint16_t h)
{
sc_w = w;
sc_h = h;
sc_mode.width = w;
sc_mode.height = h;
}
};
int gr_init();
int gr_list_modes( array<uint32_t, 50> &gsmodes );
int gr_set_mode(u_int32_t mode);
void gr_set_attributes(void);
//shut down the 2d. Restore the screen mode.

View file

@ -108,7 +108,7 @@ extern int ft_preference;
#define NDL 5 // Number of difficulty levels.
extern int Game_mode;
extern u_int32_t Game_screen_mode;
extern screen_mode Game_screen_mode;
extern int gauge_message_on;

View file

@ -407,7 +407,7 @@ int RunMovie(char *filename, int hires_flag, int must_have,int dx,int dy)
gr_palette_load(gr_palette);
(void)hires_flag;
#else
gr_set_mode(SM((hires_flag?640:320),(hires_flag?480:200)));
gr_set_mode(hires_flag ? screen_mode{640, 480} : screen_mode{320, 200});
#endif
MVE_sfCallbacks(MovieShowFrame);
MVE_palCallbacks(MovieSetPalette);

View file

@ -23,8 +23,7 @@ COPYRIGHT 1993-1999 PARALLAX SOFTWARE CORPORATION. ALL RIGHTS RESERVED.
*
*/
#ifndef _MOVIE_H
#define _MOVIE_H
#pragma once
#ifdef __cplusplus
#include "d2x-rebirth/libmve/mvelib.h"
@ -37,11 +36,11 @@ COPYRIGHT 1993-1999 PARALLAX SOFTWARE CORPORATION. ALL RIGHTS RESERVED.
#define MOVIE_ABORTED 2 // movie started by was aborted
#ifdef OGL
#define MOVIE_WIDTH (!GameArg.GfxSkipHiresMovie && grd_curscreen->get_screen_width() < 640 ? 640: grd_curscreen->get_screen_width())
#define MOVIE_HEIGHT (!GameArg.GfxSkipHiresMovie && grd_curscreen->get_screen_height() < 480 ? 480: grd_curscreen->get_screen_height())
#define MOVIE_WIDTH (!GameArg.GfxSkipHiresMovie && grd_curscreen->get_screen_width() < 640 ? static_cast<uint16_t>(640) : grd_curscreen->get_screen_width())
#define MOVIE_HEIGHT (!GameArg.GfxSkipHiresMovie && grd_curscreen->get_screen_height() < 480 ? static_cast<uint16_t>(480) : grd_curscreen->get_screen_height())
#else
#define MOVIE_WIDTH (!GameArg.GfxSkipHiresMovie?640:320)
#define MOVIE_HEIGHT (!GameArg.GfxSkipHiresMovie?480:200)
#define MOVIE_WIDTH static_cast<uint16_t>(!GameArg.GfxSkipHiresMovie? 640 : 320)
#define MOVIE_HEIGHT static_cast<uint16_t>(!GameArg.GfxSkipHiresMovie? 480 : 200)
#endif
extern int PlayMovie(const char *subtitles, const char *filename, int allow_abort);
@ -59,5 +58,3 @@ void close_extra_robot_movie();
extern int MovieHires; // specifies whether movies use low or high res
#endif
#endif /* _MOVIE_H */

View file

@ -460,14 +460,17 @@ void gr_toggle_fullscreen()
if (gl_initialized)
{
if (sdl_no_modeswitch == 0) {
if (!SDL_VideoModeOK(SM_W(Game_screen_mode), SM_H(Game_screen_mode), GameArg.DbgBpp, sdl_video_flags))
auto gsm = Game_screen_mode;
if (!SDL_VideoModeOK(gsm.width, gsm.height, GameArg.DbgBpp, sdl_video_flags))
{
con_printf(CON_URGENT,"Cannot set %ix%i. Fallback to 640x480",SM_W(Game_screen_mode), SM_H(Game_screen_mode));
Game_screen_mode=SM(640,480);
con_printf(CON_URGENT, "Cannot set %ix%i. Fallback to 640x480", gsm.width, gsm.height);
gsm.width = 640;
gsm.height = 480;
Game_screen_mode = gsm;
}
if (!SDL_SetVideoMode(SM_W(Game_screen_mode), SM_H(Game_screen_mode), GameArg.DbgBpp, sdl_video_flags))
if (!SDL_SetVideoMode(gsm.width, gsm.height, GameArg.DbgBpp, sdl_video_flags))
{
Error("Could not set %dx%dx%d opengl video mode: %s\n", SM_W(Game_screen_mode), SM_H(Game_screen_mode), GameArg.DbgBpp, SDL_GetError());
Error("Could not set %dx%dx%d opengl video mode: %s\n", gsm.width, gsm.height, GameArg.DbgBpp, SDL_GetError());
}
}
#ifdef RPI
@ -570,7 +573,7 @@ static void ogl_get_verinfo(void)
}
// returns possible (fullscreen) resolutions if any.
int gr_list_modes( array<uint32_t, 50> &gsmodes )
uint_fast32_t gr_list_modes(array<screen_mode, 50> &gsmodes)
{
SDL_Rect** modes;
int modesnum = 0;
@ -602,46 +605,37 @@ int gr_list_modes( array<uint32_t, 50> &gsmodes )
if (modes[i]->w > 0xFFF0 || modes[i]->h > 0xFFF0 // resolutions saved in 32bits. so skip bigger ones (unrealistic in 2010) (changed to 0xFFF0 to fix warning)
|| modes[i]->w < 320 || modes[i]->h < 200) // also skip everything smaller than 320x200
continue;
gsmodes[modesnum] = SM(modes[i]->w,modes[i]->h);
gsmodes[modesnum].width = modes[i]->w;
gsmodes[modesnum].height = modes[i]->h;
modesnum++;
if (modesnum >= 50) // that really seems to be enough big boy.
if (modesnum >= gsmodes.size()) // that really seems to be enough big boy.
break;
}
return modesnum;
}
}
static int gr_check_mode(uint32_t mode)
static int gr_check_mode(const screen_mode mode)
{
unsigned int w, h;
w=SM_W(mode);
h=SM_H(mode);
if (sdl_no_modeswitch == 0) {
return SDL_VideoModeOK(w, h, GameArg.DbgBpp, sdl_video_flags);
return SDL_VideoModeOK(SM_W(mode), SM_H(mode), GameArg.DbgBpp, sdl_video_flags);
} else {
// just tell the caller that any mode is valid...
return 32;
}
}
int gr_set_mode(u_int32_t mode)
int gr_set_mode(screen_mode mode)
{
unsigned int w, h;
unsigned char *gr_bm_data;
if (mode<=0)
return 0;
w=SM_W(mode);
h=SM_H(mode);
if (!gr_check_mode(mode))
{
con_printf(CON_URGENT,"Cannot set %ix%i. Fallback to 640x480",w,h);
w=640;
h=480;
Game_screen_mode=mode=SM(w,h);
con_printf(CON_URGENT, "Cannot set %ix%i. Fallback to 640x480", mode.width, mode.height);
mode.width = 640;
mode.height = 480;
Game_screen_mode = mode;
}
const uint_fast32_t w = SM_W(mode), h = SM_H(mode);
gr_bm_data = grd_curscreen->sc_canvas.cv_bitmap.get_bitmap_data();//since we use realloc, we want to keep this pointer around.
unsigned char *gr_new_bm_data = (unsigned char *)d_realloc(gr_bm_data,w*h);

View file

@ -48,7 +48,7 @@ void gr_flip()
}
// returns possible (fullscreen) resolutions if any.
int gr_list_modes( array<uint32_t, 50> &gsmodes )
uint_fast32_t gr_list_modes(array<screen_mode, 50> &gsmodes)
{
SDL_Rect** modes;
int modesnum = 0;
@ -73,42 +73,36 @@ int gr_list_modes( array<uint32_t, 50> &gsmodes )
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)
|| modes[i]->w < 320 || modes[i]->h < 200) // also skip everything smaller than 320x200
continue;
gsmodes[modesnum] = SM(modes[i]->w,modes[i]->h);
gsmodes[modesnum].width = modes[i]->w;
gsmodes[modesnum].height = modes[i]->h;
modesnum++;
if (modesnum >= 50) // that really seems to be enough big boy.
if (modesnum >= gsmodes.size()) // that really seems to be enough big boy.
break;
}
return modesnum;
}
}
int gr_set_mode(u_int32_t mode)
int gr_set_mode(screen_mode mode)
{
unsigned int w, h;
if (mode<=0)
return 0;
w=SM_W(mode);
h=SM_H(mode);
screen=NULL;
SDL_WM_SetCaption(DESCENT_VERSION, DXX_SDL_WINDOW_CAPTION);
SDL_WM_SetIcon( SDL_LoadBMP( DXX_SDL_WINDOW_ICON_BITMAP ), NULL );
const auto sdl_video_flags = ::sdl_video_flags;
if(SDL_VideoModeOK(w,h,GameArg.DbgBpp,sdl_video_flags))
if(SDL_VideoModeOK(SM_W(mode), SM_H(mode), GameArg.DbgBpp, sdl_video_flags))
{
screen=SDL_SetVideoMode(w, h, GameArg.DbgBpp, sdl_video_flags);
}
else
{
con_printf(CON_URGENT,"Cannot set %ix%i. Fallback to 640x480",w,h);
w=640;
h=480;
Game_screen_mode=mode=SM(w,h);
screen=SDL_SetVideoMode(w, h, GameArg.DbgBpp, sdl_video_flags);
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;
}
const unsigned w = SM_W(mode), h = SM_H(mode);
screen = SDL_SetVideoMode(w, h, GameArg.DbgBpp, sdl_video_flags);
if (screen == NULL)
{

View file

@ -217,7 +217,10 @@ int ReadConfigFile()
if ( GameCfg.MusicVolume > 8 ) GameCfg.MusicVolume = 8;
if (GameCfg.ResolutionX >= 320 && GameCfg.ResolutionY >= 200)
Game_screen_mode = SM(GameCfg.ResolutionX,GameCfg.ResolutionY);
{
Game_screen_mode.width = GameCfg.ResolutionX;
Game_screen_mode.height = GameCfg.ResolutionY;
}
return 0;
}

View file

@ -173,8 +173,7 @@ void reset_palette_add()
PaletteBlueAdd = 0;
}
u_int32_t Game_screen_mode = SM(640,480);
screen_mode Game_screen_mode{640, 480};
//initialize the various canvases on the game screen
//called every time the screen mode or cockpit changes
@ -189,11 +188,15 @@ void init_cockpit()
PlayerCfg.CockpitMode[1] = CM_FULL_SCREEN;
#ifndef OGL
if (PlayerCfg.CockpitMode[1] != CM_LETTERBOX)
{
#if defined(DXX_BUILD_DESCENT_II)
int HiresGFXAvailable = !GameArg.GfxSkipHiresGFX;
int HiresGFXAvailable = !GameArg.GfxSkipHiresGFX;
#endif
if ( Game_screen_mode != (HiresGFXAvailable? SM(640,480) : SM(320,200)) && PlayerCfg.CockpitMode[1] != CM_LETTERBOX) {
PlayerCfg.CockpitMode[1] = CM_FULL_SCREEN;
auto full_screen_mode = HiresGFXAvailable ? screen_mode{640, 480} : screen_mode{320, 200};
if (Game_screen_mode != full_screen_mode) {
PlayerCfg.CockpitMode[1] = CM_FULL_SCREEN;
}
}
#endif
@ -228,14 +231,14 @@ void init_cockpit()
break;
case CM_LETTERBOX: {
int x,y,w,h;
const unsigned gsm_height = SM_H(Game_screen_mode);
const unsigned w = SM_W(Game_screen_mode);
const unsigned h = (gsm_height * 3) / 4; // true letterbox size (16:9)
const unsigned x = 0;
const unsigned y = (gsm_height - h) / 2;
x = 0; w = SM_W(Game_screen_mode);
h = (SM_H(Game_screen_mode) * 3) / 4; // true letterbox size (16:9)
y = (SM_H(Game_screen_mode)-h)/2;
gr_rect(x,0,w,SM_H(Game_screen_mode)-h);
gr_rect(x,SM_H(Game_screen_mode)-h,w,SM_H(Game_screen_mode));
gr_rect(x, 0, w, gsm_height - h);
gr_rect(x, gsm_height - h, w, gsm_height);
game_init_render_sub_buffers( x, y, w, h );
break;
@ -272,7 +275,7 @@ void game_init_render_sub_buffers( int x, int y, int w, int h )
//mode if cannot init requested mode)
int set_screen_mode(int sm)
{
if ( (Screen_mode == sm) && !((sm==SCREEN_GAME) && (grd_curscreen->get_screen_width_height() != Game_screen_mode)) && !(sm==SCREEN_MENU) )
if ( (Screen_mode == sm) && !((sm==SCREEN_GAME) && (grd_curscreen->get_screen_mode() != Game_screen_mode)) && !(sm==SCREEN_MENU) )
{
gr_set_current_canvas(NULL);
return 1;
@ -287,33 +290,42 @@ int set_screen_mode(int sm)
switch( Screen_mode )
{
case SCREEN_MENU:
if (grd_curscreen->get_screen_width_height() != Game_screen_mode)
if (grd_curscreen->get_screen_mode() != Game_screen_mode)
if (gr_set_mode(Game_screen_mode))
Error("Cannot set screen mode.");
break;
case SCREEN_GAME:
if (grd_curscreen->get_screen_width_height() != Game_screen_mode)
if (grd_curscreen->get_screen_mode() != Game_screen_mode)
if (gr_set_mode(Game_screen_mode))
Error("Cannot set screen mode.");
break;
#ifdef EDITOR
case SCREEN_EDITOR:
if (grd_curscreen->get_screen_width_height() != SM(800,600)) {
{
const screen_mode editor_mode{800, 600};
if (grd_curscreen->get_screen_mode() != editor_mode)
{
int gr_error;
if ((gr_error=gr_set_mode(SM(800,600)))!=0) { //force into game scrren
if ((gr_error = gr_set_mode(editor_mode)) != 0) { //force into game scrren
Warning("Cannot init editor screen (error=%d)",gr_error);
return 0;
}
}
}
break;
#endif
#if defined(DXX_BUILD_DESCENT_II)
case SCREEN_MOVIE:
if (grd_curscreen->get_screen_width_height() != SM(MOVIE_WIDTH,MOVIE_HEIGHT)) {
if (gr_set_mode(SM(MOVIE_WIDTH,MOVIE_HEIGHT))) Error("Cannot set screen mode for game!");
{
const screen_mode movie_mode{MOVIE_WIDTH, MOVIE_HEIGHT};
if (grd_curscreen->get_screen_mode() != movie_mode)
{
if (gr_set_mode(movie_mode))
Error("Cannot set screen mode for game!");
gr_palette_load( gr_palette );
}
}
break;
#endif
default:

View file

@ -945,17 +945,15 @@ static int gcd(int a, int b)
void change_res()
{
array<uint32_t, 50> modes;
u_int32_t new_mode = 0;
int i = 0, mc = 0, citem = -1, opt_cval = -1, opt_fullscr = -1;
array<screen_mode, 50> modes;
int i = 0, mc = 0, citem = -1;
unsigned num_presets = gr_list_modes(modes);
const auto num_presets = gr_list_modes(modes);
{
newmenu_item m[50+8];
char restext[50][12], crestext[12], casptext[12];
range_for (const auto i, partial_range(modes, num_presets))
range_for (const auto &i, partial_range(modes, num_presets))
{
snprintf(restext[mc], sizeof(restext[mc]), "%ix%i", SM_W(i), SM_H(i));
@ -967,19 +965,19 @@ void change_res()
nm_set_item_text(m[mc], ""); mc++; // little space for overview
// the fields for custom resolution and aspect
opt_cval = mc;
const auto opt_cval = mc;
nm_set_item_radio(m[mc], "use custom values", (citem == -1), 0); mc++;
nm_set_item_text(m[mc], "resolution:"); mc++;
snprintf(crestext, sizeof(crestext), "%ix%i", SM_W(Game_screen_mode), SM_H(Game_screen_mode));
nm_set_item_input(m[mc], crestext);
modes[mc] = 0; mc++;
mc++;
nm_set_item_text(m[mc], "aspect:"); mc++;
snprintf(casptext, sizeof(casptext), "%ix%i", GameCfg.AspectY, GameCfg.AspectX);
nm_set_item_input(m[mc], casptext);
modes[mc] = 0; mc++;
mc++;
nm_set_item_text(m[mc], ""); mc++; // little space for overview
// fullscreen
opt_fullscr = mc;
const auto opt_fullscr = mc;
nm_set_item_checkbox(m[mc], "Fullscreen", gr_check_fullscreen());
mc++;
@ -997,25 +995,27 @@ void change_res()
if (m[opt_fullscr].value != gr_check_fullscreen())
gr_toggle_fullscreen();
screen_mode new_mode;
if (i == opt_cval) // set custom resolution and aspect
{
char *x;
unsigned long w = strtoul(crestext, &x, 10), h;
uint32_t cmode;
screen_mode cmode;
if (*x != 'x' || ((h = strtoul(x + 1, &x, 10)), *x))
{
nm_messagebox(TXT_WARNING, 1, "OK", "Entered resolution is bad.\nReverting ...");
cmode = 0;
cmode = {};
}
else if (w < 320 || h < 200)
{
// oh oh - the resolution is too small. Revert!
nm_messagebox( TXT_WARNING, 1, "OK", "Entered resolution is too small.\nReverting ..." );
cmode = 0;
cmode = {};
}
else
{
cmode = SM(w, h);
cmode.width = w;
cmode.height = h;
}
auto casp = cmode;
w = strtoul(casptext, &x, 10);
@ -1026,17 +1026,20 @@ void change_res()
else
{
// we even have a custom aspect set up
casp = SM(w, h);
casp.width = w;
casp.height = h;
}
GameCfg.AspectY = SM_W(casp)/gcd(SM_W(casp),SM_H(casp));
GameCfg.AspectX = SM_H(casp)/gcd(SM_W(casp),SM_H(casp));
const auto g = gcd(SM_W(casp), SM_H(casp));
GameCfg.AspectY = SM_W(casp) / g;
GameCfg.AspectX = SM_H(casp) / g;
new_mode = cmode;
}
else if (i >= 0 && i < num_presets) // set preset resolution
{
new_mode = modes[i];
GameCfg.AspectY = SM_W(new_mode)/gcd(SM_W(new_mode),SM_H(new_mode));
GameCfg.AspectX = SM_H(new_mode)/gcd(SM_W(new_mode),SM_H(new_mode));
const auto g = gcd(SM_W(new_mode), SM_H(new_mode));
GameCfg.AspectY = SM_W(new_mode) / g;
GameCfg.AspectX = SM_H(new_mode) / g;
}
// clean up and apply everything
@ -1054,7 +1057,6 @@ void change_res()
}
}
game_init_render_buffers(SM_W(Game_screen_mode), SM_H(Game_screen_mode));
}
}
static void input_config_sensitivity()