From 2e2867cb6ece031e84a818929c7d69618429d209 Mon Sep 17 00:00:00 2001 From: stephena Date: Thu, 19 Jun 2008 12:01:31 +0000 Subject: [PATCH] Several updates to the new UI rendering infrastructure. Overlaid frame stats and general messages are now shown correctly. ContextMenu and PopUpWidget are now drawn correctly, and take image 'centering' into account. Fixed many 'offset' bugs in rendering surfaces. Fixed long-standing issue where pressing Alt-Enter to toggle fullscreen mode actually passed the Enter to the underlying dialog (it's now properly swallowed). Probably many more items I'm forgetting ... Still TODO is work on other dialogs that aren't centered by default (InputTextDialog, etc). My plan is to stabilize these changes and then fix OpenGL mode, and only after I've achieved parity with 2.6.1 to actually make use of the new infrastructure (larger fonts, etc). git-svn-id: svn://svn.code.sf.net/p/stella/code/trunk@1539 8b62c5a3-ac7e-4cc8-8f21-d9a121418aba --- stella/src/common/FrameBufferGL.cxx | 63 ++-- stella/src/common/FrameBufferGL.hxx | 30 +- stella/src/common/FrameBufferSoft.cxx | 97 +++-- stella/src/common/FrameBufferSoft.hxx | 30 +- stella/src/common/Snapshot.cxx | 6 +- stella/src/common/VideoModeList.hxx | 21 +- stella/src/debugger/gui/RomListWidget.cxx | 15 +- stella/src/debugger/gui/TiaOutputWidget.cxx | 9 +- stella/src/debugger/gui/TiaZoomWidget.cxx | 11 +- stella/src/emucore/EventHandler.cxx | 99 +++-- stella/src/emucore/FrameBuffer.cxx | 385 +++++++++++--------- stella/src/emucore/FrameBuffer.hxx | 107 +++--- stella/src/gui/ContextMenu.cxx | 22 +- stella/src/gui/ContextMenu.hxx | 4 +- stella/src/gui/Dialog.cxx | 11 +- stella/src/gui/Launcher.cxx | 10 +- stella/src/gui/PopUpWidget.cxx | 13 +- stella/src/gui/Rect.hxx | 8 +- stella/src/gui/RomInfoWidget.cxx | 16 +- stella/src/gui/RomInfoWidget.hxx | 10 +- 20 files changed, 533 insertions(+), 434 deletions(-) diff --git a/stella/src/common/FrameBufferGL.cxx b/stella/src/common/FrameBufferGL.cxx index 6a18bc211..54023d96a 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.103 2008-06-13 13:14:50 stephena Exp $ +// $Id: FrameBufferGL.cxx,v 1.104 2008-06-19 12:01:30 stephena Exp $ //============================================================================ #ifdef DISPLAY_OPENGL @@ -180,7 +180,7 @@ bool FrameBufferGL::loadFuncs() } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -bool FrameBufferGL::initSubsystem(VideoMode mode) +bool FrameBufferGL::initSubsystem(VideoMode& mode) { mySDLFlags |= SDL_OPENGL; @@ -234,8 +234,10 @@ string FrameBufferGL::about() const } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -bool FrameBufferGL::setVidMode(VideoMode mode) +bool FrameBufferGL::setVidMode(VideoMode& mode) { +return false; +#if 0 bool inUIMode = myOSystem->eventHandler().state() == EventHandler::S_LAUNCHER || myOSystem->eventHandler().state() == EventHandler::S_DEBUGGER; @@ -354,6 +356,7 @@ bool FrameBufferGL::setVidMode(VideoMode mode) p_glClear(GL_COLOR_BUFFER_BIT); return true; +#endif } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -430,7 +433,8 @@ void FrameBufferGL::postFrameUpdate() { // Texturemap complete texture to surface so we have free scaling // and antialiasing - uInt32 w = myImageDim.w, h = myImageDim.h; +// FIXME uInt32 w = myImageDim.w, h = myImageDim.h; +uInt32 w = 0, h = 0; p_glTexSubImage2D(myBuffer.target, 0, 0, 0, myBuffer.texture_width, myBuffer.texture_height, @@ -515,10 +519,11 @@ void FrameBufferGL::scanline(uInt32 row, uInt8* data) const { // Invert the row, since OpenGL rows start at the bottom // of the framebuffer - row = myImageDim.h + myImageDim.y - row - 1; + const GUI::Rect& image = imageRect(); + row = image.height() + image.y() - row - 1; p_glPixelStorei(GL_PACK_ALIGNMENT, 1); - p_glReadPixels(myImageDim.x, row, myImageDim.w, 1, GL_RGB, GL_UNSIGNED_BYTE, data); + p_glReadPixels(image.x(), row, image.width(), 1, GL_RGB, GL_UNSIGNED_BYTE, data); } @@ -636,36 +641,11 @@ void FBSurfaceGL::addDirtyRect(uInt32 x, uInt32 y, uInt32 w, uInt32 h) } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void FBSurfaceGL::centerPos() +void FBSurfaceGL::getPos(uInt32& x, uInt32& y) const { #if 0 - // Make sure pitch is valid - recalc(); - - // X/Y Orig are the coordinates to use when blitting an entire (non-base) - // surface to the screen. As such, they're concerned with the 'usable' - // area of a surface, not its entire size (ie, we use the originally - // requested width & height, which are not necessarily the same as - // the surface width & height). - // These coordinates are not used at all for drawing base surfaces - myXOrig = (myFB.myScreenDim.w - myWidth) >> 1; - myYOrig = (myFB.myScreenDim.h - myHeight) >> 1; - - // X/Y/Base Offset determine 'how far' to go into a surface, since base - // surfaces are defined larger than necessary in some cases, and have a - // 'non-usable' area. - if(myIsBaseSurface) - { - myXOffset = myFB.myImageDim.x; - myYOffset = myFB.myImageDim.y; - myBaseOffset = myYOffset * myPitch + myXOffset; - } - else - { - myXOffset = myYOffset = myBaseOffset = 0; - } -//cerr << "center: xorig = " << myXOrig << ", yorig = " << myYOrig << endl -// << " xoffset = " << myXOffset << ", yoffset = " << myYOffset << endl; + x = myXOrig; + y = myYOrig; #endif } @@ -687,12 +667,13 @@ void FBSurfaceGL::setPos(uInt32 x, uInt32 y) } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void FBSurfaceGL::getPos(uInt32& x, uInt32& y) const +void FBSurfaceGL::setWidth(uInt32 w) +{ +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +void FBSurfaceGL::setHeight(uInt32 h) { -#if 0 - x = myXOrig; - y = myYOrig; -#endif } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -726,8 +707,8 @@ bool FrameBufferGL::createTextures() // Fill buffer struct with valid data // This changes depending on the texturing used - myBuffer.width = myBaseDim.w; - myBuffer.height = myBaseDim.h; + myBuffer.width = 0;//FIXME myBaseDim.w; + myBuffer.height = 0;//FIXME myBaseDim.h; myBuffer.tex_coord[0] = 0.0f; myBuffer.tex_coord[1] = 0.0f; if(myHaveTexRectEXT) diff --git a/stella/src/common/FrameBufferGL.hxx b/stella/src/common/FrameBufferGL.hxx index 3c508a3fa..b66d37b02 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.53 2008-06-13 13:14:50 stephena Exp $ +// $Id: FrameBufferGL.hxx,v 1.54 2008-06-19 12:01:30 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.53 2008-06-13 13:14:50 stephena Exp $ + @version $Id: FrameBufferGL.hxx,v 1.54 2008-06-19 12:01:30 stephena Exp $ */ class FrameBufferGL : public FrameBuffer { @@ -107,17 +107,24 @@ class FrameBufferGL : public FrameBuffer // The following are derived from protected methods in FrameBuffer.hxx ////////////////////////////////////////////////////////////////////// /** - This method is called to initialize OpenGL video mode. - Return false if any operation fails, otherwise return true. + This method is called to initialize the video subsystem + with the given video mode. Normally, it will also call setVidMode(). + + @param mode The video mode to use + + @return False on any errors, else true */ - bool initSubsystem(VideoMode mode); + bool initSubsystem(VideoMode& mode); /** - This method is called to change to the given video mode. + This method is called to change to the given video mode. If the mode + is successfully changed, 'mode' holds the actual dimensions used. - @param mode The mode to use for rendering the mediasource + @param mode The video mode to use + + @return False on any errors (in which case 'mode' is invalid), else true */ - bool setVidMode(VideoMode mode); + bool setVidMode(VideoMode& mode); /** Switches between the two filtering options in OpenGL. @@ -203,7 +210,7 @@ class FrameBufferGL : public FrameBuffer A surface suitable for software rendering mode. @author Stephen Anthony - @version $Id: FrameBufferGL.hxx,v 1.53 2008-06-13 13:14:50 stephena Exp $ + @version $Id: FrameBufferGL.hxx,v 1.54 2008-06-19 12:01:30 stephena Exp $ */ class FBSurfaceGL : public FBSurface { @@ -218,9 +225,10 @@ class FBSurfaceGL : public FBSurface void drawChar(const GUI::Font* font, uInt8 c, uInt32 x, uInt32 y, int color); void drawBitmap(uInt32* bitmap, Int32 x, Int32 y, int color, Int32 h = 8); void addDirtyRect(uInt32 x, uInt32 y, uInt32 w, uInt32 h); - void centerPos(); - void setPos(uInt32 x, uInt32 y); void getPos(uInt32& x, uInt32& y) const; + void setPos(uInt32 x, uInt32 y); + void setWidth(uInt32 w); + void setHeight(uInt32 h); void translateCoords(Int32& x, Int32& y) const; void update(); diff --git a/stella/src/common/FrameBufferSoft.cxx b/stella/src/common/FrameBufferSoft.cxx index 62f69f3cc..6216d37a5 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.79 2008-06-13 13:14:50 stephena Exp $ +// $Id: FrameBufferSoft.cxx,v 1.80 2008-06-19 12:01:30 stephena Exp $ //============================================================================ #include @@ -46,7 +46,7 @@ FrameBufferSoft::~FrameBufferSoft() } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -bool FrameBufferSoft::initSubsystem(VideoMode mode) +bool FrameBufferSoft::initSubsystem(VideoMode& mode) { // Set up the rectangle list to be used in the dirty update delete myRectList; @@ -83,26 +83,15 @@ string FrameBufferSoft::about() const } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -bool FrameBufferSoft::setVidMode(VideoMode mode) +bool FrameBufferSoft::setVidMode(VideoMode& mode) { - myScreenDim.x = myScreenDim.y = 0; - myScreenDim.w = mode.screen_w; - myScreenDim.h = mode.screen_h; - - myImageDim.x = mode.image_x; - myImageDim.y = mode.image_y; - myImageDim.w = mode.image_w; - myImageDim.h = mode.image_h; - - myZoomLevel = mode.zoom; - // Make sure to clear the screen if(myScreen) { SDL_FillRect(myScreen, NULL, 0); SDL_UpdateRect(myScreen, 0, 0, 0, 0); } - myScreen = SDL_SetVideoMode(myScreenDim.w, myScreenDim.h, 0, mySDLFlags); + myScreen = SDL_SetVideoMode(mode.screen_w, mode.screen_h, 0, mySDLFlags); if(myScreen == NULL) { cerr << "ERROR: Unable to open SDL window: " << SDL_GetError() << endl; @@ -111,9 +100,16 @@ bool FrameBufferSoft::setVidMode(VideoMode mode) myFormat = myScreen->format; myBytesPerPixel = myFormat->BytesPerPixel; + // If software mode can open the given screen, it will always be in the + // requested format, or not at all; we only update mode when the screen + // is successfully created + mode.screen_w = myScreen->w; + mode.screen_h = myScreen->h; + myZoomLevel = mode.zoom; + // Make sure drawMediaSource() knows which renderer to use stateChanged(myOSystem->eventHandler().state()); - myBaseOffset = myImageDim.y * myPitch + myImageDim.x; + myBaseOffset = mode.image_y * myPitch + mode.image_x; // Erase old rects, since they've probably been scaled for // a different sized screen @@ -436,12 +432,13 @@ void FrameBufferSoft::scanline(uInt32 row, uInt8* data) const uInt8 *p, r, g, b; // Row will be offset by the amount the actual image is shifted down - row += myImageDim.y; + const GUI::Rect& image = imageRect(); + row += image.y(); for(Int32 x = 0; x < myScreen->w; ++x) { p = (Uint8*) ((uInt8*)myScreen->pixels + // Start at top of RAM (row * myScreen->pitch) + // Go down 'row' lines - ((x + myImageDim.x) * myBytesPerPixel)); // Go in 'x' pixels + ((x + image.x()) * myBytesPerPixel)); // Go in 'x' pixels switch(myBytesPerPixel) { @@ -691,57 +688,53 @@ void FBSurfaceSoft::addDirtyRect(uInt32 x, uInt32 y, uInt32 w, uInt32 h) } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void FBSurfaceSoft::centerPos() +void FBSurfaceSoft::getPos(uInt32& x, uInt32& y) const +{ + // Return the origin of the 'usable' area of a surface + if(myIsBaseSurface) + { + x = myXOffset; + y = myYOffset; + } + else + { + x = myXOrig; + y = myYOrig; + } +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +void FBSurfaceSoft::setPos(uInt32 x, uInt32 y) { // Make sure pitch is valid recalc(); - // X/Y Orig are the coordinates to use when blitting an entire (non-base) - // surface to the screen. As such, they're concerned with the 'usable' - // area of a surface, not its entire size (ie, we use the originally - // requested width & height, which are not necessarily the same as - // the surface width & height). - // These coordinates are not used at all for drawing base surfaces - myXOrig = (myFB.myScreenDim.w - myWidth) >> 1; - myYOrig = (myFB.myScreenDim.h - myHeight) >> 1; + myXOrig = x; + myYOrig = y; - // X/Y/Base Offset determine 'how far' to go into a surface, since base - // surfaces are defined larger than necessary in some cases, and have a - // 'non-usable' area. if(myIsBaseSurface) { - myXOffset = myFB.myImageDim.x; - myYOffset = myFB.myImageDim.y; + const GUI::Rect& image = myFB.imageRect(); + myXOffset = image.x(); + myYOffset = image.y(); myBaseOffset = myYOffset * myPitch + myXOffset; } else { myXOffset = myYOffset = myBaseOffset = 0; } -//cerr << "center: xorig = " << myXOrig << ", yorig = " << myYOrig << endl -// << " xoffset = " << myXOffset << ", yoffset = " << myYOffset << endl; } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void FBSurfaceSoft::setPos(uInt32 x, uInt32 y) +void FBSurfaceSoft::setWidth(uInt32 w) { - // Only non-base surfaces can be arbitrarily 'moved' - if(!myIsBaseSurface) - { - // Make sure pitch is valid - recalc(); - - myXOrig = x; - myYOrig = y; - myXOffset = myYOffset = myBaseOffset = 0; - } + myWidth = w; } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void FBSurfaceSoft::getPos(uInt32& x, uInt32& y) const +void FBSurfaceSoft::setHeight(uInt32 h) { - x = myXOrig; - y = myYOrig; + myHeight = h; } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -766,6 +759,12 @@ void FBSurfaceSoft::update() } else if(mySurfaceIsDirty /* && !myIsBaseSurface */) { + SDL_Rect srcrect; + srcrect.x = 0; + srcrect.y = 0; + srcrect.w = myWidth; + srcrect.h = myHeight; + SDL_Rect dstrect; dstrect.x = myXOrig; dstrect.y = myYOrig; @@ -779,7 +778,7 @@ void FBSurfaceSoft::update() << " dst h = " << dstrect.h << endl << endl; */ - SDL_BlitSurface(mySurface, NULL, myFB.myScreen, &dstrect); + SDL_BlitSurface(mySurface, &srcrect, myFB.myScreen, &dstrect); SDL_UpdateRect(myFB.myScreen, myXOrig, myYOrig, myWidth, myHeight); mySurfaceIsDirty = false; diff --git a/stella/src/common/FrameBufferSoft.hxx b/stella/src/common/FrameBufferSoft.hxx index 7eb6f7fe2..c40be716a 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.51 2008-06-13 13:14:50 stephena Exp $ +// $Id: FrameBufferSoft.hxx,v 1.52 2008-06-19 12:01:30 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.51 2008-06-13 13:14:50 stephena Exp $ + @version $Id: FrameBufferSoft.hxx,v 1.52 2008-06-19 12:01:30 stephena Exp $ */ class FrameBufferSoft : public FrameBuffer { @@ -96,17 +96,24 @@ class FrameBufferSoft : public FrameBuffer // The following are derived from protected methods in FrameBuffer.hxx ////////////////////////////////////////////////////////////////////// /** - This method is called to initialize software video mode. - Return false if any operation fails, otherwise return true. + This method is called to initialize the video subsystem + with the given video mode. Normally, it will also call setVidMode(). + + @param mode The video mode to use + + @return False on any errors, else true */ - bool initSubsystem(VideoMode mode); + bool initSubsystem(VideoMode& mode); /** - This method is called to change to the given videomode type. + This method is called to change to the given video mode. If the mode + is successfully changed, 'mode' holds the actual dimensions used. - @param mode The video mode to use for rendering the mediasource + @param mode The video mode to use + + @return False on any errors (in which case 'mode' is invalid), else true */ - bool setVidMode(VideoMode mode); + bool setVidMode(VideoMode& mode); /** Switches between the filtering options in software mode. @@ -155,7 +162,7 @@ class FrameBufferSoft : public FrameBuffer A surface suitable for software rendering mode. @author Stephen Anthony - @version $Id: FrameBufferSoft.hxx,v 1.51 2008-06-13 13:14:50 stephena Exp $ + @version $Id: FrameBufferSoft.hxx,v 1.52 2008-06-19 12:01:30 stephena Exp $ */ class FBSurfaceSoft : public FBSurface { @@ -170,9 +177,10 @@ class FBSurfaceSoft : public FBSurface void drawChar(const GUI::Font* font, uInt8 c, uInt32 x, uInt32 y, int color); void drawBitmap(uInt32* bitmap, Int32 x, Int32 y, int color, Int32 h = 8); void addDirtyRect(uInt32 x, uInt32 y, uInt32 w, uInt32 h); - void centerPos(); - void setPos(uInt32 x, uInt32 y); void getPos(uInt32& x, uInt32& y) const; + void setPos(uInt32 x, uInt32 y); + void setWidth(uInt32 w); + void setHeight(uInt32 h); void translateCoords(Int32& x, Int32& y) const; void update(); diff --git a/stella/src/common/Snapshot.cxx b/stella/src/common/Snapshot.cxx index 6024f1d14..5819319e3 100644 --- a/stella/src/common/Snapshot.cxx +++ b/stella/src/common/Snapshot.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: Snapshot.cxx,v 1.22 2008-05-30 19:07:55 stephena Exp $ +// $Id: Snapshot.cxx,v 1.23 2008-06-19 12:01:30 stephena Exp $ //============================================================================ #include @@ -42,8 +42,8 @@ void Snapshot::savePNG(FrameBuffer& framebuffer, const Properties& props, // Get actual image dimensions. which are not always the same // as the framebuffer dimensions - int width = framebuffer.imageWidth(); - int height = framebuffer.imageHeight(); + const GUI::Rect& image = framebuffer.imageRect(); + int width = image.width(), height = image.height(); out.open(filename.c_str(), ios_base::binary); if(!out.is_open()) diff --git a/stella/src/common/VideoModeList.hxx b/stella/src/common/VideoModeList.hxx index 5e302f4f8..c30cfff40 100644 --- a/stella/src/common/VideoModeList.hxx +++ b/stella/src/common/VideoModeList.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: VideoModeList.hxx,v 1.4 2008-02-06 13:45:19 stephena Exp $ +// $Id: VideoModeList.hxx,v 1.5 2008-06-19 12:01:30 stephena Exp $ //============================================================================ #ifndef VIDMODE_LIST_HXX @@ -33,7 +33,7 @@ struct VideoMode { This class implements an iterator around an array of VideoMode objects. @author Stephen Anthony - @version $Id: VideoModeList.hxx,v 1.4 2008-02-06 13:45:19 stephena Exp $ + @version $Id: VideoModeList.hxx,v 1.5 2008-06-19 12:01:30 stephena Exp $ */ class VideoModeList { @@ -94,6 +94,23 @@ class VideoModeList } } + void print() + { + for(Common::Array::const_iterator i = myModeList.begin(); i != myModeList.end(); ++i) + { + cerr << " Mode " << i << endl + << " screen w = " << i->screen_w << endl + << " screen h = " << i->screen_h << endl + << " image x = " << i->image_x << endl + << " image y = " << i->image_y << endl + << " image w = " << i->image_w << endl + << " image h = " << i->image_h << endl + << " zoom = " << i->zoom << endl + << " name = " << i->name << endl + << endl; + } + } + private: Common::Array myModeList; int myIdx; diff --git a/stella/src/debugger/gui/RomListWidget.cxx b/stella/src/debugger/gui/RomListWidget.cxx index 8285cbd61..0208f3af9 100644 --- a/stella/src/debugger/gui/RomListWidget.cxx +++ b/stella/src/debugger/gui/RomListWidget.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: RomListWidget.cxx,v 1.13 2008-06-13 13:14:50 stephena Exp $ +// $Id: RomListWidget.cxx,v 1.14 2008-06-19 12:01:30 stephena Exp $ // // Based on code from ScummVM - Scumm Interpreter // Copyright (C) 2002-2004 The ScummVM project @@ -67,9 +67,16 @@ void RomListWidget::handleMouseDown(int x, int y, int button, int clickCount) { // Grab right mouse button for context menu, send left to base class if(button == 2) - myMenu->show(x + getAbsX(), y + getAbsY()); - - ListWidget::handleMouseDown(x, y, button, clickCount); + { + // Add menu at current x,y mouse location + uInt32 tx, ty; + dialog().surface().getPos(tx, ty); + x += getAbsX() + tx; + y += getAbsY() + ty; + myMenu->show(x, y); + } + else + ListWidget::handleMouseDown(x, y, button, clickCount); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/stella/src/debugger/gui/TiaOutputWidget.cxx b/stella/src/debugger/gui/TiaOutputWidget.cxx index aaaf157c2..cd9223cff 100644 --- a/stella/src/debugger/gui/TiaOutputWidget.cxx +++ b/stella/src/debugger/gui/TiaOutputWidget.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: TiaOutputWidget.cxx,v 1.16 2008-06-13 13:14:50 stephena Exp $ +// $Id: TiaOutputWidget.cxx,v 1.17 2008-06-19 12:01:30 stephena Exp $ // // Based on code from ScummVM - Scumm Interpreter // Copyright (C) 2002-2004 The ScummVM project @@ -92,7 +92,12 @@ void TiaOutputWidget::handleMouseDown(int x, int y, int button, int clickCount) myClickX = x; myClickY = y; - myMenu->show(x + getAbsX(), y + getAbsY()); + // Add menu at current x,y mouse location + uInt32 tx, ty; + dialog().surface().getPos(tx, ty); + x += getAbsX() + tx; + y += getAbsY() + ty; + myMenu->show(x, y); } } diff --git a/stella/src/debugger/gui/TiaZoomWidget.cxx b/stella/src/debugger/gui/TiaZoomWidget.cxx index 5e13660e1..523898099 100644 --- a/stella/src/debugger/gui/TiaZoomWidget.cxx +++ b/stella/src/debugger/gui/TiaZoomWidget.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: TiaZoomWidget.cxx,v 1.16 2008-06-13 13:14:50 stephena Exp $ +// $Id: TiaZoomWidget.cxx,v 1.17 2008-06-19 12:01:30 stephena Exp $ // // Based on code from ScummVM - Scumm Interpreter // Copyright (C) 2002-2004 The ScummVM project @@ -137,7 +137,14 @@ void TiaZoomWidget::handleMouseDown(int x, int y, int button, int clickCount) { // Grab right mouse button for zoom context menu if(button == 2) - myMenu->show(x + getAbsX(), y + getAbsY()); + { + // Add menu at current x,y mouse location + uInt32 tx, ty; + dialog().surface().getPos(tx, ty); + x += getAbsX() + tx; + y += getAbsY() + ty; + myMenu->show(x, y); + } } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/stella/src/emucore/EventHandler.cxx b/stella/src/emucore/EventHandler.cxx index 31f129035..91fdc3a43 100644 --- a/stella/src/emucore/EventHandler.cxx +++ b/stella/src/emucore/EventHandler.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: EventHandler.cxx,v 1.226 2008-06-13 13:14:50 stephena Exp $ +// $Id: EventHandler.cxx,v 1.227 2008-06-19 12:01:30 stephena Exp $ //============================================================================ #include @@ -344,38 +344,35 @@ void EventHandler::poll(uInt32 time) SDLKey key = event.key.keysym.sym; SDLMod mod = event.key.keysym.mod; uInt8 state = event.key.type == SDL_KEYDOWN ? 1 : 0; + bool handled = true; // An attempt to speed up event processing // All SDL-specific event actions are accessed by either // Control/Cmd or Alt/Shift-Cmd keys. So we quickly check for those. if(kbdAlt(mod) && state) { + #ifndef MAC_OSX // These keys work in all states - switch(int(key)) + if(key == SDLK_RETURN) { - #ifndef MAC_OSX - case SDLK_EQUALS: - myOSystem->frameBuffer().changeVidMode(+1); - break; - - case SDLK_MINUS: - myOSystem->frameBuffer().changeVidMode(-1); - break; - - case SDLK_RETURN: - myOSystem->frameBuffer().toggleFullscreen(); - break; - #endif - case SDLK_g: - myOSystem->toggleFrameBuffer(); - break; + myOSystem->frameBuffer().toggleFullscreen(); } - + else + #endif // These only work when in emulation mode if(myState == S_EMULATE) { switch(int(key)) { + #ifndef MAC_OSX + case SDLK_EQUALS: + myOSystem->frameBuffer().changeVidMode(+1); + break; + + case SDLK_MINUS: + myOSystem->frameBuffer().changeVidMode(-1); + break; + #endif case SDLK_LEFTBRACKET: myOSystem->sound().adjustVolume(-1); break; @@ -457,8 +454,13 @@ void EventHandler::poll(uInt32 time) */ //////////////////////////////////////////////////////////////////////// #endif + default: + handled = false; + break; } } + else + handled = false; } else if(kbdControl(mod) && state) { @@ -469,25 +471,6 @@ void EventHandler::poll(uInt32 time) handleEvent(Event::Quit, 1); break; - #ifdef MAC_OSX - case SDLK_h: - case SDLK_m: - case SDLK_SLASH: - handleMacOSXKeypress(int(key)); - break; - - case SDLK_EQUALS: - myOSystem->frameBuffer().changeVidMode(+1); - break; - - case SDLK_MINUS: - myOSystem->frameBuffer().changeVidMode(-1); - break; - - case SDLK_RETURN: - myOSystem->frameBuffer().toggleFullscreen(); - break; - #endif case SDLK_g: // don't change grabmouse in fullscreen mode if(!myOSystem->frameBuffer().fullScreen()) @@ -497,6 +480,11 @@ void EventHandler::poll(uInt32 time) myOSystem->frameBuffer().grabMouse(myGrabMouseFlag); } break; + #ifdef MAC_OSX + case SDLK_RETURN: + myOSystem->frameBuffer().toggleFullscreen(); + break; + #endif } // These only work when in emulation mode @@ -504,6 +492,21 @@ void EventHandler::poll(uInt32 time) { switch(int(key)) { + #ifdef MAC_OSX + case SDLK_h: + case SDLK_m: + case SDLK_SLASH: + handleMacOSXKeypress(int(key)); + break; + + case SDLK_EQUALS: + myOSystem->frameBuffer().changeVidMode(+1); + break; + + case SDLK_MINUS: + myOSystem->frameBuffer().changeVidMode(-1); + break; + #endif case SDLK_0: // Ctrl-0 sets the mouse to paddle 0 setPaddleMode(0, true); break; @@ -560,9 +563,20 @@ void EventHandler::poll(uInt32 time) myOSystem->frameBuffer().showMessage("Error saving properties"); break; } + + default: + handled = false; + break; } } + else + handled = false; } + else + handled = false; + + // Don't pass the key on if we've already taken care of it + if(handled) break; // Handle keys which switch eventhandler state // Arrange the logic to take advantage of short-circuit evaluation @@ -1874,9 +1888,14 @@ bool EventHandler::enterDebugMode() // mode, since it takes care of locking the debugger state, which will // probably be modified below myOSystem->debugger().setStartState(); - setEventState(S_DEBUGGER); - myOSystem->createFrameBuffer(); + if(!myOSystem->createFrameBuffer()) + { + myOSystem->debugger().setQuitState(); + setEventState(S_EMULATE); + myOSystem->frameBuffer().showMessage("Error creating debugger window, check dimensions"); + return false; + } myOverlay->reStack(); myOSystem->frameBuffer().setCursorState(); myOSystem->sound().mute(true); diff --git a/stella/src/emucore/FrameBuffer.cxx b/stella/src/emucore/FrameBuffer.cxx index 69ee685c6..060a46e81 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.133 2008-06-13 13:14:50 stephena Exp $ +// $Id: FrameBuffer.cxx,v 1.134 2008-06-19 12:01:30 stephena Exp $ //============================================================================ #include @@ -45,14 +45,17 @@ FrameBuffer::FrameBuffer(OSystem* osystem) myUsePhosphor(false), myPhosphorBlend(77), myInitializedCount(0), - myPausedCount(0), - myFrameStatsEnabled(false) + myPausedCount(0) { + myMsg.surface = myStatsMsg.surface = 0; + myMsg.enabled = myStatsMsg.enabled = false; } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - FrameBuffer::~FrameBuffer(void) { + delete myMsg.surface; + delete myStatsMsg.surface; } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -70,10 +73,6 @@ bool FrameBuffer::initialize(const string& title, uInt32 width, uInt32 height) } myInitializedCount++; - myBaseDim.x = myBaseDim.y = 0; - myBaseDim.w = (uInt16) width; - myBaseDim.h = (uInt16) height; - // Set fullscreen flag #ifdef WINDOWED_SUPPORT mySDLFlags = myOSystem->settings().getBool("fullscreen") ? SDL_FULLSCREEN : 0; @@ -81,20 +80,36 @@ bool FrameBuffer::initialize(const string& title, uInt32 width, uInt32 height) mySDLFlags = 0; #endif +cerr << " <== FrameBuffer::initialize: w = " << width << ", h = " << height << endl; + // Set the available video modes for this framebuffer - setAvailableVidModes(); + setAvailableVidModes(width, height); - // Set window title and icon - setWindowTitle(title); - if(myInitializedCount == 1) setWindowIcon(); - - // Initialize video subsystem + // Initialize video subsystem (make sure we get a valid mode) VideoMode mode = getSavedVidMode(); - if(!initSubsystem(mode)) + if(width <= mode.screen_w && height <= mode.screen_h) { - cerr << "ERROR: Couldn't initialize video subsystem" << endl; - return false; + // Set window title and icon + setWindowTitle(title); + if(myInitializedCount == 1) setWindowIcon(); + + if(!initSubsystem(mode)) + { + cerr << "ERROR: Couldn't initialize video subsystem" << endl; + return false; + } + else + { + myImageRect.setWidth(mode.image_w); + myImageRect.setHeight(mode.image_h); + myImageRect.moveTo(mode.image_x, mode.image_y); + + myScreenRect.setWidth(mode.screen_w); + myScreenRect.setHeight(mode.screen_h); + } } + else + return false; // And refresh the display myOSystem->eventHandler().refreshDisplay(); @@ -104,7 +119,16 @@ bool FrameBuffer::initialize(const string& title, uInt32 width, uInt32 height) SDL_EnableUNICODE(1); // Erase any messages from a previous run - myMessage.counter = 0; + myMsg.counter = 0; + + // Create surfaces for TIA statistics and general messages + myStatsMsg.color = kBtnTextColor; + myStatsMsg.w = myOSystem->consoleFont().getStringWidth("000 LINES %00.00 FPS"); + myStatsMsg.h = myOSystem->consoleFont().getFontHeight(); + if(!myStatsMsg.surface) + myStatsMsg.surface = createSurface(myStatsMsg.w, myStatsMsg.h); + if(!myMsg.surface) + myMsg.surface = createSurface(320, 15); // TODO - size depends on font used // Finally, show some information about the framebuffer, // but only on the first initialization @@ -132,19 +156,21 @@ void FrameBuffer::update() // And update the screen drawMediaSource(); -#if 0 // Show frame statistics - if(myFrameStatsEnabled) + if(myStatsMsg.enabled) { // FIXME - sizes hardcoded for now; fix during UI refactoring char msg[30]; sprintf(msg, "%u LINES %2.2f FPS", myOSystem->console().mediaSource().scanlines(), myOSystem->console().getFramerate()); - fillRect(3, 3, 95, 9, kBGColor); - drawString(&myOSystem->font(), msg, 3, 3, 95, kBtnTextColor, kTextAlignCenter); + myStatsMsg.surface->fillRect(0, 0, myStatsMsg.w, myStatsMsg.h, kBGColor); + myStatsMsg.surface->drawString(&myOSystem->consoleFont(), msg, 0, 0, + myStatsMsg.w, myStatsMsg.color, kTextAlignLeft); + myStatsMsg.surface->addDirtyRect(0, 0, 0, 0); + myStatsMsg.surface->setPos(myImageRect.x() + 3, myImageRect.y() + 3); + myStatsMsg.surface->update(); } -#endif break; // S_EMULATE } @@ -203,7 +229,7 @@ void FrameBuffer::update() } // Draw any pending messages - if(myMessage.counter > 0) + if(myMsg.counter > 0) drawMessage(); // The frame doesn't need to be completely redrawn anymore @@ -215,65 +241,67 @@ void FrameBuffer::showMessage(const string& message, MessagePosition position, int color) { // Erase old messages on the screen - if(myMessage.counter > 0) + if(myMsg.counter > 0) { theRedrawTIAIndicator = true; myOSystem->eventHandler().refreshDisplay(); } // Precompute the message coordinates - myMessage.text = message; - myMessage.counter = uInt32(myOSystem->frameRate()) << 1; // Show message for 2 seconds - myMessage.color = color; + myMsg.text = message; + myMsg.counter = uInt32(myOSystem->frameRate()) << 1; // Show message for 2 seconds + myMsg.color = color; - myMessage.w = myOSystem->font().getStringWidth(myMessage.text) + 10; - myMessage.h = myOSystem->font().getFontHeight() + 8; + myMsg.w = myOSystem->font().getStringWidth(myMsg.text) + 10; + myMsg.h = myOSystem->font().getFontHeight() + 8; + myMsg.surface->setWidth(myMsg.w); + myMsg.surface->setHeight(myMsg.h); switch(position) { case kTopLeft: - myMessage.x = 5; - myMessage.y = 5; + myMsg.x = 5; + myMsg.y = 5; break; case kTopCenter: - myMessage.x = (myBaseDim.w >> 1) - (myMessage.w >> 1); - myMessage.y = 5; + myMsg.x = (myImageRect.width() - myMsg.w) >> 1; + myMsg.y = 5; break; case kTopRight: - myMessage.x = myBaseDim.w - myMessage.w - 5; - myMessage.y = 5; + myMsg.x = myImageRect.width() - myMsg.w - 5; + myMsg.y = 5; break; case kMiddleLeft: - myMessage.x = 5; - myMessage.y = (myBaseDim.h >> 1) - (myMessage.h >> 1); + myMsg.x = 5; + myMsg.y = (myImageRect.height() - myMsg.h) >> 1; break; case kMiddleCenter: - myMessage.x = (myBaseDim.w >> 1) - (myMessage.w >> 1); - myMessage.y = (myBaseDim.h >> 1) - (myMessage.h >> 1); + myMsg.x = (myImageRect.width() - myMsg.w) >> 1; + myMsg.y = (myImageRect.height() - myMsg.h) >> 1; break; case kMiddleRight: - myMessage.x = myBaseDim.w - myMessage.w - 5; - myMessage.y = (myBaseDim.h >> 1) - (myMessage.h >> 1); + myMsg.x = myImageRect.width() - myMsg.w - 5; + myMsg.y = (myImageRect.height() - myMsg.h) >> 1; break; case kBottomLeft: - myMessage.x = 5;//(myMessage.w >> 1); - myMessage.y = myBaseDim.h - myMessage.h - 5; + myMsg.x = 5; + myMsg.y = myImageRect.height() - myMsg.h - 5; break; case kBottomCenter: - myMessage.x = (myBaseDim.w >> 1) - (myMessage.w >> 1); - myMessage.y = myBaseDim.h - myMessage.h - 5; + myMsg.x = (myImageRect.width() - myMsg.w) >> 1; + myMsg.y = myImageRect.height() - myMsg.h - 5; break; case kBottomRight: - myMessage.x = myBaseDim.w - myMessage.w - 5; - myMessage.y = myBaseDim.h - myMessage.h - 5; + myMsg.x = myImageRect.width() - myMsg.w - 5; + myMsg.y = myImageRect.height() - myMsg.h - 5; break; } } @@ -288,7 +316,7 @@ void FrameBuffer::toggleFrameStats() void FrameBuffer::showFrameStats(bool enable) { myOSystem->settings().setBool("stats", enable); - myFrameStatsEnabled = enable; + myStatsMsg.enabled = enable; myOSystem->eventHandler().refreshDisplay(); } @@ -298,15 +326,15 @@ void FrameBuffer::enableMessages(bool enable) if(enable) { // Only re-anable frame stats if they were already enabled before - myFrameStatsEnabled = myOSystem->settings().getBool("stats"); + myStatsMsg.enabled = myOSystem->settings().getBool("stats"); } else { // Temporarily disable frame stats - myFrameStatsEnabled = false; + myStatsMsg.enabled = false; // Erase old messages on the screen - myMessage.counter = 0; + myMsg.counter = 0; myOSystem->eventHandler().refreshDisplay(true); // Do this twice for myOSystem->eventHandler().refreshDisplay(true); // double-buffered modes @@ -316,21 +344,23 @@ void FrameBuffer::enableMessages(bool enable) // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - inline void FrameBuffer::drawMessage() { -#if 0 // Draw the bounded box and text - fillRect(myMessage.x+1, myMessage.y+2, myMessage.w-2, myMessage.h-4, kBGColor); - box(myMessage.x, myMessage.y+1, myMessage.w, myMessage.h-2, kColor, kShadowColor); - drawString(&myOSystem->font(), myMessage.text, myMessage.x+1, myMessage.y+4, - myMessage.w, myMessage.color, kTextAlignCenter); - myMessage.counter--; + myMsg.surface->setPos(myMsg.x + myImageRect.x(), myMsg.y + myImageRect.y()); + myMsg.surface->fillRect(0, 0, myMsg.w-2, myMsg.h-4, kBGColor); + myMsg.surface->box(0, 0, myMsg.w, myMsg.h-2, kColor, kShadowColor); + myMsg.surface->drawString(&myOSystem->font(), myMsg.text, 4, 4, + myMsg.w, myMsg.color, kTextAlignLeft); + myMsg.counter--; // Either erase the entire message (when time is reached), // or show again this frame - if(myMessage.counter == 0) // Force an immediate update + if(myMsg.counter == 0) // Force an immediate update myOSystem->eventHandler().refreshDisplay(true); else - addDirtyRect(myMessage.x, myMessage.y, myMessage.w, myMessage.h); -#endif + { + myMsg.surface->addDirtyRect(0, 0, 0, 0); + myMsg.surface->update(); + } } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -420,18 +450,33 @@ void FrameBuffer::setFullscreen(bool enable) // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - bool FrameBuffer::changeVidMode(int direction) { - bool saveModeChange = true; + EventHandler::State state = myOSystem->eventHandler().state(); + bool inUIMode = (state == EventHandler::S_DEBUGGER || + state == EventHandler::S_LAUNCHER); + + // Only save mode changes in TIA mode with a valid selector + bool saveModeChange = !inUIMode && (direction == -1 || direction == +1); VideoMode oldmode = myCurrentModeList->current(); - if(direction == +1) - myCurrentModeList->next(); - else if(direction == -1) - myCurrentModeList->previous(); - else - saveModeChange = false; // no resolution or zoom level actually changed + if(!inUIMode) + { + if(direction == +1) + myCurrentModeList->next(); + else if(direction == -1) + myCurrentModeList->previous(); + } VideoMode newmode = myCurrentModeList->current(); - if(!setVidMode(newmode)) + if(setVidMode(newmode)) + { + myImageRect.setWidth(newmode.image_w); + myImageRect.setHeight(newmode.image_h); + myImageRect.moveTo(newmode.image_x, newmode.image_y); + + myScreenRect.setWidth(newmode.screen_w); + myScreenRect.setHeight(newmode.screen_h); + } + else return false; myOSystem->eventHandler().handleResizeEvent(); @@ -439,26 +484,10 @@ bool FrameBuffer::changeVidMode(int direction) setCursorState(); showMessage(newmode.name); - if(saveModeChange) + if(!inUIMode && saveModeChange) { - // Determine which mode we're in, and save to the appropriate setting - if(fullScreen()) - { - myOSystem->settings().setSize("fullres", newmode.screen_w, newmode.screen_h); - } - else - { - EventHandler::State state = myOSystem->eventHandler().state(); - bool inTIAMode = (state == EventHandler::S_EMULATE || - state == EventHandler::S_PAUSE || - state == EventHandler::S_MENU || - state == EventHandler::S_CMDMENU); - - if(inTIAMode) - myOSystem->settings().setInt("zoom_tia", newmode.zoom); -//FIXME else -// myOSystem->settings().setInt("zoom_ui", newmode.zoom); - } + // FIXME - adapt to scaler infrastructure + myOSystem->settings().setInt("zoom_tia", newmode.zoom); } return true; /* @@ -595,14 +624,15 @@ uInt8 FrameBuffer::getPhosphor(uInt8 c1, uInt8 c2) } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -uInt32 FrameBuffer::maxWindowSizeForScreen(uInt32 screenWidth, uInt32 screenHeight) +uInt32 FrameBuffer::maxWindowSizeForScreen(uInt32 baseWidth, uInt32 baseHeight, + uInt32 screenWidth, uInt32 screenHeight) { uInt32 multiplier = 1; for(;;) { // Figure out the zoomed size of the window - uInt32 width = myBaseDim.w * multiplier; - uInt32 height = myBaseDim.h * multiplier; + uInt32 width = baseWidth * multiplier; + uInt32 height = baseHeight * multiplier; if((width > screenWidth) || (height > screenHeight)) break; @@ -613,27 +643,49 @@ uInt32 FrameBuffer::maxWindowSizeForScreen(uInt32 screenWidth, uInt32 screenHeig } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void FrameBuffer::setAvailableVidModes() +void FrameBuffer::setAvailableVidModes(uInt32 baseWidth, uInt32 baseHeight) { + // Modelists are different depending on what state we're in + EventHandler::State state = myOSystem->eventHandler().state(); + bool inUIMode = (state == EventHandler::S_DEBUGGER || + state == EventHandler::S_LAUNCHER); + // First we look at windowed modes // These can be sized exactly as required, since there's normally no // restriction on window size (up the maximum size) myWindowedModeList.clear(); - int max_zoom = maxWindowSizeForScreen(myOSystem->desktopWidth(), - myOSystem->desktopHeight()); - for(int i = 1; i <= max_zoom; ++i) + + // In UI/windowed mode, there's only one valid video mode we can use + if(inUIMode) { VideoMode m; m.image_x = m.image_y = 0; - m.image_w = m.screen_w = myBaseDim.w * i; - m.image_h = m.screen_h = myBaseDim.h * i; - m.zoom = i; - ostringstream buf; - buf << "Zoom " << i << "x"; - m.name = buf.str(); + m.image_w = m.screen_w = baseWidth; + m.image_h = m.screen_h = baseHeight; + m.zoom = 1; myWindowedModeList.add(m); } + else + { + // FIXME - scan list of scalers, see which ones are appropriate + // for the given dimensions + int max_zoom = maxWindowSizeForScreen(baseWidth, baseHeight, + myOSystem->desktopWidth(), myOSystem->desktopHeight()); + for(int i = 1; i <= max_zoom; ++i) + { + VideoMode m; + m.image_x = m.image_y = 0; + m.image_w = m.screen_w = baseWidth * i; + m.image_h = m.screen_h = baseHeight * i; + m.zoom = i; + ostringstream buf; + buf << "Zoom " << i << "x"; + m.name = buf.str(); + + myWindowedModeList.add(m); + } + } // Now consider the fullscreen modes // There are often stricter requirements on these, and they're normally @@ -641,35 +693,63 @@ void FrameBuffer::setAvailableVidModes() // As well, we usually can't get fullscreen modes in the exact size // we want, so we need to calculate image offsets myFullscreenModeList.clear(); - const ResolutionList& res = myOSystem->supportedResolutions(); - for(unsigned int i = 0; i < res.size(); ++i) + if(inUIMode) { - VideoMode m; - m.screen_w = res[i].width; - m.screen_h = res[i].height; - m.zoom = maxWindowSizeForScreen(m.screen_w, m.screen_h); - m.name = res[i].name; + // FIXME - document this + if(0)// use exact dimensions) + { + VideoMode m; + m.image_w = m.screen_w = baseWidth; + m.image_h = m.screen_h = baseHeight; + m.zoom = 1; - // Auto-calculate 'smart' centering; platform-specific framebuffers are - // free to ignore or augment it - m.image_w = myBaseDim.w * m.zoom; - m.image_h = myBaseDim.h * m.zoom; - m.image_x = (m.screen_w - m.image_w) / 2; - m.image_y = (m.screen_h - m.image_h) / 2; + myFullscreenModeList.add(m); + } + else // use dimensions as defined in 'fullres' + { + int w = -1, h = -1; + myOSystem->settings().getSize("fullres", w, h); + if(w < 0 || h < 0) + { + w = myOSystem->desktopWidth(); + h = myOSystem->desktopHeight(); + } -/* -cerr << "Fullscreen modes:" << endl - << " Mode " << i << endl - << " screen w = " << m.screen_w << endl - << " screen h = " << m.screen_h << endl - << " image x = " << m.image_x << endl - << " image y = " << m.image_y << endl - << " image w = " << m.image_w << endl - << " image h = " << m.image_h << endl - << " zoom = " << m.zoom << endl - << endl; -*/ - myFullscreenModeList.add(m); + VideoMode m; + m.screen_w = w; + m.screen_h = h; + m.zoom = 1; + + // Auto-calculate 'smart' centering; platform-specific framebuffers are + // free to ignore or augment it + m.image_w = baseWidth; + m.image_h = baseHeight; + m.image_x = (m.screen_w - m.image_w) / 2; + m.image_y = (m.screen_h - m.image_h) / 2; + + myFullscreenModeList.add(m); + } + } + else + { + const ResolutionList& res = myOSystem->supportedResolutions(); + for(unsigned int i = 0; i < res.size(); ++i) + { + VideoMode m; + m.screen_w = res[i].width; + m.screen_h = res[i].height; + m.zoom = maxWindowSizeForScreen(baseWidth, baseHeight, m.screen_w, m.screen_h); + m.name = res[i].name; + + // Auto-calculate 'smart' centering; platform-specific framebuffers are + // free to ignore or augment it + m.image_w = baseWidth * m.zoom; + m.image_h = baseHeight * m.zoom; + m.image_x = (m.screen_w - m.image_w) / 2; + m.image_y = (m.screen_h - m.image_h) / 2; + + myFullscreenModeList.add(m); + } } } @@ -679,52 +759,21 @@ VideoMode FrameBuffer::getSavedVidMode() EventHandler::State state = myOSystem->eventHandler().state(); if(myOSystem->settings().getBool("fullscreen")) - { - // Point the modelist to fullscreen modes, and set the iterator to - // the mode closest to the given resolution - int w = -1, h = -1; - myOSystem->settings().getSize("fullres", w, h); - if(w < 0 || h < 0) - { - w = myOSystem->desktopWidth(); - h = myOSystem->desktopHeight(); - } - - // The launcher and debugger modes are different, in that their size is - // set at program launch and can't be changed - // In these cases, the resolution must accommodate their size - if(state == EventHandler::S_LAUNCHER) - { - int lw, lh; - myOSystem->settings().getSize("launcherres", lw, lh); - w = BSPF_max(w, lw); - h = BSPF_max(h, lh); - } -#ifdef DEBUGGER_SUPPORT - else if(state == EventHandler::S_DEBUGGER) - { - int lw, lh; - myOSystem->settings().getSize("debuggerres", lw, lh); - w = BSPF_max(w, lw); - h = BSPF_max(h, lh); - } -#endif - myCurrentModeList = &myFullscreenModeList; - myCurrentModeList->setByResolution(w, h); + else + myCurrentModeList = &myWindowedModeList; + + // Now select the best resolution depending on the state + // UI modes (launcher and debugger) have only one supported resolution + // so the 'current' one is the only valid one + if(state == EventHandler::S_DEBUGGER || state == EventHandler::S_LAUNCHER) + { + myCurrentModeList->setByZoom(1); } else { - // Point the modelist to windowed modes, and set the iterator to - // the mode closest to the given zoom level - bool inTIAMode = (state == EventHandler::S_EMULATE || - state == EventHandler::S_PAUSE || - state == EventHandler::S_MENU || - state == EventHandler::S_CMDMENU); - int zoom = (inTIAMode ? myOSystem->settings().getInt("zoom_tia") : 1); -//FIXME myOSystem->settings().getInt("zoom_ui") ); - - myCurrentModeList = &myWindowedModeList; + // FIXME - get dimensions from scaler + int zoom = myOSystem->settings().getInt("zoom_tia"); myCurrentModeList->setByZoom(zoom); } diff --git a/stella/src/emucore/FrameBuffer.hxx b/stella/src/emucore/FrameBuffer.hxx index 967c8e264..8f22b2cfb 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.97 2008-06-13 13:14:51 stephena Exp $ +// $Id: FrameBuffer.hxx,v 1.98 2008-06-19 12:01:30 stephena Exp $ //============================================================================ #ifndef FRAMEBUFFER_HXX @@ -27,11 +27,12 @@ class Console; namespace GUI { class Font; - class Surface; + class Rect; } #include "EventHandler.hxx" #include "VideoModeList.hxx" +#include "Rect.hxx" #include "bspf.hxx" // Different types of framebuffer derived objects @@ -89,7 +90,7 @@ enum { turn drawn here as well. @author Stephen Anthony - @version $Id: FrameBuffer.hxx,v 1.97 2008-06-13 13:14:51 stephena Exp $ + @version $Id: FrameBuffer.hxx,v 1.98 2008-06-19 12:01:30 stephena Exp $ */ class FrameBuffer { @@ -150,34 +151,18 @@ class FrameBuffer void enableMessages(bool enable); /** - Returns the current width of the framebuffer *before* any scaling. - - @return The current unscaled width + Returns the current dimensions of the framebuffer image. + Note that this will take into account the current scaling (if any) + as well as image 'centering'. */ - inline const uInt32 baseWidth() { return myBaseDim.w; } + inline const GUI::Rect& imageRect() const { return myImageRect; } /** - Returns the current height of the framebuffer *before* any scaling. - - @return The current unscaled height + Returns the current dimensions of the framebuffer window. + This is the entire area containing the framebuffer image as well as any + 'unusable' area. */ - inline const uInt32 baseHeight() { return myBaseDim.h; } - - /** - Returns the current width of the framebuffer image. - Note that this will take into account the current scaling (if any). - - @return The current width - */ - inline const uInt32 imageWidth() { return myImageDim.w; } - - /** - Returns the current height of the framebuffer image. - Note that this will take into account the current scaling (if any). - - @return The current height - */ - inline const uInt32 imageHeight() { return myImageDim.h; } + inline const GUI::Rect& screenRect() const { return myScreenRect; } /** Indicates that the TIA area is dirty, and certain areas need @@ -300,15 +285,22 @@ class FrameBuffer /** This method is called to initialize the video subsystem with the given video mode. Normally, it will also call setVidMode(). + + @param mode The video mode to use + + @return False on any errors, else true */ - virtual bool initSubsystem(VideoMode mode) = 0; + virtual bool initSubsystem(VideoMode& mode) = 0; /** - This method is called to change to the given video mode. + This method is called to change to the given video mode. If the mode + is successfully changed, 'mode' holds the actual dimensions used. - @param mode The video mode to use for rendering the mediasource + @param mode The video mode to use + + @return False on any errors (in which case 'mode' is invalid), else true */ - virtual bool setVidMode(VideoMode mode) = 0; + virtual bool setVidMode(VideoMode& mode) = 0; /** Switches between the filtering options in the video subsystem. @@ -345,18 +337,6 @@ class FrameBuffer // Amount to blend when using phosphor effect int myPhosphorBlend; - // Dimensions of the base image, before scaling. - // All external GUI items should refer to these dimensions, - // since this is the *real* size of the image. - // The other sizes are simply scaled versions of these dimensions. - SDL_Rect myBaseDim; - - // Dimensions of the actual image, after zooming - SDL_Rect myImageDim; - - // Dimensions of the SDL window (not always the same as the image) - SDL_Rect myScreenDim; - // TIA palettes for normal and phosphor modes Uint32 myDefPalette[256+kNumColors]; Uint32 myAvgPalette[256][256]; @@ -386,13 +366,14 @@ class FrameBuffer Calculate the maximum level by which the base window can be zoomed and still fit in the given screen dimensions. */ - uInt32 maxWindowSizeForScreen(uInt32 screenWidth, uInt32 screenHeight); + uInt32 maxWindowSizeForScreen(uInt32 baseWidth, uInt32 baseHeight, + uInt32 screenWidth, uInt32 screenHeight); /** Set all possible video modes (both windowed and fullscreen) available for - this framebuffer based on current emulation state and maximum window size. + this framebuffer based on given image dimensions and maximum window size. */ - void setAvailableVidModes(); + void setAvailableVidModes(uInt32 basewidth, uInt32 baseheight); /** Returns an appropriate video mode based on the current eventhandler @@ -409,18 +390,25 @@ class FrameBuffer // Used to set intervals between messages while in pause mode uInt32 myPausedCount; - // Used for onscreen messages + // Dimensions of the actual image, after zooming, and taking into account + // any image 'centering' + GUI::Rect myImageRect; + + // Dimensions of the SDL window (not always the same as the image) + GUI::Rect myScreenRect; + + // Used for onscreen messages and frame statistics + // (scanline count and framerate) struct Message { string text; int counter; int x, y, w, h; uInt32 color; + FBSurface* surface; + bool enabled; }; - Message myMessage; - - // Used to show frame statistics (scanline count and framerate) - Message myFrameStats; - bool myFrameStatsEnabled; + Message myMsg; + Message myStatsMsg; // The list of all available video modes for this framebuffer VideoModeList myWindowedModeList; @@ -438,7 +426,7 @@ class FrameBuffer FrameBuffer type. @author Stephen Anthony - @version $Id: FrameBuffer.hxx,v 1.97 2008-06-13 13:14:51 stephena Exp $ + @version $Id: FrameBuffer.hxx,v 1.98 2008-06-19 12:01:30 stephena Exp $ */ // Text alignment modes for drawString() enum TextAlignment { @@ -533,9 +521,9 @@ class FBSurface virtual void addDirtyRect(uInt32 x, uInt32 y, uInt32 w, uInt32 h) = 0; /** - This method should be called to center the position of the surface. + This method answers the current position of the surface. */ - virtual void centerPos() = 0; + virtual void getPos(uInt32& x, uInt32& y) const = 0; /** This method should be called to set the position of the surface. @@ -543,9 +531,14 @@ class FBSurface virtual void setPos(uInt32 x, uInt32 y) = 0; /** - This method answers the current coordinates of the surface. + This method sets the width of the drawable area of the surface. */ - virtual void getPos(uInt32& x, uInt32& y) const = 0; + virtual void setWidth(uInt32 w) = 0; + + /** + This method sets the width of the drawable area of the surface. + */ + virtual void setHeight(uInt32 h) = 0; /** This method should be called to translate the given coordinates diff --git a/stella/src/gui/ContextMenu.cxx b/stella/src/gui/ContextMenu.cxx index 71838d281..6928ebda8 100644 --- a/stella/src/gui/ContextMenu.cxx +++ b/stella/src/gui/ContextMenu.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: ContextMenu.cxx,v 1.2 2008-06-15 15:44:30 stephena Exp $ +// $Id: ContextMenu.cxx,v 1.3 2008-06-19 12:01:31 stephena Exp $ // // Based on code from ScummVM - Scumm Interpreter // Copyright (C) 2002-2004 The ScummVM project @@ -79,6 +79,14 @@ void ContextMenu::show(uInt32 x, uInt32 y, int item) // Make sure position is set *after* the dialog is added, since the surface // may not exist before then parent().addDialog(this); + + // Are we in the current screen bounds? + const GUI::Rect& image = instance().frameBuffer().imageRect(); + uInt32 dx = image.x() + image.width(); + uInt32 dy = image.y() + image.height(); + if(x + _w > dx) x -= (x + _w - dx); + if(y + _h > dy) y -= (y + _h - dy); + surface().setPos(x, y); setSelected(item); } @@ -280,14 +288,6 @@ void ContextMenu::moveDown() drawCurrentSelection(++item); } -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void ContextMenu::center() -{ - // Adjust dialog, making sure it doesn't fall outside screen area - - // FIXME - add code to do this ... -} - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - void ContextMenu::drawDialog() { @@ -320,7 +320,7 @@ void ContextMenu::drawDialog() if(_entries.size() & 1) n++; if(i >= n) { - x = _x + 2 + _w / 2; + x = _x + 1 + _w / 2; y = _y + 2 + _rowHeight * (i - n); } else @@ -328,7 +328,7 @@ void ContextMenu::drawDialog() x = _x + 2; y = _y + 2 + _rowHeight * i; } - w = _w / 2 - 2; + w = _w / 2 - 3; } else { diff --git a/stella/src/gui/ContextMenu.hxx b/stella/src/gui/ContextMenu.hxx index c10fae7a7..3eb04f3a7 100644 --- a/stella/src/gui/ContextMenu.hxx +++ b/stella/src/gui/ContextMenu.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: ContextMenu.hxx,v 1.2 2008-06-15 15:44:30 stephena Exp $ +// $Id: ContextMenu.hxx,v 1.3 2008-06-19 12:01:31 stephena Exp $ // // Based on code from ScummVM - Scumm Interpreter // Copyright (C) 2002-2004 The ScummVM project @@ -66,7 +66,7 @@ class ContextMenu : public Dialog, public CommandSender const string& getSelectedString() const; /** This dialog uses its own positioning, so we override Dialog::center() */ - void center(); + void center() { } protected: void handleMouseDown(int x, int y, int button, int clickCount); diff --git a/stella/src/gui/Dialog.cxx b/stella/src/gui/Dialog.cxx index 9af15b2a7..3a252000d 100644 --- a/stella/src/gui/Dialog.cxx +++ b/stella/src/gui/Dialog.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: Dialog.cxx,v 1.61 2008-06-13 13:14:51 stephena Exp $ +// $Id: Dialog.cxx,v 1.62 2008-06-19 12:01:31 stephena Exp $ // // Based on code from ScummVM - Scumm Interpreter // Copyright (C) 2002-2004 The ScummVM project @@ -106,8 +106,13 @@ void Dialog::close() // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - void Dialog::center() { - if(_center && _surface) - _surface->centerPos(); + if(_surface) + { + const GUI::Rect& screen = instance().frameBuffer().screenRect(); + uInt32 x = (screen.width() - getWidth()) >> 1; + uInt32 y = (screen.height() - getHeight()) >> 1; + _surface->setPos(x, y); + } } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/stella/src/gui/Launcher.cxx b/stella/src/gui/Launcher.cxx index 99cfb2c48..d92314c79 100644 --- a/stella/src/gui/Launcher.cxx +++ b/stella/src/gui/Launcher.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: Launcher.cxx,v 1.23 2008-05-30 19:07:55 stephena Exp $ +// $Id: Launcher.cxx,v 1.24 2008-06-19 12:01:31 stephena Exp $ //============================================================================ #include @@ -31,8 +31,8 @@ class Properties; // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Launcher::Launcher(OSystem* osystem) : DialogContainer(osystem), - myWidth(400), - myHeight(300) + myWidth(640), + myHeight(480) { int w, h; myOSystem->settings().getSize("launcherres", w, h); @@ -40,9 +40,9 @@ Launcher::Launcher(OSystem* osystem) myHeight = BSPF_max(h, 0); // Error check the resolution - myWidth = BSPF_max(myWidth, 320u); + myWidth = BSPF_max(myWidth, 640u); myWidth = BSPF_min(myWidth, osystem->desktopWidth()); - myHeight = BSPF_max(myHeight, 240u); + myHeight = BSPF_max(myHeight, 480u); myHeight = BSPF_min(myHeight, osystem->desktopHeight()); myOSystem->settings().setSize("launcherres", myWidth, myHeight); diff --git a/stella/src/gui/PopUpWidget.cxx b/stella/src/gui/PopUpWidget.cxx index 72ec2cf89..8ae0c4784 100644 --- a/stella/src/gui/PopUpWidget.cxx +++ b/stella/src/gui/PopUpWidget.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: PopUpWidget.cxx,v 1.40 2008-06-13 13:14:51 stephena Exp $ +// $Id: PopUpWidget.cxx,v 1.41 2008-06-19 12:01:31 stephena Exp $ // // Based on code from ScummVM - Scumm Interpreter // Copyright (C) 2002-2004 The ScummVM project @@ -81,12 +81,11 @@ void PopUpWidget::handleMouseDown(int x, int y, int button, int clickCount) if(isEnabled()) { // Add menu just underneath parent widget - uInt32 x, y; - dialog().surface().getPos(x, y); - x += getAbsX() + _labelWidth; - y += getAbsY() + getHeight(); - - myMenu->show(x, y, myMenu->getSelected()); + uInt32 tx, ty; + dialog().surface().getPos(tx, ty); + tx += getAbsX() + _labelWidth; + ty += getAbsY() + getHeight(); + myMenu->show(tx, ty, myMenu->getSelected()); } } diff --git a/stella/src/gui/Rect.hxx b/stella/src/gui/Rect.hxx index a00246214..312a20b57 100644 --- a/stella/src/gui/Rect.hxx +++ b/stella/src/gui/Rect.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: Rect.hxx,v 1.6 2008-02-06 13:45:24 stephena Exp $ +// $Id: Rect.hxx,v 1.7 2008-06-19 12:01:31 stephena Exp $ // // Based on code from ScummVM - Scumm Interpreter // Copyright (C) 2002-2004 The ScummVM project @@ -72,8 +72,10 @@ struct Rect { assert(isValidRect()); } - int width() const { return right - left; } - int height() const { return bottom - top; } + inline int x() const { return left; } + inline int y() const { return top; } + inline int width() const { return right - left; } + inline int height() const { return bottom - top; } void setWidth(int aWidth) { right = left + aWidth; diff --git a/stella/src/gui/RomInfoWidget.cxx b/stella/src/gui/RomInfoWidget.cxx index e24321d1d..cf9c7b171 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.8 2008-06-13 13:14:51 stephena Exp $ +// $Id: RomInfoWidget.cxx,v 1.9 2008-06-19 12:01:31 stephena Exp $ //============================================================================ #include @@ -31,7 +31,7 @@ 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) { @@ -42,11 +42,13 @@ RomInfoWidget::RomInfoWidget(GuiObject* boss, const GUI::Font& font, // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - RomInfoWidget::~RomInfoWidget() { +/* if(mySurface) { delete mySurface; mySurface = NULL; } +*/ myRomInfo.clear(); } @@ -93,8 +95,8 @@ void RomInfoWidget::clearProperties() void RomInfoWidget::initialize() { // Delete surface; a new one will be created by parseProperties - delete mySurface; - mySurface = NULL; +// delete mySurface; +// mySurface = NULL; } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -280,12 +282,12 @@ bool RomInfoWidget::parseIHDR(int& width, int& height, uInt8* data, int size) return memcmp(trailer, data + 8, 5) == 0; } +// FIXME +#if 0 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - bool RomInfoWidget::parseIDATChunk(const FrameBuffer& fb, GUI::Surface* surface, int width, int height, uInt8* data, int size) { -// FIXME -#if 0 // The entire decompressed image data uLongf bufsize = (width * 3 + 1) * height; uInt8* buffer = new uInt8[bufsize]; @@ -304,8 +306,8 @@ bool RomInfoWidget::parseIDATChunk(const FrameBuffer& fb, GUI::Surface* surface, } delete[] buffer; return false; -#endif } +#endif // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - string RomInfoWidget::parseTextChunk(uInt8* data, int size) diff --git a/stella/src/gui/RomInfoWidget.hxx b/stella/src/gui/RomInfoWidget.hxx index 3b45f22da..968c18735 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.4 2008-03-13 22:58:07 stephena Exp $ +// $Id: RomInfoWidget.hxx,v 1.5 2008-06-19 12:01:31 stephena Exp $ //============================================================================ #ifndef ROM_INFO_WIDGET_HXX @@ -21,8 +21,6 @@ #include -class GUI::Surface; - #include "Props.hxx" #include "Widget.hxx" #include "Command.hxx" @@ -50,13 +48,13 @@ class RomInfoWidget : public Widget 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); - static bool parseIDATChunk(const FrameBuffer& fb, GUI::Surface* surface, - int width, int height, uInt8* data, int size); +// static bool parseIDATChunk(const FrameBuffer& fb, GUI::Surface* surface, +// int width, int height, uInt8* data, int size); static string parseTextChunk(uInt8* data, int size); private: // Surface holding the scaled PNG image - GUI::Surface* mySurface; +// GUI::Surface* mySurface; // Whether the surface should be redrawn by drawWidget() bool myDrawSurface;