From 6faa9b4b6965133ae07134535e0f4c9fce20e7ee Mon Sep 17 00:00:00 2001 From: stephena Date: Thu, 22 Jul 2010 15:41:46 +0000 Subject: [PATCH] Several fixes across the board for better functionality in 'small' window mode. Using modes smaller that 640x480 should now work in all cases when using the 'maxres' commandline argument. Also, the lower limit of 320x240 is now strictly enforced in all cases. git-svn-id: svn://svn.code.sf.net/p/stella/code/trunk@2075 8b62c5a3-ac7e-4cc8-8f21-d9a121418aba --- src/common/FrameBufferGL.cxx | 7 +---- src/debugger/Debugger.cxx | 2 +- src/debugger/Debugger.hxx | 2 +- src/emucore/Console.cxx | 17 ++++++----- src/emucore/Console.hxx | 5 ++-- src/emucore/EventHandler.cxx | 11 ++++--- src/emucore/FrameBuffer.cxx | 57 +++++++++++++++++++++++++++--------- src/emucore/FrameBuffer.hxx | 12 +++++++- src/emucore/OSystem.cxx | 36 +++++++++++++---------- src/emucore/OSystem.hxx | 7 +++-- src/emucore/Settings.cxx | 2 +- src/gui/DialogContainer.cxx | 4 +-- src/gui/Launcher.cxx | 2 +- src/gui/Launcher.hxx | 3 +- src/gui/OptionsDialog.cxx | 22 -------------- 15 files changed, 108 insertions(+), 81 deletions(-) diff --git a/src/common/FrameBufferGL.cxx b/src/common/FrameBufferGL.cxx index 42bcf4950..5ee34e26f 100644 --- a/src/common/FrameBufferGL.cxx +++ b/src/common/FrameBufferGL.cxx @@ -437,18 +437,13 @@ cerr << "dimensions: " << (fullScreen() ? "(full)" : "") << endl myTiaSurface->setFilter(myOSystem->settings().getString("gl_filter")); } - // Make sure any old parts of the screen are erased - p_glClear(GL_COLOR_BUFFER_BIT); - SDL_GL_SwapBuffers(); - p_glClear(GL_COLOR_BUFFER_BIT); - return true; } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - void FrameBufferGL::invalidate() { -// TODO - add code for this + p_glClear(GL_COLOR_BUFFER_BIT); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/debugger/Debugger.cxx b/src/debugger/Debugger.cxx index 585fb4c83..922c1f59f 100644 --- a/src/debugger/Debugger.cxx +++ b/src/debugger/Debugger.cxx @@ -187,7 +187,7 @@ void Debugger::initialize() } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -bool Debugger::initializeVideo() +FBInitStatus Debugger::initializeVideo() { const GUI::Rect& r = getDialogBounds(); diff --git a/src/debugger/Debugger.hxx b/src/debugger/Debugger.hxx index 4087d5d76..798d19677 100644 --- a/src/debugger/Debugger.hxx +++ b/src/debugger/Debugger.hxx @@ -99,7 +99,7 @@ class Debugger : public DialogContainer /** Initialize the video subsystem wrt this class. */ - bool initializeVideo(); + FBInitStatus initializeVideo(); /** Inform this object of a console change. diff --git a/src/emucore/Console.cxx b/src/emucore/Console.cxx index 95e4e3d6a..8659f3f2a 100644 --- a/src/emucore/Console.cxx +++ b/src/emucore/Console.cxx @@ -415,19 +415,20 @@ void Console::setProperties(const Properties& props) } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -bool Console::initializeVideo(bool full) +FBInitStatus Console::initializeVideo(bool full) { + FBInitStatus fbstatus = kSuccess; + if(full) { string title = string("Stella ") + STELLA_VERSION + ": \"" + myProperties.get(Cartridge_Name) + "\""; - if(!myOSystem->frameBuffer().initialize(title, - myTIA->width() << 1, myTIA->height())) - return false; - - myOSystem->frameBuffer().showFrameStats( - myOSystem->settings().getBool("stats")); + fbstatus = myOSystem->frameBuffer().initialize(title, + myTIA->width() << 1, myTIA->height()); + if(fbstatus != kSuccess) + return fbstatus; + myOSystem->frameBuffer().showFrameStats(myOSystem->settings().getBool("stats")); setColorLossPalette(); } @@ -447,7 +448,7 @@ bool Console::initializeVideo(bool full) // Make sure auto-frame calculation is only enabled when necessary myTIA->enableAutoFrame(framerate <= 0); - return true; + return fbstatus; } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/emucore/Console.hxx b/src/emucore/Console.hxx index c4a120592..c21fcaa9f 100644 --- a/src/emucore/Console.hxx +++ b/src/emucore/Console.hxx @@ -31,6 +31,7 @@ class TIA; #include "Props.hxx" #include "TIA.hxx" #include "Cart.hxx" +#include "FrameBuffer.hxx" #include "M6532.hxx" #include "AtariVox.hxx" #include "Serializable.hxx" @@ -212,9 +213,9 @@ class Console : public Serializable @param full Whether we want a full initialization, or only reset certain attributes. - @return False on any errors, else true + @return The results from FrameBuffer::initialize() */ - bool initializeVideo(bool full = true); + FBInitStatus initializeVideo(bool full = true); /** Initialize the audio subsystem wrt this class. diff --git a/src/emucore/EventHandler.cxx b/src/emucore/EventHandler.cxx index 7b5f6954d..4e97c07e6 100644 --- a/src/emucore/EventHandler.cxx +++ b/src/emucore/EventHandler.cxx @@ -2024,19 +2024,22 @@ bool EventHandler::enterDebugMode() // probably be modified below myOSystem->debugger().setStartState(); setEventState(S_DEBUGGER); - if(!myOSystem->createFrameBuffer()) + + FBInitStatus fbstatus = myOSystem->createFrameBuffer(); + if(fbstatus != kSuccess) { myOSystem->debugger().setQuitState(); setEventState(S_EMULATE); - myOSystem->frameBuffer().showMessage("Debugger window too large", - kBottomCenter, true); + if(fbstatus == kFailTooLarge) + myOSystem->frameBuffer().showMessage("Debugger window too large for screen", + kBottomCenter, true); return false; } myOverlay->reStack(); myOSystem->frameBuffer().setCursorState(); myOSystem->sound().mute(true); #else - myOSystem->frameBuffer().showMessage("Debugger unsupported", + myOSystem->frameBuffer().showMessage("Debugger support not included", kBottomCenter, true); #endif diff --git a/src/emucore/FrameBuffer.cxx b/src/emucore/FrameBuffer.cxx index ac6c1dec9..2b7a86459 100644 --- a/src/emucore/FrameBuffer.cxx +++ b/src/emucore/FrameBuffer.cxx @@ -66,7 +66,7 @@ FrameBuffer::~FrameBuffer(void) } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -bool FrameBuffer::initialize(const string& title, uInt32 width, uInt32 height) +FBInitStatus FrameBuffer::initialize(const string& title, uInt32 width, uInt32 height) { ostringstream buf; @@ -78,24 +78,42 @@ bool FrameBuffer::initialize(const string& title, uInt32 width, uInt32 height) { buf << "ERROR: Couldn't initialize SDL: " << SDL_GetError() << endl; myOSystem->logMessage(buf.str(), 0); - return false; + return kFailComplete; } } myInitializedCount++; - // Make sure this mode is even possible - // We only really need to worry about it in non-windowed environments, - // where requesting a window that's too large will probably cause a crash -#ifndef WINDOWED_SUPPORT - if(myOSystem->desktopWidth() < width || myOSystem->desktopHeight() < height) - return false; -#endif + // A 'windowed' system is defined as one where the window size can be + // larger than the screen size, as there's some sort of window manager + // that takes care of it (all current desktop systems fall in this category) + // However, some systems have no concept of windowing, and have hard limits + // on how large a window can be (ie, the size of the 'desktop' is the + // absolute upper limit on window size) + // + // If the WINDOWED_SUPPORT macro is defined, we treat the system as the + // former type; if not, as the latter type // Initialize SDL flags and set fullscreen flag // This must be done before any modes are initialized mySDLFlags = 0; + #ifdef WINDOWED_SUPPORT - if(myOSystem->settings().getString("fullscreen") == "1") mySDLFlags = SDL_FULLSCREEN; + if(myOSystem->settings().getString("fullscreen") == "1") + mySDLFlags = SDL_FULLSCREEN; + + // We assume that a desktop size of at least 640x480 means that we're + // running on a 'large' system, and the window size requirements can + // be relaxed + // Otherwise, we treat the system as if WINDOWED_SUPPORT is not defined + if(myOSystem->desktopWidth() < 640 && myOSystem->desktopHeight() < 480 && + (myOSystem->desktopWidth() < width || myOSystem->desktopHeight() < height)) + return kFailTooLarge; +#else + // Make sure this mode is even possible + // We only really need to worry about it in non-windowed environments, + // where requesting a window that's too large will probably cause a crash + if(myOSystem->desktopWidth() < width || myOSystem->desktopHeight() < height) + return kFailTooLarge; #endif // Set the available video modes for this framebuffer @@ -112,7 +130,7 @@ bool FrameBuffer::initialize(const string& title, uInt32 width, uInt32 height) if(!initSubsystem(mode)) { myOSystem->logMessage("ERROR: Couldn't initialize video subsystem\n", 0); - return false; + return kFailNotSupported; } else { @@ -131,7 +149,7 @@ bool FrameBuffer::initialize(const string& title, uInt32 width, uInt32 height) } } else - return false; + return kFailTooLarge; // Enable unicode so we can see translated key events // (lowercase vs. uppercase characters) @@ -161,7 +179,7 @@ bool FrameBuffer::initialize(const string& title, uInt32 width, uInt32 height) if(myInitializedCount == 1) myOSystem->logMessage(about() + "\n", 1); - return true; + return kSuccess; } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -420,54 +438,65 @@ void FrameBuffer::refresh() // This method is in essence a FULL refresh, putting all rendering // buffers in a known, fully redrawn state - invalidate(); bool doubleBuffered = (type() == kGLBuffer); switch(myOSystem->eventHandler().state()) { case EventHandler::S_EMULATE: case EventHandler::S_PAUSE: + invalidate(); drawTIA(true); if(doubleBuffered) + { + invalidate(); drawTIA(true); + } break; case EventHandler::S_MENU: + invalidate(); drawTIA(true); myOSystem->menu().draw(true); if(doubleBuffered) { postFrameUpdate(); + invalidate(); drawTIA(true); myOSystem->menu().draw(true); } break; case EventHandler::S_CMDMENU: + invalidate(); drawTIA(true); myOSystem->commandMenu().draw(true); if(doubleBuffered) { postFrameUpdate(); + invalidate(); drawTIA(true); myOSystem->commandMenu().draw(true); } break; case EventHandler::S_LAUNCHER: + invalidate(); myOSystem->launcher().draw(true); if(doubleBuffered) { postFrameUpdate(); + invalidate(); myOSystem->launcher().draw(true); } break; #ifdef DEBUGGER_SUPPORT case EventHandler::S_DEBUGGER: + invalidate(); myOSystem->debugger().draw(true); if(doubleBuffered) { postFrameUpdate(); + invalidate(); myOSystem->debugger().draw(true); } break; diff --git a/src/emucore/FrameBuffer.hxx b/src/emucore/FrameBuffer.hxx index abcf047ff..98da4cb3e 100644 --- a/src/emucore/FrameBuffer.hxx +++ b/src/emucore/FrameBuffer.hxx @@ -43,6 +43,14 @@ enum BufferType { kGLBuffer }; +// Return values for initialization of framebuffer window +enum FBInitStatus { + kSuccess, + kFailComplete, + kFailTooLarge, + kFailNotSupported, +}; + // Positions for onscreen/overlaid messages enum MessagePosition { kTopLeft, @@ -114,8 +122,10 @@ class FrameBuffer @param title The title of the window @param width The width of the framebuffer @param height The height of the framebuffer + + @return Status of initialization (see FBInitStatus 'enum') */ - bool initialize(const string& title, uInt32 width, uInt32 height); + FBInitStatus initialize(const string& title, uInt32 width, uInt32 height); /** Updates the display, which depending on the current mode could mean diff --git a/src/emucore/OSystem.cxx b/src/emucore/OSystem.cxx index a796cb714..7cbffdf20 100644 --- a/src/emucore/OSystem.cxx +++ b/src/emucore/OSystem.cxx @@ -385,7 +385,7 @@ void OSystem::setFramerate(float framerate) } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -bool OSystem::createFrameBuffer() +FBInitStatus OSystem::createFrameBuffer() { // There is only ever one FrameBuffer created per run of Stella // Due to the multi-surface nature of the FrameBuffer, repeatedly @@ -400,24 +400,28 @@ bool OSystem::createFrameBuffer() myFrameBuffer = MediaFactory::createVideo(this); // Re-initialize the framebuffer to current settings + FBInitStatus fbstatus = kFailComplete; switch(myEventHandler->state()) { case EventHandler::S_EMULATE: case EventHandler::S_PAUSE: case EventHandler::S_MENU: case EventHandler::S_CMDMENU: - if(!myConsole->initializeVideo()) + fbstatus = myConsole->initializeVideo(); + if(fbstatus != kSuccess) goto fallback; break; // S_EMULATE, S_PAUSE, S_MENU, S_CMDMENU case EventHandler::S_LAUNCHER: - if(!myLauncher->initializeVideo()) + fbstatus = myLauncher->initializeVideo(); + if(fbstatus != kSuccess) goto fallback; break; // S_LAUNCHER #ifdef DEBUGGER_SUPPORT case EventHandler::S_DEBUGGER: - if(!myDebugger->initializeVideo()) + fbstatus = myDebugger->initializeVideo(); + if(fbstatus != kSuccess) goto fallback; break; // S_DEBUGGER #endif @@ -437,28 +441,30 @@ bool OSystem::createFrameBuffer() setUIPalette(); } - return true; + return fbstatus; // GOTO are normally considered evil, unless well documented :) - // If initialization of video system fails while in OpenGL mode, - // attempt to fallback to software mode + // If initialization of video system fails while in OpenGL mode + // because OpenGL is unavailable, attempt to fallback to software mode + // Otherwise, pass the error to the parent fallback: - if(myFrameBuffer && myFrameBuffer->type() == kGLBuffer) + if(fbstatus == kFailNotSupported && myFrameBuffer && + myFrameBuffer->type() == kGLBuffer) { logMessage("ERROR: OpenGL mode failed, fallback to software\n", 0); delete myFrameBuffer; myFrameBuffer = NULL; mySettings->setString("video", "soft"); - bool ret = createFrameBuffer(); - if(ret) + FBInitStatus newstatus = createFrameBuffer(); + if(newstatus == kSuccess) { setFramerate(60); myFrameBuffer->showMessage("OpenGL mode failed, fallback to software", kMiddleCenter, true); } - return ret; + return newstatus; } else - return false; + return fbstatus; } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -522,7 +528,7 @@ bool OSystem::createConsole(const string& romfile, const string& md5sum) ////////////////////////////////////////////////////////////////////////// if(audiofirst) myConsole->initializeAudio(); myEventHandler->reset(EventHandler::S_EMULATE); - if(!createFrameBuffer()) // Takes care of initializeVideo() + if(createFrameBuffer() != kSuccess) // Takes care of initializeVideo() { logMessage("ERROR: Couldn't create framebuffer for console\n", 0); myEventHandler->reset(EventHandler::S_LAUNCHER); @@ -594,7 +600,7 @@ void OSystem::deleteConsole() bool OSystem::createLauncher() { myEventHandler->reset(EventHandler::S_LAUNCHER); - if(!createFrameBuffer()) + if(createFrameBuffer() != kSuccess) { logMessage("ERROR: Couldn't create launcher\n", 0); return false; @@ -1020,7 +1026,7 @@ bool OSystem::queryVideoHardware() // Normally, this wouldn't be set, and we ask SDL directly int w, h; mySettings->getSize("maxres", w, h); - if(w == 0 || h == 0) + if(w <= 0 || h <= 0) { const SDL_VideoInfo* info = SDL_GetVideoInfo(); myDesktopWidth = info->current_w; diff --git a/src/emucore/OSystem.hxx b/src/emucore/OSystem.hxx index f242daea5..7ccd2295e 100644 --- a/src/emucore/OSystem.hxx +++ b/src/emucore/OSystem.hxx @@ -559,9 +559,12 @@ class OSystem (for now, that means either 'software' or 'opengl'). Note that it will only create one type per run of Stella. - @return Success or failure of the framebuffer creation + @return Success or failure of the framebuffer creation + Note that if OpenGL mode fails because OpenGL is not + available, rendering will attempt to fall back to + software mode */ - bool createFrameBuffer(); + FBInitStatus createFrameBuffer(); /** Creates the various sound devices available in this system diff --git a/src/emucore/Settings.cxx b/src/emucore/Settings.cxx index fb3307634..323726215 100644 --- a/src/emucore/Settings.cxx +++ b/src/emucore/Settings.cxx @@ -126,7 +126,7 @@ Settings::Settings(OSystem* osystem) setInternal("audiofirst", "true"); setInternal("fastscbios", "false"); setExternal("romloadcount", "0"); - setExternal("maxres", "0x0"); + setExternal("maxres", ""); // Debugger options setInternal("resolvedata", "auto"); diff --git a/src/gui/DialogContainer.cxx b/src/gui/DialogContainer.cxx index bd8eec36a..784214cbd 100644 --- a/src/gui/DialogContainer.cxx +++ b/src/gui/DialogContainer.cxx @@ -116,8 +116,8 @@ void DialogContainer::draw(bool full) // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - void DialogContainer::addDialog(Dialog* d) { - const GUI::Rect& image = myOSystem->frameBuffer().imageRect(); - assert(d->getWidth() <= image.width() && d->getHeight() <= image.height()); + const GUI::Rect& screen = myOSystem->frameBuffer().screenRect(); + assert(d->getWidth() <= screen.width() && d->getHeight() <= screen.height()); myDialogStack.push(d); d->open(); diff --git a/src/gui/Launcher.cxx b/src/gui/Launcher.cxx index 4ebb463f1..0e8a8801b 100644 --- a/src/gui/Launcher.cxx +++ b/src/gui/Launcher.cxx @@ -50,7 +50,7 @@ Launcher::~Launcher() } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -bool Launcher::initializeVideo() +FBInitStatus Launcher::initializeVideo() { string title = string("Stella ") + STELLA_VERSION; return myOSystem->frameBuffer().initialize(title, myWidth, myHeight); diff --git a/src/gui/Launcher.hxx b/src/gui/Launcher.hxx index eaae3af64..b0bc1537c 100644 --- a/src/gui/Launcher.hxx +++ b/src/gui/Launcher.hxx @@ -24,6 +24,7 @@ class Properties; class OSystem; #include "DialogContainer.hxx" +#include "FrameBuffer.hxx" /** The base dialog for the ROM launcher in Stella. @@ -47,7 +48,7 @@ class Launcher : public DialogContainer /** Initialize the video subsystem wrt this class. */ - bool initializeVideo(); + FBInitStatus initializeVideo(); /** Wrapper for LauncherDialog::selectedRomMD5() method. diff --git a/src/gui/OptionsDialog.cxx b/src/gui/OptionsDialog.cxx index 19a8a737c..d9bb8e8c6 100644 --- a/src/gui/OptionsDialog.cxx +++ b/src/gui/OptionsDialog.cxx @@ -119,18 +119,6 @@ OptionsDialog::OptionsDialog(OSystem* osystem, DialogContainer* parent, // Now create all the dialogs attached to each menu button myVideoDialog = new VideoDialog(osystem, parent, font, max_w, max_h); myAudioDialog = new AudioDialog(osystem, parent, font); - -/* FIXME - may not be needed with small-font functionality -#ifdef _WIN32_WCE - // FIXME - adjust size for WINCE using a smaller font - // we scale the input dialog down a bit in low res devices. - // looks only a little ugly, but the functionality is very welcome - if(instance().desktopWidth() < 320) { w = 220; h = 176; } - else { w = 230; h = 185; } -#else - w = 380; h = 310; -#endif -*/ myInputDialog = new InputDialog(osystem, parent, font); myUIDialog = new UIDialog(osystem, parent, font); myFileSnapDialog = new FileSnapDialog(osystem, parent, font, boss, max_w, max_h); @@ -156,16 +144,6 @@ OptionsDialog::OptionsDialog(OSystem* osystem, DialogContainer* parent, #ifdef _WIN32_WCE myAudioSettingsButton->clearFlags(WIDGET_ENABLED); // not honored in wince port #endif -//FIXME - this may no longer be true (with the new small font functionality) - if(instance().desktopWidth() < 320) - { - // These cannot be displayed in low res devices - myVideoSettingsButton->clearFlags(WIDGET_ENABLED); - myFileSnapButton->clearFlags(WIDGET_ENABLED); - myGameInfoButton->clearFlags(WIDGET_ENABLED); - myHelpButton->clearFlags(WIDGET_ENABLED); - myAboutButton->clearFlags(WIDGET_ENABLED); - } } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -