Added a stretch mode (-stretch) and modified new renderer's viewport code (hopefully correctly) to handle aspect ratio correction and widening the way the legacy one does.

This commit is contained in:
Bart Trzynadlowski 2018-05-03 03:46:44 +00:00
parent c6b86c0812
commit 3f9b1b76e5
3 changed files with 46 additions and 11 deletions

View file

@ -72,6 +72,8 @@ bool CNew3D::Init(unsigned xOffset, unsigned yOffset, unsigned xRes, unsigned yR
m_yRatio = yRes / 384.0f;
m_xOffs = xOffset;
m_yOffs = yOffset;
m_xRes = xRes;
m_yRes = yRes;
m_totalXRes = totalXResParam;
m_totalYRes = totalYResParam;
@ -1583,9 +1585,32 @@ void CNew3D::CalcViewport(Viewport* vp, float near, float far)
if ((vp->vpX == 0) && (vp->vpWidth >= 495) && (vp->vpY == 0) && (vp->vpHeight >= 383)) {
/*
* Compute aspect ratio correction factor. "Window" refers to the full GL
* viewport (i.e., totalXRes x totalYRes). "Viewable area" is the effective
* Model 3 screen (xRes x yRes). In non-wide-screen, non-stretch mode, this
* is intended to replicate the 496x384 display and may in general be
* smaller than the window. The rest of the window appears to have a
* border, which is created by a scissor box.
*
* In wide-screen mode, we want to expand the frustum horizontally to fill
* the window. We want the aspect ratio to be correct. To accomplish this,
* the viewable area is set *the same* as in non-wide-screen mode (e.g.,
* often smaller than the window) but glScissor() is set by the OSD layer's
* screen setup code to reveal the entire window.
*
* In stretch mode, the window and viewable area are both set the same,
* which means there will be no aspect ratio correction and the display
* will stretch to fill the entire window while keeping the view frustum
* the same as a 496x384 Model 3 display. The display will be distorted.
*/
float windowAR = (float)m_totalXRes / (float)m_totalYRes;
float originalAR = 496 / 384.f;
float correction = windowAR / originalAR; // expand horizontal frustum planes
float viewableAreaAR = (float)m_xRes / (float)m_yRes;
// Will expand horizontal frustum planes only in non-stretch mode (wide-
// screen and non-wide-screen modes have identical resolution parameters
// and only their scissor box differs)
float correction = windowAR / viewableAreaAR;
vp->x = 0;
vp->y = m_yOffs + (int)((384 - (vp->vpY + vp->vpHeight))*m_yRatio);

View file

@ -233,7 +233,8 @@ private:
// Resolution and scaling factors (to support resolutions higher than 496x384) and offsets
float m_xRatio, m_yRatio;
unsigned m_xOffs, m_yOffs;
unsigned m_totalXRes, m_totalYRes;
unsigned m_xRes, m_yRes; // resolution of Model 3's 496x384 display area within the window
unsigned m_totalXRes, m_totalYRes; // total OpenGL window resolution
// Real3D Base Matrix Pointer
const float *m_matrixBasePtr;

View file

@ -804,7 +804,9 @@ int Supermodel(const Game &game, ROMSet *rom_set, IEmulator *Model3, CInputs *In
totalXRes = xRes = s_runtime_config["XResolution"].ValueAs<unsigned>();
totalYRes = yRes = s_runtime_config["YResolution"].ValueAs<unsigned>();
sprintf(baseTitleStr, "Supermodel - %s", game.title.c_str());
if (OKAY != CreateGLScreen(baseTitleStr, &xOffset, &yOffset ,&xRes, &yRes, &totalXRes, &totalYRes, true, s_runtime_config["FullScreen"].ValueAs<bool>()))
bool stretch = s_runtime_config["Stretch"].ValueAs<bool>();
bool fullscreen = s_runtime_config["FullScreen"].ValueAs<bool>();
if (OKAY != CreateGLScreen(baseTitleStr, &xOffset, &yOffset ,&xRes, &yRes, &totalXRes, &totalYRes, !stretch, fullscreen))
return 1;
// Info log GL information
@ -972,7 +974,9 @@ int Supermodel(const Game &game, ROMSet *rom_set, IEmulator *Model3, CInputs *In
// Resize screen
totalXRes = xRes = s_runtime_config["XResolution"].ValueAs<unsigned>();
totalYRes = yRes = s_runtime_config["YResolution"].ValueAs<unsigned>();
if (OKAY != ResizeGLScreen(&xOffset,&yOffset,&xRes,&yRes,&totalXRes,&totalYRes,true,s_runtime_config["FullScreen"].ValueAs<bool>()))
bool stretch = s_runtime_config["Stretch"].ValueAs<bool>();
bool fullscreen = s_runtime_config["FullScreen"].ValueAs<bool>();
if (OKAY != ResizeGLScreen(&xOffset,&yOffset,&xRes,&yRes,&totalXRes,&totalYRes,!stretch,fullscreen))
goto QuitError;
// Recreate renderers and attach to the emulator
@ -1309,6 +1313,7 @@ static Util::Config::Node DefaultConfig()
config.Set("YResolution", "384");
config.Set("FullScreen", false);
config.Set("WideScreen", false);
config.Set("Stretch", false);
config.Set("VSync", true);
config.Set("Throttle", true);
config.Set("ShowFrameRate", false);
@ -1340,7 +1345,8 @@ static Util::Config::Node DefaultConfig()
static void Title(void)
{
puts("Supermodel: A Sega Model 3 Arcade Emulator (Version " SUPERMODEL_VERSION ")");
puts("Copyright 2011-2018 by Bart Trzynadlowski, Nik Henson, Ian Curtis, Harry Tuttle and Spindizzi\n");
puts("Copyright 2011-2018 by Bart Trzynadlowski, Nik Henson, Ian Curtis,");
puts(" Harry Tuttle, and Spindizzi\n");
}
static void Help(void)
@ -1366,6 +1372,7 @@ static void Help(void)
puts(" -window Windowed mode [Default]");
puts(" -fullscreen Full screen mode");
puts(" -wide-screen Expand 3D field of view to screen width");
puts(" -stretch Fit viewport to resolution, ignoring aspect ratio");
puts(" -no-throttle Disable 60 Hz frame rate lock");
puts(" -vsync Lock to vertical refresh rate [Default]");
puts(" -no-vsync Do not lock to vertical refresh rate");
@ -1465,6 +1472,8 @@ static ParsedCommandLine ParseCommandLine(int argc, char **argv)
{ "-fullscreen", { "FullScreen", true } },
{ "-no-wide-screen", { "WideScreen", false } },
{ "-wide-screen", { "WideScreen", true } },
{ "-stretch", { "Stretch", true } },
{ "-no-stretch", { "Stretch", false } },
{ "-no-multi-texture", { "MultiTexture", false } },
{ "-multi-texture", { "MultiTexture", true } },
{ "-throttle", { "Throttle", true } },