mirror of https://github.com/stella-emu/stella.git
added autofire (resolves #676)
This commit is contained in:
parent
78419f10d6
commit
41f501868a
|
@ -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.
|
||||
|
|
Binary file not shown.
Before Width: | Height: | Size: 7.2 KiB After Width: | Height: | Size: 4.4 KiB |
|
@ -2379,6 +2379,11 @@
|
|||
faster movement.</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td><pre>-autofirerate <0 - 30></pre></td>
|
||||
<td>Automatic trigger rate of the fire buttons in Hz (0 = disabled)</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td><pre>-joyallow4 <1|0></pre></td>
|
||||
<td>Allow all 4 directions on a joystick to be pressed
|
||||
|
@ -3302,6 +3307,7 @@
|
|||
<tr><td>Analog paddle) Dejitter averaging</td><td>Strength of paddle input averaging, suppresses mouse jitter</td><td>-dejitter.base</td></tr>
|
||||
<tr><td>(Analog paddle) Dejitter reaction</td><td>Strength of paddle reaction to fast paddle movements, suppresses mouse jitter</td><td>-dejitter.diff</td></tr>
|
||||
<tr><td>Digital paddle sensitivity</td><td>Sensitivity used when emulating a paddle using a digital device</td><td>-dsense</td></tr>
|
||||
<tr><td>Autofire rate</td><td>Automatic trigger rate of the fire buttons in Hz</td><td>-autofirerate</td></tr>
|
||||
<tr><td>Allow all 4 directions ...</td><td>Allow all 4 joystick directions to be pressed simultaneously</td><td>-joyallow4</td></tr>
|
||||
<tr><td>Use modifier key combos</td><td>Enable using modifier keys in keyboard actions</td><td>-modcombo</td></tr>
|
||||
<tr><td>Swap Stelladaptor ports</td><td>Swap the order of the detected Stelladaptors/2600-daptors (see <b>Advanced Configuration - <a href="#Adaptor">Stelladaptor/2600-daptor Support</a></b>)</td><td>-saport</td></tr>
|
||||
|
|
|
@ -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},
|
||||
|
|
|
@ -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));
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
|
|
|
@ -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<Controller> Console::getControllerPort(const Controller::Type type,
|
|||
return controller;
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void Console::changeAutoFireRate(int direction)
|
||||
{
|
||||
const Int32 scanlines = std::max<Int32>(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
|
||||
{
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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<bool, 5> myDigitalPinState{true, true, true, true, true};
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
};
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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
|
||||
;
|
||||
|
||||
|
|
|
@ -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));
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
|
|
|
@ -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));
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
|
|
|
@ -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));
|
||||
}
|
||||
|
|
|
@ -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<Controller::DigitalPin, 2> Paddles::ourButtonPin = {
|
||||
DigitalPin::Four, DigitalPin::Three
|
||||
};
|
||||
|
|
|
@ -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<Controller::DigitalPin, 2> ourButtonPin;
|
||||
|
||||
private:
|
||||
// Following constructors and assignment operators not supported
|
||||
Paddles() = delete;
|
||||
|
|
|
@ -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)));
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
|
|
|
@ -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 <lr|rl> How to assign virtual ports to multiple\n"
|
||||
<< " Stelladaptor/2600-daptors\n"
|
||||
<< " -modcombo <1|0> Enable modifer key combos\n"
|
||||
|
|
|
@ -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()
|
||||
{
|
||||
|
|
|
@ -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};
|
||||
|
||||
|
|
Loading…
Reference in New Issue