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>
<tr> <tr>
<td><pre>FIXSDL-gl_fsscale &lt;1|0&gt;</pre></td> <td><pre>-tia.fsfill &lt;1|0&gt;</pre></td>
<td>OpenGL mode only. Stretch TIA image completely while in fullscreen mode <td>Stretch TIA image completely while in fullscreen mode
(vs. an integral stretch which won't necessarily completely fill the screen).</td> (vs. an integral stretch which won't necessarily completely fill the screen).</td>
</tr> </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 not initialized by this point, then immediately fail
if(SDL_WasInit(SDL_INIT_VIDEO) == 0) if(SDL_WasInit(SDL_INIT_VIDEO) == 0)
return false; return false;
@ -118,7 +126,7 @@ bool FrameBufferSDL2::setVideoMode(const string& title, const VideoMode& mode)
int pos = myOSystem.settings().getBool("center") int pos = myOSystem.settings().getBool("center")
? SDL_WINDOWPOS_CENTERED : SDL_WINDOWPOS_UNDEFINED; ? SDL_WINDOWPOS_CENTERED : SDL_WINDOWPOS_UNDEFINED;
myWindow = SDL_CreateWindow(title.c_str(), myWindow = SDL_CreateWindow(title.c_str(),
pos, pos, mode.image.width(), mode.image.height(), pos, pos, mode.screen.w, mode.screen.h,
0); 0);
if(myWindow == NULL) if(myWindow == NULL)
{ {
@ -193,14 +201,6 @@ void FrameBufferSDL2::grabMouse(bool grab)
//FIXSDL SDL_WM_GrabInput(grab ? SDL_GRAB_ON : SDL_GRAB_OFF); //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 bool FrameBufferSDL2::fullScreen() const
{ {

View File

@ -121,12 +121,8 @@ class FrameBufferSDL2 : public FrameBuffer
@return False on any errors, else true @return False on any errors, else true
*/ */
bool setVideoMode(const string& title, const VideoMode& mode); bool setVideoMode(const string& title, const VideoMode& mode,
bool fullscreen_toggle);
/**
Enables/disables fullscreen mode.
*/
void enableFullscreen(bool enable);
/** /**
This method is called to invalidate the contents of the entire 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; return kFailTooLarge;
// FIXSDL - remove size limitations here? // FIXSDL - remove size limitations here?
if(myOSystem.settings().getString("fullscreen") == "1") if(myOSystem.settings().getBool("fullscreen"))
{ {
if(myDesktopSize.w < width || myDesktopSize.h < height) if(myDesktopSize.w < width || myDesktopSize.h < height)
return kFailTooLarge; return kFailTooLarge;
@ -216,12 +216,13 @@ FBInitStatus FrameBuffer::createDisplay(const string& title,
// Initialize video subsystem (make sure we get a valid mode) // Initialize video subsystem (make sure we get a valid mode)
string pre_about = about(); string pre_about = about();
const VideoMode& mode = getSavedVidMode(useFullscreen); const VideoMode& mode = getSavedVidMode(useFullscreen);
myImageRect = mode.image; if(width <= (uInt32)mode.screen.w && height <= (uInt32)mode.screen.h)
myScreenSize = mode.screen;
if(width <= (uInt32)myScreenSize.w && height <= (uInt32)myScreenSize.h)
{ {
if(setVideoMode(myScreenTitle, mode)) if(setVideoMode(myScreenTitle, mode))
{ {
myImageRect = mode.image;
myScreenSize = mode.screen;
// Inform TIA surface about new mode // Inform TIA surface about new mode
if(myOSystem.eventHandler().state() != EventHandler::S_LAUNCHER && if(myOSystem.eventHandler().state() != EventHandler::S_LAUNCHER &&
myOSystem.eventHandler().state() != EventHandler::S_DEBUGGER) myOSystem.eventHandler().state() != EventHandler::S_DEBUGGER)
@ -523,9 +524,6 @@ inline void FrameBuffer::drawMessage()
inline void FrameBuffer::drawTIA() inline void FrameBuffer::drawTIA()
{ {
myTIASurface->render(); 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 // Set palette for normal fill
for(int i = 0; i < 256; ++i) for(int i = 0; i < 256; ++i)
{ {
Uint8 r = (palette[i] >> 16) & 0xff; Uint8 r = (raw_palette[i] >> 16) & 0xff;
Uint8 g = (palette[i] >> 8) & 0xff; Uint8 g = (raw_palette[i] >> 8) & 0xff;
Uint8 b = palette[i] & 0xff; Uint8 b = raw_palette[i] & 0xff;
myPalette[i] = mapRGB(r, g, b); myPalette[i] = mapRGB(r, g, b);
} }
// Let the TIA surface know about the new palette // Let the TIA surface know about the new palette
myTIASurface->setPalette(myPalette, palette); myTIASurface->setPalette(myPalette, raw_palette);
myRedrawEntireFrame = true; myRedrawEntireFrame = true;
} }
@ -677,26 +675,24 @@ void FrameBuffer::stateChanged(EventHandler::State state)
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void FrameBuffer::setFullscreen(bool enable) void FrameBuffer::setFullscreen(bool enable)
{ {
cerr << "setFullscreen: " << enable << endl; const VideoMode& mode = getSavedVidMode(enable);
enableFullscreen(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 // Did we get the requested fullscreen state?
#ifdef WINDOWED_SUPPORT myOSystem.settings().setValue("fullscreen", fullScreen());
// '-1' means fullscreen mode is completely disabled resetSurfaces();
bool full = enable && myOSystem.settings().getString("fullscreen") != "-1"; setCursorState();
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
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@ -725,14 +721,13 @@ bool FrameBuffer::changeWindowedVidMode(int direction)
return false; return false;
const VideoMode& mode = myCurrentModeList->current(); const VideoMode& mode = myCurrentModeList->current();
myImageRect = mode.image;
myScreenSize = mode.screen;
if(setVideoMode(myScreenTitle, mode)) if(setVideoMode(myScreenTitle, mode))
{ {
myImageRect = mode.image;
myScreenSize = mode.screen;
// Inform TIA surface about new mode // Inform TIA surface about new mode
if(myOSystem.eventHandler().state() != EventHandler::S_LAUNCHER && myTIASurface->initialize(myOSystem.console(), mode);
myOSystem.eventHandler().state() != EventHandler::S_DEBUGGER)
myTIASurface->initialize(myOSystem.console(), mode);
resetSurfaces(); resetSurfaces();
showMessage(mode.description); showMessage(mode.description);
@ -824,11 +819,10 @@ void FrameBuffer::setAvailableVidModes(uInt32 baseWidth, uInt32 baseHeight)
} }
// TIA fullscreen mode // TIA fullscreen mode
// GUI::Size screen(myDesktopWidth, myDesktopHeight); VideoMode mode(baseWidth*maxZoom, baseHeight*maxZoom,
myFullscreenModeList.add( myDesktopSize.w, myDesktopSize.h, true);
VideoMode(baseWidth, baseHeight, myDesktopSize.w, myDesktopSize.h, true) mode.applyAspectCorrection(aspect, myOSystem.settings().getBool("tia.fsfill"));
); myFullscreenModeList.add(mode);
} }
else // UI mode else // UI mode
{ {
@ -840,12 +834,6 @@ void FrameBuffer::setAvailableVidModes(uInt32 baseWidth, uInt32 baseHeight)
VideoMode(baseWidth, baseHeight, myDesktopSize.w, myDesktopSize.h, true) 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 // Width is modified by aspect ratio; other factors may be applied below
uInt32 iw = (uInt32)(float(image.width() * aspect) / 100.0); uInt32 iw = (uInt32)(float(image.width() * aspect) / 100.0);
uInt32 ih = image.height(); uInt32 ih = image.height();
if(stretch) if(fullscreen)
{ {
#if 0
// Fullscreen mode stretching // Fullscreen mode stretching
if(fullScreen() && float stretchFactor = 1.0;
(mode.image_w < mode.screen_w) && (mode.image_h < mode.screen_h)) float scaleX = float(image.width()) / screen.w;
{ float scaleY = float(image.height()) / screen.h;
float stretchFactor = 1.0;
float scaleX = float(mode.image_w) / mode.screen_w;
float scaleY = float(mode.image_h) / mode.screen_h;
// Scale to actual or integral factors // Scale to actual or integral factors
if(myOSystem.settings().getBool("gl_fsscale")) 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 int bw = image.width() / zoom;
if(scaleX > scaleY) stretchFactor = float(int(screen.w / bw) * bw) / image.width();
stretchFactor = float(mode.screen_w) / mode.image_w;
else
stretchFactor = float(mode.screen_h) / mode.image_h;
} }
else else
{ {
// Only scale to an integral amount int bh = image.height() / zoom;
if(scaleX > scaleY) stretchFactor = float(int(screen.h / bh) * bh) / image.height();
{
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;
}
} }
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 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 // Height is never modified in this mode
screen.w = iw; screen.w = iw;
} }

View File

@ -108,14 +108,14 @@ class VideoMode
friend ostream& operator<<(ostream& os, const VideoMode& vm) friend ostream& operator<<(ostream& os, const VideoMode& vm)
{ {
os << "image=" << vm.image << " screen=" << vm.screen << endl os << "image=" << vm.image << " screen=" << vm.screen
<< "full= " << vm.fullscreen << " zoom=" << vm.zoom << " full= " << vm.fullscreen << " zoom=" << vm.zoom
<< " desc=" << vm.description; << " desc=" << vm.description;
return os; return os;
} }
private: 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. 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. Informs the Framebuffer of a change in EventHandler state.
@ -375,16 +375,15 @@ class FrameBuffer
@param title The title for the created window @param title The title for the created window
@param mode The video mode to use @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 @return False on any errors, else true
*/ */
virtual bool setVideoMode(const string& title, const VideoMode& mode) = 0; virtual bool setVideoMode(const string& title, const VideoMode& mode,
bool fullscreen_toggle = false) = 0;
/**
Enables/disables fullscreen mode.
@param enable Set the fullscreen mode to this value
*/
virtual void enableFullscreen(bool enable) = 0;
/** /**
This method is called to invalidate the contents of the entire 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.inter", "false");
setInternal("tia.aspectn", "90"); setInternal("tia.aspectn", "90");
setInternal("tia.aspectp", "100"); setInternal("tia.aspectp", "100");
setInternal("gl_fsscale", "false"); //FIXSDL - deprecated setInternal("tia.fsfill", "false");
// TV filtering options // TV filtering options
setInternal("tv.filter", "0"); setInternal("tv.filter", "0");
@ -341,7 +341,7 @@ void Settings::usage()
<< endl << endl
<< " -video <type> Type is one of the following:\n" << " -video <type> Type is one of the following:\n"
#ifdef BSPF_WINDOWS #ifdef BSPF_WINDOWS
<< " direct3d Direct3D 9/11 acceleration\n" << " direct3d Direct3D acceleration\n"
#endif #endif
<< " opengl OpenGL acceleration\n" << " opengl OpenGL acceleration\n"
<< " opengles2 OpenGLES 2 acceleration\n" << " opengles2 OpenGLES 2 acceleration\n"
@ -368,9 +368,9 @@ void Settings::usage()
#endif #endif
<< " -tia.zoom <zoom> Use the specified zoom level (windowed mode) for TIA image\n" << " -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.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.aspectn <number> Scale 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" << " -tia.aspectp <number> Scale 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.fsfill <1|0> Stretch TIA image to fill fullscreen mode\n"
<< endl << endl
<< " -tv.filter <0-5> Set TV effects off (0) or to specified mode (1-5)\n" << " -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" << " -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")); myFullscreen->setState(instance().settings().getBool("fullscreen"));
// Fullscreen stretch setting // Fullscreen stretch setting
myUseStretch->setState(instance().settings().getBool("tia.fs_stretch")); myUseStretch->setState(instance().settings().getBool("tia.fsfill"));
// Use sync to vertical blank // Use sync to vertical blank
myUseVSync->setState(instance().settings().getBool("vsync")); myUseVSync->setState(instance().settings().getBool("vsync"));
@ -433,7 +433,7 @@ void VideoDialog::saveConfig()
instance().console().toggleColorLoss(myColorLoss->getState()); instance().console().toggleColorLoss(myColorLoss->getState());
// Fullscreen stretch setting // Fullscreen stretch setting
instance().settings().setValue("tia,fs_stretch", myUseStretch->getState()); instance().settings().setValue("tia.fsfill", myUseStretch->getState());
// Use sync to vertical blank // Use sync to vertical blank
instance().settings().setValue("vsync", myUseVSync->getState()); instance().settings().setValue("vsync", myUseVSync->getState());