summaryrefslogtreecommitdiffstats
path: root/src/emu/render.cpp
diff options
context:
space:
mode:
author Antonio Giner <estudio@antonioginer.com>2016-03-20 21:57:38 +0100
committer Antonio Giner <estudio@antonioginer.com>2016-03-20 21:57:38 +0100
commitbb5188522985dc71d7e744d02abf28d1ae9e270a (patch)
tree3f8efe2d89b88defac7897385b1019f1bc6830e1 /src/emu/render.cpp
parent57199a7dff8d53f88951a08dc0f8fbff9d11ad8d (diff)
Move integer scaling implementation to render_target::compute_visible_area
- Add core option -unevenstretch - Add core option -unevenstretchx
Diffstat (limited to 'src/emu/render.cpp')
-rw-r--r--src/emu/render.cpp116
1 files changed, 85 insertions, 31 deletions
diff --git a/src/emu/render.cpp b/src/emu/render.cpp
index 9b4782c2b85..db4f1442ec2 100644
--- a/src/emu/render.cpp
+++ b/src/emu/render.cpp
@@ -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;
- // stretch-to-fit case
- else
- {
- width = (float)target_width;
- height = (float)target_height;
- scale = 1.0f;
- }
+ // 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));
+ }
- // set the final width/height
- visible_width = render_round_nearest(width * scale);
- visible_height = render_round_nearest(height * scale);
+ // 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;
+ }
+ }
}