mirror of
https://github.com/holub/mame
synced 2025-04-20 23:42:22 +03:00
Move integer scaling implementation to render_target::compute_visible_area
- Add core option -unevenstretch - Add core option -unevenstretchx
This commit is contained in:
parent
57199a7dff
commit
bb51885229
@ -91,8 +91,10 @@ const options_entry emu_options::s_option_entries[] =
|
||||
// render options
|
||||
{ nullptr, nullptr, OPTION_HEADER, "CORE RENDER OPTIONS" },
|
||||
{ OPTION_KEEPASPECT ";ka", "1", OPTION_BOOLEAN, "constrain to the proper aspect ratio" },
|
||||
{ OPTION_INTSCALEX ";sx", "0", OPTION_INTEGER, "set horizontal scale factor for integer scaled views."},
|
||||
{ OPTION_INTSCALEY ";sy", "0", OPTION_INTEGER, "set vertical scale factor for integer scaled views."},
|
||||
{ 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" },
|
||||
|
@ -100,6 +100,8 @@ enum
|
||||
|
||||
// core render options
|
||||
#define OPTION_KEEPASPECT "keepaspect"
|
||||
#define OPTION_UNEVENSTRETCH "unevenstretch"
|
||||
#define OPTION_UNEVENSTRETCHX "unevenstretchx"
|
||||
#define OPTION_INTSCALEX "intscalex"
|
||||
#define OPTION_INTSCALEY "intscaley"
|
||||
|
||||
@ -289,6 +291,8 @@ public:
|
||||
|
||||
// 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); }
|
||||
|
||||
|
@ -933,8 +933,12 @@ render_target::render_target(render_manager &manager, const char *layoutfile, UI
|
||||
|
||||
// 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();
|
||||
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())
|
||||
@ -1010,6 +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 != 0.0? pixel_aspect : 1.0;
|
||||
}
|
||||
|
||||
|
||||
@ -1144,41 +1149,90 @@ 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 (m_keepaspect)
|
||||
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:
|
||||
{
|
||||
INT32 src_width, src_height;
|
||||
compute_minimum_size(src_width, src_height);
|
||||
|
||||
float dest_width, dest_width_asp, dest_height, dest_height_asp;
|
||||
dest_width = dest_width_asp = (float)target_width;
|
||||
dest_height = dest_height_asp = (float)target_height;
|
||||
|
||||
float src_aspect = m_curview->effective_aspect(m_layerconfig);
|
||||
float dest_aspect = dest_width / dest_height * target_pixel_aspect;
|
||||
|
||||
// We need to work out which one is the horizontal axis, regardless of the monitor orientation
|
||||
float xscale, yscale;
|
||||
if (dest_aspect > 1.0)
|
||||
{
|
||||
// x-axis matches monitor's horizontal dimension
|
||||
dest_width_asp *= m_keepaspect? src_aspect / dest_aspect : 1.0;
|
||||
xscale = m_scale_mode == SCALE_INTEGER?
|
||||
MAX(1, render_round_nearest(dest_width_asp / src_width)) : dest_width_asp / src_width;
|
||||
yscale = MAX(1, render_round_nearest(dest_height / src_height));
|
||||
}
|
||||
else
|
||||
{
|
||||
// y-axis matches monitor's vertical dimension
|
||||
dest_height_asp *= m_keepaspect? dest_aspect / src_aspect : 1.0;
|
||||
yscale = m_scale_mode == SCALE_INTEGER?
|
||||
MAX(1, render_round_nearest(dest_height_asp / src_height)) : dest_height_asp / src_height;
|
||||
xscale = MAX(1, render_round_nearest(dest_width / src_width));
|
||||
}
|
||||
|
||||
// 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);
|
||||
}
|
||||
|
||||
|
||||
|
@ -73,11 +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 types
|
||||
const UINT32 RENDER_SCALE_FRACTIONAL = 0x00; // compute bounds using dimensionless proportions (default)
|
||||
const UINT32 RENDER_SCALE_INTEGER = 0x01; // compute integer scaling factors for both axes, based on target dimensions
|
||||
const UINT32 RENDER_SCALE_STRETCH_H = 0x02; // compute fractional scaling factor for x-axis, and integer factor for y-axis
|
||||
const UINT32 RENDER_SCALE_STRETCH_FULL = 0x03; // match bounds with physical target dimensions in pixels
|
||||
// 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;
|
||||
@ -91,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;
|
||||
|
||||
@ -897,7 +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_type() const { return m_scale_type; }
|
||||
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; }
|
||||
@ -1002,7 +1003,7 @@ private:
|
||||
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_type; // type of scale to apply
|
||||
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
|
||||
|
@ -1192,7 +1192,7 @@ osd_rect sdl_window_info::constrain_to_aspect_ratio(const osd_rect &rect, int ad
|
||||
osd_monitor_info *monitor = m_monitor;
|
||||
|
||||
// do not constrain aspect ratio for integer scaled views
|
||||
if (m_target->scale_type() != RENDER_SCALE_FRACTIONAL)
|
||||
if (m_target->scale_mode() != SCALE_FRACTIONAL)
|
||||
return rect;
|
||||
|
||||
// get the pixel aspect ratio for the target monitor
|
||||
@ -1316,7 +1316,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 && m_target->scale_type() == RENDER_SCALE_FRACTIONAL)
|
||||
if (constrain && m_target->scale_mode() == SCALE_FRACTIONAL)
|
||||
{
|
||||
// first constrain with no height limit
|
||||
osd_rect test1(0,0,minwidth,10000);
|
||||
@ -1380,7 +1380,7 @@ osd_dim sdl_window_info::get_max_bounds(int constrain)
|
||||
maximum = maximum.resize(tempw, temph);
|
||||
|
||||
// constrain to fit
|
||||
if (constrain && m_target->scale_type() == RENDER_SCALE_FRACTIONAL)
|
||||
if (constrain && m_target->scale_mode() == SCALE_FRACTIONAL)
|
||||
maximum = constrain_to_aspect_ratio(maximum, WMSZ_BOTTOMRIGHT);
|
||||
|
||||
// remove extra window stuff
|
||||
|
@ -1663,7 +1663,7 @@ osd_rect win_window_info::constrain_to_aspect_ratio(const osd_rect &rect, int ad
|
||||
assert(GetCurrentThreadId() == window_threadid);
|
||||
|
||||
// do not constrain aspect ratio for integer scaled views
|
||||
if (m_target->scale_type() != RENDER_SCALE_FRACTIONAL)
|
||||
if (m_target->scale_mode() != SCALE_FRACTIONAL)
|
||||
return rect;
|
||||
|
||||
// get the pixel aspect ratio for the target monitor
|
||||
@ -1787,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 && m_target->scale_type() == RENDER_SCALE_FRACTIONAL)
|
||||
if (constrain && m_target->scale_mode() == SCALE_FRACTIONAL)
|
||||
{
|
||||
// first constrain with no height limit
|
||||
osd_rect test1(0,0,minwidth,10000);
|
||||
@ -1847,7 +1847,7 @@ osd_dim win_window_info::get_max_bounds(int constrain)
|
||||
maximum = maximum.resize(tempw, temph);
|
||||
|
||||
// constrain to fit
|
||||
if (constrain && m_target->scale_type() == RENDER_SCALE_FRACTIONAL)
|
||||
if (constrain && m_target->scale_mode() == SCALE_FRACTIONAL)
|
||||
maximum = constrain_to_aspect_ratio(maximum, WMSZ_BOTTOMRIGHT);
|
||||
|
||||
return maximum.dim();
|
||||
|
Loading…
Reference in New Issue
Block a user