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_yRatio = yRes / 384.0f;
m_xOffs = xOffset; m_xOffs = xOffset;
m_yOffs = yOffset; m_yOffs = yOffset;
m_xRes = xRes;
m_yRes = yRes;
m_totalXRes = totalXResParam; m_totalXRes = totalXResParam;
m_totalYRes = totalYResParam; 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)) { 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 windowAR = (float)m_totalXRes / (float)m_totalYRes;
float originalAR = 496 / 384.f; float viewableAreaAR = (float)m_xRes / (float)m_yRes;
float correction = windowAR / originalAR; // expand horizontal frustum planes
// 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->x = 0;
vp->y = m_yOffs + (int)((384 - (vp->vpY + vp->vpHeight))*m_yRatio); 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 // Resolution and scaling factors (to support resolutions higher than 496x384) and offsets
float m_xRatio, m_yRatio; float m_xRatio, m_yRatio;
unsigned m_xOffs, m_yOffs; 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 // Real3D Base Matrix Pointer
const float *m_matrixBasePtr; const float *m_matrixBasePtr;

View file

@ -119,7 +119,7 @@ static bool SetGLGeometry(unsigned *xOffsetPtr, unsigned *yOffsetPtr, unsigned *
if (yRes < (xRes/model3Ratio)) if (yRes < (xRes/model3Ratio))
xRes = yRes*model3Ratio; xRes = yRes*model3Ratio;
if (xRes < (yRes*model3Ratio)) if (xRes < (yRes*model3Ratio))
yRes = xRes/model3Ratio; yRes = xRes/model3Ratio;
} }
// Center the visible area // Center the visible area
@ -804,7 +804,9 @@ int Supermodel(const Game &game, ROMSet *rom_set, IEmulator *Model3, CInputs *In
totalXRes = xRes = s_runtime_config["XResolution"].ValueAs<unsigned>(); totalXRes = xRes = s_runtime_config["XResolution"].ValueAs<unsigned>();
totalYRes = yRes = s_runtime_config["YResolution"].ValueAs<unsigned>(); totalYRes = yRes = s_runtime_config["YResolution"].ValueAs<unsigned>();
sprintf(baseTitleStr, "Supermodel - %s", game.title.c_str()); 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; return 1;
// Info log GL information // Info log GL information
@ -972,12 +974,14 @@ int Supermodel(const Game &game, ROMSet *rom_set, IEmulator *Model3, CInputs *In
// Resize screen // Resize screen
totalXRes = xRes = s_runtime_config["XResolution"].ValueAs<unsigned>(); totalXRes = xRes = s_runtime_config["XResolution"].ValueAs<unsigned>();
totalYRes = yRes = s_runtime_config["YResolution"].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; goto QuitError;
// Recreate renderers and attach to the emulator // Recreate renderers and attach to the emulator
Render2D = new CRender2D(s_runtime_config); Render2D = new CRender2D(s_runtime_config);
Render3D = s_runtime_config["New3DEngine"].ValueAs<bool>() ? ((IRender3D *) new New3D::CNew3D(s_runtime_config, Model3->GetGame().name)) : ((IRender3D *) new Legacy3D::CLegacy3D(s_runtime_config)); Render3D = s_runtime_config["New3DEngine"].ValueAs<bool>() ? ((IRender3D *) new New3D::CNew3D(s_runtime_config, Model3->GetGame().name)) : ((IRender3D *) new Legacy3D::CLegacy3D(s_runtime_config));
if (OKAY != Render2D->Init(xOffset, yOffset, xRes, yRes, totalXRes, totalYRes)) if (OKAY != Render2D->Init(xOffset, yOffset, xRes, yRes, totalXRes, totalYRes))
goto QuitError; goto QuitError;
if (OKAY != Render3D->Init(xOffset, yOffset, xRes, yRes, totalXRes, totalYRes)) if (OKAY != Render3D->Init(xOffset, yOffset, xRes, yRes, totalXRes, totalYRes))
@ -1068,7 +1072,7 @@ int Supermodel(const Game &game, ROMSet *rom_set, IEmulator *Model3, CInputs *In
else if (Inputs->uiSoundVolUp->Pressed()) else if (Inputs->uiSoundVolUp->Pressed())
{ {
// Increase sound volume by 10% // Increase sound volume by 10%
int vol = (std::min)(200, s_runtime_config["SoundVolume"].ValueAs<int>() + 10); int vol = (std::min)(200, s_runtime_config["SoundVolume"].ValueAs<int>() + 10);
s_runtime_config.Get("SoundVolume").SetValue(vol); s_runtime_config.Get("SoundVolume").SetValue(vol);
printf("Sound volume: %d%%", vol); printf("Sound volume: %d%%", vol);
if (200 == vol) if (200 == vol)
@ -1309,6 +1313,7 @@ static Util::Config::Node DefaultConfig()
config.Set("YResolution", "384"); config.Set("YResolution", "384");
config.Set("FullScreen", false); config.Set("FullScreen", false);
config.Set("WideScreen", false); config.Set("WideScreen", false);
config.Set("Stretch", false);
config.Set("VSync", true); config.Set("VSync", true);
config.Set("Throttle", true); config.Set("Throttle", true);
config.Set("ShowFrameRate", false); config.Set("ShowFrameRate", false);
@ -1340,7 +1345,8 @@ static Util::Config::Node DefaultConfig()
static void Title(void) static void Title(void)
{ {
puts("Supermodel: A Sega Model 3 Arcade Emulator (Version " SUPERMODEL_VERSION ")"); 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) static void Help(void)
@ -1366,6 +1372,7 @@ static void Help(void)
puts(" -window Windowed mode [Default]"); puts(" -window Windowed mode [Default]");
puts(" -fullscreen Full screen mode"); puts(" -fullscreen Full screen mode");
puts(" -wide-screen Expand 3D field of view to screen width"); 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(" -no-throttle Disable 60 Hz frame rate lock");
puts(" -vsync Lock to vertical refresh rate [Default]"); puts(" -vsync Lock to vertical refresh rate [Default]");
puts(" -no-vsync Do not lock to vertical refresh rate"); puts(" -no-vsync Do not lock to vertical refresh rate");
@ -1465,6 +1472,8 @@ static ParsedCommandLine ParseCommandLine(int argc, char **argv)
{ "-fullscreen", { "FullScreen", true } }, { "-fullscreen", { "FullScreen", true } },
{ "-no-wide-screen", { "WideScreen", false } }, { "-no-wide-screen", { "WideScreen", false } },
{ "-wide-screen", { "WideScreen", true } }, { "-wide-screen", { "WideScreen", true } },
{ "-stretch", { "Stretch", true } },
{ "-no-stretch", { "Stretch", false } },
{ "-no-multi-texture", { "MultiTexture", false } }, { "-no-multi-texture", { "MultiTexture", false } },
{ "-multi-texture", { "MultiTexture", true } }, { "-multi-texture", { "MultiTexture", true } },
{ "-throttle", { "Throttle", true } }, { "-throttle", { "Throttle", true } },
@ -1482,8 +1491,8 @@ static ParsedCommandLine ParseCommandLine(int argc, char **argv)
{ "-dsb", { "EmulateDSB", true } }, { "-dsb", { "EmulateDSB", true } },
{ "-no-dsb", { "EmulateDSB", false } }, { "-no-dsb", { "EmulateDSB", false } },
#ifdef NET_BOARD #ifdef NET_BOARD
{ "-net", { "EmulateNet", true } }, { "-net", { "EmulateNet", true } },
{ "-no-net", { "EmulateNet", false } }, { "-no-net", { "EmulateNet", false } },
#endif #endif
#ifdef SUPERMODEL_WIN32 #ifdef SUPERMODEL_WIN32
{ "-no-force-feedback", { "ForceFeedback", false } }, { "-no-force-feedback", { "ForceFeedback", false } },