From b6598c1d9b74c5dd5adbd21941f461260196276f Mon Sep 17 00:00:00 2001 From: stephena Date: Thu, 13 Mar 2008 22:58:07 +0000 Subject: [PATCH] Fixed 'rom info viewer' mode, and added a checkbox to 'UI Settings' to enable/disable it. Currently, you have to exit and restart the program for this to take effect. Fixed issues with resizing and toggling video renderers and the image not being updated correctly. Also, saving a snapshot within emulation mode and exiting to launcher mode now shows the new snapshot. Currently, the rom info viewer only works with PNG images 320x250 or less (ie, 1x zoom mode in Stella). If the image is bigger, a message is displayed stating that fact. At some point I have to add another snapshot mode where it always saves in 1x mode (or maybe not; it depends on how many people will want to save snapshots for viewing in the rom info viewer). git-svn-id: svn://svn.code.sf.net/p/stella/code/trunk@1428 8b62c5a3-ac7e-4cc8-8f21-d9a121418aba --- stella/src/common/FrameBufferGL.cxx | 20 +-- stella/src/common/FrameBufferGL.hxx | 14 ++- stella/src/common/FrameBufferSoft.cxx | 60 ++++----- stella/src/common/FrameBufferSoft.hxx | 14 ++- stella/src/emucore/EventHandler.cxx | 14 ++- stella/src/emucore/FrameBuffer.cxx | 12 +- stella/src/emucore/FrameBuffer.hxx | 13 +- stella/src/emucore/OSystem.cxx | 24 +--- stella/src/emucore/OSystem.hxx | 21 +--- stella/src/gp2x/FrameBufferGP2X.cxx | 9 +- stella/src/gp2x/FrameBufferGP2X.hxx | 15 +-- stella/src/gui/DialogContainer.cxx | 8 +- stella/src/gui/LauncherDialog.cxx | 17 ++- stella/src/gui/OptionsDialog.cxx | 4 +- stella/src/gui/RomInfoWidget.cxx | 174 +++++++++++++++++--------- stella/src/gui/RomInfoWidget.hxx | 22 +++- stella/src/gui/Surface.cxx | 4 +- stella/src/gui/Surface.hxx | 24 ++-- stella/src/gui/UIDialog.cxx | 19 ++- stella/src/gui/UIDialog.hxx | 5 +- 20 files changed, 274 insertions(+), 219 deletions(-) diff --git a/stella/src/common/FrameBufferGL.cxx b/stella/src/common/FrameBufferGL.cxx index 5fc23d58b..7d15ea123 100644 --- a/stella/src/common/FrameBufferGL.cxx +++ b/stella/src/common/FrameBufferGL.cxx @@ -13,7 +13,7 @@ // See the file "license" for information on usage and redistribution of // this file, and for a DISCLAIMER OF ALL WARRANTIES. // -// $Id: FrameBufferGL.cxx,v 1.98 2008-03-08 13:22:12 stephena Exp $ +// $Id: FrameBufferGL.cxx,v 1.99 2008-03-13 22:58:05 stephena Exp $ //============================================================================ #ifdef DISPLAY_OPENGL @@ -578,23 +578,27 @@ void FrameBufferGL::drawBitmap(uInt32* bitmap, Int32 tx, Int32 ty, // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - void FrameBufferGL::drawSurface(const GUI::Surface* surface, Int32 x, Int32 y) { - SDL_Rect clip; - clip.x = x; - clip.y = y; + SDL_Rect dstrect; + dstrect.x = x; + dstrect.y = y; + SDL_Rect srcrect; + srcrect.x = 0; + srcrect.y = 0; + srcrect.w = surface->myClipWidth; + srcrect.h = surface->myClipHeight; - SDL_BlitSurface(surface->myData, 0, myTexture, &clip); + SDL_BlitSurface(surface->myData, &srcrect, myTexture, &dstrect); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - void FrameBufferGL::bytesToSurface(GUI::Surface* surface, int row, - uInt8* data) const + uInt8* data, int rowbytes) const { SDL_Surface* s = surface->myData; uInt16* pixels = (uInt16*) s->pixels; pixels += (row * s->pitch/2); - int rowsize = surface->getWidth() * 3; - for(int c = 0; c < rowsize; c += 3) + for(int c = 0; c < rowbytes; c += 3) *pixels++ = SDL_MapRGB(s->format, data[c], data[c+1], data[c+2]); } diff --git a/stella/src/common/FrameBufferGL.hxx b/stella/src/common/FrameBufferGL.hxx index df73ec5f1..20df1585d 100644 --- a/stella/src/common/FrameBufferGL.hxx +++ b/stella/src/common/FrameBufferGL.hxx @@ -13,7 +13,7 @@ // See the file "license" for information on usage and redistribution of // this file, and for a DISCLAIMER OF ALL WARRANTIES. // -// $Id: FrameBufferGL.hxx,v 1.51 2008-02-06 13:45:19 stephena Exp $ +// $Id: FrameBufferGL.hxx,v 1.52 2008-03-13 22:58:06 stephena Exp $ //============================================================================ #ifndef FRAMEBUFFER_GL_HXX @@ -35,7 +35,7 @@ class GUI::Font; This class implements an SDL OpenGL framebuffer. @author Stephen Anthony - @version $Id: FrameBufferGL.hxx,v 1.51 2008-02-06 13:45:19 stephena Exp $ + @version $Id: FrameBufferGL.hxx,v 1.52 2008-03-13 22:58:06 stephena Exp $ */ class FrameBufferGL : public FrameBuffer { @@ -200,11 +200,13 @@ class FrameBufferGL : public FrameBuffer This method should be called to convert and copy a given row of RGB data into an SDL surface. - @param surface The data to draw - @param row The row of the surface the data should be placed in - @param data The data in uInt8 R/G/B format + @param surface The data to draw + @param row The row of the surface the data should be placed in + @param data The data in uInt8 R/G/B format + @param rowbytes The number of bytes in row of 'data' */ - void bytesToSurface(GUI::Surface* surface, int row, uInt8* data) const; + void bytesToSurface(GUI::Surface* surface, int row, + uInt8* data, int rowbytes) const; /** This method translates the given coordinates to their diff --git a/stella/src/common/FrameBufferSoft.cxx b/stella/src/common/FrameBufferSoft.cxx index 78cc18345..770f57e6a 100644 --- a/stella/src/common/FrameBufferSoft.cxx +++ b/stella/src/common/FrameBufferSoft.cxx @@ -13,7 +13,7 @@ // See the file "license" for information on usage and redistribution of // this file, and for a DISCLAIMER OF ALL WARRANTIES. // -// $Id: FrameBufferSoft.cxx,v 1.76 2008-02-19 12:33:02 stephena Exp $ +// $Id: FrameBufferSoft.cxx,v 1.77 2008-03-13 22:58:06 stephena Exp $ //============================================================================ #include @@ -640,51 +640,33 @@ void FrameBufferSoft::drawBitmap(uInt32* bitmap, Int32 xorig, Int32 yorig, // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - void FrameBufferSoft::drawSurface(const GUI::Surface* surface, Int32 x, Int32 y) { - SDL_Rect clip; - clip.x = x * myZoomLevel + myImageDim.x; - clip.y = y * myZoomLevel + myImageDim.y; - - SDL_BlitSurface(surface->myData, 0, myScreen, &clip); + SDL_Rect dstrect; + dstrect.x = x * myZoomLevel + myImageDim.x; + dstrect.y = y * myZoomLevel + myImageDim.y; + SDL_Rect srcrect; + srcrect.x = 0; + srcrect.y = 0; + srcrect.w = surface->myClipWidth * myZoomLevel; + srcrect.h = surface->myClipHeight * myZoomLevel; + + SDL_BlitSurface(surface->myData, &srcrect, myScreen, &dstrect); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - void FrameBufferSoft::bytesToSurface(GUI::Surface* surface, int row, - uInt8* data) const + uInt8* data, int rowbytes) const { + // Calculate a scanline of zoomed surface data SDL_Surface* s = surface->myData; - int rowbytes = s->w * 3; - row *= myZoomLevel; - - switch(myBytesPerPixel) + SDL_Rect rect; + rect.x = 0; + rect.y = row * myZoomLevel; + for(int c = 0; c < rowbytes; c += 3) { - case 2: - { - uInt16* pixels = (uInt16*) s->pixels; - int surfbytes = s->pitch/2; - pixels += (row * surfbytes); - uInt8* pixel_ptr = (uInt8*)pixels; - - // Calculate a scanline of zoomed surface data - for(int c = 0; c < rowbytes/myZoomLevel; c += 3) - { - uInt32 pixel = SDL_MapRGB(s->format, data[c], data[c+1], data[c+2]); - uInt32 xstride = myZoomLevel; - while(xstride--) - *pixels++ = pixel; - } - - // Now duplicate the scanlines (we've already done the first one) - uInt32 ystride = myZoomLevel-1; - while(ystride--) - { - memcpy(pixel_ptr + s->pitch, pixel_ptr, s->pitch); - pixel_ptr += s->pitch; - } - break; - } - - default: - break; + uInt32 pixel = SDL_MapRGB(s->format, data[c], data[c+1], data[c+2]); + rect.x += myZoomLevel; + rect.w = rect.h = myZoomLevel; + SDL_FillRect(surface->myData, &rect, pixel); } } diff --git a/stella/src/common/FrameBufferSoft.hxx b/stella/src/common/FrameBufferSoft.hxx index 56d584f77..946dfa6ba 100644 --- a/stella/src/common/FrameBufferSoft.hxx +++ b/stella/src/common/FrameBufferSoft.hxx @@ -13,7 +13,7 @@ // See the file "license" for information on usage and redistribution of // this file, and for a DISCLAIMER OF ALL WARRANTIES. // -// $Id: FrameBufferSoft.hxx,v 1.49 2008-02-06 13:45:19 stephena Exp $ +// $Id: FrameBufferSoft.hxx,v 1.50 2008-03-13 22:58:06 stephena Exp $ //============================================================================ #ifndef FRAMEBUFFER_SOFT_HXX @@ -33,7 +33,7 @@ class RectList; This class implements an SDL software framebuffer. @author Stephen Anthony - @version $Id: FrameBufferSoft.hxx,v 1.49 2008-02-06 13:45:19 stephena Exp $ + @version $Id: FrameBufferSoft.hxx,v 1.50 2008-03-13 22:58:06 stephena Exp $ */ class FrameBufferSoft : public FrameBuffer { @@ -189,11 +189,13 @@ class FrameBufferSoft : public FrameBuffer This method should be called to convert and copy a given row of RGB data into an SDL surface. - @param surface The data to draw - @param row The row of the surface the data should be placed in - @param data The data in uInt8 R/G/B format + @param surface The data to draw + @param row The row of the surface the data should be placed in + @param data The data in uInt8 R/G/B format + @param rowbytes The number of bytes in row of 'data' */ - void bytesToSurface(GUI::Surface* surface, int row, uInt8* data) const; + void bytesToSurface(GUI::Surface* surface, int row, + uInt8* data, int rowbytes) const; /** This method translates the given coordinates to their diff --git a/stella/src/emucore/EventHandler.cxx b/stella/src/emucore/EventHandler.cxx index 9bb1f1355..94c46fc2b 100644 --- a/stella/src/emucore/EventHandler.cxx +++ b/stella/src/emucore/EventHandler.cxx @@ -14,7 +14,7 @@ // See the file "license" for information on usage and redistribution of // this file, and for a DISCLAIMER OF ALL WARRANTIES. // -// $Id: EventHandler.cxx,v 1.217 2008-03-03 16:14:50 stephena Exp $ +// $Id: EventHandler.cxx,v 1.218 2008-03-13 22:58:06 stephena Exp $ //============================================================================ #include @@ -756,7 +756,8 @@ void EventHandler::poll(uInt32 time) myOverlay->updateTime(time); } - // Turn off relative events + // Turn off relative events; we assume they've been taken care of + // in at least one of the ::update() methods above myEvent->set(Event::MouseAxisXValue, 0); myEvent->set(Event::MouseAxisYValue, 0); } @@ -898,8 +899,10 @@ void EventHandler::handleJoyHatEvent(int stick, int hat, int value) void EventHandler::handleResizeEvent() { // For now, only the overlay cares about resize events - if(myOverlay != NULL) - myOverlay->handleResizeEvent(); + // We don't know which one wants it, so we send it to all of them + // These events need to be sent even if the overlay isn't active + if(&myOSystem->launcher()) + myOSystem->launcher().handleResizeEvent(); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -1800,8 +1803,7 @@ void EventHandler::takeSnapshot() if(sspath.length() > 0) if(sspath.substr(sspath.length()-1) != BSPF_PATH_SEPARATOR) sspath += BSPF_PATH_SEPARATOR; - sspath += myOSystem->console().properties().get(Cartridge_Name) + "." + - myOSystem->console().properties().get(Cartridge_MD5); + sspath += myOSystem->console().properties().get(Cartridge_Name); // Check whether we want multiple snapshots created if(!myOSystem->settings().getBool("sssingle")) diff --git a/stella/src/emucore/FrameBuffer.cxx b/stella/src/emucore/FrameBuffer.cxx index 8163e180f..5da82071d 100644 --- a/stella/src/emucore/FrameBuffer.cxx +++ b/stella/src/emucore/FrameBuffer.cxx @@ -13,7 +13,7 @@ // See the file "license" for information on usage and redistribution of // this file, and for a DISCLAIMER OF ALL WARRANTIES. // -// $Id: FrameBuffer.cxx,v 1.125 2008-02-06 13:45:21 stephena Exp $ +// $Id: FrameBuffer.cxx,v 1.126 2008-03-13 22:58:06 stephena Exp $ //============================================================================ #include @@ -456,19 +456,13 @@ void FrameBuffer::setCursorState() // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - void FrameBuffer::showCursor(bool show) { - if(show) - SDL_ShowCursor(SDL_ENABLE); - else - SDL_ShowCursor(SDL_DISABLE); + SDL_ShowCursor(show ? SDL_ENABLE : SDL_DISABLE); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - void FrameBuffer::grabMouse(bool grab) { - if(grab) - SDL_WM_GrabInput(SDL_GRAB_ON); - else - SDL_WM_GrabInput(SDL_GRAB_OFF); + SDL_WM_GrabInput(grab ? SDL_GRAB_ON : SDL_GRAB_OFF); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/stella/src/emucore/FrameBuffer.hxx b/stella/src/emucore/FrameBuffer.hxx index 519e41adc..d244cc9df 100644 --- a/stella/src/emucore/FrameBuffer.hxx +++ b/stella/src/emucore/FrameBuffer.hxx @@ -13,7 +13,7 @@ // See the file "license" for information on usage and redistribution of // this file, and for a DISCLAIMER OF ALL WARRANTIES. // -// $Id: FrameBuffer.hxx,v 1.93 2008-02-06 13:45:21 stephena Exp $ +// $Id: FrameBuffer.hxx,v 1.94 2008-03-13 22:58:06 stephena Exp $ //============================================================================ #ifndef FRAMEBUFFER_HXX @@ -101,7 +101,7 @@ enum { All GUI elements (ala ScummVM) are drawn here as well. @author Stephen Anthony - @version $Id: FrameBuffer.hxx,v 1.93 2008-02-06 13:45:21 stephena Exp $ + @version $Id: FrameBuffer.hxx,v 1.94 2008-03-13 22:58:06 stephena Exp $ */ class FrameBuffer { @@ -382,12 +382,13 @@ class FrameBuffer This method should be called to convert and copy a given row of RGB data into an SDL surface. - @param surface The data to draw - @param row The row of the surface the data should be placed in - @param data The data in uInt8 R/G/B format + @param surface The data to draw + @param row The row of the surface the data should be placed in + @param data The data in uInt8 R/G/B format + @param rowbytes The number of bytes in row of 'data' */ virtual void bytesToSurface(GUI::Surface* surface, int row, - uInt8* data) const = 0; + uInt8* data, int rowbytes) const = 0; /** This method should be called to translate the given coordinates diff --git a/stella/src/emucore/OSystem.cxx b/stella/src/emucore/OSystem.cxx index 6329ae31e..39425274c 100644 --- a/stella/src/emucore/OSystem.cxx +++ b/stella/src/emucore/OSystem.cxx @@ -13,7 +13,7 @@ // See the file "license" for information on usage and redistribution of // this file, and for a DISCLAIMER OF ALL WARRANTIES. // -// $Id: OSystem.cxx,v 1.116 2008-03-03 14:53:34 stephena Exp $ +// $Id: OSystem.cxx,v 1.117 2008-03-13 22:58:06 stephena Exp $ //============================================================================ #include @@ -320,28 +320,6 @@ bool OSystem::createFrameBuffer(bool showmessage) return true; } -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -string OSystem::getFilename(const string& path, const Properties& props, - const string& ext) const -{ - const string& full_name = - path + BSPF_PATH_SEPARATOR + props.get(Cartridge_Name) + "." + - props.get(Cartridge_MD5) + "." + ext; - const string& rom_name = - path + BSPF_PATH_SEPARATOR + props.get(Cartridge_Name) + "." + ext; - const string& md5_name = - path + BSPF_PATH_SEPARATOR + props.get(Cartridge_MD5) + "." + ext; - - if(FilesystemNode::fileExists(full_name)) - return full_name; - else if(FilesystemNode::fileExists(rom_name)) - return rom_name; - else if(FilesystemNode::fileExists(md5_name)) - return md5_name; - else - return EmptyString; -} - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - void OSystem::toggleFrameBuffer() { diff --git a/stella/src/emucore/OSystem.hxx b/stella/src/emucore/OSystem.hxx index 6bfb0380a..772ffe7b9 100644 --- a/stella/src/emucore/OSystem.hxx +++ b/stella/src/emucore/OSystem.hxx @@ -13,7 +13,7 @@ // See the file "license" for information on usage and redistribution of // this file, and for a DISCLAIMER OF ALL WARRANTIES. // -// $Id: OSystem.hxx,v 1.60 2008-02-06 13:45:22 stephena Exp $ +// $Id: OSystem.hxx,v 1.61 2008-03-13 22:58:06 stephena Exp $ //============================================================================ #ifndef OSYSTEM_HXX @@ -55,7 +55,7 @@ typedef Common::Array ResolutionList; other objects belong. @author Stephen Anthony - @version $Id: OSystem.hxx,v 1.60 2008-02-06 13:45:22 stephena Exp $ + @version $Id: OSystem.hxx,v 1.61 2008-03-13 22:58:06 stephena Exp $ */ class OSystem { @@ -289,23 +289,6 @@ class OSystem */ const string& romFile() const { return myRomFile; } - /** - Determines a valid filename for the given properties and extension. - Currently, there are three possibilities, in order of precedence: - - Cart_Name.Cart_MD5.ext - Cart_Name.ext - Cart_MD5.ext - - @param path The full path to prepend to the filename - @param props The ROM properties for the given ROM - @param ext The extension to append to the filename - - @return A valid file (which exists), or the empty string - */ - string getFilename(const string& path, const Properties& props, - const string& ext) const; - /** Switches between software and OpenGL framebuffer modes. */ diff --git a/stella/src/gp2x/FrameBufferGP2X.cxx b/stella/src/gp2x/FrameBufferGP2X.cxx index 47ea24280..b4b3d953b 100644 --- a/stella/src/gp2x/FrameBufferGP2X.cxx +++ b/stella/src/gp2x/FrameBufferGP2X.cxx @@ -13,7 +13,7 @@ // See the file "license" for information on usage and redistribution of // this file, and for a DISCLAIMER OF ALL WARRANTIES. // -// $Id: FrameBufferGP2X.cxx,v 1.25 2008-02-20 00:17:49 stephena Exp $ +// $Id: FrameBufferGP2X.cxx,v 1.26 2008-03-13 22:58:06 stephena Exp $ //============================================================================ #include @@ -345,19 +345,21 @@ void FrameBufferGP2X::drawBitmap(uInt32* bitmap, Int32 xorig, Int32 yorig, // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - void FrameBufferGP2X::drawSurface(const GUI::Surface* surface, Int32 x, Int32 y) { +/* TODO - not supported yet SDL_Rect clip; clip.x = x; clip.y = y; SDL_BlitSurface(surface->myData, 0, myScreen, &clip); +*/ } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - void FrameBufferGP2X::bytesToSurface(GUI::Surface* surface, int row, - uInt8* data) const + uInt8* data, int rowbytes) const { +/* TODO - not supported yet SDL_Surface* s = surface->myData; - int rowbytes = s->w * 3; uInt16* pixels = (uInt16*) s->pixels; int surfbytes = s->pitch/2; @@ -369,6 +371,7 @@ void FrameBufferGP2X::bytesToSurface(GUI::Surface* surface, int row, uInt32 pixel = SDL_MapRGB(s->format, data[c], data[c+1], data[c+2]); *pixels++ = pixel; } +*/ } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/stella/src/gp2x/FrameBufferGP2X.hxx b/stella/src/gp2x/FrameBufferGP2X.hxx index 5eaba1eae..18a1cc0d6 100644 --- a/stella/src/gp2x/FrameBufferGP2X.hxx +++ b/stella/src/gp2x/FrameBufferGP2X.hxx @@ -13,7 +13,7 @@ // See the file "license" for information on usage and redistribution of // this file, and for a DISCLAIMER OF ALL WARRANTIES. // -// $Id: FrameBufferGP2X.hxx,v 1.12 2008-02-20 00:17:49 stephena Exp $ +// $Id: FrameBufferGP2X.hxx,v 1.13 2008-03-13 22:58:06 stephena Exp $ //============================================================================ #ifndef FRAMEBUFFER_GP2X_HXX @@ -32,7 +32,7 @@ class GUI::Font; This class implements an SDL hardware framebuffer for the GP2X device. @author Stephen Anthony - @version $Id: FrameBufferGP2X.hxx,v 1.12 2008-02-20 00:17:49 stephena Exp $ + @version $Id: FrameBufferGP2X.hxx,v 1.13 2008-03-13 22:58:06 stephena Exp $ */ class FrameBufferGP2X : public FrameBuffer { @@ -191,12 +191,13 @@ class FrameBufferGP2X : public FrameBuffer This method should be called to convert and copy a given row of RGB data into an SDL surface. - @param surface The data to draw - @param row The row of the surface the data should be placed in - @param data The data in uInt8 R/G/B format + @param surface The data to draw + @param row The row of the surface the data should be placed in + @param data The data in uInt8 R/G/B format + @param rowbytes The number of bytes in row of 'data' */ - void bytesToSurface(GUI::Surface* surface, int row, uInt8* data) const; - + void bytesToSurface(GUI::Surface* surface, int row, + uInt8* data, int rowbytes) const; /** This method translates the given coordinates to their diff --git a/stella/src/gui/DialogContainer.cxx b/stella/src/gui/DialogContainer.cxx index fcc02d9cd..32ecc1eb8 100644 --- a/stella/src/gui/DialogContainer.cxx +++ b/stella/src/gui/DialogContainer.cxx @@ -13,7 +13,7 @@ // See the file "license" for information on usage and redistribution of // this file, and for a DISCLAIMER OF ALL WARRANTIES. // -// $Id: DialogContainer.cxx,v 1.40 2008-03-02 19:20:50 stephena Exp $ +// $Id: DialogContainer.cxx,v 1.41 2008-03-13 22:58:06 stephena Exp $ //============================================================================ #include "OSystem.hxx" @@ -329,10 +329,8 @@ void DialogContainer::handleJoyHatEvent(int stick, int hat, int value) // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - void DialogContainer::handleResizeEvent() { - // Send resize events to all dialogs - // It's up to a specific dialog to actually listen - for(int i = 0; i < myDialogStack.size(); i++) - myDialogStack[i]->handleCommand(NULL, kResizeCmd, 0, 0); + // Send resize event to base dialog; it's up to the dialog to actually listen + myBaseDialog->handleCommand(NULL, kResizeCmd, 0, 0); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/stella/src/gui/LauncherDialog.cxx b/stella/src/gui/LauncherDialog.cxx index 725ec6160..c54f2cc0f 100644 --- a/stella/src/gui/LauncherDialog.cxx +++ b/stella/src/gui/LauncherDialog.cxx @@ -13,7 +13,7 @@ // See the file "license" for information on usage and redistribution of // this file, and for a DISCLAIMER OF ALL WARRANTIES. // -// $Id: LauncherDialog.cxx,v 1.78 2008-03-12 22:04:52 stephena Exp $ +// $Id: LauncherDialog.cxx,v 1.79 2008-03-13 22:58:06 stephena Exp $ // // Based on code from ScummVM - Scumm Interpreter // Copyright (C) 2002-2004 The ScummVM project @@ -201,6 +201,9 @@ void LauncherDialog::loadConfig() updateListing(); } Dialog::setFocus(getFocusList()[mySelectedItem]); + + if(myRomInfoFlag) + myRomInfoWidget->loadConfig(); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -370,7 +373,7 @@ void LauncherDialog::createListCache() // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - void LauncherDialog::loadRomInfo() { - if(!myRomInfoFlag) return; + if(!(myRomInfoFlag && myRomInfoWidget)) return; int item = myList->getSelected(); if(item < 0 || myGameList->isDir(item)) return; @@ -385,10 +388,10 @@ void LauncherDialog::loadRomInfo() const string& md5 = myGameList->md5(item); instance()->propSet().getMD5(md5, props); - myRomInfoWidget->showInfo(props); + myRomInfoWidget->setProperties(props); } else - myRomInfoWidget->clearInfo(); + myRomInfoWidget->clearProperties(); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -489,7 +492,11 @@ void LauncherDialog::handleCommand(CommandSender* sender, int cmd, case kResizeCmd: // Instead of figuring out how to resize the snapshot image, // we just reload it - loadRomInfo(); + if(myRomInfoFlag) + { + myRomInfoWidget->initialize(); + loadRomInfo(); + } break; default: diff --git a/stella/src/gui/OptionsDialog.cxx b/stella/src/gui/OptionsDialog.cxx index c25070bf7..6d73df935 100644 --- a/stella/src/gui/OptionsDialog.cxx +++ b/stella/src/gui/OptionsDialog.cxx @@ -13,7 +13,7 @@ // See the file "license" for information on usage and redistribution of // this file, and for a DISCLAIMER OF ALL WARRANTIES. // -// $Id: OptionsDialog.cxx,v 1.64 2008-03-12 22:04:53 stephena Exp $ +// $Id: OptionsDialog.cxx,v 1.65 2008-03-13 22:58:07 stephena Exp $ // // Based on code from ScummVM - Scumm Interpreter // Copyright (C) 2002-2004 The ScummVM project @@ -124,7 +124,7 @@ OptionsDialog::OptionsDialog(OSystem* osystem, DialogContainer* parent, #endif myInputDialog = new InputDialog(myOSystem, parent, font, x, y, w, h); - w = 200; h = 155; + w = 200; h = 175; myUIDialog = new UIDialog(myOSystem, parent, font, x, y, w, h); w = 280; h = 180; diff --git a/stella/src/gui/RomInfoWidget.cxx b/stella/src/gui/RomInfoWidget.cxx index 72adb5758..d1d6719a3 100644 --- a/stella/src/gui/RomInfoWidget.cxx +++ b/stella/src/gui/RomInfoWidget.cxx @@ -13,7 +13,7 @@ // See the file "license" for information on usage and redistribution of // this file, and for a DISCLAIMER OF ALL WARRANTIES. // -// $Id: RomInfoWidget.cxx,v 1.4 2008-03-08 13:22:12 stephena Exp $ +// $Id: RomInfoWidget.cxx,v 1.5 2008-03-13 22:58:07 stephena Exp $ //============================================================================ #include @@ -31,7 +31,9 @@ RomInfoWidget::RomInfoWidget(GuiObject* boss, const GUI::Font& font, int x, int y, int w, int h) : Widget(boss, font, x, y, w, h), - mySurface(NULL) + mySurface(NULL), + myDrawSurface(false), + myHaveProperties(false) { _flags = WIDGET_ENABLED | WIDGET_RETAIN_FOCUS; _bgcolor = _bgcolorhi = kWidColor; @@ -40,17 +42,75 @@ RomInfoWidget::RomInfoWidget(GuiObject* boss, const GUI::Font& font, // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - RomInfoWidget::~RomInfoWidget() { - clearInfo(false); + if(mySurface) + { + delete mySurface; + mySurface = NULL; + } + myRomInfo.clear(); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - void RomInfoWidget::loadConfig() { + // The ROM may have changed since we were last in the browser, either + // by saving a different image or through a change in video renderer, + // so we reload the properties + if(myHaveProperties) + { + parseProperties(); + setDirty(); draw(); + } } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void RomInfoWidget::showInfo(const Properties& props) +void RomInfoWidget::setProperties(const Properties& props) { + myHaveProperties = true; + myProperties = props; + + // Decide whether the information should be shown immediately + if(instance()->eventHandler().state() == EventHandler::S_LAUNCHER) + { + parseProperties(); + setDirty(); draw(); + } +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +void RomInfoWidget::clearProperties() +{ + myHaveProperties = myDrawSurface = false; + + // Decide whether the information should be shown immediately + if(instance()->eventHandler().state() == EventHandler::S_LAUNCHER) + { + setDirty(); draw(); + } +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +void RomInfoWidget::initialize() +{ + // Delete surface; a new one will be created by parseProperties + delete mySurface; + mySurface = NULL; +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +void RomInfoWidget::parseProperties() +{ + // Initialize to empty properties entry + mySurfaceErrorMsg = ""; + myDrawSurface = false; + myRomInfo.clear(); + + // Check if a surface has ever been created; if so, we use it + // The surface will always be the maximum size, but sometimes we'll + // only draw certain parts of it + if(mySurface == NULL) + mySurface = instance()->frameBuffer().createSurface(320, 250); + // The input stream for the PNG file ifstream in; @@ -63,11 +123,11 @@ void RomInfoWidget::showInfo(const Properties& props) StringList textChucks; // Get a valid filename representing a snapshot file for this rom - const string& path = instance()->settings().getString("ssdir"); - const string& filename = instance()->getFilename(path, props, "png"); + const string& filename = + instance()->settings().getString("ssdir") + BSPF_PATH_SEPARATOR + + myProperties.get(Cartridge_Name) + ".png"; // Open the PNG and check for a valid signature - clearInfo(false); in.open(filename.c_str(), ios_base::binary); if(in) { @@ -76,7 +136,7 @@ void RomInfoWidget::showInfo(const Properties& props) uInt8 header[8]; in.read((char*)header, 8); if(!isValidPNGHeader(header)) - throw "RomInfoWidget: Not a PNG image"; + throw "Invalid PNG image"; // Read all chunks until we reach the end int width = 0, height = 0; @@ -84,18 +144,19 @@ void RomInfoWidget::showInfo(const Properties& props) { readPNGChunk(in, type, &data, size); - if(type == "IHDR" && !parseIHDR(width, height, data, size)) - throw "RomInfoWidget: IHDR chunk not supported"; + if(type == "IHDR") + { + if(!parseIHDR(width, height, data, size)) + throw "Invalid PNG image (IHDR)"; + + mySurface->setClipWidth(width); + mySurface->setClipHeight(height); + } else if(type == "IDAT") { - // Restrict surface size to available space - int s_width = BSPF_min(320, width); - int s_height = BSPF_min(250, height); - - FrameBuffer& fb = instance()->frameBuffer(); - mySurface = fb.createSurface(s_width, s_height); - if(!parseIDATChunk(fb, mySurface, width, height, data, size)) - throw "RomInfoWidget: IDAT processing failed"; + if(!parseIDATChunk(instance()->frameBuffer(), mySurface, + width, height, data, size)) + throw "PNG image too large"; } else if(type == "tEXt") textChucks.push_back(parseTextChunk(data, size)); @@ -104,41 +165,32 @@ void RomInfoWidget::showInfo(const Properties& props) } in.close(); + myDrawSurface = true; } - catch(const char *msg) + catch(const char* msg) { - clearInfo(false); + myDrawSurface = false; + myRomInfo.clear(); if(data) delete[] data; data = NULL; + in.close(); - cerr << msg << endl; + mySurfaceErrorMsg = msg; + return; } } + else + mySurfaceErrorMsg = "No image found"; + // Now add some info for the message box below the image - myRomInfo.push_back("Name: " + props.get(Cartridge_Name)); - myRomInfo.push_back("Manufacturer: " + props.get(Cartridge_Manufacturer)); - myRomInfo.push_back("Model: " + props.get(Cartridge_ModelNo)); - myRomInfo.push_back("Rarity: " + props.get(Cartridge_Rarity)); - myRomInfo.push_back("Note: " + props.get(Cartridge_Note)); - myRomInfo.push_back("Controllers: " + props.get(Controller_Left) + - " (left), " + props.get(Controller_Right) + " (right)"); + myRomInfo.push_back("Name: " + myProperties.get(Cartridge_Name)); + myRomInfo.push_back("Manufacturer: " + myProperties.get(Cartridge_Manufacturer)); + myRomInfo.push_back("Model: " + myProperties.get(Cartridge_ModelNo)); + myRomInfo.push_back("Rarity: " + myProperties.get(Cartridge_Rarity)); + myRomInfo.push_back("Note: " + myProperties.get(Cartridge_Note)); + myRomInfo.push_back("Controllers: " + myProperties.get(Controller_Left) + + " (left), " + myProperties.get(Controller_Right) + " (right)"); // TODO - add the PNG tEXt chunks - - setDirty(); draw(); -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void RomInfoWidget::clearInfo(bool redraw) -{ - if(mySurface) - delete mySurface; - mySurface = NULL; - myRomInfo.clear(); - - if(redraw) - { - setDirty(); draw(); - } } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -150,12 +202,19 @@ void RomInfoWidget::drawWidget(bool hilite) fb.box(_x, _y, _w, _h, kColor, kShadowColor); fb.box(_x, _y+254, _w, _h-254, kColor, kShadowColor); - if(mySurface) + if(!myHaveProperties) return; + + if(myDrawSurface && mySurface) { - int x = (_w - mySurface->getWidth()) >> 1; - int y = (256 - mySurface->getHeight()) >> 1; + int x = (_w - mySurface->getClipWidth()) >> 1; + int y = (256 - mySurface->getClipHeight()) >> 1; fb.drawSurface(mySurface, x + getAbsX(), y + getAbsY()); } + else if(mySurfaceErrorMsg != "") + { + int x = _x + ((_w - _font->getStringWidth(mySurfaceErrorMsg)) >> 1); + fb.drawString(_font, mySurfaceErrorMsg, x, 120, _w - 10, _textcolor); + } int xpos = _x + 5, ypos = _y + 256 + 5; for(unsigned int i = 0; i < myRomInfo.size(); ++i) { @@ -208,6 +267,10 @@ bool RomInfoWidget::parseIHDR(int& width, int& height, uInt8* data, int size) width = data[0] << 24 | data[1] << 16 | data[2] << 8 | data[3]; height = data[4] << 24 | data[5] << 16 | data[6] << 8 | data[7]; + // Make sure image can fit in widget bounds + width = BSPF_min(320, width); + height = BSPF_min(250, height); + uInt8 trailer[5] = { 8, 2, 0, 0, 0 }; // 24-bit RGB return memcmp(trailer, data + 8, 5) == 0; } @@ -220,27 +283,20 @@ bool RomInfoWidget::parseIDATChunk(const FrameBuffer& fb, GUI::Surface* surface, uLongf bufsize = (width * 3 + 1) * height; uInt8* buffer = new uInt8[bufsize]; - // Only get as many scanlines as necessary to fill the surface - height = BSPF_min(250, height); - + int pitch = width * 3; // bytes per line of the image if(uncompress(buffer, &bufsize, data, size) == Z_OK) { uInt8* buf_ptr = buffer; - int pitch = width * 3; // bytes per line of the image for(int row = 0; row < height; row++, buf_ptr += pitch) { buf_ptr++; // skip past first byte (PNG filter type) - fb.bytesToSurface(surface, row, buf_ptr); + fb.bytesToSurface(surface, row, buf_ptr, pitch); } + delete[] buffer; + return true; } - else - { - cerr << "RomInfoWidget: error decompressing data\n"; - return false; - } - delete[] buffer; - return true; + return false; } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/stella/src/gui/RomInfoWidget.hxx b/stella/src/gui/RomInfoWidget.hxx index c5eb0a557..3b45f22da 100644 --- a/stella/src/gui/RomInfoWidget.hxx +++ b/stella/src/gui/RomInfoWidget.hxx @@ -13,7 +13,7 @@ // See the file "license" for information on usage and redistribution of // this file, and for a DISCLAIMER OF ALL WARRANTIES. // -// $Id: RomInfoWidget.hxx,v 1.3 2008-02-06 13:45:24 stephena Exp $ +// $Id: RomInfoWidget.hxx,v 1.4 2008-03-13 22:58:07 stephena Exp $ //============================================================================ #ifndef ROM_INFO_WIDGET_HXX @@ -37,14 +37,16 @@ class RomInfoWidget : public Widget int x, int y, int w, int h); virtual ~RomInfoWidget(); - void showInfo(const Properties& props); - void clearInfo(bool redraw = true); + void setProperties(const Properties& props); + void clearProperties(); + void initialize(); + void loadConfig(); protected: - void loadConfig(); void drawWidget(bool hilite); private: + void parseProperties(); static bool isValidPNGHeader(uInt8* header); static void readPNGChunk(ifstream& in, string& type, uInt8** data, int& size); static bool parseIHDR(int& width, int& height, uInt8* data, int size); @@ -56,8 +58,20 @@ class RomInfoWidget : public Widget // Surface holding the scaled PNG image GUI::Surface* mySurface; + // Whether the surface should be redrawn by drawWidget() + bool myDrawSurface; + // Some ROM properties info, as well as 'tEXt' chunks from the PNG image StringList myRomInfo; + + // The properties for the currently selected ROM + Properties myProperties; + + // Indicates if the current properties should actually be used + bool myHaveProperties; + + // Indicates if an error occurred in creating/displaying the surface + string mySurfaceErrorMsg; }; #endif diff --git a/stella/src/gui/Surface.cxx b/stella/src/gui/Surface.cxx index 226371260..fa3c78fd7 100644 --- a/stella/src/gui/Surface.cxx +++ b/stella/src/gui/Surface.cxx @@ -13,7 +13,7 @@ // See the file "license" for information on usage and redistribution of // this file, and for a DISCLAIMER OF ALL WARRANTIES. // -// $Id: Surface.cxx,v 1.2 2008-02-06 13:45:24 stephena Exp $ +// $Id: Surface.cxx,v 1.3 2008-03-13 22:58:07 stephena Exp $ // // Based on code from ScummVM - Scumm Interpreter // Copyright (C) 2002-2004 The ScummVM project @@ -29,6 +29,8 @@ namespace GUI { Surface::Surface(int width, int height, SDL_Surface* data) : myBaseWidth(width), myBaseHeight(height), + myClipWidth(width), + myClipHeight(height), myData(data) { } diff --git a/stella/src/gui/Surface.hxx b/stella/src/gui/Surface.hxx index 1787a6dc5..570757f19 100644 --- a/stella/src/gui/Surface.hxx +++ b/stella/src/gui/Surface.hxx @@ -13,7 +13,7 @@ // See the file "license" for information on usage and redistribution of // this file, and for a DISCLAIMER OF ALL WARRANTIES. // -// $Id: Surface.hxx,v 1.2 2008-02-06 13:45:24 stephena Exp $ +// $Id: Surface.hxx,v 1.3 2008-03-13 22:58:07 stephena Exp $ //============================================================================ #ifndef GUI_SURFACE_HXX @@ -26,26 +26,36 @@ namespace GUI { /** This class is basically a thin wrapper around an SDL_Surface structure. We do it this way so the SDL stuff won't be dragged into the depths of - the codebase. + the codebase. Although everything is public and SDL structures can be + used directly, it's recommended to only access the variables from the + advertised interface, or from FrameBuffer-derived classes. @author Stephen Anthony - @version $Id: Surface.hxx,v 1.2 2008-02-06 13:45:24 stephena Exp $ + @version $Id: Surface.hxx,v 1.3 2008-03-13 22:58:07 stephena Exp $ */ class Surface { - friend class FrameBuffer; - public: Surface(int width, int height, SDL_Surface* surface); virtual ~Surface(); - int getWidth() const { return myBaseWidth; } - int getHeight() const { return myBaseHeight; } + /** Actual width and height of the SDL surface */ + inline int getWidth() const { return myBaseWidth; } + inline int getHeight() const { return myBaseHeight; } + + /** Clipped/drawn width and height of the SDL surface */ + inline int getClipWidth() const { return myClipWidth; } + inline int getClipHeight() const { return myClipHeight; } + inline void setClipWidth(int w) { myClipWidth = w; } + inline void setClipHeight(int h) { myClipHeight = h; } public: int myBaseWidth; int myBaseHeight; + int myClipWidth; + int myClipHeight; + SDL_Surface* myData; }; diff --git a/stella/src/gui/UIDialog.cxx b/stella/src/gui/UIDialog.cxx index 7cf9c1f7c..be4fcc8da 100644 --- a/stella/src/gui/UIDialog.cxx +++ b/stella/src/gui/UIDialog.cxx @@ -13,7 +13,7 @@ // See the file "license" for information on usage and redistribution of // this file, and for a DISCLAIMER OF ALL WARRANTIES. // -// $Id: UIDialog.cxx,v 1.9 2008-02-06 13:45:24 stephena Exp $ +// $Id: UIDialog.cxx,v 1.10 2008-03-13 22:58:07 stephena Exp $ // // Based on code from ScummVM - Scumm Interpreter // Copyright (C) 2002-2004 The ScummVM project @@ -128,6 +128,11 @@ UIDialog::UIDialog(OSystem* osystem, DialogContainer* parent, wid.push_back(myPalettePopup); ypos += lineHeight + 4; + // ROM info viewer + xpos += ((_w - 40 - font.getStringWidth("ROM Info viewer (*)")) >> 1); + myRomViewerCheckbox = new CheckboxWidget(this, font, xpos, ypos, + "ROM Info viewer (*)", 0); + // Add message concerning usage lwidth = font.getStringWidth("(*) Requires application restart"); new StaticTextWidget(this, font, 10, _h - 38, lwidth, fontHeight, @@ -212,6 +217,10 @@ void UIDialog::loadConfig() int i = instance()->settings().getInt("uipalette"); if(i < 1 || i > 2) i = 1; myPalettePopup->setSelectedTag(i); + + // ROM info viewer + bool b = instance()->settings().getBool("romviewer"); + myRomViewerCheckbox->setState(b); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -233,13 +242,17 @@ void UIDialog::saveConfig() // UI palette instance()->settings().setInt("uipalette", myPalettePopup->getSelectedTag()); + + // ROM info viewer + instance()->settings().setBool("romviewer", + myRomViewerCheckbox->getState()); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - void UIDialog::setDefaults() { - int w = BSPF_min(instance()->desktopWidth(), (const uInt32) 400); - int h = BSPF_min(instance()->desktopHeight(), (const uInt32) 300); + int w = BSPF_min(instance()->desktopWidth(), 400u); + int h = BSPF_min(instance()->desktopHeight(), 300u); myLauncherWidthSlider->setValue(w); myLauncherWidthLabel->setValue(w); myLauncherHeightSlider->setValue(h); diff --git a/stella/src/gui/UIDialog.hxx b/stella/src/gui/UIDialog.hxx index 1350fdf5a..17c69a77b 100644 --- a/stella/src/gui/UIDialog.hxx +++ b/stella/src/gui/UIDialog.hxx @@ -13,7 +13,7 @@ // See the file "license" for information on usage and redistribution of // this file, and for a DISCLAIMER OF ALL WARRANTIES. // -// $Id: UIDialog.hxx,v 1.6 2008-02-06 13:45:24 stephena Exp $ +// $Id: UIDialog.hxx,v 1.7 2008-03-13 22:58:07 stephena Exp $ // // Based on code from ScummVM - Scumm Interpreter // Copyright (C) 2002-2004 The ScummVM project @@ -25,6 +25,7 @@ class CommandSender; class Dialog; class DialogContainer; +class CheckboxWidget; class PopUpWidget; class SliderWidget; class StaticTextWidget; @@ -55,6 +56,8 @@ class UIDialog : public Dialog PopUpWidget* myPalettePopup; + CheckboxWidget* myRomViewerCheckbox; + private: void loadConfig(); void saveConfig();