mirror of
https://github.com/holub/mame
synced 2025-04-27 18:53:05 +03:00
Merge pull request #722 from antonioginer/master
Implement integer scaling in core renderer [Calamity]
This commit is contained in:
commit
4b61493c7c
@ -88,6 +88,14 @@ const options_entry emu_options::s_option_entries[] =
|
||||
{ OPTION_SPEED "(0.01-100)", "1.0", OPTION_FLOAT, "controls the speed of gameplay, relative to realtime; smaller numbers are slower" },
|
||||
{ OPTION_REFRESHSPEED ";rs", "0", OPTION_BOOLEAN, "automatically adjusts the speed of gameplay to keep the refresh rate lower than the screen" },
|
||||
|
||||
// render options
|
||||
{ nullptr, nullptr, OPTION_HEADER, "CORE RENDER OPTIONS" },
|
||||
{ OPTION_KEEPASPECT ";ka", "1", OPTION_BOOLEAN, "constrain to the proper aspect ratio" },
|
||||
{ OPTION_UNEVENSTRETCH ";ues", "1", OPTION_BOOLEAN, "allow non-integer stretch factors" },
|
||||
{ OPTION_UNEVENSTRETCHX ";uesx", "0", OPTION_BOOLEAN, "allow non-integer stretch factors only on horizontal axis"},
|
||||
{ OPTION_INTSCALEX ";sx", "0", OPTION_INTEGER, "set horizontal integer scale factor."},
|
||||
{ OPTION_INTSCALEY ";sy", "0", OPTION_INTEGER, "set vertical integer scale."},
|
||||
|
||||
// rotation options
|
||||
{ nullptr, nullptr, OPTION_HEADER, "CORE ROTATION OPTIONS" },
|
||||
{ OPTION_ROTATE, "1", OPTION_BOOLEAN, "rotate the game screen according to the game's orientation needs it" },
|
||||
|
@ -98,6 +98,13 @@ enum
|
||||
#define OPTION_SPEED "speed"
|
||||
#define OPTION_REFRESHSPEED "refreshspeed"
|
||||
|
||||
// core render options
|
||||
#define OPTION_KEEPASPECT "keepaspect"
|
||||
#define OPTION_UNEVENSTRETCH "unevenstretch"
|
||||
#define OPTION_UNEVENSTRETCHX "unevenstretchx"
|
||||
#define OPTION_INTSCALEX "intscalex"
|
||||
#define OPTION_INTSCALEY "intscaley"
|
||||
|
||||
// core rotation options
|
||||
#define OPTION_ROTATE "rotate"
|
||||
#define OPTION_ROR "ror"
|
||||
@ -282,6 +289,13 @@ public:
|
||||
float speed() const { return float_value(OPTION_SPEED); }
|
||||
bool refresh_speed() const { return m_refresh_speed; }
|
||||
|
||||
// core render options
|
||||
bool keep_aspect() const { return bool_value(OPTION_KEEPASPECT); }
|
||||
bool uneven_stretch() const { return bool_value(OPTION_UNEVENSTRETCH); }
|
||||
bool uneven_stretch_x() const { return bool_value(OPTION_UNEVENSTRETCHX); }
|
||||
int int_scale_x() const { return int_value(OPTION_INTSCALEX); }
|
||||
int int_scale_y() const { return int_value(OPTION_INTSCALEY); }
|
||||
|
||||
// core rotation options
|
||||
bool rotate() const { return bool_value(OPTION_ROTATE); }
|
||||
bool ror() const { return bool_value(OPTION_ROR); }
|
||||
|
@ -931,6 +931,15 @@ render_target::render_target(render_manager &manager, const char *layoutfile, UI
|
||||
m_base_layerconfig.set_marquees_enabled(manager.machine().options().use_marquees());
|
||||
m_base_layerconfig.set_zoom_to_screen(manager.machine().options().artwork_crop());
|
||||
|
||||
// aspect and scale options
|
||||
m_keepaspect = manager.machine().options().keep_aspect();
|
||||
m_int_scale_x = manager.machine().options().int_scale_x();
|
||||
m_int_scale_y = manager.machine().options().int_scale_y();
|
||||
if (manager.machine().options().uneven_stretch() && !manager.machine().options().uneven_stretch_x())
|
||||
m_scale_mode = SCALE_FRACTIONAL;
|
||||
else
|
||||
m_scale_mode = manager.machine().options().uneven_stretch_x()? SCALE_FRACTIONAL_X : SCALE_INTEGER;
|
||||
|
||||
// determine the base orientation based on options
|
||||
if (!manager.machine().options().rotate())
|
||||
m_base_orientation = orientation_reverse(manager.machine().system().flags & ORIENTATION_MASK);
|
||||
@ -1005,7 +1014,7 @@ void render_target::set_bounds(INT32 width, INT32 height, float pixel_aspect)
|
||||
m_bounds.x0 = m_bounds.y0 = 0;
|
||||
m_bounds.x1 = (float)width;
|
||||
m_bounds.y1 = (float)height;
|
||||
m_pixel_aspect = pixel_aspect;
|
||||
m_pixel_aspect = pixel_aspect != 0.0? pixel_aspect : 1.0;
|
||||
}
|
||||
|
||||
|
||||
@ -1140,41 +1149,87 @@ const render_screen_list &render_target::view_screens(int viewindex)
|
||||
|
||||
void render_target::compute_visible_area(INT32 target_width, INT32 target_height, float target_pixel_aspect, int target_orientation, INT32 &visible_width, INT32 &visible_height)
|
||||
{
|
||||
float width, height;
|
||||
float scale;
|
||||
|
||||
// constrained case
|
||||
if (target_pixel_aspect != 0.0f)
|
||||
switch (m_scale_mode)
|
||||
{
|
||||
// start with the aspect ratio of the square pixel layout
|
||||
width = m_curview->effective_aspect(m_layerconfig);
|
||||
height = 1.0f;
|
||||
case SCALE_FRACTIONAL:
|
||||
{
|
||||
float width, height;
|
||||
float scale;
|
||||
|
||||
// first apply target orientation
|
||||
if (target_orientation & ORIENTATION_SWAP_XY)
|
||||
FSWAP(width, height);
|
||||
// constrained case
|
||||
if (m_keepaspect)
|
||||
{
|
||||
// start with the aspect ratio of the square pixel layout
|
||||
width = m_curview->effective_aspect(m_layerconfig);
|
||||
height = 1.0f;
|
||||
|
||||
// apply the target pixel aspect ratio
|
||||
height *= target_pixel_aspect;
|
||||
// first apply target orientation
|
||||
if (target_orientation & ORIENTATION_SWAP_XY)
|
||||
FSWAP(width, height);
|
||||
|
||||
// based on the height/width ratio of the source and target, compute the scale factor
|
||||
if (width / height > (float)target_width / (float)target_height)
|
||||
scale = (float)target_width / width;
|
||||
else
|
||||
scale = (float)target_height / height;
|
||||
// apply the target pixel aspect ratio
|
||||
height *= target_pixel_aspect;
|
||||
|
||||
// based on the height/width ratio of the source and target, compute the scale factor
|
||||
if (width / height > (float)target_width / (float)target_height)
|
||||
scale = (float)target_width / width;
|
||||
else
|
||||
scale = (float)target_height / height;
|
||||
}
|
||||
|
||||
// stretch-to-fit case
|
||||
else
|
||||
{
|
||||
width = (float)target_width;
|
||||
height = (float)target_height;
|
||||
scale = 1.0f;
|
||||
}
|
||||
|
||||
// set the final width/height
|
||||
visible_width = render_round_nearest(width * scale);
|
||||
visible_height = render_round_nearest(height * scale);
|
||||
break;
|
||||
}
|
||||
|
||||
case SCALE_FRACTIONAL_X:
|
||||
case SCALE_INTEGER:
|
||||
{
|
||||
// get source size and aspect
|
||||
INT32 src_width, src_height;
|
||||
compute_minimum_size(src_width, src_height);
|
||||
float src_aspect = m_curview->effective_aspect(m_layerconfig);
|
||||
|
||||
// apply orientation if required
|
||||
if (target_orientation & ORIENTATION_SWAP_XY)
|
||||
src_aspect = 1.0 / src_aspect;
|
||||
|
||||
// get destination size and aspect
|
||||
float dest_width = (float)target_width;
|
||||
float dest_height = (float)target_height;
|
||||
float dest_aspect = dest_width / dest_height * target_pixel_aspect;
|
||||
|
||||
// apply aspect correction to destination rectangle
|
||||
if (dest_aspect > src_aspect)
|
||||
dest_width *= m_keepaspect? src_aspect / dest_aspect : 1.0f;
|
||||
else
|
||||
dest_height *= m_keepaspect? dest_aspect / src_aspect : 1.0f;
|
||||
|
||||
// compute scale factors
|
||||
float xscale = dest_width / src_width;
|
||||
float yscale = dest_height / src_height;
|
||||
xscale = dest_aspect >= 1.0f && m_scale_mode == SCALE_FRACTIONAL_X? xscale : MAX(1, render_round_nearest(xscale));
|
||||
yscale = dest_aspect < 1.0f && m_scale_mode == SCALE_FRACTIONAL_X? yscale : MAX(1, render_round_nearest(yscale));
|
||||
|
||||
// check if we have user defined scale factors, if so use them instead
|
||||
xscale = m_int_scale_x? m_int_scale_x : xscale;
|
||||
yscale = m_int_scale_y? m_int_scale_y : yscale;
|
||||
|
||||
// set the final width/height
|
||||
visible_width = render_round_nearest(src_width * xscale);
|
||||
visible_height = render_round_nearest(src_height * yscale);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// stretch-to-fit case
|
||||
else
|
||||
{
|
||||
width = (float)target_width;
|
||||
height = (float)target_height;
|
||||
scale = 1.0f;
|
||||
}
|
||||
|
||||
// set the final width/height
|
||||
visible_width = render_round_nearest(width * scale);
|
||||
visible_height = render_round_nearest(height * scale);
|
||||
}
|
||||
|
||||
|
||||
@ -2528,7 +2583,7 @@ float render_manager::ui_aspect(render_container *rc)
|
||||
|
||||
// if we have a valid pixel aspect, apply that and return
|
||||
if (m_ui_target->pixel_aspect() != 0.0f)
|
||||
return (aspect / m_ui_target->pixel_aspect());
|
||||
aspect /= m_ui_target->pixel_aspect();
|
||||
} else {
|
||||
// single screen container
|
||||
|
||||
|
@ -73,6 +73,13 @@ const UINT8 RENDER_CREATE_NO_ART = 0x01; // ignore any views that
|
||||
const UINT8 RENDER_CREATE_SINGLE_FILE = 0x02; // only load views from the file specified
|
||||
const UINT8 RENDER_CREATE_HIDDEN = 0x04; // don't make this target visible
|
||||
|
||||
// render scaling modes
|
||||
enum
|
||||
{
|
||||
SCALE_FRACTIONAL = 0, // compute fractional scaling factors for both axes
|
||||
SCALE_FRACTIONAL_X, // compute fractional scaling factor for x-axis, and integer factor for y-axis
|
||||
SCALE_INTEGER // compute integer scaling factors for both axes, based on target dimensions
|
||||
};
|
||||
|
||||
// flags for primitives
|
||||
const int PRIMFLAG_TEXORIENT_SHIFT = 0;
|
||||
@ -86,7 +93,6 @@ const UINT32 PRIMFLAG_BLENDMODE_MASK = 15 << PRIMFLAG_BLENDMODE_SHIFT;
|
||||
|
||||
const int PRIMFLAG_ANTIALIAS_SHIFT = 12;
|
||||
const UINT32 PRIMFLAG_ANTIALIAS_MASK = 1 << PRIMFLAG_ANTIALIAS_SHIFT;
|
||||
|
||||
const int PRIMFLAG_SCREENTEX_SHIFT = 13;
|
||||
const UINT32 PRIMFLAG_SCREENTEX_MASK = 1 << PRIMFLAG_SCREENTEX_SHIFT;
|
||||
|
||||
@ -892,6 +898,7 @@ public:
|
||||
UINT32 width() const { return m_width; }
|
||||
UINT32 height() const { return m_height; }
|
||||
float pixel_aspect() const { return m_pixel_aspect; }
|
||||
int scale_mode() const { return m_scale_mode; }
|
||||
float max_update_rate() const { return m_max_refresh; }
|
||||
int orientation() const { return m_orientation; }
|
||||
render_layer_config layer_config() const { return m_layerconfig; }
|
||||
@ -994,7 +1001,11 @@ private:
|
||||
INT32 m_width; // width in pixels
|
||||
INT32 m_height; // height in pixels
|
||||
render_bounds m_bounds; // bounds of the target
|
||||
bool m_keepaspect; // constrain aspect ratio
|
||||
float m_pixel_aspect; // aspect ratio of individual pixels
|
||||
int m_scale_mode; // type of scale to apply
|
||||
int m_int_scale_x; // horizontal integer scale factor
|
||||
int m_int_scale_y; // vertical integer scale factor
|
||||
float m_max_refresh; // maximum refresh rate, 0 or if none
|
||||
int m_orientation; // orientation
|
||||
render_layer_config m_layerconfig; // layer configuration
|
||||
|
@ -37,7 +37,6 @@ ui_menu_display_options::dspl_option ui_menu_display_options::m_options[] = {
|
||||
{ 0, nullptr, nullptr },
|
||||
{ 0, __("Video Mode"), OSDOPTION_VIDEO },
|
||||
#if defined(UI_WINDOWS) && !defined(UI_SDL)
|
||||
{ 0, __("Hardware Stretch"), WINOPTION_HWSTRETCH },
|
||||
{ 0, __("Triple Buffering"), WINOPTION_TRIPLEBUFFER },
|
||||
{ 0, __("HLSL"), WINOPTION_HLSL_ENABLE },
|
||||
#endif
|
||||
@ -46,7 +45,7 @@ ui_menu_display_options::dspl_option ui_menu_display_options::m_options[] = {
|
||||
{ 0, __("Bitmap Prescaling"), OSDOPTION_PRESCALE },
|
||||
{ 0, __("Multi-Threaded Rendering"), OSDOPTION_MULTITHREADING },
|
||||
{ 0, __("Window Mode"), OSDOPTION_WINDOW },
|
||||
{ 0, __("Enforce Aspect Ratio"), OSDOPTION_KEEPASPECT },
|
||||
{ 0, __("Enforce Aspect Ratio"), OPTION_KEEPASPECT },
|
||||
{ 0, __("Start Out Maximized"), OSDOPTION_MAXIMIZE },
|
||||
{ 0, __("Synchronized Refresh"), OSDOPTION_SYNCREFRESH },
|
||||
{ 0, __("Wait Vertical Sync"), OSDOPTION_WAITVSYNC }
|
||||
|
@ -52,8 +52,6 @@ const options_entry osd_options::s_option_entries[] =
|
||||
{ OSDOPTION_NUMSCREENS "(1-4)", "1", OPTION_INTEGER, "number of screens to create; usually, you want just one" },
|
||||
{ OSDOPTION_WINDOW ";w", "0", OPTION_BOOLEAN, "enable window mode; otherwise, full screen mode is assumed" },
|
||||
{ OSDOPTION_MAXIMIZE ";max", "1", OPTION_BOOLEAN, "default to maximized windows; otherwise, windows will be minimized" },
|
||||
{ OSDOPTION_KEEPASPECT ";ka", "1", OPTION_BOOLEAN, "constrain to the proper aspect ratio" },
|
||||
{ OSDOPTION_UNEVENSTRETCH ";ues", "1", OPTION_BOOLEAN, "allow non-integer stretch factors" },
|
||||
{ OSDOPTION_WAITVSYNC ";vs", "0", OPTION_BOOLEAN, "enable waiting for the start of VBLANK before flipping screens; reduces tearing effects" },
|
||||
{ OSDOPTION_SYNCREFRESH ";srf", "0", OPTION_BOOLEAN, "enable using the start of VBLANK for throttling instead of the game time" },
|
||||
|
||||
|
@ -45,8 +45,6 @@
|
||||
#define OSDOPTION_NUMSCREENS "numscreens"
|
||||
#define OSDOPTION_WINDOW "window"
|
||||
#define OSDOPTION_MAXIMIZE "maximize"
|
||||
#define OSDOPTION_KEEPASPECT "keepaspect"
|
||||
#define OSDOPTION_UNEVENSTRETCH "unevenstretch"
|
||||
#define OSDOPTION_WAITVSYNC "waitvsync"
|
||||
#define OSDOPTION_SYNCREFRESH "syncrefresh"
|
||||
|
||||
@ -109,8 +107,6 @@ public:
|
||||
int numscreens() const { return int_value(OSDOPTION_NUMSCREENS); }
|
||||
bool window() const { return bool_value(OSDOPTION_WINDOW); }
|
||||
bool maximize() const { return bool_value(OSDOPTION_MAXIMIZE); }
|
||||
bool keep_aspect() const { return bool_value(OSDOPTION_KEEPASPECT); }
|
||||
bool uneven_stretch() const { return bool_value(OSDOPTION_UNEVENSTRETCH); }
|
||||
bool wait_vsync() const { return bool_value(OSDOPTION_WAITVSYNC); }
|
||||
bool sync_refresh() const { return bool_value(OSDOPTION_SYNCREFRESH); }
|
||||
|
||||
|
@ -110,8 +110,10 @@ public:
|
||||
|
||||
const char *devicename() { return m_name[0] ? m_name : "UNKNOWN"; }
|
||||
|
||||
float aspect();
|
||||
float aspect() { return m_aspect; }
|
||||
float pixel_aspect() { return m_aspect / ((float)m_pos_size.width() / (float)m_pos_size.height()); }
|
||||
|
||||
void update_resolution(const int new_width, const int new_height) { m_pos_size.resize(new_width, new_height); }
|
||||
void set_aspect(const float a) { m_aspect = a; }
|
||||
bool is_primary() { return m_is_primary; }
|
||||
|
||||
@ -131,6 +133,7 @@ private:
|
||||
|
||||
void * m_handle; // handle to the monitor
|
||||
float m_aspect; // computed/configured aspect ratio of the physical device
|
||||
float m_pixel_aspect; // computed pixel aspect ratio
|
||||
};
|
||||
|
||||
class osd_window_config
|
||||
@ -166,12 +169,11 @@ public:
|
||||
|
||||
int prescale() const { return m_prescale; };
|
||||
|
||||
float aspect() const { return monitor()->aspect(); }
|
||||
float pixel_aspect() const { return monitor()->pixel_aspect(); }
|
||||
|
||||
virtual osd_dim get_size() = 0;
|
||||
|
||||
#ifdef OSD_SDL
|
||||
virtual osd_dim blit_surface_size() = 0;
|
||||
virtual osd_monitor_info *monitor() const = 0;
|
||||
virtual SDL_Window *sdl_window() = 0;
|
||||
#else
|
||||
|
@ -960,12 +960,12 @@ texture_info * renderer_sdl1::texture_update(const render_primitive &prim)
|
||||
|
||||
render_primitive_list *renderer_sdl1::get_primitives()
|
||||
{
|
||||
osd_dim nd = window().blit_surface_size();
|
||||
osd_dim nd = window().get_size();
|
||||
if (nd != m_blit_dim)
|
||||
{
|
||||
m_blit_dim = nd;
|
||||
notify_changed();
|
||||
}
|
||||
window().target()->set_bounds(m_blit_dim.width(), m_blit_dim.height(), window().aspect());
|
||||
window().target()->set_bounds(m_blit_dim.width(), m_blit_dim.height(), window().pixel_aspect());
|
||||
return &window().target()->get_primitives();
|
||||
}
|
||||
|
@ -49,7 +49,7 @@ public:
|
||||
virtual render_primitive_list *get_primitives() override
|
||||
{
|
||||
osd_dim wdim = window().get_size();
|
||||
window().target()->set_bounds(wdim.width(), wdim.height(), window().aspect());
|
||||
window().target()->set_bounds(wdim.width(), wdim.height(), window().pixel_aspect());
|
||||
return &window().target()->get_primitives();
|
||||
}
|
||||
|
||||
|
@ -204,7 +204,7 @@ render_primitive_list *renderer_d3d9::get_primitives()
|
||||
GetClientRectExceptMenu(window().m_hwnd, &client, window().fullscreen());
|
||||
if (rect_width(&client) > 0 && rect_height(&client) > 0)
|
||||
{
|
||||
window().target()->set_bounds(rect_width(&client), rect_height(&client), window().aspect());
|
||||
window().target()->set_bounds(rect_width(&client), rect_height(&client), window().pixel_aspect());
|
||||
window().target()->set_max_update_rate((get_refresh() == 0) ? get_origmode().RefreshRate : get_refresh());
|
||||
}
|
||||
if (m_shaders != nullptr)
|
||||
|
@ -47,7 +47,7 @@ render_primitive_list *renderer_gdi::get_primitives()
|
||||
{
|
||||
RECT client;
|
||||
GetClientRect(window().m_hwnd, &client);
|
||||
window().target()->set_bounds(rect_width(&client), rect_height(&client), window().aspect());
|
||||
window().target()->set_bounds(rect_width(&client), rect_height(&client), window().pixel_aspect());
|
||||
return &window().target()->get_primitives();
|
||||
}
|
||||
|
||||
|
@ -23,6 +23,6 @@ render_primitive_list *renderer_none::get_primitives()
|
||||
{
|
||||
RECT client;
|
||||
GetClientRect(window().m_hwnd, &client);
|
||||
window().target()->set_bounds(rect_width(&client), rect_height(&client), window().aspect());
|
||||
window().target()->set_bounds(rect_width(&client), rect_height(&client), window().pixel_aspect());
|
||||
return &window().target()->get_primitives();
|
||||
}
|
||||
|
@ -141,17 +141,13 @@ public:
|
||||
#endif
|
||||
virtual render_primitive_list *get_primitives() override
|
||||
{
|
||||
#ifdef OSD_WINDOWS
|
||||
osd_dim nd = window().get_size();
|
||||
#else
|
||||
osd_dim nd = window().blit_surface_size();
|
||||
#endif
|
||||
if (nd != m_blit_dim)
|
||||
{
|
||||
m_blit_dim = nd;
|
||||
notify_changed();
|
||||
}
|
||||
window().target()->set_bounds(m_blit_dim.width(), m_blit_dim.height(), window().aspect());
|
||||
window().target()->set_bounds(m_blit_dim.width(), m_blit_dim.height(), window().pixel_aspect());
|
||||
return &window().target()->get_primitives();
|
||||
}
|
||||
|
||||
|
@ -672,12 +672,12 @@ static void yuv_RGB_to_YUY2X2(const UINT16 *bitmap, UINT8 *ptr, const int pitch,
|
||||
|
||||
render_primitive_list *renderer_sdl2::get_primitives()
|
||||
{
|
||||
osd_dim nd = window().blit_surface_size();
|
||||
osd_dim nd = window().get_size();
|
||||
if (nd != m_blit_dim)
|
||||
{
|
||||
m_blit_dim = nd;
|
||||
notify_changed();
|
||||
}
|
||||
window().target()->set_bounds(m_blit_dim.width(), m_blit_dim.height(), window().aspect());
|
||||
window().target()->set_bounds(m_blit_dim.width(), m_blit_dim.height(), window().pixel_aspect());
|
||||
return &window().target()->get_primitives();
|
||||
}
|
||||
|
@ -124,22 +124,6 @@ void sdl_monitor_info::refresh()
|
||||
m_is_primary = (m_handle == 0);
|
||||
}
|
||||
|
||||
//============================================================
|
||||
// sdlvideo_monitor_get_aspect
|
||||
//============================================================
|
||||
|
||||
float osd_monitor_info::aspect()
|
||||
{
|
||||
// FIXME: returning 0 looks odd, video_config is bad
|
||||
if (video_config.keepaspect)
|
||||
{
|
||||
return m_aspect / ((float)m_pos_size.width() / (float)m_pos_size.height());
|
||||
}
|
||||
return 0.0f;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
//============================================================
|
||||
// update
|
||||
@ -300,13 +284,6 @@ static void check_osd_inputs(running_machine &machine)
|
||||
}
|
||||
}
|
||||
|
||||
if (machine.ui_input().pressed(IPT_OSD_2))
|
||||
{
|
||||
//FIXME: on a per window basis
|
||||
video_config.fullstretch = !video_config.fullstretch;
|
||||
machine.ui().popup_time(1, "Uneven stretch %s", video_config.fullstretch? "enabled":"disabled");
|
||||
}
|
||||
|
||||
if (machine.ui_input().pressed(IPT_OSD_4))
|
||||
{
|
||||
//FIXME: on a per window basis
|
||||
@ -346,7 +323,6 @@ void sdl_osd_interface::extract_video_config()
|
||||
video_config.filter = options().filter();
|
||||
video_config.keepaspect = options().keep_aspect();
|
||||
video_config.numscreens = options().numscreens();
|
||||
video_config.fullstretch = options().uneven_stretch();
|
||||
#ifdef SDLMAME_X11
|
||||
video_config.restrictonemonitor = !options().use_all_heads();
|
||||
#endif
|
||||
|
@ -388,94 +388,6 @@ void sdl_osd_interface::window_exit()
|
||||
}
|
||||
|
||||
|
||||
//============================================================
|
||||
// sdlwindow_blit_surface_size
|
||||
//============================================================
|
||||
|
||||
static inline int better_mode(int width0, int height0, int width1, int height1, float desired_aspect)
|
||||
{
|
||||
float aspect0 = (float)width0 / (float)height0;
|
||||
float aspect1 = (float)width1 / (float)height1;
|
||||
return (fabs(desired_aspect - aspect0) < fabs(desired_aspect - aspect1)) ? 0 : 1;
|
||||
}
|
||||
|
||||
osd_dim sdl_window_info::blit_surface_size()
|
||||
{
|
||||
osd_dim window_dim = get_size();
|
||||
|
||||
int newwidth, newheight;
|
||||
int xscale = 1, yscale = 1;
|
||||
float desired_aspect = 1.0f;
|
||||
INT32 target_width = window_dim.width();
|
||||
INT32 target_height = window_dim.height();
|
||||
|
||||
// start with the minimum size
|
||||
m_target->compute_minimum_size(newwidth, newheight);
|
||||
|
||||
// compute the appropriate visible area if we're trying to keepaspect
|
||||
if (video_config.keepaspect)
|
||||
{
|
||||
// make sure the monitor is up-to-date
|
||||
m_target->compute_visible_area(target_width, target_height, m_monitor->aspect(), m_target->orientation(), target_width, target_height);
|
||||
desired_aspect = (float)target_width / (float)target_height;
|
||||
}
|
||||
|
||||
// non-integer scaling - often gives more pleasing results in full screen
|
||||
if (!video_config.fullstretch)
|
||||
{
|
||||
// compute maximum integral scaling to fit the window
|
||||
xscale = (target_width + 2) / newwidth;
|
||||
yscale = (target_height + 2) / newheight;
|
||||
|
||||
// try a little harder to keep the aspect ratio if desired
|
||||
if (video_config.keepaspect)
|
||||
{
|
||||
// if we could stretch more in the X direction, and that makes a better fit, bump the xscale
|
||||
while (newwidth * (xscale + 1) <= window_dim.width() &&
|
||||
better_mode(newwidth * xscale, newheight * yscale, newwidth * (xscale + 1), newheight * yscale, desired_aspect))
|
||||
xscale++;
|
||||
|
||||
// if we could stretch more in the Y direction, and that makes a better fit, bump the yscale
|
||||
while (newheight * (yscale + 1) <= window_dim.height() &&
|
||||
better_mode(newwidth * xscale, newheight * yscale, newwidth * xscale, newheight * (yscale + 1), desired_aspect))
|
||||
yscale++;
|
||||
|
||||
// now that we've maxed out, see if backing off the maximally stretched one makes a better fit
|
||||
if (window_dim.width() - newwidth * xscale < window_dim.height() - newheight * yscale)
|
||||
{
|
||||
while (better_mode(newwidth * xscale, newheight * yscale, newwidth * (xscale - 1), newheight * yscale, desired_aspect) && (xscale >= 0))
|
||||
xscale--;
|
||||
}
|
||||
else
|
||||
{
|
||||
while (better_mode(newwidth * xscale, newheight * yscale, newwidth * xscale, newheight * (yscale - 1), desired_aspect) && (yscale >= 0))
|
||||
yscale--;
|
||||
}
|
||||
}
|
||||
|
||||
// ensure at least a scale factor of 1
|
||||
if (xscale <= 0) xscale = 1;
|
||||
if (yscale <= 0) yscale = 1;
|
||||
|
||||
// apply the final scale
|
||||
newwidth *= xscale;
|
||||
newheight *= yscale;
|
||||
}
|
||||
else
|
||||
{
|
||||
newwidth = target_width;
|
||||
newheight = target_height;
|
||||
}
|
||||
|
||||
//FIXME: really necessary to distinguish for yuv_modes ?
|
||||
if (m_target->zoom_to_screen()
|
||||
&& (video_config.scale_mode == VIDEO_SCALE_MODE_NONE ))
|
||||
newwidth = window_dim.width();
|
||||
|
||||
return osd_dim(newwidth, newheight);
|
||||
}
|
||||
|
||||
|
||||
//============================================================
|
||||
// sdlwindow_resize
|
||||
// (main thread)
|
||||
@ -997,27 +909,10 @@ OSDWORK_CALLBACK( sdl_window_info::complete_create_wt )
|
||||
// if we have a remembered size force the new window size to it
|
||||
temp = window->m_windowed_dim;
|
||||
}
|
||||
else if (window->m_startmaximized)
|
||||
temp = window->get_max_bounds(video_config.keepaspect );
|
||||
else
|
||||
{
|
||||
if (window->m_startmaximized)
|
||||
{
|
||||
temp = window->get_max_bounds(video_config.keepaspect );
|
||||
}
|
||||
else
|
||||
{
|
||||
#if 0
|
||||
// Couriersud: This code never has worked with the last version of get_min_bounds
|
||||
/* Create the window directly with the correct aspect
|
||||
instead of letting sdlwindow_blit_surface_size() resize it
|
||||
this stops the window from "flashing" from the wrong aspect
|
||||
size to the right one at startup. */
|
||||
tempwidth = (window->m_win_config.width != 0) ? window->m_win_config.width : 640;
|
||||
tempheight = (window->m_win_config.height != 0) ? window->m_win_config.height : 480;
|
||||
#endif
|
||||
temp = window->get_min_bounds(video_config.keepaspect );
|
||||
}
|
||||
}
|
||||
|
||||
temp = window->get_min_bounds(video_config.keepaspect );
|
||||
|
||||
// create the window .....
|
||||
|
||||
@ -1059,9 +954,14 @@ OSDWORK_CALLBACK( sdl_window_info::complete_create_wt )
|
||||
#if defined(SDLMAME_WIN32)
|
||||
SDL_SetHint(SDL_HINT_VIDEO_MINIMIZE_ON_FOCUS_LOSS, "0");
|
||||
#endif
|
||||
|
||||
// get monitor work area for centering
|
||||
osd_rect work = window->monitor()->usuable_position_size();
|
||||
|
||||
// create the SDL window
|
||||
window->m_sdl_window = SDL_CreateWindow(window->m_title,
|
||||
window->monitor()->position_size().left(), window->monitor()->position_size().top(),
|
||||
work.left() + (work.width() - temp.width()) / 2,
|
||||
work.top() + (work.height() - temp.height()) / 2,
|
||||
temp.width(), temp.height(), window->m_extra_flags);
|
||||
//window().sdl_window() = SDL_CreateWindow(window().m_title, SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED,
|
||||
// width, height, m_extra_flags);
|
||||
@ -1124,7 +1024,12 @@ OSDWORK_CALLBACK( sdl_window_info::complete_create_wt )
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// update monitor resolution after mode change to ensure proper pixel aspect
|
||||
window->monitor()->refresh();
|
||||
if (window->fullscreen() && video_config.switchres)
|
||||
window->monitor()->update_resolution(temp.width(), temp.height());
|
||||
|
||||
// initialize the drawing backend
|
||||
if (window->renderer().create())
|
||||
return (void *) &result[1];
|
||||
@ -1272,8 +1177,12 @@ osd_rect sdl_window_info::constrain_to_aspect_ratio(const osd_rect &rect, int ad
|
||||
float pixel_aspect;
|
||||
osd_monitor_info *monitor = m_monitor;
|
||||
|
||||
// do not constrain aspect ratio for integer scaled views
|
||||
if (m_target->scale_mode() != SCALE_FRACTIONAL)
|
||||
return rect;
|
||||
|
||||
// get the pixel aspect ratio for the target monitor
|
||||
pixel_aspect = monitor->aspect();
|
||||
pixel_aspect = monitor->pixel_aspect();
|
||||
|
||||
// determine the proposed width/height
|
||||
propwidth = rect.width() - extrawidth;
|
||||
@ -1393,7 +1302,7 @@ osd_dim sdl_window_info::get_min_bounds(int constrain)
|
||||
minheight += wnd_extra_height();
|
||||
|
||||
// if we want it constrained, figure out which one is larger
|
||||
if (constrain)
|
||||
if (constrain && m_target->scale_mode() == SCALE_FRACTIONAL)
|
||||
{
|
||||
// first constrain with no height limit
|
||||
osd_rect test1(0,0,minwidth,10000);
|
||||
@ -1457,11 +1366,11 @@ osd_dim sdl_window_info::get_max_bounds(int constrain)
|
||||
maximum = maximum.resize(tempw, temph);
|
||||
|
||||
// constrain to fit
|
||||
if (constrain)
|
||||
if (constrain && m_target->scale_mode() == SCALE_FRACTIONAL)
|
||||
maximum = constrain_to_aspect_ratio(maximum, WMSZ_BOTTOMRIGHT);
|
||||
else
|
||||
{
|
||||
maximum = maximum.resize(maximum.width() - wnd_extra_width(), maximum.height() - wnd_extra_height());
|
||||
}
|
||||
|
||||
// remove extra window stuff
|
||||
maximum = maximum.resize(maximum.width() - wnd_extra_width(), maximum.height() - wnd_extra_height());
|
||||
|
||||
return maximum.dim();
|
||||
}
|
||||
|
@ -85,7 +85,6 @@ public:
|
||||
render_target *target() override { return m_target; }
|
||||
SDL_Window *sdl_window() override { return m_sdl_window; }
|
||||
|
||||
osd_dim blit_surface_size() override;
|
||||
int prescale() const { return m_prescale; }
|
||||
|
||||
// Pointer to next window
|
||||
|
@ -152,20 +152,6 @@ void win_monitor_info::refresh()
|
||||
|
||||
|
||||
|
||||
//============================================================
|
||||
// sdlvideo_monitor_get_aspect
|
||||
//============================================================
|
||||
|
||||
float osd_monitor_info::aspect()
|
||||
{
|
||||
// FIXME: returning 0 looks odd, video_config is bad
|
||||
if (video_config.keepaspect)
|
||||
{
|
||||
return m_aspect / ((float)m_pos_size.width() / (float)m_pos_size.height());
|
||||
}
|
||||
return 0.0f;
|
||||
}
|
||||
|
||||
//============================================================
|
||||
// winvideo_monitor_from_handle
|
||||
//============================================================
|
||||
@ -369,7 +355,6 @@ void windows_osd_interface::extract_video_config()
|
||||
video_config.filter = options().filter();
|
||||
video_config.keepaspect = options().keep_aspect();
|
||||
video_config.numscreens = options().numscreens();
|
||||
video_config.fullstretch = options().uneven_stretch();
|
||||
|
||||
// if we are in debug mode, never go full screen
|
||||
if (machine().debug_flags & DEBUG_FLAG_OSD_ENABLED)
|
||||
|
@ -64,8 +64,6 @@ struct osd_video_config
|
||||
int syncrefresh; // sync only to refresh rate
|
||||
int switchres; // switch resolutions
|
||||
|
||||
int fullstretch; // FXIME: implement in windows!
|
||||
|
||||
// d3d, accel, opengl
|
||||
int filter; // enable filtering
|
||||
//int filter; // enable filtering, disabled if glsl_filter>0
|
||||
|
@ -1581,6 +1581,7 @@ LRESULT CALLBACK win_window_info::video_window_proc(HWND wnd, UINT message, WPAR
|
||||
* should be used.
|
||||
*/
|
||||
window->m_monitor->refresh();
|
||||
window->m_monitor->update_resolution(LOWORD(lparam), HIWORD(lparam));
|
||||
break;
|
||||
|
||||
// set focus: if we're not the primary window, switch back
|
||||
@ -1642,13 +1643,6 @@ void win_window_info::draw_video_contents(HDC dc, int update)
|
||||
}
|
||||
|
||||
|
||||
static inline int better_mode(int width0, int height0, int width1, int height1, float desired_aspect)
|
||||
{
|
||||
float aspect0 = (float)width0 / (float)height0;
|
||||
float aspect1 = (float)width1 / (float)height1;
|
||||
return (fabs(desired_aspect - aspect0) < fabs(desired_aspect - aspect1)) ? 0 : 1;
|
||||
}
|
||||
|
||||
//============================================================
|
||||
// constrain_to_aspect_ratio
|
||||
// (window thread)
|
||||
@ -1661,19 +1655,19 @@ osd_rect win_window_info::constrain_to_aspect_ratio(const osd_rect &rect, int ad
|
||||
INT32 propwidth, propheight;
|
||||
INT32 minwidth, minheight;
|
||||
INT32 maxwidth, maxheight;
|
||||
INT32 viswidth, visheight;
|
||||
INT32 adjwidth, adjheight;
|
||||
float desired_aspect = 1.0f;
|
||||
osd_dim window_dim = get_size();
|
||||
INT32 target_width = window_dim.width();
|
||||
INT32 target_height = window_dim.height();
|
||||
INT32 xscale = 1, yscale = 1;
|
||||
int newwidth, newheight;
|
||||
float pixel_aspect;
|
||||
osd_monitor_info *monitor = winwindow_video_window_monitor(&rect);
|
||||
|
||||
assert(GetCurrentThreadId() == window_threadid);
|
||||
|
||||
// do not constrain aspect ratio for integer scaled views
|
||||
if (m_target->scale_mode() != SCALE_FRACTIONAL)
|
||||
return rect;
|
||||
|
||||
// get the pixel aspect ratio for the target monitor
|
||||
float pixel_aspect = monitor->aspect();
|
||||
pixel_aspect = monitor->pixel_aspect();
|
||||
|
||||
// determine the proposed width/height
|
||||
propwidth = rect.width() - extrawidth;
|
||||
@ -1701,58 +1695,6 @@ osd_rect win_window_info::constrain_to_aspect_ratio(const osd_rect &rect, int ad
|
||||
// get the minimum width/height for the current layout
|
||||
m_target->compute_minimum_size(minwidth, minheight);
|
||||
|
||||
// compute the appropriate visible area if we're trying to keepaspect
|
||||
if (video_config.keepaspect)
|
||||
{
|
||||
// make sure the monitor is up-to-date
|
||||
m_target->compute_visible_area(target_width, target_height, m_monitor->aspect(), m_target->orientation(), target_width, target_height);
|
||||
desired_aspect = (float)target_width / (float)target_height;
|
||||
}
|
||||
|
||||
// non-integer scaling - often gives more pleasing results in full screen
|
||||
newwidth = target_width;
|
||||
newheight = target_height;
|
||||
if (!video_config.fullstretch)
|
||||
{
|
||||
// compute maximum integral scaling to fit the window
|
||||
xscale = (target_width + 2) / newwidth;
|
||||
yscale = (target_height + 2) / newheight;
|
||||
|
||||
// try a little harder to keep the aspect ratio if desired
|
||||
if (video_config.keepaspect)
|
||||
{
|
||||
// if we could stretch more in the X direction, and that makes a better fit, bump the xscale
|
||||
while (newwidth * (xscale + 1) <= window_dim.width() &&
|
||||
better_mode(newwidth * xscale, newheight * yscale, newwidth * (xscale + 1), newheight * yscale, desired_aspect))
|
||||
xscale++;
|
||||
|
||||
// if we could stretch more in the Y direction, and that makes a better fit, bump the yscale
|
||||
while (newheight * (yscale + 1) <= window_dim.height() &&
|
||||
better_mode(newwidth * xscale, newheight * yscale, newwidth * xscale, newheight * (yscale + 1), desired_aspect))
|
||||
yscale++;
|
||||
|
||||
// now that we've maxed out, see if backing off the maximally stretched one makes a better fit
|
||||
if (window_dim.width() - newwidth * xscale < window_dim.height() - newheight * yscale)
|
||||
{
|
||||
while (better_mode(newwidth * xscale, newheight * yscale, newwidth * (xscale - 1), newheight * yscale, desired_aspect) && (xscale >= 0))
|
||||
xscale--;
|
||||
}
|
||||
else
|
||||
{
|
||||
while (better_mode(newwidth * xscale, newheight * yscale, newwidth * xscale, newheight * (yscale - 1), desired_aspect) && (yscale >= 0))
|
||||
yscale--;
|
||||
}
|
||||
}
|
||||
|
||||
// ensure at least a scale factor of 1
|
||||
if (xscale <= 0) xscale = 1;
|
||||
if (yscale <= 0) yscale = 1;
|
||||
|
||||
// apply the final scale
|
||||
newwidth *= xscale;
|
||||
newheight *= yscale;
|
||||
}
|
||||
|
||||
// clamp against the absolute minimum
|
||||
propwidth = MAX(propwidth, MIN_WINDOW_DIM);
|
||||
propheight = MAX(propheight, MIN_WINDOW_DIM);
|
||||
@ -1783,9 +1725,12 @@ osd_rect win_window_info::constrain_to_aspect_ratio(const osd_rect &rect, int ad
|
||||
propwidth = MIN(propwidth, maxwidth);
|
||||
propheight = MIN(propheight, maxheight);
|
||||
|
||||
// compute the visible area based on the proposed rectangle
|
||||
m_target->compute_visible_area(propwidth, propheight, pixel_aspect, m_target->orientation(), viswidth, visheight);
|
||||
|
||||
// compute the adjustments we need to make
|
||||
adjwidth = (propwidth + extrawidth) - rect.width();
|
||||
adjheight = (propheight + extraheight) - rect.height();
|
||||
adjwidth = (viswidth + extrawidth) - rect.width();
|
||||
adjheight = (visheight + extraheight) - rect.height();
|
||||
|
||||
// based on which corner we're adjusting, constrain in different ways
|
||||
osd_rect ret(rect);
|
||||
@ -1812,7 +1757,6 @@ osd_rect win_window_info::constrain_to_aspect_ratio(const osd_rect &rect, int ad
|
||||
ret = rect.move_by(0, -adjheight).resize(rect.width() + adjwidth, rect.height() + adjheight);
|
||||
break;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
@ -1843,7 +1787,7 @@ osd_dim win_window_info::get_min_bounds(int constrain)
|
||||
minheight += wnd_extra_height();
|
||||
|
||||
// if we want it constrained, figure out which one is larger
|
||||
if (constrain)
|
||||
if (constrain && m_target->scale_mode() == SCALE_FRACTIONAL)
|
||||
{
|
||||
// first constrain with no height limit
|
||||
osd_rect test1(0,0,minwidth,10000);
|
||||
@ -1903,15 +1847,9 @@ osd_dim win_window_info::get_max_bounds(int constrain)
|
||||
maximum = maximum.resize(tempw, temph);
|
||||
|
||||
// constrain to fit
|
||||
if (constrain)
|
||||
{
|
||||
if (constrain && m_target->scale_mode() == SCALE_FRACTIONAL)
|
||||
maximum = constrain_to_aspect_ratio(maximum, WMSZ_BOTTOMRIGHT);
|
||||
}
|
||||
else
|
||||
{
|
||||
// No - the maxima returned by usable_position_size are in window units, not usable units
|
||||
//maximum = maximum.resize(maximum.width() - wnd_extra_width(), maximum.height() - wnd_extra_height());
|
||||
}
|
||||
|
||||
return maximum.dim();
|
||||
}
|
||||
|
||||
|
@ -275,10 +275,6 @@ const options_entry windows_options::s_option_entries[] =
|
||||
{ nullptr, nullptr, OPTION_HEADER, "WINDOWS VIDEO OPTIONS" },
|
||||
{ WINOPTION_MENU, "0", OPTION_BOOLEAN, "enables menu bar if available by UI implementation" },
|
||||
|
||||
// DirectDraw-specific options
|
||||
{ nullptr, nullptr, OPTION_HEADER, "DIRECTDRAW-SPECIFIC OPTIONS" },
|
||||
{ WINOPTION_HWSTRETCH ";hws", "1", OPTION_BOOLEAN, "enables hardware stretching" },
|
||||
|
||||
// post-processing options
|
||||
{ nullptr, nullptr, OPTION_HEADER, "DIRECT3D POST-PROCESSING OPTIONS" },
|
||||
{ WINOPTION_HLSL_ENABLE";hlsl", "0", OPTION_BOOLEAN, "enables HLSL post-processing (PS3.0 required)" },
|
||||
|
@ -25,9 +25,6 @@
|
||||
// video options
|
||||
#define WINOPTION_MENU "menu"
|
||||
|
||||
// DirectDraw-specific options
|
||||
#define WINOPTION_HWSTRETCH "hwstretch"
|
||||
|
||||
// core post-processing options
|
||||
#define WINOPTION_HLSL_ENABLE "hlsl_enable"
|
||||
#define WINOPTION_HLSLPATH "hlslpath"
|
||||
@ -128,9 +125,6 @@ public:
|
||||
// video options
|
||||
bool menu() const { return bool_value(WINOPTION_MENU); }
|
||||
|
||||
// DirectDraw-specific options
|
||||
bool hwstretch() const { return bool_value(WINOPTION_HWSTRETCH); }
|
||||
|
||||
// core post-processing options
|
||||
const char *screen_post_fx_dir() const { return value(WINOPTION_HLSLPATH); }
|
||||
bool d3d_hlsl_enable() const { return bool_value(WINOPTION_HLSL_ENABLE); }
|
||||
|
Loading…
Reference in New Issue
Block a user