Aspect ratio correction is now properly applied to the TIA in windowed

and (simulated) fullscreen mode.

Fullscreen mode is now simulated in that it creates a window that matches
what would appear in fullscreen.  The next thing to do is actually have
the backend create this fullscreen mode correctly.

Changed 'gl_fsscale' to 'tia.fsfill' to more properly indicate what the
option does.


git-svn-id: svn://svn.code.sf.net/p/stella/code/trunk@2894 8b62c5a3-ac7e-4cc8-8f21-d9a121418aba
This commit is contained in:
stephena 2014-06-02 14:34:12 +00:00
parent 38b586ae7b
commit 8f2123a5bf
7 changed files with 91 additions and 114 deletions

View File

@ -1837,8 +1837,8 @@
</tr>
<tr>
<td><pre>FIXSDL-gl_fsscale &lt;1|0&gt;</pre></td>
<td>OpenGL mode only. Stretch TIA image completely while in fullscreen mode
<td><pre>-tia.fsfill &lt;1|0&gt;</pre></td>
<td>Stretch TIA image completely while in fullscreen mode
(vs. an integral stretch which won't necessarily completely fill the screen).</td>
</tr>

View File

@ -96,8 +96,16 @@ void FrameBufferSDL2::queryHardware(uInt32& w, uInt32& h, VariantList& renderers
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
bool FrameBufferSDL2::setVideoMode(const string& title, const VideoMode& mode)
bool FrameBufferSDL2::setVideoMode(const string& title, const VideoMode& mode,
bool fullscreen_toggle)
{
cerr << "fullscreen_toggle=" << fullscreen_toggle << endl;
#if 0
uInt32 flags = enable ? SDL_WINDOW_FULLSCREEN_DESKTOP : 0;
if(SDL_SetWindowFullscreen(myWindow, flags))
myOSystem.settings().setValue("fullscreen", enable);
#endif
// If not initialized by this point, then immediately fail
if(SDL_WasInit(SDL_INIT_VIDEO) == 0)
return false;
@ -118,7 +126,7 @@ bool FrameBufferSDL2::setVideoMode(const string& title, const VideoMode& mode)
int pos = myOSystem.settings().getBool("center")
? SDL_WINDOWPOS_CENTERED : SDL_WINDOWPOS_UNDEFINED;
myWindow = SDL_CreateWindow(title.c_str(),
pos, pos, mode.image.width(), mode.image.height(),
pos, pos, mode.screen.w, mode.screen.h,
0);
if(myWindow == NULL)
{
@ -193,14 +201,6 @@ void FrameBufferSDL2::grabMouse(bool grab)
//FIXSDL SDL_WM_GrabInput(grab ? SDL_GRAB_ON : SDL_GRAB_OFF);
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void FrameBufferSDL2::enableFullscreen(bool enable)
{
uInt32 flags = enable ? SDL_WINDOW_FULLSCREEN_DESKTOP : 0;
if(SDL_SetWindowFullscreen(myWindow, flags))
myOSystem.settings().setValue("fullscreen", enable);
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
bool FrameBufferSDL2::fullScreen() const
{

View File

@ -121,12 +121,8 @@ class FrameBufferSDL2 : public FrameBuffer
@return False on any errors, else true
*/
bool setVideoMode(const string& title, const VideoMode& mode);
/**
Enables/disables fullscreen mode.
*/
void enableFullscreen(bool enable);
bool setVideoMode(const string& title, const VideoMode& mode,
bool fullscreen_toggle);
/**
This method is called to invalidate the contents of the entire

View File

@ -193,7 +193,7 @@ FBInitStatus FrameBuffer::createDisplay(const string& title,
return kFailTooLarge;
// FIXSDL - remove size limitations here?
if(myOSystem.settings().getString("fullscreen") == "1")
if(myOSystem.settings().getBool("fullscreen"))
{
if(myDesktopSize.w < width || myDesktopSize.h < height)
return kFailTooLarge;
@ -216,12 +216,13 @@ FBInitStatus FrameBuffer::createDisplay(const string& title,
// Initialize video subsystem (make sure we get a valid mode)
string pre_about = about();
const VideoMode& mode = getSavedVidMode(useFullscreen);
myImageRect = mode.image;
myScreenSize = mode.screen;
if(width <= (uInt32)myScreenSize.w && height <= (uInt32)myScreenSize.h)
if(width <= (uInt32)mode.screen.w && height <= (uInt32)mode.screen.h)
{
if(setVideoMode(myScreenTitle, mode))
{
myImageRect = mode.image;
myScreenSize = mode.screen;
// Inform TIA surface about new mode
if(myOSystem.eventHandler().state() != EventHandler::S_LAUNCHER &&
myOSystem.eventHandler().state() != EventHandler::S_DEBUGGER)
@ -523,9 +524,6 @@ inline void FrameBuffer::drawMessage()
inline void FrameBuffer::drawTIA()
{
myTIASurface->render();
// Let postFrameUpdate() know that a change has been made
//FIXSDL invalidate();
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@ -646,20 +644,20 @@ void FrameBuffer::resetSurfaces()
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void FrameBuffer::setPalette(const uInt32* palette)
void FrameBuffer::setPalette(const uInt32* raw_palette)
{
// Set palette for normal fill
for(int i = 0; i < 256; ++i)
{
Uint8 r = (palette[i] >> 16) & 0xff;
Uint8 g = (palette[i] >> 8) & 0xff;
Uint8 b = palette[i] & 0xff;
Uint8 r = (raw_palette[i] >> 16) & 0xff;
Uint8 g = (raw_palette[i] >> 8) & 0xff;
Uint8 b = raw_palette[i] & 0xff;
myPalette[i] = mapRGB(r, g, b);
}
// Let the TIA surface know about the new palette
myTIASurface->setPalette(myPalette, palette);
myTIASurface->setPalette(myPalette, raw_palette);
myRedrawEntireFrame = true;
}
@ -677,26 +675,24 @@ void FrameBuffer::stateChanged(EventHandler::State state)
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void FrameBuffer::setFullscreen(bool enable)
{
cerr << "setFullscreen: " << enable << endl;
enableFullscreen(enable);
const VideoMode& mode = getSavedVidMode(enable);
cerr << "setFullscreen: " << enable << " " << mode << endl;
if(setVideoMode(myScreenTitle, mode, true))
{
myImageRect = mode.image;
myScreenSize = mode.screen;
// Inform TIA surface about new mode
if(myOSystem.eventHandler().state() != EventHandler::S_LAUNCHER &&
myOSystem.eventHandler().state() != EventHandler::S_DEBUGGER)
myTIASurface->initialize(myOSystem.console(), mode);
#if 0 //FIXSDL
#ifdef WINDOWED_SUPPORT
// '-1' means fullscreen mode is completely disabled
bool full = enable && myOSystem.settings().getString("fullscreen") != "-1";
setHint(kFullScreen, full);
// Do a dummy call to getSavedVidMode to set up the modelists
// and have it point to the correct 'current' mode
getSavedVidMode();
// Do a mode change to the 'current' mode by not passing a '+1' or '-1'
// to changeVidMode()
changeVidMode(0);
#endif
#endif
// Did we get the requested fullscreen state?
myOSystem.settings().setValue("fullscreen", fullScreen());
resetSurfaces();
setCursorState();
}
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@ -725,14 +721,13 @@ bool FrameBuffer::changeWindowedVidMode(int direction)
return false;
const VideoMode& mode = myCurrentModeList->current();
myImageRect = mode.image;
myScreenSize = mode.screen;
if(setVideoMode(myScreenTitle, mode))
{
myImageRect = mode.image;
myScreenSize = mode.screen;
// Inform TIA surface about new mode
if(myOSystem.eventHandler().state() != EventHandler::S_LAUNCHER &&
myOSystem.eventHandler().state() != EventHandler::S_DEBUGGER)
myTIASurface->initialize(myOSystem.console(), mode);
myTIASurface->initialize(myOSystem.console(), mode);
resetSurfaces();
showMessage(mode.description);
@ -824,11 +819,10 @@ void FrameBuffer::setAvailableVidModes(uInt32 baseWidth, uInt32 baseHeight)
}
// TIA fullscreen mode
// GUI::Size screen(myDesktopWidth, myDesktopHeight);
myFullscreenModeList.add(
VideoMode(baseWidth, baseHeight, myDesktopSize.w, myDesktopSize.h, true)
);
VideoMode mode(baseWidth*maxZoom, baseHeight*maxZoom,
myDesktopSize.w, myDesktopSize.h, true);
mode.applyAspectCorrection(aspect, myOSystem.settings().getBool("tia.fsfill"));
myFullscreenModeList.add(mode);
}
else // UI mode
{
@ -840,12 +834,6 @@ void FrameBuffer::setAvailableVidModes(uInt32 baseWidth, uInt32 baseHeight)
VideoMode(baseWidth, baseHeight, myDesktopSize.w, myDesktopSize.h, true)
);
}
#if 0 //FIXSDL
cerr << "Windowed modes:\n" << myWindowedModeList << endl
<< "Fullscreen modes:\n" << myFullscreenModeList << endl
<< endl;
#endif
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@ -899,54 +887,48 @@ VideoMode::VideoMode(uInt32 iw, uInt32 ih, uInt32 sw, uInt32 sh,
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void VideoMode::applyAspectCorrection(uInt32 aspect, uInt32 stretch)
void VideoMode::applyAspectCorrection(uInt32 aspect, bool stretch)
{
// Width is modified by aspect ratio; other factors may be applied below
uInt32 iw = (uInt32)(float(image.width() * aspect) / 100.0);
uInt32 ih = image.height();
if(stretch)
if(fullscreen)
{
#if 0
// Fullscreen mode stretching
if(fullScreen() &&
(mode.image_w < mode.screen_w) && (mode.image_h < mode.screen_h))
{
float stretchFactor = 1.0;
float scaleX = float(mode.image_w) / mode.screen_w;
float scaleY = float(mode.image_h) / mode.screen_h;
float stretchFactor = 1.0;
float scaleX = float(image.width()) / screen.w;
float scaleY = float(image.height()) / screen.h;
// Scale to actual or integral factors
if(myOSystem.settings().getBool("gl_fsscale"))
// Scale to actual or integral factors
if(stretch)
{
// Scale to full (non-integral) available space
if(scaleX > scaleY)
stretchFactor = float(screen.w) / image.width();
else
stretchFactor = float(screen.h) / image.height();
}
else
{
// Only scale to an integral amount
if(scaleX > scaleY)
{
// Scale to full (non-integral) available space
if(scaleX > scaleY)
stretchFactor = float(mode.screen_w) / mode.image_w;
else
stretchFactor = float(mode.screen_h) / mode.image_h;
int bw = image.width() / zoom;
stretchFactor = float(int(screen.w / bw) * bw) / image.width();
}
else
{
// Only scale to an integral amount
if(scaleX > scaleY)
{
int bw = mode.image_w / mode.gfxmode.zoom;
stretchFactor = float(int(mode.screen_w / bw) * bw) / mode.image_w;
}
else
{
int bh = mode.image_h / mode.gfxmode.zoom;
stretchFactor = float(int(mode.screen_h / bh) * bh) / mode.image_h;
}
int bh = image.height() / zoom;
stretchFactor = float(int(screen.h / bh) * bh) / image.height();
}
mode.image_w = (Uint16) (stretchFactor * mode.image_w);
mode.image_h = (Uint16) (stretchFactor * mode.image_h);
}
#endif
iw = (uInt32) (stretchFactor * image.width());
ih = (uInt32) (stretchFactor * image.height());
}
else
{
// In non-stretch mode, the screen size changes to match the image width
// In windowed mode, the screen size changes to match the image width
// Height is never modified in this mode
screen.w = iw;
}

View File

@ -108,14 +108,14 @@ class VideoMode
friend ostream& operator<<(ostream& os, const VideoMode& vm)
{
os << "image=" << vm.image << " screen=" << vm.screen << endl
<< "full= " << vm.fullscreen << " zoom=" << vm.zoom
os << "image=" << vm.image << " screen=" << vm.screen
<< " full= " << vm.fullscreen << " zoom=" << vm.zoom
<< " desc=" << vm.description;
return os;
}
private:
void applyAspectCorrection(uInt32 aspect, uInt32 stretch = false);
void applyAspectCorrection(uInt32 aspect, bool stretch = false);
};
/**
@ -303,9 +303,9 @@ class FrameBuffer
/**
Set up the TIA/emulation palette for a screen of any depth > 8.
@param palette The array of colors
@param palette The array of colors in R/G/B format
*/
void setPalette(const uInt32* palette);
void setPalette(const uInt32* raw_palette);
/**
Informs the Framebuffer of a change in EventHandler state.
@ -375,16 +375,15 @@ class FrameBuffer
@param title The title for the created window
@param mode The video mode to use
@param fullscreen_toggle Indicate whether this video mode change is
due to a fullscreen/windowed toggle or not; some backends
can use this information to perform a more optimized mode
change
@return False on any errors, else true
*/
virtual bool setVideoMode(const string& title, const VideoMode& mode) = 0;
/**
Enables/disables fullscreen mode.
@param enable Set the fullscreen mode to this value
*/
virtual void enableFullscreen(bool enable) = 0;
virtual bool setVideoMode(const string& title, const VideoMode& mode,
bool fullscreen_toggle = false) = 0;
/**
This method is called to invalidate the contents of the entire

View File

@ -53,7 +53,7 @@ Settings::Settings(OSystem& osystem)
setInternal("tia.inter", "false");
setInternal("tia.aspectn", "90");
setInternal("tia.aspectp", "100");
setInternal("gl_fsscale", "false"); //FIXSDL - deprecated
setInternal("tia.fsfill", "false");
// TV filtering options
setInternal("tv.filter", "0");
@ -341,7 +341,7 @@ void Settings::usage()
<< endl
<< " -video <type> Type is one of the following:\n"
#ifdef BSPF_WINDOWS
<< " direct3d Direct3D 9/11 acceleration\n"
<< " direct3d Direct3D acceleration\n"
#endif
<< " opengl OpenGL acceleration\n"
<< " opengles2 OpenGLES 2 acceleration\n"
@ -368,9 +368,9 @@ void Settings::usage()
#endif
<< " -tia.zoom <zoom> Use the specified zoom level (windowed mode) for TIA image\n"
<< " -tia.inter <1|0> Enable interpolated (smooth) scaling for TIA image\n"
<< " -tia.aspectn <number> Scale the TIA width by the given percentage in NTSC mode\n"
<< " -tia.aspectp <number> Scale the TIA width by the given percentage in PAL mode\n"
<< " -gl_fsscale <1|0> Stretch GL image in fullscreen emulation mode to max/integer scale\n"
<< " -tia.aspectn <number> Scale TIA width by the given percentage in NTSC mode\n"
<< " -tia.aspectp <number> Scale TIA width by the given percentage in PAL mode\n"
<< " -tia.fsfill <1|0> Stretch TIA image to fill fullscreen mode\n"
<< endl
<< " -tv.filter <0-5> Set TV effects off (0) or to specified mode (1-5)\n"
<< " -tv.scanlines <0-100> Set scanline intensity to percentage (0 disables completely)\n"

View File

@ -353,7 +353,7 @@ void VideoDialog::loadConfig()
myFullscreen->setState(instance().settings().getBool("fullscreen"));
// Fullscreen stretch setting
myUseStretch->setState(instance().settings().getBool("tia.fs_stretch"));
myUseStretch->setState(instance().settings().getBool("tia.fsfill"));
// Use sync to vertical blank
myUseVSync->setState(instance().settings().getBool("vsync"));
@ -433,7 +433,7 @@ void VideoDialog::saveConfig()
instance().console().toggleColorLoss(myColorLoss->getState());
// Fullscreen stretch setting
instance().settings().setValue("tia,fs_stretch", myUseStretch->getState());
instance().settings().setValue("tia.fsfill", myUseStretch->getState());
// Use sync to vertical blank
instance().settings().setValue("vsync", myUseVSync->getState());