diff --git a/Changes.txt b/Changes.txt index 6d3b5b2f1..3e0571978 100644 --- a/Changes.txt +++ b/Changes.txt @@ -14,6 +14,8 @@ 6.2.1 to 6.3 (XXXX XX, 2020) + * Added autofire. + * Added new interface palette 'Dark'. (TODO: DOC) * Extended global hotkeys for debug options. diff --git a/docs/graphics/eventmapping_devsports.png b/docs/graphics/eventmapping_devsports.png index ab187595e..55dc205c6 100644 Binary files a/docs/graphics/eventmapping_devsports.png and b/docs/graphics/eventmapping_devsports.png differ diff --git a/docs/index.html b/docs/index.html index 554f2cdbd..a12d7e457 100644 --- a/docs/index.html +++ b/docs/index.html @@ -2379,6 +2379,11 @@ faster movement. + +
-autofirerate <0 - 30>
+ Automatic trigger rate of the fire buttons in Hz (0 = disabled) + +
-joyallow4 <1|0>
Allow all 4 directions on a joystick to be pressed @@ -3302,6 +3307,7 @@ Analog paddle) Dejitter averagingStrength of paddle input averaging, suppresses mouse jitter-dejitter.base (Analog paddle) Dejitter reactionStrength of paddle reaction to fast paddle movements, suppresses mouse jitter-dejitter.diff Digital paddle sensitivitySensitivity used when emulating a paddle using a digital device-dsense + Autofire rateAutomatic trigger rate of the fire buttons in Hz-autofirerate Allow all 4 directions ...Allow all 4 joystick directions to be pressed simultaneously-joyallow4 Use modifier key combosEnable using modifier keys in keyboard actions-modcombo Swap Stelladaptor portsSwap the order of the detected Stelladaptors/2600-daptors (see Advanced Configuration - Stelladaptor/2600-daptor Support)-saport diff --git a/src/common/PKeyboardHandler.cxx b/src/common/PKeyboardHandler.cxx index f5d39b20a..6d726f3fc 100644 --- a/src/common/PKeyboardHandler.cxx +++ b/src/common/PKeyboardHandler.cxx @@ -534,6 +534,9 @@ PhysicalKeyboardHandler::EventMappingArray PhysicalKeyboardHandler::DefaultCommo {Event::ToggleContSnapshots, KBDK_S, MOD3}, {Event::ToggleContSnapshotsFrame, KBDK_S, KBDM_SHIFT | MOD3}, #endif + + {Event::DecreaseAutoFire, KBDK_A, KBDM_SHIFT | KBDM_CTRL}, + {Event::IncreaseAutoFire, KBDK_A, KBDM_CTRL }, {Event::HandleMouseControl, KBDK_0, KBDM_CTRL}, {Event::ToggleGrabMouse, KBDK_G, KBDM_CTRL}, {Event::ToggleSAPortOrder, KBDK_1, KBDM_CTRL}, diff --git a/src/emucore/Booster.cxx b/src/emucore/Booster.cxx index fddd51c21..96d328b8a 100644 --- a/src/emucore/Booster.cxx +++ b/src/emucore/Booster.cxx @@ -59,7 +59,7 @@ void BoosterGrip::update() setPin(DigitalPin::Two, myEvent.get(myDownEvent) == 0); setPin(DigitalPin::Three, myEvent.get(myLeftEvent) == 0); setPin(DigitalPin::Four, myEvent.get(myRightEvent) == 0); - setPin(DigitalPin::Six, myEvent.get(myFireEvent) == 0); + bool firePressed = myEvent.get(myFireEvent) != 0; // The CBS Booster-grip has two more buttons on it. These buttons are // connected to the inputs usually used by paddles. @@ -120,11 +120,12 @@ void BoosterGrip::update() } } // Get mouse button state - if(myEvent.get(Event::MouseButtonLeftValue)) - setPin(DigitalPin::Six, false); + firePressed = firePressed + || myEvent.get(Event::MouseButtonLeftValue); if(myEvent.get(Event::MouseButtonRightValue)) setPin(AnalogPin::Nine, MIN_RESISTANCE); } + setPin(DigitalPin::Six, !getAutoFireState(firePressed)); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/emucore/Console.cxx b/src/emucore/Console.cxx index be2907fe9..dd9146ac9 100644 --- a/src/emucore/Console.cxx +++ b/src/emucore/Console.cxx @@ -434,7 +434,7 @@ void Console::setFormat(uInt32 format, bool force) setTIAProperties(); initializeVideo(); // takes care of refreshing the screen - initializeAudio(); // ensure that audio synthesis is set up to match emulation speed + initializeAudio(); // ensure that audio synthesis is set up to match emulation rate myOSystem.resetFps(); // Reset FPS measurement myOSystem.frameBuffer().showMessage(message); @@ -492,7 +492,7 @@ void Console::toggleTurbo() myOSystem.settings().setValue("turbo", !enabled); - // update speed + // update rate initializeAudio(); // update VSync @@ -870,6 +870,30 @@ unique_ptr Console::getControllerPort(const Controller::Type type, return controller; } +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +void Console::changeAutoFireRate(int direction) +{ + const Int32 scanlines = std::max(tia().scanlinesLastFrame(), 240); + const bool isNTSC = scanlines <= 287; + + int rate = myOSystem.settings().getInt("autofirerate"); + + rate = BSPF::clamp(rate + direction, 0, isNTSC ? 30 : 25); + + myOSystem.settings().setValue("autofirerate", rate); + Controller::setAutoFireRate(rate); + + ostringstream val; + + if(rate) + val << rate << " Hz"; + else + { + val << "Off"; + } + myOSystem.frameBuffer().showMessage("Autofire rate", val.str(), rate, 0, isNTSC ? 30 : 25); +} + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - float Console::getFramerate() const { diff --git a/src/emucore/Console.hxx b/src/emucore/Console.hxx index 1cc37fc0b..86595da9f 100644 --- a/src/emucore/Console.hxx +++ b/src/emucore/Console.hxx @@ -318,6 +318,11 @@ class Console : public Serializable, public ConsoleIO */ void setTIAProperties(); + /** + Change the autofire speed for all controllers + */ + void changeAutoFireRate(int direction = +1); + private: /** * Define console timing based on current display format diff --git a/src/emucore/Control.cxx b/src/emucore/Control.cxx index 0584626de..813063c04 100644 --- a/src/emucore/Control.cxx +++ b/src/emucore/Control.cxx @@ -147,3 +147,14 @@ Controller::Type Controller::getType(const string& propName) return Type::Unknown; } + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +void Controller::setAutoFireRate(int rate, bool isNTSC) +{ + rate = BSPF::clamp(rate, 0, isNTSC ? 30 : 25); + AUTO_FIRE_RATE = 32 * 1024 * rate / (isNTSC ? 60 : 50); +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +int Controller::AUTO_FIRE_RATE = 0; + diff --git a/src/emucore/Control.hxx b/src/emucore/Control.hxx index a670f39f6..aa7e2aed3 100644 --- a/src/emucore/Control.hxx +++ b/src/emucore/Control.hxx @@ -272,6 +272,14 @@ class Controller : public Serializable */ static Type getType(const string& propName); + /** + Sets the auto fire rate. 0 disables auto fire. + + @param speed Auto fire rate (0..30/25) in Hz + @param isNTSC NTSC or PAL frame rate + */ + static void setAutoFireRate(int rate, bool isNTSC = true); + public: /// Constant which represents maximum resistance for analog pins static constexpr Int32 MAX_RESISTANCE = 0x7FFFFFFF; @@ -310,6 +318,44 @@ class Controller : public Serializable setPin(AnalogPin::Nine, MAX_RESISTANCE); } + /** + Checks for the next auto fire event. + + @param pressed True if the fire button is current pressed + @return The result of the auto fire event check + */ + inline bool getAutoFireState(bool pressed) + { + if(AUTO_FIRE_RATE && pressed) + { + myFireDelay -= AUTO_FIRE_RATE; + if(myFireDelay <= 0) + myFireDelay += 32 * 1024; + return myFireDelay > 16 * 1024; + } + myFireDelay = 0; + return pressed; + } + + /** + Checks for the next auto fire event for paddle 1. + + @param pressed True if the fire button is current pressed + @return The result of the auto fire event check + */ + inline bool getAutoFireStateP1(bool pressed) + { + if(AUTO_FIRE_RATE && pressed) + { + myFireDelayP1 -= AUTO_FIRE_RATE; + if(myFireDelayP1 <= 0) + myFireDelayP1 += 32 * 1024; + return myFireDelayP1 > 16 * 1024; + } + myFireDelayP1 = 0; + return pressed; + } + protected: /// Specifies which jack the controller is plugged in const Jack myJack; @@ -326,6 +372,13 @@ class Controller : public Serializable /// The callback that is dispatched whenver an analog pin has changed onAnalogPinUpdateCallback myOnAnalogPinUpdateCallback{nullptr}; + /// Defines the speed of the auto fire + static int AUTO_FIRE_RATE; + + /// Delay[frames] until the next fire event + int myFireDelay{0}; + int myFireDelayP1{0}; // required for paddles only + private: /// The boolean value on each digital pin std::array myDigitalPinState{true, true, true, true, true}; diff --git a/src/emucore/Driving.cxx b/src/emucore/Driving.cxx index 83f27e336..bd08a03e0 100644 --- a/src/emucore/Driving.cxx +++ b/src/emucore/Driving.cxx @@ -50,7 +50,8 @@ Driving::Driving(Jack jack, const Event& event, const System& system) void Driving::update() { // Digital events (from keyboard or joystick hats & buttons) - setPin(DigitalPin::Six, myEvent.get(myFireEvent) == 0); + bool firePressed = myEvent.get(myFireEvent) != 0; + int d_axis = myEvent.get(myXAxisValue); if(myEvent.get(myCCWEvent) != 0 || d_axis < -16384) --myCounter; else if(myEvent.get(myCWEvent) != 0 || d_axis > 16384) ++myCounter; @@ -61,9 +62,9 @@ void Driving::update() int m_axis = myEvent.get(Event::MouseAxisXMove); if(m_axis < -2) --myCounter; else if(m_axis > 2) ++myCounter; - if(myEvent.get(Event::MouseButtonLeftValue) || - myEvent.get(Event::MouseButtonRightValue)) - setPin(DigitalPin::Six, false); + firePressed = firePressed + || myEvent.get(Event::MouseButtonLeftValue) + || myEvent.get(Event::MouseButtonRightValue); } else { @@ -74,18 +75,19 @@ void Driving::update() int m_axis = myEvent.get(Event::MouseAxisXMove); if(m_axis < -2) --myCounter; else if(m_axis > 2) ++myCounter; - if(myEvent.get(Event::MouseButtonLeftValue)) - setPin(DigitalPin::Six, false); + firePressed = firePressed + || myEvent.get(Event::MouseButtonLeftValue); } if(myControlIDY > -1) { int m_axis = myEvent.get(Event::MouseAxisYMove); if(m_axis < -2) --myCounter; else if(m_axis > 2) ++myCounter; - if(myEvent.get(Event::MouseButtonRightValue)) - setPin(DigitalPin::Six, false); + firePressed = firePressed + || myEvent.get(Event::MouseButtonRightValue); } } + setPin(DigitalPin::Six, !getAutoFireState(firePressed)); // Only consider the lower-most bits (corresponding to pins 1 & 2) myGrayIndex = Int32(myCounter * SENSITIVITY / 4.0F) & 0b11; diff --git a/src/emucore/Event.hxx b/src/emucore/Event.hxx index 010007c72..b9a301e7f 100644 --- a/src/emucore/Event.hxx +++ b/src/emucore/Event.hxx @@ -126,6 +126,7 @@ class Event // add new events from here to avoid that user remapped events get overwritten PreviousSettingGroup, NextSettingGroup, TogglePlayBackMode, + DecreaseAutoFire, IncreaseAutoFire, LastType }; diff --git a/src/emucore/EventHandler.cxx b/src/emucore/EventHandler.cxx index 5dbd2ca2f..6e6f38b50 100644 --- a/src/emucore/EventHandler.cxx +++ b/src/emucore/EventHandler.cxx @@ -102,6 +102,7 @@ void EventHandler::initialize() Paddles::setMouseSensitivity(myOSystem.settings().getInt("msense")); PointingDevice::setSensitivity(myOSystem.settings().getInt("tsense")); Driving::setSensitivity(myOSystem.settings().getInt("dcsense")); + Controller::setAutoFireRate(myOSystem.settings().getInt("autofirerate")); #ifdef GUI_SUPPORT // Set quick select delay when typing characters in listwidgets @@ -1249,6 +1250,14 @@ void EventHandler::handleEvent(Event::Type event, Int32 value, bool repeated) return; #endif + case Event::DecreaseAutoFire: + if(pressed) myOSystem.console().changeAutoFireRate(-1); + return; + + case Event::IncreaseAutoFire: + if(pressed) myOSystem.console().changeAutoFireRate(+1); + return; + case Event::HandleMouseControl: if (pressed && !repeated) handleMouseControl(); return; @@ -2558,6 +2567,8 @@ EventHandler::EmulActionList EventHandler::ourEmulActionList = { { { Event::VolumeDecrease, "Decrease volume", "" }, { Event::VolumeIncrease, "Increase volume", "" }, + { Event::DecreaseAutoFire, "Decrease auto fire speed", "" }, + { Event::IncreaseAutoFire, "Increase auto fire speed", "" }, { Event::HandleMouseControl, "Switch mouse emulation modes", "" }, { Event::ToggleGrabMouse, "Toggle grab mouse", "" }, { Event::ToggleSAPortOrder, "Swap Stelladaptor port ordering", "" }, @@ -2627,6 +2638,7 @@ const Event::EventSet EventHandler::MiscEvents = { Event::TakeSnapshot, Event::ToggleContSnapshots, Event::ToggleContSnapshotsFrame, // Event::MouseAxisXMove, Event::MouseAxisYMove, // Event::MouseButtonLeftValue, Event::MouseButtonRightValue, + Event::DecreaseAutoFire, Event::IncreaseAutoFire, Event::HandleMouseControl, Event::ToggleGrabMouse, Event::ToggleSAPortOrder, Event::PreviousMultiCartRom, Event::PreviousSettingGroup, Event::NextSettingGroup, diff --git a/src/emucore/EventHandler.hxx b/src/emucore/EventHandler.hxx index 3f780b150..055d56d64 100644 --- a/src/emucore/EventHandler.hxx +++ b/src/emucore/EventHandler.hxx @@ -558,7 +558,7 @@ class EventHandler #else REFRESH_SIZE = 0, #endif - EMUL_ACTIONLIST_SIZE = 160 + PNG_SIZE + COMBO_SIZE + REFRESH_SIZE, + EMUL_ACTIONLIST_SIZE = 162 + PNG_SIZE + COMBO_SIZE + REFRESH_SIZE, MENU_ACTIONLIST_SIZE = 18 ; diff --git a/src/emucore/Genesis.cxx b/src/emucore/Genesis.cxx index 488f04980..0b1ef7a2f 100644 --- a/src/emucore/Genesis.cxx +++ b/src/emucore/Genesis.cxx @@ -53,7 +53,7 @@ void Genesis::update() setPin(DigitalPin::Two, myEvent.get(myDownEvent) == 0); setPin(DigitalPin::Three, myEvent.get(myLeftEvent) == 0); setPin(DigitalPin::Four, myEvent.get(myRightEvent) == 0); - setPin(DigitalPin::Six, myEvent.get(myFire1Event) == 0); + bool firePressed = myEvent.get(myFire1Event) != 0; // The Genesis has one more button (C) that can be read by the 2600 // However, it seems to work opposite to the BoosterGrip controller, @@ -88,11 +88,12 @@ void Genesis::update() } } // Get mouse button state - if(myEvent.get(Event::MouseButtonLeftValue)) - setPin(DigitalPin::Six, false); + firePressed = firePressed + || myEvent.get(Event::MouseButtonLeftValue); if(myEvent.get(Event::MouseButtonRightValue)) setPin(AnalogPin::Five, MAX_RESISTANCE); } + setPin(DigitalPin::Six, !getAutoFireState(firePressed)); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/emucore/Joystick.cxx b/src/emucore/Joystick.cxx index f9ee75545..ea0d71300 100644 --- a/src/emucore/Joystick.cxx +++ b/src/emucore/Joystick.cxx @@ -52,7 +52,7 @@ void Joystick::update() setPin(DigitalPin::Two, myEvent.get(myDownEvent) == 0); setPin(DigitalPin::Three, myEvent.get(myLeftEvent) == 0); setPin(DigitalPin::Four, myEvent.get(myRightEvent) == 0); - setPin(DigitalPin::Six, myEvent.get(myFireEvent) == 0); + bool firePressed = myEvent.get(myFireEvent) != 0; // Axis events (usually generated by the Stelladaptor) int xaxis = myEvent.get(myXAxisValue); @@ -102,10 +102,11 @@ void Joystick::update() } } // Get mouse button state - if(myEvent.get(Event::MouseButtonLeftValue) || - myEvent.get(Event::MouseButtonRightValue)) - setPin(DigitalPin::Six, false); + firePressed = firePressed + || myEvent.get(Event::MouseButtonLeftValue) + || myEvent.get(Event::MouseButtonRightValue); } + setPin(DigitalPin::Six, !getAutoFireState(firePressed)); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/emucore/Lightgun.cxx b/src/emucore/Lightgun.cxx index 1c6c82ba7..3ae39d8e5 100644 --- a/src/emucore/Lightgun.cxx +++ b/src/emucore/Lightgun.cxx @@ -116,10 +116,12 @@ bool Lightgun::read(DigitalPin pin) void Lightgun::update() { // Digital events (from keyboard or joystick hats & buttons) - setPin(DigitalPin::One, myEvent.get(Event::JoystickZeroFire) == 0); + bool firePressed = myEvent.get(Event::JoystickZeroFire) != 0; // We allow left and right mouse buttons for fire button - if(myEvent.get(Event::MouseButtonLeftValue) || - myEvent.get(Event::MouseButtonRightValue)) - setPin(DigitalPin::One, false); + firePressed = firePressed + || myEvent.get(Event::MouseButtonLeftValue) + || myEvent.get(Event::MouseButtonRightValue); + + setPin(DigitalPin::One, !getAutoFireState(firePressed)); } diff --git a/src/emucore/Paddles.cxx b/src/emucore/Paddles.cxx index 31ba8875d..a7f72ce1d 100644 --- a/src/emucore/Paddles.cxx +++ b/src/emucore/Paddles.cxx @@ -186,8 +186,8 @@ void Paddles::update() setPin(DigitalPin::Four, true); // Digital events (from keyboard or joystick hats & buttons) - setPin(DigitalPin::Three, myEvent.get(myP1FireEvent) == 0); - setPin(DigitalPin::Four, myEvent.get(myP0FireEvent) == 0); + bool firePressedP0 = myEvent.get(myP0FireEvent) != 0; + bool firePressedP1 = myEvent.get(myP1FireEvent) != 0; // Paddle movement is a very difficult thing to accurately emulate, // since it originally came from an analog device that had very @@ -269,9 +269,14 @@ void Paddles::update() myCharge[myMPaddleID] = BSPF::clamp(myCharge[myMPaddleID] - (myEvent.get(myAxisMouseMotion) * MOUSE_SENSITIVITY), TRIGMIN, TRIGRANGE); - if(myEvent.get(Event::MouseButtonLeftValue) || - myEvent.get(Event::MouseButtonRightValue)) - setPin(ourButtonPin[myMPaddleID], false); + if(myMPaddleID == 0) + firePressedP0 = firePressedP0 + || myEvent.get(Event::MouseButtonLeftValue) + || myEvent.get(Event::MouseButtonRightValue); + else + firePressedP1 = firePressedP1 + || myEvent.get(Event::MouseButtonLeftValue) + || myEvent.get(Event::MouseButtonRightValue); } else { @@ -282,18 +287,30 @@ void Paddles::update() myCharge[myMPaddleIDX] = BSPF::clamp(myCharge[myMPaddleIDX] - (myEvent.get(Event::MouseAxisXMove) * MOUSE_SENSITIVITY), TRIGMIN, TRIGRANGE); - if(myEvent.get(Event::MouseButtonLeftValue)) - setPin(ourButtonPin[myMPaddleIDX], false); + + if(myMPaddleIDX == 0) + firePressedP0 = firePressedP0 + || myEvent.get(Event::MouseButtonLeftValue); + else + firePressedP1 = firePressedP1 + || myEvent.get(Event::MouseButtonLeftValue); } if(myMPaddleIDY > -1) { myCharge[myMPaddleIDY] = BSPF::clamp(myCharge[myMPaddleIDY] - (myEvent.get(Event::MouseAxisYMove) * MOUSE_SENSITIVITY), TRIGMIN, TRIGRANGE); - if(myEvent.get(Event::MouseButtonRightValue)) - setPin(ourButtonPin[myMPaddleIDY], false); + + if(myMPaddleIDY == 0) + firePressedP0 = firePressedP0 + || myEvent.get(Event::MouseButtonRightValue); + else + firePressedP1 = firePressedP1 + || myEvent.get(Event::MouseButtonRightValue); } } + setPin(DigitalPin::Four, !getAutoFireState(firePressedP0)); + setPin(DigitalPin::Three, !getAutoFireStateP1(firePressedP1)); // Finally, consider digital input, where movement happens // until a digital event is released @@ -449,8 +466,3 @@ int Paddles::DIGITAL_DISTANCE = -1; int Paddles::MOUSE_SENSITIVITY = -1; int Paddles::DEJITTER_BASE = 0; int Paddles::DEJITTER_DIFF = 0; - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -const std::array Paddles::ourButtonPin = { - DigitalPin::Four, DigitalPin::Three -}; diff --git a/src/emucore/Paddles.hxx b/src/emucore/Paddles.hxx index 57acda958..bb8144b21 100644 --- a/src/emucore/Paddles.hxx +++ b/src/emucore/Paddles.hxx @@ -190,10 +190,6 @@ class Paddles : public Controller static int DEJITTER_BASE, DEJITTER_DIFF; static int MOUSE_SENSITIVITY; - // Lookup table for associating paddle buttons with controller pins - // Yes, this is hideously complex - static const std::array ourButtonPin; - private: // Following constructors and assignment operators not supported Paddles() = delete; diff --git a/src/emucore/PointingDevice.cxx b/src/emucore/PointingDevice.cxx index 4d91d010c..05cf7c031 100644 --- a/src/emucore/PointingDevice.cxx +++ b/src/emucore/PointingDevice.cxx @@ -92,9 +92,8 @@ void PointingDevice::update() setPin(DigitalPin::Six, myEvent.get(Event::JoystickZeroFire) == 0); // We allow left and right mouse buttons for fire button - if(myEvent.get(Event::MouseButtonLeftValue) || - myEvent.get(Event::MouseButtonRightValue)) - setPin(DigitalPin::Six, false); + setPin(DigitalPin::Six, !getAutoFireState( + myEvent.get(Event::MouseButtonLeftValue) || myEvent.get(Event::MouseButtonRightValue))); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/emucore/Settings.cxx b/src/emucore/Settings.cxx index 0c5073d45..0ccc7ebd5 100644 --- a/src/emucore/Settings.cxx +++ b/src/emucore/Settings.cxx @@ -100,6 +100,7 @@ Settings::Settings() setPermanent("combomap", ""); setPermanent("joydeadzone", "13"); setPermanent("joyallow4", "false"); + setPermanent("autofirerate", "0"); setPermanent("usemouse", "analog"); setPermanent("grabmouse", "true"); setPermanent("cursor", "2"); @@ -481,6 +482,7 @@ void Settings::usage() const << " -tsense <1-20> Sensitivity of mouse emulated trackball movement\n" << " -dcsense <1-20> Sensitivity of digital emulated driving controller\n" << " movement\n" + << " -autofirerate <0-30> Set fire button's autofire rate (0 means off)\n" << " -saport How to assign virtual ports to multiple\n" << " Stelladaptor/2600-daptors\n" << " -modcombo <1|0> Enable modifer key combos\n" diff --git a/src/gui/InputDialog.cxx b/src/gui/InputDialog.cxx index 3cced561b..4e792348c 100644 --- a/src/gui/InputDialog.cxx +++ b/src/gui/InputDialog.cxx @@ -134,7 +134,7 @@ void InputDialog::addDevicePortTab() xpos += fontWidth * 2; // Add analog paddle sensitivity - ypos += lineHeight + VGAP; + ypos += lineHeight; myPaddleSpeed = new SliderWidget(myTab, _font, xpos, ypos - 1, 13 * fontWidth, lineHeight, "Sensitivity", lwidth - fontWidth * 2, kPSpeedChanged, 4 * fontWidth, "%"); @@ -172,6 +172,14 @@ void InputDialog::addDevicePortTab() myDPaddleSpeed->setTickmarkIntervals(4); wid.push_back(myDPaddleSpeed); + ypos += lineHeight + VGAP * 4; + myAutoFireRate = new SliderWidget(myTab, _font, HBORDER, ypos - 1, 13 * fontWidth, lineHeight, + "Autofire rate", + lwidth, kAutoFireChanged, 5 * fontWidth, "Hz"); + myAutoFireRate->setMinValue(0); myAutoFireRate->setMaxValue(30); + myAutoFireRate->setTickmarkIntervals(6); + wid.push_back(myAutoFireRate); + // Add 'allow all 4 directions' for joystick ypos += lineHeight + VGAP * 4; myAllowAll4 = new CheckboxWidget(myTab, _font, HBORDER, ypos, @@ -315,38 +323,43 @@ void InputDialog::addMouseTab() // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - void InputDialog::loadConfig() { + Settings& settings = instance().settings(); + // Left & right ports - mySAPort->setState(instance().settings().getString("saport") == "rl"); + mySAPort->setState(settings.getString("saport") == "rl"); // Use mouse as a controller myMouseControl->setSelected( - instance().settings().getString("usemouse"), "analog"); + settings.getString("usemouse"), "analog"); handleMouseControlState(); // Mouse cursor state - myCursorState->setSelected(instance().settings().getString("cursor"), "2"); + myCursorState->setSelected(settings.getString("cursor"), "2"); handleCursorState(); // Joystick deadzone - myDeadzone->setValue(instance().settings().getInt("joydeadzone")); + myDeadzone->setValue(settings.getInt("joydeadzone")); // Paddle speed (analog) - myPaddleSpeed->setValue(instance().settings().getInt("psense")); + myPaddleSpeed->setValue(settings.getInt("psense")); // Paddle dejitter (analog) - myDejitterBase->setValue(instance().settings().getInt("dejitter.base")); - myDejitterDiff->setValue(instance().settings().getInt("dejitter.diff")); + myDejitterBase->setValue(settings.getInt("dejitter.base")); + myDejitterDiff->setValue(settings.getInt("dejitter.diff")); // Paddle speed (digital and mouse) - myDPaddleSpeed->setValue(instance().settings().getInt("dsense")); - myMPaddleSpeed->setValue(instance().settings().getInt("msense")); + myDPaddleSpeed->setValue(settings.getInt("dsense")); + myMPaddleSpeed->setValue(settings.getInt("msense")); // Trackball speed - myTrackBallSpeed->setValue(instance().settings().getInt("tsense")); + myTrackBallSpeed->setValue(settings.getInt("tsense")); // Driving controller speed - myDrivingSpeed->setValue(instance().settings().getInt("dcsense")); + myDrivingSpeed->setValue(settings.getInt("dcsense")); + + // Autofire rate + myAutoFireRate->setValue(settings.getInt("autofirerate")); // AtariVox serial port - myAVoxPort->setText(instance().settings().getString("avoxport")); + myAVoxPort->setText(settings.getString("avoxport")); // EEPROM erase (only enable in emulation mode and for valid controllers) if(instance().hasConsole()) @@ -361,13 +374,13 @@ void InputDialog::loadConfig() myEraseEEPROMButton->setEnabled(false); // Allow all 4 joystick directions - myAllowAll4->setState(instance().settings().getBool("joyallow4")); + myAllowAll4->setState(settings.getBool("joyallow4")); // Grab mouse - myGrabMouse->setState(instance().settings().getBool("grabmouse")); + myGrabMouse->setState(settings.getBool("grabmouse")); // Enable/disable modifier key-combos - myModCombo->setState(instance().settings().getBool("modcombo")); + myModCombo->setState(settings.getBool("modcombo")); myTab->loadConfig(); } @@ -375,70 +388,77 @@ void InputDialog::loadConfig() // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - void InputDialog::saveConfig() { + Settings& settings = instance().settings(); + // Left & right ports instance().eventHandler().mapStelladaptors(mySAPort->getState() ? "rl": "lr"); // Use mouse as a controller const string& usemouse = myMouseControl->getSelectedTag().toString(); - instance().settings().setValue("usemouse", usemouse); + settings.setValue("usemouse", usemouse); instance().eventHandler().setMouseControllerMode(usemouse); // Joystick deadzone int deadzone = myDeadzone->getValue(); - instance().settings().setValue("joydeadzone", deadzone); + settings.setValue("joydeadzone", deadzone); Joystick::setDeadZone(deadzone); // Paddle speed (analog) int sensitivity = myPaddleSpeed->getValue(); - instance().settings().setValue("psense", sensitivity); + settings.setValue("psense", sensitivity); Paddles::setAnalogSensitivity(sensitivity); // Paddle speed (digital and mouse) int dejitter = myDejitterBase->getValue(); - instance().settings().setValue("dejitter.base", dejitter); + settings.setValue("dejitter.base", dejitter); Paddles::setDejitterBase(dejitter); dejitter = myDejitterDiff->getValue(); - instance().settings().setValue("dejitter.diff", dejitter); + settings.setValue("dejitter.diff", dejitter); Paddles::setDejitterDiff(dejitter); sensitivity = myDPaddleSpeed->getValue(); - instance().settings().setValue("dsense", sensitivity); + settings.setValue("dsense", sensitivity); Paddles::setDigitalSensitivity(sensitivity); sensitivity = myMPaddleSpeed->getValue(); - instance().settings().setValue("msense", sensitivity); + settings.setValue("msense", sensitivity); Paddles::setMouseSensitivity(sensitivity); // Trackball speed sensitivity = myTrackBallSpeed->getValue(); - instance().settings().setValue("tsense", sensitivity); + settings.setValue("tsense", sensitivity); PointingDevice::setSensitivity(sensitivity); // Driving controller speed sensitivity = myDrivingSpeed->getValue(); - instance().settings().setValue("dcsense", sensitivity); + settings.setValue("dcsense", sensitivity); Driving::setSensitivity(sensitivity); + // Autofire rate + int rate = myAutoFireRate->getValue(); + settings.setValue("autofirerate", rate); + Controller::setAutoFireRate(rate); + // AtariVox serial port - instance().settings().setValue("avoxport", myAVoxPort->getText()); + settings.setValue("avoxport", myAVoxPort->getText()); // Allow all 4 joystick directions bool allowall4 = myAllowAll4->getState(); - instance().settings().setValue("joyallow4", allowall4); + settings.setValue("joyallow4", allowall4); instance().eventHandler().allowAllDirections(allowall4); // Grab mouse and hide cursor const string& cursor = myCursorState->getSelectedTag().toString(); - instance().settings().setValue("cursor", cursor); + settings.setValue("cursor", cursor); // only allow grab mouse if cursor is hidden in emulation int state = myCursorState->getSelected(); bool enableGrab = state != 1 && state != 3; bool grab = enableGrab ? myGrabMouse->getState() : false; - instance().settings().setValue("grabmouse", grab); + settings.setValue("grabmouse", grab); instance().frameBuffer().enableGrabMouse(grab); // Enable/disable modifier key-combos - instance().settings().setValue("modcombo", myModCombo->getState()); + settings.setValue("modcombo", myModCombo->getState()); instance().eventHandler().saveKeyMapping(); instance().eventHandler().saveJoyMapping(); @@ -477,6 +497,8 @@ void InputDialog::setDefaults() myDejitterBase->setValue(0); myDejitterDiff->setValue(0); #endif + // Autofire rate + myAutoFireRate->setValue(0); // AtariVox serial port myAVoxPort->setText(""); @@ -659,6 +681,10 @@ void InputDialog::handleCommand(CommandSender* sender, int cmd, myTrackBallSpeed->setValueLabel(myTrackBallSpeed->getValue() * 10); break; + case kAutoFireChanged: + updateAutoFireRate(); + break; + case kDBButtonPressed: if(!myJoyDialog) { @@ -726,6 +752,15 @@ void InputDialog::updateDejitterReaction() myDejitterDiff->setValueLabel(strength ? std::to_string(strength) : "Off"); } +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +void InputDialog::updateAutoFireRate() +{ + int rate = myAutoFireRate->getValue(); + + myAutoFireRate->setValueLabel(rate ? std::to_string(rate) : "Off"); + myAutoFireRate->setValueUnit(rate ? " Hz" : ""); +} + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - void InputDialog::handleMouseControlState() { diff --git a/src/gui/InputDialog.hxx b/src/gui/InputDialog.hxx index 48e1629a3..6893d2c43 100644 --- a/src/gui/InputDialog.hxx +++ b/src/gui/InputDialog.hxx @@ -66,6 +66,7 @@ class InputDialog : public Dialog void handleCursorState(); void updateDejitterAveraging(); void updateDejitterReaction(); + void updateAutoFireRate(); void eraseEEPROM(); private: @@ -75,6 +76,7 @@ class InputDialog : public Dialog kDejitterAvChanged = 'JAch', kDejitterReChanged = 'JRch', kDPSpeedChanged = 'PDch', + kAutoFireChanged = 'AFch', kTBSpeedChanged = 'TBch', kDCSpeedChanged = 'DCch', kDBButtonPressed = 'DBbp', @@ -99,6 +101,7 @@ class InputDialog : public Dialog SliderWidget* myDejitterBase{nullptr}; SliderWidget* myDejitterDiff{nullptr}; SliderWidget* myDPaddleSpeed{nullptr}; + SliderWidget* myAutoFireRate{nullptr}; CheckboxWidget* myAllowAll4{nullptr}; CheckboxWidget* myModCombo{nullptr};