From 27118f3ed03fb2f53f11835e9afb5e97dfe37760 Mon Sep 17 00:00:00 2001 From: thrust26 Date: Thu, 14 Jan 2021 09:32:39 +0100 Subject: [PATCH 1/3] added option to disable emulation shading in pause mode via command line (resolves #755) --- docs/index.html | 4 ++++ src/emucore/FrameBuffer.cxx | 6 ++++-- src/emucore/Settings.cxx | 2 ++ 3 files changed, 10 insertions(+), 2 deletions(-) diff --git a/docs/index.html b/docs/index.html index cc57d0546..1d11d0eee 100644 --- a/docs/index.html +++ b/docs/index.html @@ -2730,6 +2730,10 @@ indicating serious errors override this setting, and are always shown. + +
-pauseshade <1|0>
+ Enable or disable emulation shading in pause mode. +
-audio.enabled <1|0>
diff --git a/src/emucore/FrameBuffer.cxx b/src/emucore/FrameBuffer.cxx index dbb287220..838c2c445 100644 --- a/src/emucore/FrameBuffer.cxx +++ b/src/emucore/FrameBuffer.cxx @@ -343,14 +343,16 @@ void FrameBuffer::update(UpdateMode mode) case EventHandlerState::PAUSE: { // Show a pause message immediately and then every 7 seconds + bool shade = myOSystem.settings().getBool("pauseshade"); + if(myPausedCount-- <= 0) { myPausedCount = uInt32(7 * myOSystem.frameRate()); showTextMessage("Paused", MessagePosition::MiddleCenter); - myTIASurface->render(true); + myTIASurface->render(shade); } if(rerender) - myTIASurface->render(true); + myTIASurface->render(shade); break; // EventHandlerState::PAUSE } diff --git a/src/emucore/Settings.cxx b/src/emucore/Settings.cxx index 215588c31..948a1e1a8 100644 --- a/src/emucore/Settings.cxx +++ b/src/emucore/Settings.cxx @@ -47,6 +47,7 @@ Settings::Settings() setPermanent("windowedpos", Common::Point(50, 50)); setPermanent("display", 0); setPermanent("uimessages", "true"); + setPermanent("pauseshade", "true"); // TIA specific options setPermanent("tia.inter", "false"); setPermanent("tia.zoom", "3"); @@ -446,6 +447,7 @@ void Settings::usage() const << " -speed Run emulation at the given speed\n" << " -turbo <1|0> Enable 'Turbo' mode for maximum emulation speed\n" << " -uimessages <1|0> Show onscreen UI messages for different events\n" + << " -pauseshade <1|0> Enable emulation shading in pause mode\n" << endl #ifdef SOUND_SUPPORT << " -audio.enabled <1|0> Enable audio\n" From d9c8750d011499ff47b78f15ba37342390e64d10 Mon Sep 17 00:00:00 2001 From: thrust26 Date: Thu, 14 Jan 2021 09:40:02 +0100 Subject: [PATCH 2/3] renamed pause dimming setting --- docs/index.html | 4 ++-- src/emucore/FrameBuffer.cxx | 2 +- src/emucore/Settings.cxx | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/docs/index.html b/docs/index.html index 1d11d0eee..b11f7b770 100644 --- a/docs/index.html +++ b/docs/index.html @@ -2731,8 +2731,8 @@ shown. -
-pauseshade <1|0>
- Enable or disable emulation shading in pause mode. +
-pausedim <1|0>
+ Enable or disable emulation dimming in pause mode. diff --git a/src/emucore/FrameBuffer.cxx b/src/emucore/FrameBuffer.cxx index 838c2c445..967311ed6 100644 --- a/src/emucore/FrameBuffer.cxx +++ b/src/emucore/FrameBuffer.cxx @@ -343,7 +343,7 @@ void FrameBuffer::update(UpdateMode mode) case EventHandlerState::PAUSE: { // Show a pause message immediately and then every 7 seconds - bool shade = myOSystem.settings().getBool("pauseshade"); + bool shade = myOSystem.settings().getBool("pausedim"); if(myPausedCount-- <= 0) { diff --git a/src/emucore/Settings.cxx b/src/emucore/Settings.cxx index 948a1e1a8..bbd1b24b3 100644 --- a/src/emucore/Settings.cxx +++ b/src/emucore/Settings.cxx @@ -47,7 +47,7 @@ Settings::Settings() setPermanent("windowedpos", Common::Point(50, 50)); setPermanent("display", 0); setPermanent("uimessages", "true"); - setPermanent("pauseshade", "true"); + setPermanent("pausedim", "true"); // TIA specific options setPermanent("tia.inter", "false"); setPermanent("tia.zoom", "3"); @@ -447,7 +447,7 @@ void Settings::usage() const << " -speed Run emulation at the given speed\n" << " -turbo <1|0> Enable 'Turbo' mode for maximum emulation speed\n" << " -uimessages <1|0> Show onscreen UI messages for different events\n" - << " -pauseshade <1|0> Enable emulation shading in pause mode\n" + << " -pausedim <1|0> Enable emulation dimming in pause mode\n" << endl #ifdef SOUND_SUPPORT << " -audio.enabled <1|0> Enable audio\n" From fb73d90cf954041e7e188e64880d492b88b51665 Mon Sep 17 00:00:00 2001 From: thrust26 Date: Tue, 19 Jan 2021 10:23:41 +0100 Subject: [PATCH 3/3] refactored Paddles class --- src/emucore/Paddles.cxx | 231 +++++++++++++++++----------------------- src/emucore/Paddles.hxx | 20 ++++ 2 files changed, 119 insertions(+), 132 deletions(-) diff --git a/src/emucore/Paddles.cxx b/src/emucore/Paddles.cxx index 737eb048b..e5e9146ac 100644 --- a/src/emucore/Paddles.cxx +++ b/src/emucore/Paddles.cxx @@ -47,113 +47,50 @@ Paddles::Paddles(Jack jack, const Event& event, const System& system, // Consider whether this is the left or right port if(myJack == Jack::Left) { - if(!swappaddle) // First paddle is 0, second is 1 - { - // These aren't affected by changes in axis orientation - myP0AxisValue = Event::PaddleZeroAnalog; - myP1AxisValue = Event::PaddleOneAnalog; - myP0FireEvent = Event::PaddleZeroFire; - myP1FireEvent = Event::PaddleOneFire; + // First paddle is 0, second is 1 + myP0AxisValue = Event::PaddleZeroAnalog; + myP1AxisValue = Event::PaddleOneAnalog; + myP0FireEvent = Event::PaddleZeroFire; + myP1FireEvent = Event::PaddleOneFire; - // Direction of movement is swapped - // That is, moving in a certain direction on an axis can - // result in either increasing or decreasing paddle movement - if(!swapdir) - { - myP0DecEvent = Event::PaddleZeroDecrease; - myP0IncEvent = Event::PaddleZeroIncrease; - myP1DecEvent = Event::PaddleOneDecrease; - myP1IncEvent = Event::PaddleOneIncrease; - } - else - { - myP0DecEvent = Event::PaddleZeroIncrease; - myP0IncEvent = Event::PaddleZeroDecrease; - myP1DecEvent = Event::PaddleOneIncrease; - myP1IncEvent = Event::PaddleOneDecrease; - } - } - else // First paddle is 1, second is 0 - { - // These aren't affected by changes in axis orientation - myP0AxisValue = Event::PaddleOneAnalog; - myP1AxisValue = Event::PaddleZeroAnalog; - myP0FireEvent = Event::PaddleOneFire; - myP1FireEvent = Event::PaddleZeroFire; - - // Direction of movement is swapped - // That is, moving in a certain direction on an axis can - // result in either increasing or decreasing paddle movement - if(!swapdir) - { - myP0DecEvent = Event::PaddleOneDecrease; - myP0IncEvent = Event::PaddleOneIncrease; - myP1DecEvent = Event::PaddleZeroDecrease; - myP1IncEvent = Event::PaddleZeroIncrease; - } - else - { - myP0DecEvent = Event::PaddleOneIncrease; - myP0IncEvent = Event::PaddleOneDecrease; - myP1DecEvent = Event::PaddleZeroIncrease; - myP1IncEvent = Event::PaddleZeroDecrease; - } - } + // These can be affected by changes in axis orientation + myP0DecEvent = Event::PaddleZeroDecrease; + myP0IncEvent = Event::PaddleZeroIncrease; + myP1DecEvent = Event::PaddleOneDecrease; + myP1IncEvent = Event::PaddleOneIncrease; } else // Jack is right port { - if(!swappaddle) // First paddle is 2, second is 3 - { - // These aren't affected by changes in axis orientation - myP0AxisValue = Event::PaddleTwoAnalog; - myP1AxisValue = Event::PaddleThreeAnalog; - myP0FireEvent = Event::PaddleTwoFire; - myP1FireEvent = Event::PaddleThreeFire; + // First paddle is 2, second is 3 + myP0AxisValue = Event::PaddleTwoAnalog; + myP1AxisValue = Event::PaddleThreeAnalog; + myP0FireEvent = Event::PaddleTwoFire; + myP1FireEvent = Event::PaddleThreeFire; - // Direction of movement is swapped - // That is, moving in a certain direction on an axis can - // result in either increasing or decreasing paddle movement - if(!swapdir) - { - myP0DecEvent = Event::PaddleTwoDecrease; - myP0IncEvent = Event::PaddleTwoIncrease; - myP1DecEvent = Event::PaddleThreeDecrease; - myP1IncEvent = Event::PaddleThreeIncrease; - } - else - { - myP0DecEvent = Event::PaddleTwoIncrease; - myP0IncEvent = Event::PaddleTwoDecrease; - myP1DecEvent = Event::PaddleThreeIncrease; - myP1IncEvent = Event::PaddleThreeDecrease; - } - } - else // First paddle is 3, second is 2 - { - // These aren't affected by changes in axis orientation - myP0AxisValue = Event::PaddleThreeAnalog; - myP1AxisValue = Event::PaddleTwoAnalog; - myP0FireEvent = Event::PaddleThreeFire; - myP1FireEvent = Event::PaddleTwoFire; + // These can be affected by changes in axis orientation + myP0DecEvent = Event::PaddleTwoDecrease; + myP0IncEvent = Event::PaddleTwoIncrease; + myP1DecEvent = Event::PaddleThreeDecrease; + myP1IncEvent = Event::PaddleThreeIncrease; + } - // Direction of movement is swapped - // That is, moving in a certain direction on an axis can - // result in either increasing or decreasing paddle movement - if(!swapdir) - { - myP0DecEvent = Event::PaddleThreeDecrease; - myP0IncEvent = Event::PaddleThreeIncrease; - myP1DecEvent = Event::PaddleTwoDecrease; - myP1IncEvent = Event::PaddleTwoIncrease; - } - else - { - myP0DecEvent = Event::PaddleThreeIncrease; - myP0IncEvent = Event::PaddleThreeDecrease; - myP1DecEvent = Event::PaddleTwoIncrease; - myP1IncEvent = Event::PaddleTwoDecrease; - } - } + // Some games swap the paddles + if(swappaddle) + { + // First paddle is 1|3, second is 0|2 + swapEvents(myP0AxisValue, myP1AxisValue); + swapEvents(myP0FireEvent, myP1FireEvent); + swapEvents(myP0DecEvent, myP1DecEvent); + swapEvents(myP0IncEvent, myP1IncEvent); + } + + // Direction of movement can be swapped + // That is, moving in a certain direction on an axis can + // result in either increasing or decreasing paddle movement + if(swapdir) + { + swapEvents(myP0DecEvent, myP0IncEvent); + swapEvents(myP1DecEvent, myP1IncEvent); } // The following are independent of whether or not the port @@ -179,6 +116,16 @@ Paddles::Paddles(Jack jack, const Event& event, const System& system, setPin(DigitalPin::Six, true); } +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +void Paddles::swapEvents(Event::Type& event1, Event::Type& event2) +{ + Event::Type swappedEvent; + + swappedEvent = event1; + event1 = event2; + event2 = swappedEvent; +} + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - void Paddles::update() { @@ -200,6 +147,31 @@ void Paddles::update() // And to top it all off, we don't want one devices input to conflict // with the others ... + if(!updateAnalogAxes()) + { + updateMouse(firePressedP0, firePressedP1); + updateDigitalAxes(); + + // Only change state if the charge has actually changed + if(myCharge[1] != myLastCharge[1]) + { + setPin(AnalogPin::Five, Int32(MAX_RESISTANCE * (myCharge[1] / double(TRIGMAX)))); + myLastCharge[1] = myCharge[1]; + } + if(myCharge[0] != myLastCharge[0]) + { + setPin(AnalogPin::Nine, Int32(MAX_RESISTANCE * (myCharge[0] / double(TRIGMAX)))); + myLastCharge[0] = myCharge[0]; + } + } + + setPin(DigitalPin::Four, !getAutoFireState(firePressedP0)); + setPin(DigitalPin::Three, !getAutoFireStateP1(firePressedP1)); +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +bool Paddles::updateAnalogAxes() +{ // Analog axis events from Stelladaptor-like devices // These devices generate data in the range -32768 to 32767, // so we have to scale appropriately @@ -207,10 +179,6 @@ void Paddles::update() // we only process the first one we see (when it differs from // previous values by a pre-defined amount) // Otherwise, it would always override input from digital and mouse - bool sa_changed = false; - int sa_xaxis = myEvent.get(myP0AxisValue); - int sa_yaxis = myEvent.get(myP1AxisValue); - int new_val; static constexpr std::array bFac = { // higher values mean more dejitter strength @@ -221,24 +189,28 @@ void Paddles::update() static constexpr std::array dFac = { // lower values mean more dejitter strength 1, // off - 1.0 / 181, 1.0 / 256, 1.0 / 362, 1.0 / 512, 1.0 / 724, + 1.0 / 181, 1.0 / 256, 1.0 / 362, 1.0 / 512, 1.0 / 724, 1.0 / 1024, 1.0 / 1448, 1.0 / 2048, 1.0 / 2896, 1.0 / 4096 }; const double baseFactor = bFac[DEJITTER_BASE]; const double diffFactor = dFac[DEJITTER_DIFF]; + int sa_xaxis = myEvent.get(myP0AxisValue); + int sa_yaxis = myEvent.get(myP1AxisValue); + bool sa_changed = false; + if(abs(myLastAxisX - sa_xaxis) > 10) { // dejitter, suppress small changes only double dejitter = std::pow(baseFactor, abs(sa_xaxis - myLastAxisX) * diffFactor); - new_val = sa_xaxis * (1 - dejitter) + myLastAxisX * dejitter; + int new_val = sa_xaxis * (1 - dejitter) + myLastAxisX * dejitter; // only use new dejittered value for larger differences if(abs(new_val - sa_xaxis) > 10) sa_xaxis = new_val; setPin(AnalogPin::Nine, Int32(MAX_RESISTANCE * - (BSPF::clamp(32768 - Int32(Int32(sa_xaxis) * SENSITIVITY + XCENTER), 0, 65536) / 65536.0))); + (BSPF::clamp(32768 - Int32(Int32(sa_xaxis) * SENSITIVITY + XCENTER), 0, 65536) / 65536.0))); sa_changed = true; } @@ -246,29 +218,33 @@ void Paddles::update() { // dejitter, suppress small changes only double dejitter = std::pow(baseFactor, abs(sa_yaxis - myLastAxisY) * diffFactor); - new_val = sa_yaxis * (1 - dejitter) + myLastAxisY * dejitter; + int new_val = sa_yaxis * (1 - dejitter) + myLastAxisY * dejitter; // only use new dejittered value for larger differences - if (abs(new_val - sa_yaxis) > 10) + if(abs(new_val - sa_yaxis) > 10) sa_yaxis = new_val; setPin(AnalogPin::Five, Int32(MAX_RESISTANCE * - (BSPF::clamp(32768 - Int32(Int32(sa_yaxis) * SENSITIVITY + YCENTER), 0, 65536) / 65536.0))); + (BSPF::clamp(32768 - Int32(Int32(sa_yaxis) * SENSITIVITY + YCENTER), 0, 65536) / 65536.0))); sa_changed = true; } myLastAxisX = sa_xaxis; myLastAxisY = sa_yaxis; - if(sa_changed) - return; + return sa_changed; +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +void Paddles::updateMouse(bool& firePressedP0, bool& firePressedP1) +{ // Mouse motion events give relative movement // That is, they're only relevant if they're non-zero if(myMPaddleID > -1) { // We're in auto mode, where a single axis is used for one paddle only myCharge[myMPaddleID] = BSPF::clamp(myCharge[myMPaddleID] - - (myEvent.get(myAxisMouseMotion) * MOUSE_SENSITIVITY), - TRIGMIN, TRIGRANGE); + (myEvent.get(myAxisMouseMotion) * MOUSE_SENSITIVITY), + TRIGMIN, TRIGRANGE); if(myMPaddleID == 0) firePressedP0 = firePressedP0 || myEvent.get(Event::MouseButtonLeftValue) @@ -285,9 +261,8 @@ void Paddles::update() if(myMPaddleIDX > -1) { myCharge[myMPaddleIDX] = BSPF::clamp(myCharge[myMPaddleIDX] - - (myEvent.get(Event::MouseAxisXMove) * MOUSE_SENSITIVITY), - TRIGMIN, TRIGRANGE); - + (myEvent.get(Event::MouseAxisXMove) * MOUSE_SENSITIVITY), + TRIGMIN, TRIGRANGE); if(myMPaddleIDX == 0) firePressedP0 = firePressedP0 || myEvent.get(Event::MouseButtonLeftValue); @@ -298,9 +273,8 @@ void Paddles::update() if(myMPaddleIDY > -1) { myCharge[myMPaddleIDY] = BSPF::clamp(myCharge[myMPaddleIDY] - - (myEvent.get(Event::MouseAxisYMove) * MOUSE_SENSITIVITY), - TRIGMIN, TRIGRANGE); - + (myEvent.get(Event::MouseAxisYMove) * MOUSE_SENSITIVITY), + TRIGMIN, TRIGRANGE); if(myMPaddleIDY == 0) firePressedP0 = firePressedP0 || myEvent.get(Event::MouseButtonRightValue); @@ -309,9 +283,11 @@ void Paddles::update() || myEvent.get(Event::MouseButtonRightValue); } } - setPin(DigitalPin::Four, !getAutoFireState(firePressedP0)); - setPin(DigitalPin::Three, !getAutoFireStateP1(firePressedP1)); +} +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +void Paddles::updateDigitalAxes() +{ // Finally, consider digital input, where movement happens // until a digital event is released if(myKeyRepeat0) @@ -354,15 +330,6 @@ void Paddles::update() if((myCharge[myAxisDigitalOne] + myPaddleRepeat1) < TRIGRANGE) myCharge[myAxisDigitalOne] += myPaddleRepeat1; } - - // Only change state if the charge has actually changed - if(myCharge[1] != myLastCharge[1]) - setPin(AnalogPin::Five, Int32(MAX_RESISTANCE * (myCharge[1] / double(TRIGMAX)))); - if(myCharge[0] != myLastCharge[0]) - setPin(AnalogPin::Nine, Int32(MAX_RESISTANCE * (myCharge[0] / double(TRIGMAX)))); - - myLastCharge[1] = myCharge[1]; - myLastCharge[0] = myCharge[0]; } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/emucore/Paddles.hxx b/src/emucore/Paddles.hxx index 0ba4cd8c8..ea77de6ad 100644 --- a/src/emucore/Paddles.hxx +++ b/src/emucore/Paddles.hxx @@ -197,6 +197,26 @@ class Paddles : public Controller static int DEJITTER_BASE, DEJITTER_DIFF; static int MOUSE_SENSITIVITY; + /** + Swap two events. + */ + void swapEvents(Event::Type& event1, Event::Type& event2); + + /** + Update the axes pin state according to the events currently set. + */ + bool updateAnalogAxes(); + + /** + Update the entire state according to mouse events currently set. + */ + void updateMouse(bool& firePressedP0, bool& firePressedP1); + + /** + Update the axes pin state according to the keyboard events currently set. + */ + void updateDigitalAxes(); + private: // Following constructors and assignment operators not supported Paddles() = delete;