From a6bea6438f2b5dee78073923e2dab732cf4f0666 Mon Sep 17 00:00:00 2001 From: thrust26 Date: Wed, 17 Jan 2018 19:29:36 +0100 Subject: [PATCH 01/18] fix #279 --- src/emucore/tia/TIA.cxx | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/emucore/tia/TIA.cxx b/src/emucore/tia/TIA.cxx index a2805d9d2..e5f828c93 100644 --- a/src/emucore/tia/TIA.cxx +++ b/src/emucore/tia/TIA.cxx @@ -812,10 +812,9 @@ void TIA::update() // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - bool TIA::enableColorLoss(bool enabled) { - if (consoleTiming() != ConsoleTiming::pal) - return false; + bool allowColorLoss = consoleTiming() == ConsoleTiming::pal; - if(enabled) + if(allowColorLoss && enabled) { myColorLossEnabled = true; myColorLossActive = myFrameManager->scanlinesLastFrame() & 0x1; @@ -833,7 +832,7 @@ bool TIA::enableColorLoss(bool enabled) myBackground.applyColorLoss(); } - return true; + return allowColorLoss; } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - From 95f7c96ec14b909ece86e92626018152c58af719 Mon Sep 17 00:00:00 2001 From: thrust26 Date: Thu, 18 Jan 2018 09:16:51 +0100 Subject: [PATCH 02/18] added trackballs to Stelladaptor support doc --- docs/index.html | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/docs/index.html b/docs/index.html index dbc1313c9..86280080a 100644 --- a/docs/index.html +++ b/docs/index.html @@ -268,7 +268,7 @@ joysticks or mouse
  • Emulates the Sega Genesis Controller using your computer's keyboard, joysticks or mouse
  • -
  • Emulates CX22/CX80 style trakballs and Amiga/Atari Mouse using your +
  • Emulates CX22/CX80 style trackballs and Amiga/Atari Mouse using your computer's mouse
  • Emulates Spectravideo CompuMate system using your computer's keyboard, including mapping of CompuMate 'Backspace', 'Space' and 'Enter' functionality to @@ -1745,12 +1745,12 @@ ✓ - Trakball/Mouse + Trackball/Mouse ✕ ✕ ✓ ✓ (axis ignored) - ✕ + ✓ CompuMate @@ -2103,7 +2103,7 @@
    -usemouse <always|analog|never>
    Use mouse as a controller as specified by ROM properties in specific case. Always and never are self-explanatory, analog means only for analog-type devices - (paddles, trakball, etc.). + (paddles, trackball, etc.). @@ -2995,8 +2995,9 @@

    Stelladaptor/2600-daptor Support

    -

    Stella supports real Atari 2600 joysticks, paddles and driving controllers - using the Stelladaptor and +

    Stella supports real Atari 2600 joysticks, paddles, driving controllers + and trackballs (CX22/CX80 'Trak-Ball', Atari and Amiga mouse) using the + Stelladaptor and 2600-daptor devices.

    Stella can use up to two adaptors; any extra ones are ignored. From 7d3a331f9db3a93e8fa0bbe9802cdf7821d5cddc Mon Sep 17 00:00:00 2001 From: thrust26 Date: Fri, 19 Jan 2018 10:24:16 +0100 Subject: [PATCH 03/18] fixed hotkey description for exiting the Options mode (also see #282) --- docs/index.html | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/index.html b/docs/index.html index 86280080a..49c319547 100644 --- a/docs/index.html +++ b/docs/index.html @@ -645,8 +645,8 @@ Enter/exit options mode - Tab - Tab + Tab/Escape + Tab/Escape From af19f9f2b89670eff7a185fbf0ced2c0deb66692 Mon Sep 17 00:00:00 2001 From: thrust26 Date: Fri, 19 Jan 2018 10:35:52 +0100 Subject: [PATCH 04/18] enter debugger from time machine mode option added --- src/emucore/EventHandler.cxx | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/emucore/EventHandler.cxx b/src/emucore/EventHandler.cxx index ff3f24bf7..b65507a4a 100644 --- a/src/emucore/EventHandler.cxx +++ b/src/emucore/EventHandler.cxx @@ -1248,7 +1248,9 @@ bool EventHandler::eventStateChange(Event::Type type) break; case Event::DebuggerMode: - if(myState == EventHandlerState::EMULATION || myState == EventHandlerState::PAUSE) + if(myState == EventHandlerState::EMULATION + || myState == EventHandlerState::PAUSE + || myState == EventHandlerState::TIMEMACHINE) enterDebugMode(); else if(myState == EventHandlerState::DEBUGGER) leaveDebugMode(); From 9e403826d29b89b05746ac7c76a0ddaace0383e1 Mon Sep 17 00:00:00 2001 From: Stephen Anthony Date: Tue, 9 Jan 2018 23:16:50 -0330 Subject: [PATCH 05/18] Fixed compilation when '--disable-debugger' is used. --- src/emucore/EventHandler.cxx | 4 ++-- src/emucore/FrameBuffer.cxx | 4 ++-- src/emucore/M6502.cxx | 19 ++++++++++++------- src/emucore/M6502.hxx | 10 +++++----- src/emucore/OSystem.cxx | 4 ++-- src/emucore/tia/TIA.cxx | 4 ---- src/emucore/tia/TIA.hxx | 5 +++-- src/gui/DeveloperDialog.cxx | 8 +++++--- src/gui/DeveloperDialog.hxx | 2 -- 9 files changed, 31 insertions(+), 29 deletions(-) diff --git a/src/emucore/EventHandler.cxx b/src/emucore/EventHandler.cxx index b65507a4a..2db12c0bd 100644 --- a/src/emucore/EventHandler.cxx +++ b/src/emucore/EventHandler.cxx @@ -2189,12 +2189,12 @@ void EventHandler::setEventState(EventHandlerState state) myEvent.clear(); break; -#ifdef DEBUGGER_SUPPORT case EventHandlerState::DEBUGGER: + #ifdef DEBUGGER_SUPPORT myOverlay = &myOSystem.debugger(); enableTextEvents(true); + #endif break; -#endif case EventHandlerState::NONE: myOverlay = nullptr; diff --git a/src/emucore/FrameBuffer.cxx b/src/emucore/FrameBuffer.cxx index 231656b9c..ca7b17d04 100644 --- a/src/emucore/FrameBuffer.cxx +++ b/src/emucore/FrameBuffer.cxx @@ -339,13 +339,13 @@ void FrameBuffer::update() break; // EventHandlerState::LAUNCHER } -#ifdef DEBUGGER_SUPPORT case EventHandlerState::DEBUGGER: { + #ifdef DEBUGGER_SUPPORT myOSystem.debugger().draw(true); + #endif break; // EventHandlerState::DEBUGGER } -#endif case EventHandlerState::NONE: return; diff --git a/src/emucore/M6502.cxx b/src/emucore/M6502.cxx index 367c80845..be39a27e6 100644 --- a/src/emucore/M6502.cxx +++ b/src/emucore/M6502.cxx @@ -69,12 +69,12 @@ M6502::M6502(const Settings& settings) myDataAddressForPoke(0), myOnHaltCallback(nullptr), myHaltRequested(false), + myGhostReadsTrap(true), myStepStateByInstruction(false) { #ifdef DEBUGGER_SUPPORT myDebugger = nullptr; myJustHitReadTrapFlag = myJustHitWriteTrapFlag = false; - myGhostReadsTrap = true; #endif } @@ -210,7 +210,10 @@ inline void M6502::handleHalt() // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - void M6502::updateStepStateByInstruction() { + // Currently only used in debugger mode +#ifdef DEBUGGER_SUPPORT myStepStateByInstruction = myCondBreaks.size() || myCondSaveStates.size() || myTrapConds.size(); +#endif } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -218,6 +221,7 @@ bool M6502::execute(uInt32 number) { const bool status = _execute(number); +#ifdef DEBUGGER_SUPPORT // Debugger hack: this ensures that stepping a "STA WSYNC" will actually end at the // beginning of the next line (otherwise, the next instruction would be stepped in order for // the halt to take effect). This is safe because as we know that the next cycle will be a read @@ -228,6 +232,7 @@ bool M6502::execute(uInt32 number) // to maintain a consistent state for the debugger after stepping. mySystem->tia().updateEmulation(); mySystem->m6532().updateEmulation(); +#endif return status; } @@ -248,7 +253,7 @@ inline bool M6502::_execute(uInt32 number) { for(; !myExecutionStatus && (number != 0); --number) { -#ifdef DEBUGGER_SUPPORT + #ifdef DEBUGGER_SUPPORT if(myJustHitReadTrapFlag || myJustHitWriteTrapFlag) { bool read = myJustHitReadTrapFlag; @@ -279,7 +284,7 @@ inline bool M6502::_execute(uInt32 number) msg << "conditional savestate [" << Common::Base::HEX2 << cond << "]"; myDebugger->addState(msg.str()); } -#endif // DEBUGGER_SUPPORT + #endif // DEBUGGER_SUPPORT uInt16 operandAddress = 0, intermediateAddress = 0; uInt8 operand = 0; @@ -301,17 +306,17 @@ inline bool M6502::_execute(uInt32 number) // Oops, illegal instruction executed so set fatal error flag myExecutionStatus |= FatalErrorBit; } - //cycles = mySystem->cycles() - c0; -#ifdef DEBUGGER_SUPPORT - if (myStepStateByInstruction) { + #ifdef DEBUGGER_SUPPORT + if(myStepStateByInstruction) + { // Check out M6502::execute for an explanation. handleHalt(); tia.updateEmulation(); riot.updateEmulation(); } -#endif + #endif } // See if we need to handle an interrupt diff --git a/src/emucore/M6502.hxx b/src/emucore/M6502.hxx index c0b114664..3c88674ac 100644 --- a/src/emucore/M6502.hxx +++ b/src/emucore/M6502.hxx @@ -445,8 +445,6 @@ class M6502 : public Serializable int address; }; HitTrapInfo myHitTrapInfo; - // trap on ghost reads - bool myGhostReadsTrap; vector> myCondBreaks; StringList myCondBreakNames; @@ -454,11 +452,13 @@ class M6502 : public Serializable StringList myCondSaveStateNames; vector> myTrapConds; StringList myTrapCondNames; - - bool myStepStateByInstruction; - #endif // DEBUGGER_SUPPORT + // These are both used only by the debugger, but since they're included + // in save states, they cannot be conditionally compiled + bool myGhostReadsTrap; // trap on ghost reads + bool myStepStateByInstruction; + private: // Following constructors and assignment operators not supported M6502() = delete; diff --git a/src/emucore/OSystem.cxx b/src/emucore/OSystem.cxx index 4c5110a1b..95175dc67 100644 --- a/src/emucore/OSystem.cxx +++ b/src/emucore/OSystem.cxx @@ -264,12 +264,12 @@ FBInitStatus OSystem::createFrameBuffer() return fbstatus; break; -#ifdef DEBUGGER_SUPPORT case EventHandlerState::DEBUGGER: + #ifdef DEBUGGER_SUPPORT if((fbstatus = myDebugger->initializeVideo()) != FBInitStatus::Success) return fbstatus; + #endif break; -#endif case EventHandlerState::NONE: // Should never happen logMessage("ERROR: Unknown emulation state in createFrameBuffer()", 0); diff --git a/src/emucore/tia/TIA.cxx b/src/emucore/tia/TIA.cxx index e5f828c93..21ea48767 100644 --- a/src/emucore/tia/TIA.cxx +++ b/src/emucore/tia/TIA.cxx @@ -1708,14 +1708,10 @@ void TIA::toggleCollBLPF() // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - void TIA::createAccessBase() { -#ifdef DEBUGGER_SUPPORT myAccessBase = make_unique(TIA_SIZE); memset(myAccessBase.get(), CartDebug::NONE, TIA_SIZE); myAccessDelay = make_unique(TIA_SIZE); memset(myAccessDelay.get(), TIA_DELAY, TIA_SIZE); -#else - myAccessBase = nullptr; -#endif } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/emucore/tia/TIA.hxx b/src/emucore/tia/TIA.hxx index 0fb54caee..84e2b8a06 100644 --- a/src/emucore/tia/TIA.hxx +++ b/src/emucore/tia/TIA.hxx @@ -776,13 +776,14 @@ class TIA : public Device bool myEnableJitter; uInt8 myJitterFactor; -#ifdef DEBUGGER_SUPPORT + #ifdef DEBUGGER_SUPPORT // The arrays containing information about every byte of TIA // indicating whether and how (RW) it is used. BytePtr myAccessBase; + // The array used to skip the first two TIA access trackings BytePtr myAccessDelay; -#endif // DEBUGGER_SUPPORT + #endif // DEBUGGER_SUPPORT static constexpr uInt16 TIA_SIZE = 0x40, TIA_MASK = TIA_SIZE - 1, TIA_READ_MASK = 0x0f, TIA_BIT = 0x080, TIA_DELAY = 2; diff --git a/src/gui/DeveloperDialog.cxx b/src/gui/DeveloperDialog.cxx index b68010369..b19a7ebcb 100644 --- a/src/gui/DeveloperDialog.cxx +++ b/src/gui/DeveloperDialog.cxx @@ -44,7 +44,7 @@ // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - DeveloperDialog::DeveloperDialog(OSystem& osystem, DialogContainer& parent, - const GUI::Font& font, int max_w, int max_h) + const GUI::Font& font, int max_w, int max_h) : Dialog(osystem, parent) { const int VGAP = 4; @@ -375,13 +375,13 @@ void DeveloperDialog::addTimeMachineTab(const GUI::Font& font) void DeveloperDialog::addDebuggerTab(const GUI::Font& font) { int tabID = myTab->addTab("Debugger"); + WidgetArray wid; #ifdef DEBUGGER_SUPPORT const int HBORDER = 10; const int VBORDER = 8; const int VGAP = 4; - WidgetArray wid; VariantList items; int fontWidth = font.getMaxCharWidth(), fontHeight = font.getFontHeight(), @@ -473,7 +473,7 @@ void DeveloperDialog::addDebuggerTab(const GUI::Font& font) // Add items for tab 1 addToFocusList(wid, myTab, tabID); #else - new StaticTextWidget(myTab, font, 0, 20, _w - 20, fontHeight, + new StaticTextWidget(myTab, font, 0, 20, _w - 20, font.getFontHeight(), "Debugger support not included", TextAlign::Center); #endif @@ -1199,6 +1199,7 @@ void DeveloperDialog::handleDebugColours(const string& colors) // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - void DeveloperDialog::handleFontSize() { +#ifdef DEBUGGER_SUPPORT uInt32 minW, minH; int fontSize = myDebuggerFontSize->getSelected(); @@ -1233,4 +1234,5 @@ void DeveloperDialog::handleFontSize() myDebuggerHeightSlider->setValue(minH); myDebuggerHeightLabel->setValue(minH); } +#endif } diff --git a/src/gui/DeveloperDialog.hxx b/src/gui/DeveloperDialog.hxx index 113b34b2b..27577b89f 100644 --- a/src/gui/DeveloperDialog.hxx +++ b/src/gui/DeveloperDialog.hxx @@ -183,9 +183,7 @@ class DeveloperDialog : public Dialog void handleUncompressed(); void handleInterval(); void handleHorizon(); -#ifdef DEBUGGER_SUPPORT void handleFontSize(); -#endif // Following constructors and assignment operators not supported DeveloperDialog() = delete; From a1b54680bd69aeac706fabcac97b6a714bffa14f Mon Sep 17 00:00:00 2001 From: thrust26 Date: Mon, 15 Jan 2018 14:44:09 +0100 Subject: [PATCH 06/18] frame stats overlay made transparent --- src/emucore/FrameBuffer.cxx | 30 ++++++++++++++++++++++++------ 1 file changed, 24 insertions(+), 6 deletions(-) diff --git a/src/emucore/FrameBuffer.cxx b/src/emucore/FrameBuffer.cxx index ca7b17d04..4ffa1b2f4 100644 --- a/src/emucore/FrameBuffer.cxx +++ b/src/emucore/FrameBuffer.cxx @@ -180,7 +180,7 @@ FBInitStatus FrameBuffer::createDisplay(const string& title, // can be relaxed // Otherwise, we treat the system as if WINDOWED_SUPPORT is not defined if(myDesktopSize.w < kFBMinW && myDesktopSize.h < kFBMinH && - (myDesktopSize.w < width || myDesktopSize.h < height)) + (myDesktopSize.w < width || myDesktopSize.h < height)) return FBInitStatus::FailTooLarge; useFullscreen = myOSystem.settings().getBool("fullscreen"); @@ -233,7 +233,12 @@ FBInitStatus FrameBuffer::createDisplay(const string& title, myStatsMsg.h = (infoFont().getFontHeight() + 2) * 2; if(!myStatsMsg.surface) + { myStatsMsg.surface = allocateSurface(myStatsMsg.w, myStatsMsg.h); + myStatsMsg.surface->attributes().blending = true; + //myStatsMsg.surface->attributes().blendalpha = 80; + myStatsMsg.surface->applyAttributes(); + } if(!myMsg.surface) myMsg.surface = allocateSurface(kFBMinW, font().getFontHeight()+10); @@ -286,11 +291,24 @@ void FrameBuffer::update() std::snprintf(msg, 30, "%3u @ %3.2ffps => %s", myOSystem.console().tia().scanlinesLastFrame(), myOSystem.console().getFramerate(), info.DisplayFormat.c_str()); - myStatsMsg.surface->fillRect(0, 0, myStatsMsg.w, myStatsMsg.h, kBGColor); - myStatsMsg.surface->drawString(infoFont(), - msg, 1, 1, myStatsMsg.w, myStatsMsg.color, TextAlign::Left); - myStatsMsg.surface->drawString(infoFont(), - info.BankSwitch, 1, 15, myStatsMsg.w, myStatsMsg.color, TextAlign::Left); + myStatsMsg.surface->invalidate(); + // draw shadowed text + myStatsMsg.surface->drawString(infoFont(), msg, 1 + 1, 1 + 0, + myStatsMsg.w, kBGColor); + myStatsMsg.surface->drawString(infoFont(), msg, 1 + 0, 1 + 1, + myStatsMsg.w, kBGColor); + myStatsMsg.surface->drawString(infoFont(), msg, 1 + 1, 1 + 1, + myStatsMsg.w, kBGColor); + myStatsMsg.surface->drawString(infoFont(), msg, 1, 1, + myStatsMsg.w, myStatsMsg.color); + myStatsMsg.surface->drawString(infoFont(), info.BankSwitch, 1 + 1, 15 + 0, + myStatsMsg.w, kBGColor); + myStatsMsg.surface->drawString(infoFont(), info.BankSwitch, 1 + 0, 15 + 1, + myStatsMsg.w, kBGColor); + myStatsMsg.surface->drawString(infoFont(), info.BankSwitch, 1 + 1, 15 + 1, + myStatsMsg.w, kBGColor); + myStatsMsg.surface->drawString(infoFont(), info.BankSwitch, 1, 15, + myStatsMsg.w, myStatsMsg.color); myStatsMsg.surface->setDirty(); myStatsMsg.surface->setDstPos(myImageRect.x() + 1, myImageRect.y() + 1); myStatsMsg.surface->render(); From 72ff2a40fa418fbc15b639d619a855e5b9ac249c Mon Sep 17 00:00:00 2001 From: thrust26 Date: Mon, 15 Jan 2018 20:25:28 +0100 Subject: [PATCH 07/18] developer/player settings added to frame stats overlay --- src/common/FrameBufferSDL2.cxx | 8 ++++++++ src/common/FrameBufferSDL2.hxx | 8 +++++--- src/emucore/Console.cxx | 3 ++- src/emucore/FrameBuffer.cxx | 10 ++++++---- src/emucore/FrameBuffer.hxx | 14 +++++++++++--- 5 files changed, 32 insertions(+), 11 deletions(-) diff --git a/src/common/FrameBufferSDL2.cxx b/src/common/FrameBufferSDL2.cxx index 76d6ece46..d9338eeb9 100644 --- a/src/common/FrameBufferSDL2.cxx +++ b/src/common/FrameBufferSDL2.cxx @@ -235,6 +235,14 @@ bool FrameBufferSDL2::setVideoMode(const string& title, const VideoMode& mode) return true; } +void FrameBufferSDL2::setTitle(const string& title) +{ + myScreenTitle = title; + + if(myWindow) + SDL_SetWindowTitle(myWindow, title.c_str()); +} + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - string FrameBufferSDL2::about() const { diff --git a/src/common/FrameBufferSDL2.hxx b/src/common/FrameBufferSDL2.hxx index cf134e96e..3944849ce 100644 --- a/src/common/FrameBufferSDL2.hxx +++ b/src/common/FrameBufferSDL2.hxx @@ -46,11 +46,13 @@ class FrameBufferSDL2 : public FrameBuffer ////////////////////////////////////////////////////////////////////// // The following are derived from public methods in FrameBuffer.hxx ////////////////////////////////////////////////////////////////////// + /** - Toggles the use of grabmouse (only has effect in emulation mode). - The method changes the 'grabmouse' setting and saves it. + Updates window title + + @param title The title of the application / window */ - void toggleGrabMouse(); + void setTitle(const string& title); /** Shows or hides the cursor based on the given boolean value. diff --git a/src/emucore/Console.cxx b/src/emucore/Console.cxx index 16f122693..d9e6ab65b 100644 --- a/src/emucore/Console.cxx +++ b/src/emucore/Console.cxx @@ -531,6 +531,7 @@ FBInitStatus Console::initializeVideo(bool full) if(full) { + bool devSettings = myOSystem.settings().getBool("dev.settings"); const string& title = string("Stella ") + STELLA_VERSION + ": \"" + myProperties.get(Cartridge_Name) + "\""; fbstatus = myOSystem.frameBuffer().createDisplay(title, @@ -539,7 +540,7 @@ FBInitStatus Console::initializeVideo(bool full) return fbstatus; myOSystem.frameBuffer().showFrameStats( - myOSystem.settings().getBool(myOSystem.settings().getBool("dev.settings") ? "dev.stats" : "plr.stats")); + myOSystem.settings().getBool(devSettings ? "dev.stats" : "plr.stats")); generateColorLossPalette(); } setPalette(myOSystem.settings().getString("palette")); diff --git a/src/emucore/FrameBuffer.cxx b/src/emucore/FrameBuffer.cxx index 4ffa1b2f4..456175997 100644 --- a/src/emucore/FrameBuffer.cxx +++ b/src/emucore/FrameBuffer.cxx @@ -292,6 +292,8 @@ void FrameBuffer::update() myOSystem.console().tia().scanlinesLastFrame(), myOSystem.console().getFramerate(), info.DisplayFormat.c_str()); myStatsMsg.surface->invalidate(); + string bsinfo = info.BankSwitch + + (myOSystem.settings().getBool("dev.settings") ? "| Developer" : "| Player"); // draw shadowed text myStatsMsg.surface->drawString(infoFont(), msg, 1 + 1, 1 + 0, myStatsMsg.w, kBGColor); @@ -301,13 +303,13 @@ void FrameBuffer::update() myStatsMsg.w, kBGColor); myStatsMsg.surface->drawString(infoFont(), msg, 1, 1, myStatsMsg.w, myStatsMsg.color); - myStatsMsg.surface->drawString(infoFont(), info.BankSwitch, 1 + 1, 15 + 0, + myStatsMsg.surface->drawString(infoFont(), bsinfo, 1 + 1, 15 + 0, myStatsMsg.w, kBGColor); - myStatsMsg.surface->drawString(infoFont(), info.BankSwitch, 1 + 0, 15 + 1, + myStatsMsg.surface->drawString(infoFont(), bsinfo, 1 + 0, 15 + 1, myStatsMsg.w, kBGColor); - myStatsMsg.surface->drawString(infoFont(), info.BankSwitch, 1 + 1, 15 + 1, + myStatsMsg.surface->drawString(infoFont(), bsinfo, 1 + 1, 15 + 1, myStatsMsg.w, kBGColor); - myStatsMsg.surface->drawString(infoFont(), info.BankSwitch, 1, 15, + myStatsMsg.surface->drawString(infoFont(), bsinfo, 1, 15, myStatsMsg.w, myStatsMsg.color); myStatsMsg.surface->setDirty(); myStatsMsg.surface->setDstPos(myImageRect.x() + 1, myImageRect.y() + 1); diff --git a/src/emucore/FrameBuffer.hxx b/src/emucore/FrameBuffer.hxx index da1f984e4..975ecbf4e 100644 --- a/src/emucore/FrameBuffer.hxx +++ b/src/emucore/FrameBuffer.hxx @@ -268,6 +268,13 @@ class FrameBuffer // implemented in derived classes. ////////////////////////////////////////////////////////////////////// public: + /** + Updates window title + + @param title The title of the application / window + */ + virtual void setTitle(const string& title) = 0; + /** Shows or hides the cursor based on the given boolean value. */ @@ -446,6 +453,10 @@ class FrameBuffer int myIdx; }; + protected: + // Title of the main window/screen + string myScreenTitle; + private: // Indicates the number of times the framebuffer was initialized uInt32 myInitializedCount; @@ -460,9 +471,6 @@ class FrameBuffer // Dimensions of the main window (not always the same as the image) GUI::Size myScreenSize; - // Title of the main window/screen - string myScreenTitle; - // Maximum dimensions of the desktop area GUI::Size myDesktopSize; From 6f7ff023a65b04b2aa42ff0cd0dfe603ba5c80ec Mon Sep 17 00:00:00 2001 From: thrust26 Date: Tue, 16 Jan 2018 11:14:26 +0100 Subject: [PATCH 08/18] generic shadowed char/string drawing added TimeMachineDialog fully transparent now (experimental) info stats indicates scanline/frame rate changes in red --- src/emucore/FBSurface.cxx | 13 ++++++++++--- src/emucore/FBSurface.hxx | 4 ++-- src/emucore/FrameBuffer.cxx | 35 +++++++++++++++++------------------ src/emucore/FrameBuffer.hxx | 3 +++ src/gui/Dialog.cxx | 2 ++ src/gui/TimeMachineDialog.cxx | 21 +++++++++++++-------- src/gui/Widget.cxx | 11 +++++++---- src/gui/Widget.hxx | 8 ++++++-- 8 files changed, 60 insertions(+), 37 deletions(-) diff --git a/src/emucore/FBSurface.cxx b/src/emucore/FBSurface.cxx index 2b0362857..32e751997 100644 --- a/src/emucore/FBSurface.cxx +++ b/src/emucore/FBSurface.cxx @@ -154,8 +154,15 @@ void FBSurface::fillRect(uInt32 x, uInt32 y, uInt32 w, uInt32 h, uInt32 color) // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - void FBSurface::drawChar(const GUI::Font& font, uInt8 chr, - uInt32 tx, uInt32 ty, uInt32 color) + uInt32 tx, uInt32 ty, uInt32 color, uInt32 shadowColor) { + if(shadowColor != 0) + { + drawChar(font, chr, tx + 1, ty + 0, shadowColor); + drawChar(font, chr, tx + 0, ty + 1, shadowColor); + drawChar(font, chr, tx + 1, ty + 1, shadowColor); + } + const FontDesc& desc = font.desc(); // If this character is not included in the font, use the default char. @@ -300,7 +307,7 @@ void FBSurface::frameRect(uInt32 x, uInt32 y, uInt32 w, uInt32 h, void FBSurface::drawString(const GUI::Font& font, const string& s, int x, int y, int w, uInt32 color, TextAlign align, - int deltax, bool useEllipsis) + int deltax, bool useEllipsis, uInt32 shadowColor) { const string ELLIPSIS = "\x1d"; // "..." const int leftX = x, rightX = x + w; @@ -367,7 +374,7 @@ void FBSurface::drawString(const GUI::Font& font, const string& s, if(x+w > rightX) break; if(x >= leftX) - drawChar(font, str[i], x, y, color); + drawChar(font, str[i], x, y, color, shadowColor); x += w; } diff --git a/src/emucore/FBSurface.hxx b/src/emucore/FBSurface.hxx index 87757078b..21d06306f 100644 --- a/src/emucore/FBSurface.hxx +++ b/src/emucore/FBSurface.hxx @@ -134,7 +134,7 @@ class FBSurface @param color The color of the character */ virtual void drawChar(const GUI::Font& font, uInt8 c, uInt32 x, uInt32 y, - uInt32 color); + uInt32 color, uInt32 shadowColor = 0); /** This method should be called to draw the bitmap image. @@ -217,7 +217,7 @@ class FBSurface virtual void drawString( const GUI::Font& font, const string& s, int x, int y, int w, uInt32 color, TextAlign align = TextAlign::Left, - int deltax = 0, bool useEllipsis = true); + int deltax = 0, bool useEllipsis = true, uInt32 shadowColor = 0); /** This method should be called to indicate that the surface has been diff --git a/src/emucore/FrameBuffer.cxx b/src/emucore/FrameBuffer.cxx index 456175997..c0cafb029 100644 --- a/src/emucore/FrameBuffer.cxx +++ b/src/emucore/FrameBuffer.cxx @@ -229,7 +229,7 @@ FBInitStatus FrameBuffer::createDisplay(const string& title, // Create surfaces for TIA statistics and general messages myStatsMsg.color = kColorInfo; - myStatsMsg.w = infoFont().getMaxCharWidth() * 24 + 2; + myStatsMsg.w = infoFont().getMaxCharWidth() * 30 + 2; myStatsMsg.h = (infoFont().getFontHeight() + 2) * 2; if(!myStatsMsg.surface) @@ -288,33 +288,32 @@ void FrameBuffer::update() { const ConsoleInfo& info = myOSystem.console().about(); char msg[30]; - std::snprintf(msg, 30, "%3u @ %3.2ffps => %s", - myOSystem.console().tia().scanlinesLastFrame(), - myOSystem.console().getFramerate(), info.DisplayFormat.c_str()); + uInt32 color; + myStatsMsg.surface->invalidate(); string bsinfo = info.BankSwitch + (myOSystem.settings().getBool("dev.settings") ? "| Developer" : "| Player"); // draw shadowed text - myStatsMsg.surface->drawString(infoFont(), msg, 1 + 1, 1 + 0, - myStatsMsg.w, kBGColor); - myStatsMsg.surface->drawString(infoFont(), msg, 1 + 0, 1 + 1, - myStatsMsg.w, kBGColor); - myStatsMsg.surface->drawString(infoFont(), msg, 1 + 1, 1 + 1, - myStatsMsg.w, kBGColor); + color = myOSystem.console().tia().scanlinesLastFrame() != myLastScanlines ? kDbgColorRed : myStatsMsg.color; + std::snprintf(msg, 30, "%3u", myOSystem.console().tia().scanlinesLastFrame()); myStatsMsg.surface->drawString(infoFont(), msg, 1, 1, - myStatsMsg.w, myStatsMsg.color); - myStatsMsg.surface->drawString(infoFont(), bsinfo, 1 + 1, 15 + 0, - myStatsMsg.w, kBGColor); - myStatsMsg.surface->drawString(infoFont(), bsinfo, 1 + 0, 15 + 1, - myStatsMsg.w, kBGColor); - myStatsMsg.surface->drawString(infoFont(), bsinfo, 1 + 1, 15 + 1, - myStatsMsg.w, kBGColor); + myStatsMsg.w, color, TextAlign::Left, 0, true, kBGColor); + color = myOSystem.console().getFramerate() != myLastFrameRate ? kDbgColorRed : myStatsMsg.color; + std::snprintf(msg, 30, "@ %3.2ffps", myOSystem.console().getFramerate()); + myStatsMsg.surface->drawString(infoFont(), msg, 1 + infoFont().getStringWidth("262 "), 1, + myStatsMsg.w, color, TextAlign::Left, 0, true, kBGColor); + std::snprintf(msg, 30, "=> %s", info.DisplayFormat.c_str()); + myStatsMsg.surface->drawString(infoFont(), msg, 1+ infoFont().getStringWidth("262 @ 60.00fps "), 1, + myStatsMsg.w, myStatsMsg.color, TextAlign::Left, 0, true, kBGColor); + myStatsMsg.surface->drawString(infoFont(), bsinfo, 1, 15, - myStatsMsg.w, myStatsMsg.color); + myStatsMsg.w, myStatsMsg.color, TextAlign::Left, 0, true, kBGColor); myStatsMsg.surface->setDirty(); myStatsMsg.surface->setDstPos(myImageRect.x() + 1, myImageRect.y() + 1); myStatsMsg.surface->render(); } + myLastScanlines = myOSystem.console().tia().scanlinesLastFrame(); + myLastFrameRate = myOSystem.console().getFramerate(); myPausedCount = 0; break; // EventHandlerState::EMULATION } diff --git a/src/emucore/FrameBuffer.hxx b/src/emucore/FrameBuffer.hxx index 975ecbf4e..472213b3c 100644 --- a/src/emucore/FrameBuffer.hxx +++ b/src/emucore/FrameBuffer.hxx @@ -510,6 +510,9 @@ class FrameBuffer Message myMsg; Message myStatsMsg; bool myStatsEnabled; + uInt32 myLastScanlines; + float myLastFrameRate; + bool myGrabMouse; diff --git a/src/gui/Dialog.cxx b/src/gui/Dialog.cxx index 8caceff55..93e632dd5 100644 --- a/src/gui/Dialog.cxx +++ b/src/gui/Dialog.cxx @@ -273,6 +273,8 @@ void Dialog::drawDialog() if(_flags & WIDGET_CLEARBG) // cerr << "Dialog::drawDialog(): w = " << _w << ", h = " << _h << " @ " << &s << endl << endl; s.fillRect(_x, _y, _w, _h, kDlgColor); + else + s.invalidate(); if(_flags & WIDGET_BORDER) #ifndef FLAT_UI s.box(_x, _y, _w, _h, kColor, kShadowColor); diff --git a/src/gui/TimeMachineDialog.cxx b/src/gui/TimeMachineDialog.cxx index bd38faf45..a732bbdd9 100644 --- a/src/gui/TimeMachineDialog.cxx +++ b/src/gui/TimeMachineDialog.cxx @@ -193,23 +193,26 @@ TimeMachineDialog::TimeMachineDialog(OSystem& osystem, DialogContainer& parent, _w = 20 * (buttonWidth + BUTTON_GAP) + 20; _h = V_BORDER * 2 + rowHeight + buttonHeight + 2; - //this->clearFlags(WIDGET_CLEARBG); // does only work combined with blending! - //this->clearFlags(WIDGET_BORDER); + this->clearFlags(WIDGET_CLEARBG); // does only work combined with blending (0..100)! + this->clearFlags(WIDGET_BORDER); xpos = H_BORDER; ypos = V_BORDER; // Add index info - myCurrentIdxWidget = new StaticTextWidget(this, font, xpos, ypos, " "); + myCurrentIdxWidget = new StaticTextWidget(this, font, xpos, ypos, " ", TextAlign::Left, kBGColor); + myCurrentIdxWidget->setTextColor(kWidColor); myLastIdxWidget = new StaticTextWidget(this, font, _w - H_BORDER - font.getStringWidth("8888"), ypos, - " ", TextAlign::Right); + " ", TextAlign::Right, kBGColor); + myLastIdxWidget->setTextColor(kWidColor); ypos += rowHeight; // Add time info - myCurrentTimeWidget = new StaticTextWidget(this, font, xpos, ypos + 3, "04:32 59"); - //myCurrentTimeWidget->setFlags(WIDGET_CLEARBG); + myCurrentTimeWidget = new StaticTextWidget(this, font, xpos, ypos + 3, "04:32 59", TextAlign::Left, kBGColor); + myCurrentTimeWidget->setTextColor(kWidColor); myLastTimeWidget = new StaticTextWidget(this, font, _w - H_BORDER - font.getStringWidth("XX:XX XX"), ypos + 3, - "12:25 59"); + "12:25 59", TextAlign::Right, kBGColor); + myLastTimeWidget->setTextColor(kWidColor); xpos = myCurrentTimeWidget->getRight() + BUTTON_GAP * 4; // Add buttons @@ -253,7 +256,9 @@ TimeMachineDialog::TimeMachineDialog(OSystem& osystem, DialogContainer& parent, xpos = myUnwindAllWidget->getRight() + BUTTON_GAP * 3; // Add message - myMessageWidget = new StaticTextWidget(this, font, xpos, ypos + 3, " "); + myMessageWidget = new StaticTextWidget(this, font, xpos, ypos + 3, " ", + TextAlign::Left, kBGColor); + myMessageWidget->setTextColor(kWidColor); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/gui/Widget.cxx b/src/gui/Widget.cxx index c432c7506..8c1850226 100644 --- a/src/gui/Widget.cxx +++ b/src/gui/Widget.cxx @@ -304,7 +304,8 @@ void Widget::setDirtyInChain(Widget* start) // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - StaticTextWidget::StaticTextWidget(GuiObject* boss, const GUI::Font& font, int x, int y, int w, int h, - const string& text, TextAlign align) + const string& text, TextAlign align, + uInt32 shadowColor) : Widget(boss, font, x, y, w, h), _align(align) { @@ -313,6 +314,7 @@ StaticTextWidget::StaticTextWidget(GuiObject* boss, const GUI::Font& font, _bgcolorhi = kDlgColor; _textcolor = kTextColor; _textcolorhi = kTextColor; + _shadowcolor = shadowColor; _label = text; _editable = false; @@ -321,8 +323,9 @@ StaticTextWidget::StaticTextWidget(GuiObject* boss, const GUI::Font& font, // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - StaticTextWidget::StaticTextWidget(GuiObject* boss, const GUI::Font& font, int x, int y, - const string& text, TextAlign align) - : StaticTextWidget(boss, font, x, y, font.getStringWidth(text), font.getLineHeight(), text, align) + const string& text, TextAlign align, + uInt32 shadowColor) + : StaticTextWidget(boss, font, x, y, font.getStringWidth(text), font.getLineHeight(), text, align, shadowColor) { } @@ -349,7 +352,7 @@ void StaticTextWidget::drawWidget(bool hilite) { FBSurface& s = _boss->dialog().surface(); s.drawString(_font, _label, _x, _y, _w, - isEnabled() ? _textcolor : uInt32(kColor), _align); + isEnabled() ? _textcolor : uInt32(kColor), _align, 0, true, _shadowcolor); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/gui/Widget.hxx b/src/gui/Widget.hxx index 21baeccb3..a029312c2 100644 --- a/src/gui/Widget.hxx +++ b/src/gui/Widget.hxx @@ -111,6 +111,7 @@ class Widget : public GuiObject void setTextColorHi(uInt32 color) { _textcolorhi = color; } void setBGColor(uInt32 color) { _bgcolor = color; } void setBGColorHi(uInt32 color) { _bgcolorhi = color; } + void setShadowColor(uInt32 color) { _shadowcolor = color; } virtual void loadConfig() { } @@ -141,6 +142,7 @@ class Widget : public GuiObject uInt32 _bgcolorhi; uInt32 _textcolor; uInt32 _textcolorhi; + uInt32 _shadowcolor; public: static Widget* findWidgetInChain(Widget* start, int x, int y); @@ -176,10 +178,12 @@ class StaticTextWidget : public Widget public: StaticTextWidget(GuiObject* boss, const GUI::Font& font, int x, int y, int w, int h, - const string& text, TextAlign align = TextAlign::Left); + const string& text, TextAlign align = TextAlign::Left, + uInt32 shadowColor = 0); StaticTextWidget(GuiObject* boss, const GUI::Font& font, int x, int y, - const string& text, TextAlign align = TextAlign::Left); + const string& text, TextAlign align = TextAlign::Left, + uInt32 shadowColor = 0); void setValue(int value); void setLabel(const string& label); void setAlign(TextAlign align) { _align = align; } From 7b8dff8e46b91d0f45608951cd0b8904c3f107d9 Mon Sep 17 00:00:00 2001 From: thrust26 Date: Tue, 16 Jan 2018 18:16:56 +0100 Subject: [PATCH 09/18] when strings are shortened, ellipsis is added at the END now --- src/emucore/FBSurface.cxx | 31 +++++-------------------------- 1 file changed, 5 insertions(+), 26 deletions(-) diff --git a/src/emucore/FBSurface.cxx b/src/emucore/FBSurface.cxx index 32e751997..f0678f1ee 100644 --- a/src/emucore/FBSurface.cxx +++ b/src/emucore/FBSurface.cxx @@ -320,43 +320,22 @@ void FBSurface::drawString(const GUI::Font& font, const string& s, // String is too wide. So we shorten it "intelligently", by replacing // parts of it by an ellipsis ("..."). There are three possibilities // for this: replace the start, the end, or the middle of the string. - // What is best really depends on the context; but unless we want to - // make this configurable, replacing the middle probably is a good - // compromise. - const int ellipsisWidth = font.getStringWidth(ELLIPSIS); - - // SLOW algorithm to remove enough of the middle. But it is good enough for now. - const int halfWidth = (w - ellipsisWidth) / 2; - int w2 = 0; + // What is best really depends on the context; but most applications + // replace the end. So we use that too. + int w2 = font.getStringWidth(ELLIPSIS); + // SLOW algorithm to find the acceptable length. But it is good enough for now. for(i = 0; i < s.size(); ++i) { int charWidth = font.getCharWidth(s[i]); - if(w2 + charWidth > halfWidth) + if(w2 + charWidth > w) break; w2 += charWidth; str += s[i]; } - - // At this point we know that the first 'i' chars are together 'w2' - // pixels wide. We took the first i-1, and add "..." to them. str += ELLIPSIS; - // The original string is width wide. Of those we already skipped past - // w2 pixels, which means (width - w2) remain. - // The new str is (w2+ellipsisWidth) wide, so we can accomodate about - // (w - (w2+ellipsisWidth)) more pixels. - // Thus we skip ((width - w2) - (w - (w2+ellipsisWidth))) = - // (width + ellipsisWidth - w) - int skip = width + ellipsisWidth - w; - for(; i < s.size() && skip > 0; ++i) - skip -= font.getCharWidth(s[i]); - - // Append the remaining chars, if any - for(; i < s.size(); ++i) - str += s[i]; - width = font.getStringWidth(str); } else From 2cb2eed3e7f8727174790d1a87e179cf9c22f6e1 Mon Sep 17 00:00:00 2001 From: Stephen Anthony Date: Tue, 16 Jan 2018 20:58:35 -0330 Subject: [PATCH 10/18] Add 'override' to method, to eliminate warning in clang. --- src/common/FrameBufferSDL2.hxx | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/common/FrameBufferSDL2.hxx b/src/common/FrameBufferSDL2.hxx index 3944849ce..489ff4b4b 100644 --- a/src/common/FrameBufferSDL2.hxx +++ b/src/common/FrameBufferSDL2.hxx @@ -48,11 +48,11 @@ class FrameBufferSDL2 : public FrameBuffer ////////////////////////////////////////////////////////////////////// /** - Updates window title + Updates window title/ - @param title The title of the application / window + @param title The title of the application / window */ - void setTitle(const string& title); + void setTitle(const string& title) override; /** Shows or hides the cursor based on the given boolean value. From dc9f92ecdbfe371e12b0db09bd5ff94d3f4c52fd Mon Sep 17 00:00:00 2001 From: sa666666 Date: Wed, 17 Jan 2018 13:22:49 -0330 Subject: [PATCH 11/18] A fix for the previous fix. --- src/common/FrameBufferSDL2.hxx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/common/FrameBufferSDL2.hxx b/src/common/FrameBufferSDL2.hxx index 489ff4b4b..74969ed55 100644 --- a/src/common/FrameBufferSDL2.hxx +++ b/src/common/FrameBufferSDL2.hxx @@ -48,7 +48,7 @@ class FrameBufferSDL2 : public FrameBuffer ////////////////////////////////////////////////////////////////////// /** - Updates window title/ + Updates window title. @param title The title of the application / window */ From 2e51511c80b4fbdf980e9e6df7f387879acb14d5 Mon Sep 17 00:00:00 2001 From: thrust26 Date: Wed, 17 Jan 2018 10:27:18 +0100 Subject: [PATCH 12/18] message for SaveKey/AtariVox EEPROM access added --- src/emucore/MT24LC256.cxx | 12 ++++++++++++ src/emucore/Settings.cxx | 4 ++++ src/emucore/System.hxx | 7 +++++++ src/gui/DeveloperDialog.cxx | 18 +++++++++++++++++- src/gui/DeveloperDialog.hxx | 2 ++ 5 files changed, 42 insertions(+), 1 deletion(-) diff --git a/src/emucore/MT24LC256.cxx b/src/emucore/MT24LC256.cxx index 62d7e4446..80fe2f4e3 100644 --- a/src/emucore/MT24LC256.cxx +++ b/src/emucore/MT24LC256.cxx @@ -18,6 +18,9 @@ #include #include "System.hxx" + +#include "Settings.hxx" + #include "MT24LC256.hxx" #define DEBUG_EEPROM 0 @@ -250,6 +253,9 @@ void MT24LC256::jpee_data_stop() { myDataChanged = true; myPageHit[jpee_address / PAGE_SIZE] = true; + bool devSettings = mySystem.oSystem().settings().getBool("dev.settings"); + if(mySystem.oSystem().settings().getBool(devSettings ? "dev.eepromaccess" : "plr.eepromaccess")) + mySystem.oSystem().frameBuffer().showMessage("AtariVox/SaveKey EEPROM write"); myData[(jpee_address++) & jpee_sizemask] = jpee_packet[i]; if (!(jpee_address & jpee_pagemask)) break; /* Writes can't cross page boundary! */ @@ -347,6 +353,12 @@ void MT24LC256::jpee_clock_fall() } jpee_state=3; myPageHit[jpee_address / PAGE_SIZE] = true; + + { + bool devSettings = mySystem.oSystem().settings().getBool("dev.settings"); + if(mySystem.oSystem().settings().getBool(devSettings ? "dev.eepromaccess" : "plr.eepromaccess")) + mySystem.oSystem().frameBuffer().showMessage("AtariVox/SaveKey EEPROM read"); + } jpee_nb = (myData[jpee_address & jpee_sizemask] << 1) | 1; /* Fall through */ JPEE_LOG2("I2C_READ(%04X=%02X)",jpee_address,jpee_nb/2); [[fallthrough]]; diff --git a/src/emucore/Settings.cxx b/src/emucore/Settings.cxx index ac09c2478..b54c366ed 100644 --- a/src/emucore/Settings.cxx +++ b/src/emucore/Settings.cxx @@ -164,6 +164,7 @@ Settings::Settings(OSystem& osystem) setInternal("plr.tm.horizon", "10m"); // = ~10 minutes // Thumb ARM emulation options setInternal("plr.thumb.trapfatal", "false"); + setInternal("plr.eepromaccess", "false"); // developer settings setInternal("dev.settings", "false"); @@ -184,6 +185,7 @@ Settings::Settings(OSystem& osystem) setInternal("dev.tm.horizon", "10s"); // = ~10 seconds // Thumb ARM emulation options setInternal("dev.thumb.trapfatal", "true"); + setInternal("dev.eepromaccess", "true"); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -574,6 +576,7 @@ void Settings::usage() const << " -plr.tv.jitter_recovery <1-20> Set recovery time for TV jitter effect\n" << " -plr.tiadriven <1|0> Drive unused TIA pins randomly on a read/peek\n" << " -plr.thumb.trapfatal <1|0> Determines whether errors in ARM emulation throw an exception\n" + << " -plr.eepromaccess <1|0> Enable messages for AtariVox/SaveKey access messages\n" << endl << " The same parameters but for developer settings mode\n" << " -dev.stats <1|0> Overlay console info during emulation\n" @@ -587,6 +590,7 @@ void Settings::usage() const << " -dev.tv.jitter_recovery <1-20> Set recovery time for TV jitter effect\n" << " -dev.tiadriven <1|0> Drive unused TIA pins randomly on a read/peek\n" << " -dev.thumb.trapfatal <1|0> Determines whether errors in ARM emulation throw an exception\n" + << " -dev.eepromaccess <1|0> Enable messages for AtariVox/SaveKey access messages\n" << endl << std::flush; } diff --git a/src/emucore/System.hxx b/src/emucore/System.hxx index b9dd5ee3b..de6e354df 100644 --- a/src/emucore/System.hxx +++ b/src/emucore/System.hxx @@ -88,6 +88,13 @@ class System : public Serializable void reset(bool autodetect = false); public: + /** + Answer the OSystem attached to the system. + + @return The attached OSystem + */ + const OSystem& oSystem() const { return myOSystem; } + /** Answer the 6502 microprocessor attached to the system. If a processor has not been attached calling this function will fail. diff --git a/src/gui/DeveloperDialog.cxx b/src/gui/DeveloperDialog.cxx index b19a7ebcb..cc5189061 100644 --- a/src/gui/DeveloperDialog.cxx +++ b/src/gui/DeveloperDialog.cxx @@ -83,7 +83,7 @@ void DeveloperDialog::addEmulationTab(const GUI::Font& font) int lineHeight = font.getLineHeight(); WidgetArray wid; VariantList items; - int tabID = myTab->addTab(" Emulation "); + int tabID = myTab->addTab("Emulation"); // settings set mySettingsGroup0 = new RadioButtonGroup(); @@ -154,6 +154,12 @@ void DeveloperDialog::addEmulationTab(const GUI::Font& font) myThumbExceptionWidget = new CheckboxWidget(myTab, font, HBORDER + INDENT * 1, ypos + 1, "Fatal ARM emulation error throws exception"); wid.push_back(myThumbExceptionWidget); + ypos += lineHeight + VGAP; + + // AtariVox/SaveKey EEPROM access + myEEPROMAccessWidget = new CheckboxWidget(myTab, font, HBORDER + INDENT * 1, ypos + 1, + "Display AtariVox/SaveKey EEPROM R/W access"); + wid.push_back(myEEPROMAccessWidget); // Add items for tab 0 addToFocusList(wid, myTab, tabID); @@ -510,6 +516,8 @@ void DeveloperDialog::loadSettings(SettingsSet set) myUndrivenPins[set] = instance().settings().getBool(prefix + "tiadriven"); // Thumb ARM emulation exception myThumbException[set] = instance().settings().getBool(prefix + "thumb.trapfatal"); + // AtariVox/SaveKey EEPROM access + myEEPROMAccess[set] = instance().settings().getBool(prefix + "eepromaccess"); // Debug colors myDebugColors[set] = instance().settings().getBool(prefix + "debugcolors"); @@ -542,6 +550,8 @@ void DeveloperDialog::saveSettings(SettingsSet set) instance().settings().setValue(prefix + "tiadriven", myUndrivenPins[set]); // Thumb ARM emulation exception instance().settings().setValue(prefix + "thumb.trapfatal", myThumbException[set]); + // AtariVox/SaveKey EEPROM access + instance().settings().setValue(prefix + "eepromaccess", myEEPROMAccess[set]); // Debug colors instance().settings().setValue(prefix + "debugcolors", myDebugColors[set]); @@ -577,6 +587,8 @@ void DeveloperDialog::getWidgetStates(SettingsSet set) myUndrivenPins[set] = myUndrivenPinsWidget->getState(); // Thumb ARM emulation exception myThumbException[set] = myThumbExceptionWidget->getState(); + // AtariVox/SaveKey EEPROM access + myEEPROMAccess[set] = myEEPROMAccessWidget->getState(); // Debug colors myDebugColors[set] = myDebugColorsWidget->getState(); @@ -612,6 +624,8 @@ void DeveloperDialog::setWidgetStates(SettingsSet set) myUndrivenPinsWidget->setState(myUndrivenPins[set]); // Thumb ARM emulation exception myThumbExceptionWidget->setState(myThumbException[set]); + // AtariVox/SaveKey EEPROM access + myEEPROMAccessWidget->setState(myEEPROMAccess[set]); handleConsole(); @@ -760,6 +774,8 @@ void DeveloperDialog::setDefaults() myUndrivenPins[set] = devSettings ? true : false; // Thumb ARM emulation exception myThumbException[set] = devSettings ? true : false; + // AtariVox/SaveKey EEPROM access + myEEPROMAccess[set] = devSettings ? true : false; setWidgetStates(set); break; diff --git a/src/gui/DeveloperDialog.hxx b/src/gui/DeveloperDialog.hxx index 27577b89f..794819caf 100644 --- a/src/gui/DeveloperDialog.hxx +++ b/src/gui/DeveloperDialog.hxx @@ -105,6 +105,7 @@ class DeveloperDialog : public Dialog CheckboxWidget* myRandomizeCPUWidget[5]; CheckboxWidget* myUndrivenPinsWidget; CheckboxWidget* myThumbExceptionWidget; + CheckboxWidget* myEEPROMAccessWidget; // Video widgets RadioButtonGroup* mySettingsGroup1; @@ -150,6 +151,7 @@ class DeveloperDialog : public Dialog bool myDebugColors[2]; bool myUndrivenPins[2]; bool myThumbException[2]; + bool myEEPROMAccess[2]; // States sets bool myTimeMachine[2]; int myStateSize[2]; From 9441cc43c4d8ab1f8105ded33c474aa7c4efa93b Mon Sep 17 00:00:00 2001 From: Stephen Anthony Date: Sat, 20 Jan 2018 20:45:56 -0330 Subject: [PATCH 13/18] Cherry-picked some commits from master. --- Changes.txt | 3 ++- src/gui/TimeMachineDialog.cxx | 7 +++++-- src/gui/TimeMachineDialog.hxx | 2 +- 3 files changed, 8 insertions(+), 4 deletions(-) diff --git a/Changes.txt b/Changes.txt index 4600e6451..fbd594b57 100644 --- a/Changes.txt +++ b/Changes.txt @@ -69,7 +69,8 @@ * Fixed swapped ports being displayed wrong in System Logs and debugger. * Added options to erase the AtariVox/Savekey flash memory, either for - all ROMs or only the current one. + all ROMs or only the current one. Also added a message (configurable) + when the flash memory is accessed. * Moved various developer related settings in new Developer Settings dialog. These settings now come in two groups (player/developer) and diff --git a/src/gui/TimeMachineDialog.cxx b/src/gui/TimeMachineDialog.cxx index a732bbdd9..cd009330d 100644 --- a/src/gui/TimeMachineDialog.cxx +++ b/src/gui/TimeMachineDialog.cxx @@ -181,7 +181,7 @@ TimeMachineDialog::TimeMachineDialog(OSystem& osystem, DialogContainer& parent, }; const GUI::Font& font = instance().frameBuffer().font(); - const int H_BORDER = 6, BUTTON_GAP = 4, V_BORDER = 4, V_GAP = 4; + const int H_BORDER = 6, BUTTON_GAP = 4, V_BORDER = 4; // FIXME, V_GAP = 4; const int buttonWidth = BUTTON_W + 8, buttonHeight = BUTTON_H + 10, rowHeight = font.getLineHeight(); @@ -351,7 +351,10 @@ void TimeMachineDialog::handleWinds(Int32 numWinds) if(numWinds) { uInt64 startCycles = instance().console().tia().cycles(); - uInt32 winds = numWinds < 0 ? r.rewindState(-numWinds) : r.unwindState(numWinds); + if(numWinds < 0) + r.rewindState(-numWinds); + else + r.unwindState(numWinds); string message = r.getUnitString(instance().console().tia().cycles() - startCycles); myMessageWidget->setLabel((numWinds < 0 ? "(-" : "(+") + message + ")"); diff --git a/src/gui/TimeMachineDialog.hxx b/src/gui/TimeMachineDialog.hxx index 06a1e36e9..05b49ce25 100644 --- a/src/gui/TimeMachineDialog.hxx +++ b/src/gui/TimeMachineDialog.hxx @@ -55,7 +55,7 @@ class TimeMachineDialog : public Dialog kUnwind1 = 'TMun', }; - ButtonWidget* myPauseWidget; + // FIXME ButtonWidget* myPauseWidget; ButtonWidget* myPlayWidget; ButtonWidget* myRewindAllWidget; ButtonWidget* myRewind10Widget; From 436c380a7ea2211bb7fdf20b345359e486ed54c5 Mon Sep 17 00:00:00 2001 From: thrust26 Date: Wed, 17 Jan 2018 19:03:25 +0100 Subject: [PATCH 14/18] benchmark: frame stats now display real frame rate when 'Auto' is not selected --- src/emucore/FrameBuffer.cxx | 93 +++++++++++++++++++++++++------------ src/emucore/FrameBuffer.hxx | 10 +++- src/emucore/OSystem.cxx | 2 +- 3 files changed, 72 insertions(+), 33 deletions(-) diff --git a/src/emucore/FrameBuffer.cxx b/src/emucore/FrameBuffer.cxx index c0cafb029..016ba103f 100644 --- a/src/emucore/FrameBuffer.cxx +++ b/src/emucore/FrameBuffer.cxx @@ -46,7 +46,10 @@ FrameBuffer::FrameBuffer(OSystem& osystem) : myOSystem(osystem), myInitializedCount(0), myPausedCount(0), - myCurrentModeList(nullptr) + myCurrentModeList(nullptr), + myTotalTime(0), + myTotalFrames(0), + myLastRunFrameRate(0) { myMsg.surface = myStatsMsg.surface = nullptr; myStatsEnabled = myMsg.enabled = myStatsMsg.enabled = false; @@ -230,7 +233,7 @@ FBInitStatus FrameBuffer::createDisplay(const string& title, // Create surfaces for TIA statistics and general messages myStatsMsg.color = kColorInfo; myStatsMsg.w = infoFont().getMaxCharWidth() * 30 + 2; - myStatsMsg.h = (infoFont().getFontHeight() + 2) * 2; + myStatsMsg.h = (infoFont().getFontHeight() + 2) * 3; if(!myStatsMsg.surface) { @@ -285,35 +288,10 @@ void FrameBuffer::update() // Show frame statistics if(myStatsMsg.enabled) - { - const ConsoleInfo& info = myOSystem.console().about(); - char msg[30]; - uInt32 color; - - myStatsMsg.surface->invalidate(); - string bsinfo = info.BankSwitch + - (myOSystem.settings().getBool("dev.settings") ? "| Developer" : "| Player"); - // draw shadowed text - color = myOSystem.console().tia().scanlinesLastFrame() != myLastScanlines ? kDbgColorRed : myStatsMsg.color; - std::snprintf(msg, 30, "%3u", myOSystem.console().tia().scanlinesLastFrame()); - myStatsMsg.surface->drawString(infoFont(), msg, 1, 1, - myStatsMsg.w, color, TextAlign::Left, 0, true, kBGColor); - color = myOSystem.console().getFramerate() != myLastFrameRate ? kDbgColorRed : myStatsMsg.color; - std::snprintf(msg, 30, "@ %3.2ffps", myOSystem.console().getFramerate()); - myStatsMsg.surface->drawString(infoFont(), msg, 1 + infoFont().getStringWidth("262 "), 1, - myStatsMsg.w, color, TextAlign::Left, 0, true, kBGColor); - std::snprintf(msg, 30, "=> %s", info.DisplayFormat.c_str()); - myStatsMsg.surface->drawString(infoFont(), msg, 1+ infoFont().getStringWidth("262 @ 60.00fps "), 1, - myStatsMsg.w, myStatsMsg.color, TextAlign::Left, 0, true, kBGColor); - - myStatsMsg.surface->drawString(infoFont(), bsinfo, 1, 15, - myStatsMsg.w, myStatsMsg.color, TextAlign::Left, 0, true, kBGColor); - myStatsMsg.surface->setDirty(); - myStatsMsg.surface->setDstPos(myImageRect.x() + 1, myImageRect.y() + 1); - myStatsMsg.surface->render(); - } + drawFrameStats(); + else + myLastFrameRate = myOSystem.console().getFramerate(); myLastScanlines = myOSystem.console().tia().scanlinesLastFrame(); - myLastFrameRate = myOSystem.console().getFramerate(); myPausedCount = 0; break; // EventHandlerState::EMULATION } @@ -399,6 +377,61 @@ void FrameBuffer::showMessage(const string& message, MessagePosition position, myMsg.enabled = true; } +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +void FrameBuffer::drawFrameStats() +{ + const ConsoleInfo& info = myOSystem.console().about(); + char msg[30]; + uInt32 color; + + myStatsMsg.surface->invalidate(); + string bsinfo = info.BankSwitch + + (myOSystem.settings().getBool("dev.settings") ? "| Developer" : "| Player"); + // draw shadowed text + color = myOSystem.console().tia().scanlinesLastFrame() != myLastScanlines ? kDbgColorRed : myStatsMsg.color; + std::snprintf(msg, 30, "%3u", myOSystem.console().tia().scanlinesLastFrame()); + myStatsMsg.surface->drawString(infoFont(), msg, 1, 1, + myStatsMsg.w, color, TextAlign::Left, 0, true, kBGColor); + // draw framerate + float frameRate; + if(myOSystem.settings().getInt("framerate") == 0) + { + // if 'Auto' is selected, draw the calculated framerate + frameRate = myOSystem.console().getFramerate(); + } + else + { + // if 'Auto' is not selected, draw the effective framerate + const TimingInfo& ti = myOSystem.timingInfo(); + if(ti.totalFrames - myTotalFrames >= myLastFrameRate) + { + frameRate = 1000000.0 * (ti.totalFrames - myTotalFrames) / (ti.totalTime - myTotalTime); + if(frameRate > myOSystem.console().getFramerate() + 1) + frameRate = 1; + myTotalFrames = ti.totalFrames; + myTotalTime = ti.totalTime; + } + else + frameRate = myLastFrameRate; + } + color = frameRate != myLastFrameRate ? kDbgColorRed : myStatsMsg.color; + myLastFrameRate = frameRate; + std::snprintf(msg, 30, "@%6.2ffps", frameRate); + myStatsMsg.surface->drawString(infoFont(), msg, 1 + infoFont().getStringWidth("262 "), 1, + myStatsMsg.w, color, TextAlign::Left, 0, true, kBGColor); + std::snprintf(msg, 30, "=> %s", info.DisplayFormat.c_str()); + myStatsMsg.surface->drawString(infoFont(), msg, 1 + infoFont().getStringWidth("262 @ 60.00fps "), 1, + myStatsMsg.w, myStatsMsg.color, TextAlign::Left, 0, true, kBGColor); + + myStatsMsg.surface->drawString(infoFont(), bsinfo, 1, 15, + myStatsMsg.w, myStatsMsg.color, TextAlign::Left, 0, true, kBGColor); + + myStatsMsg.surface->setDirty(); + myStatsMsg.surface->setDstPos(myImageRect.x() + 1, myImageRect.y() + 1); + myStatsMsg.surface->render(); + +} + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - void FrameBuffer::toggleFrameStats() { diff --git a/src/emucore/FrameBuffer.hxx b/src/emucore/FrameBuffer.hxx index 472213b3c..f5d6580fd 100644 --- a/src/emucore/FrameBuffer.hxx +++ b/src/emucore/FrameBuffer.hxx @@ -458,6 +458,9 @@ class FrameBuffer string myScreenTitle; private: + // Draws the frame stats overlay + void drawFrameStats(); + // Indicates the number of times the framebuffer was initialized uInt32 myInitializedCount; @@ -512,8 +515,7 @@ class FrameBuffer bool myStatsEnabled; uInt32 myLastScanlines; float myLastFrameRate; - - + bool myGrabMouse; // The list of all available video modes for this framebuffer @@ -533,6 +535,10 @@ class FrameBuffer // Holds UI palette data (standard and classic colours) static uInt32 ourGUIColors[3][kNumColors-256]; + uInt64 myTotalTime; + uInt64 myTotalFrames; + float myLastRunFrameRate; + private: // Following constructors and assignment operators not supported FrameBuffer() = delete; diff --git a/src/emucore/OSystem.cxx b/src/emucore/OSystem.cxx index 95175dc67..2a5704382 100644 --- a/src/emucore/OSystem.cxx +++ b/src/emucore/OSystem.cxx @@ -633,7 +633,7 @@ void OSystem::mainLoop() // for that and reset the timers when appropriate if((myTimingInfo.virt - myTimingInfo.current) > (myTimePerFrame << 1)) { - myTimingInfo.start = myTimingInfo.current = myTimingInfo.virt = getTicks(); + myTimingInfo.current = myTimingInfo.virt = getTicks(); } if(myTimingInfo.current < myTimingInfo.virt) From 27291dd5d286c421ee30fee1d11d6e48119c95f1 Mon Sep 17 00:00:00 2001 From: thrust26 Date: Wed, 17 Jan 2018 19:12:39 +0100 Subject: [PATCH 15/18] small fix for benchmark commit --- src/emucore/FrameBuffer.cxx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/emucore/FrameBuffer.cxx b/src/emucore/FrameBuffer.cxx index 016ba103f..15e8428ee 100644 --- a/src/emucore/FrameBuffer.cxx +++ b/src/emucore/FrameBuffer.cxx @@ -49,7 +49,7 @@ FrameBuffer::FrameBuffer(OSystem& osystem) myCurrentModeList(nullptr), myTotalTime(0), myTotalFrames(0), - myLastRunFrameRate(0) + myLastFrameRate(60) { myMsg.surface = myStatsMsg.surface = nullptr; myStatsEnabled = myMsg.enabled = myStatsMsg.enabled = false; From b67b7956424c0f5d1ec95a6384582ed06a1c3e34 Mon Sep 17 00:00:00 2001 From: thrust26 Date: Thu, 18 Jan 2018 23:06:51 +0100 Subject: [PATCH 16/18] larger font for frame stats --- src/emucore/FrameBuffer.cxx | 13 +++++++------ src/emucore/FrameBuffer.hxx | 2 +- 2 files changed, 8 insertions(+), 7 deletions(-) diff --git a/src/emucore/FrameBuffer.cxx b/src/emucore/FrameBuffer.cxx index 15e8428ee..4338cf820 100644 --- a/src/emucore/FrameBuffer.cxx +++ b/src/emucore/FrameBuffer.cxx @@ -232,8 +232,8 @@ FBInitStatus FrameBuffer::createDisplay(const string& title, // Create surfaces for TIA statistics and general messages myStatsMsg.color = kColorInfo; - myStatsMsg.w = infoFont().getMaxCharWidth() * 30 + 2; - myStatsMsg.h = (infoFont().getFontHeight() + 2) * 3; + myStatsMsg.w = font().getMaxCharWidth() * 30 + 3; + myStatsMsg.h = (font().getFontHeight() + 2) * 2; if(!myStatsMsg.surface) { @@ -383,6 +383,7 @@ void FrameBuffer::drawFrameStats() const ConsoleInfo& info = myOSystem.console().about(); char msg[30]; uInt32 color; + const int XPOS = 2, YPOS = 0; myStatsMsg.surface->invalidate(); string bsinfo = info.BankSwitch + @@ -390,7 +391,7 @@ void FrameBuffer::drawFrameStats() // draw shadowed text color = myOSystem.console().tia().scanlinesLastFrame() != myLastScanlines ? kDbgColorRed : myStatsMsg.color; std::snprintf(msg, 30, "%3u", myOSystem.console().tia().scanlinesLastFrame()); - myStatsMsg.surface->drawString(infoFont(), msg, 1, 1, + myStatsMsg.surface->drawString(font(), msg, XPOS, YPOS, myStatsMsg.w, color, TextAlign::Left, 0, true, kBGColor); // draw framerate float frameRate; @@ -417,13 +418,13 @@ void FrameBuffer::drawFrameStats() color = frameRate != myLastFrameRate ? kDbgColorRed : myStatsMsg.color; myLastFrameRate = frameRate; std::snprintf(msg, 30, "@%6.2ffps", frameRate); - myStatsMsg.surface->drawString(infoFont(), msg, 1 + infoFont().getStringWidth("262 "), 1, + myStatsMsg.surface->drawString(font(), msg, XPOS + font().getStringWidth("262 "), YPOS, myStatsMsg.w, color, TextAlign::Left, 0, true, kBGColor); std::snprintf(msg, 30, "=> %s", info.DisplayFormat.c_str()); - myStatsMsg.surface->drawString(infoFont(), msg, 1 + infoFont().getStringWidth("262 @ 60.00fps "), 1, + myStatsMsg.surface->drawString(font(), msg, XPOS + font().getStringWidth("262 @ 60.00fps "), YPOS, myStatsMsg.w, myStatsMsg.color, TextAlign::Left, 0, true, kBGColor); - myStatsMsg.surface->drawString(infoFont(), bsinfo, 1, 15, + myStatsMsg.surface->drawString(font(), bsinfo, XPOS, YPOS + font().getFontHeight(), myStatsMsg.w, myStatsMsg.color, TextAlign::Left, 0, true, kBGColor); myStatsMsg.surface->setDirty(); diff --git a/src/emucore/FrameBuffer.hxx b/src/emucore/FrameBuffer.hxx index f5d6580fd..b49a70c56 100644 --- a/src/emucore/FrameBuffer.hxx +++ b/src/emucore/FrameBuffer.hxx @@ -515,7 +515,7 @@ class FrameBuffer bool myStatsEnabled; uInt32 myLastScanlines; float myLastFrameRate; - + bool myGrabMouse; // The list of all available video modes for this framebuffer From 2d03a2d0599e83ef53353705c41bceac68cf7a05 Mon Sep 17 00:00:00 2001 From: thrust26 Date: Fri, 19 Jan 2018 10:45:29 +0100 Subject: [PATCH 17/18] aligned implementation parameter of handleEvent with definition parameter --- src/emucore/EventHandler.cxx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/emucore/EventHandler.cxx b/src/emucore/EventHandler.cxx index 2db12c0bd..8b0038e1f 100644 --- a/src/emucore/EventHandler.cxx +++ b/src/emucore/EventHandler.cxx @@ -919,7 +919,7 @@ void EventHandler::handleSystemEvent(SystemEvent e, int, int) } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void EventHandler::handleEvent(Event::Type event, int state) +void EventHandler::handleEvent(Event::Type event, Int32 state) { // Take care of special events that aren't part of the emulation core // or need to be preprocessed before passing them on From 1055a4bd067ff20ff952e2b7e3d8ba5fa139d3d3 Mon Sep 17 00:00:00 2001 From: Stephen Anthony Date: Fri, 19 Jan 2018 18:32:11 -0330 Subject: [PATCH 18/18] Minor cleanup of warnings in FrameBuffer class. --- src/emucore/FrameBuffer.cxx | 7 +++---- src/emucore/FrameBuffer.hxx | 3 ++- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/emucore/FrameBuffer.cxx b/src/emucore/FrameBuffer.cxx index 4338cf820..4145b2892 100644 --- a/src/emucore/FrameBuffer.cxx +++ b/src/emucore/FrameBuffer.cxx @@ -46,13 +46,12 @@ FrameBuffer::FrameBuffer(OSystem& osystem) : myOSystem(osystem), myInitializedCount(0), myPausedCount(0), + myStatsEnabled(false), + myLastFrameRate(60), myCurrentModeList(nullptr), myTotalTime(0), - myTotalFrames(0), - myLastFrameRate(60) + myTotalFrames(0) { - myMsg.surface = myStatsMsg.surface = nullptr; - myStatsEnabled = myMsg.enabled = myStatsMsg.enabled = false; } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/emucore/FrameBuffer.hxx b/src/emucore/FrameBuffer.hxx index b49a70c56..eb834815e 100644 --- a/src/emucore/FrameBuffer.hxx +++ b/src/emucore/FrameBuffer.hxx @@ -509,6 +509,8 @@ class FrameBuffer uInt32 color; shared_ptr surface; bool enabled; + + Message() : counter(0), x(0), y(0), w(0), h(0), color(0), enabled(false) { } }; Message myMsg; Message myStatsMsg; @@ -537,7 +539,6 @@ class FrameBuffer uInt64 myTotalTime; uInt64 myTotalFrames; - float myLastRunFrameRate; private: // Following constructors and assignment operators not supported