mirror of https://github.com/stella-emu/stella.git
fixed broken driving controller support (see #760)
This commit is contained in:
parent
a7bde4603e
commit
6e6a1f4b43
|
@ -35,9 +35,10 @@ using json = nlohmann::json;
|
|||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
PhysicalJoystickHandler::PhysicalJoystickHandler(
|
||||
OSystem& system, EventHandler& handler)
|
||||
OSystem& system, EventHandler& handler, Event& event)
|
||||
: myOSystem{system},
|
||||
myHandler{handler}
|
||||
myHandler{handler},
|
||||
myEvent(event)
|
||||
{
|
||||
if(myOSystem.settings().getInt("event_ver") != Event::VERSION) {
|
||||
Logger::info("event version mismatch; dropping previous joystick mappings");
|
||||
|
@ -161,6 +162,15 @@ int PhysicalJoystickHandler::add(const PhysicalJoystickPtr& stick)
|
|||
setStickDefaultMapping(stick->ID, Event::NoType, EventMode::kMenuMode);
|
||||
}
|
||||
|
||||
// We're potentially swapping out an input device behind the back of
|
||||
// the Event system, so we make sure all Stelladaptor-generated events
|
||||
// are reset
|
||||
for(int port = 0; port < NUM_PORTS; ++port)
|
||||
{
|
||||
for(int axis = 0; axis < NUM_SA_AXIS; ++axis)
|
||||
myEvent.set(SA_Axis[port][axis], 0);
|
||||
}
|
||||
|
||||
return stick->ID;
|
||||
}
|
||||
|
||||
|
@ -222,6 +232,7 @@ void PhysicalJoystickHandler::mapStelladaptors(const string& saport)
|
|||
// in setupJoysticks take care of that
|
||||
int saCount = 0;
|
||||
int saOrder[] = { 1, 2 };
|
||||
|
||||
if(BSPF::equalsIgnoreCase(saport, "rl"))
|
||||
{
|
||||
saOrder[0] = 2; saOrder[1] = 1;
|
||||
|
@ -229,6 +240,7 @@ void PhysicalJoystickHandler::mapStelladaptors(const string& saport)
|
|||
|
||||
for(auto& [_id, _joyptr]: mySticks)
|
||||
{
|
||||
bool found = false;
|
||||
// remove previously added emulated ports
|
||||
size_t pos = _joyptr->name.find(" (emulates ");
|
||||
|
||||
|
@ -238,30 +250,29 @@ void PhysicalJoystickHandler::mapStelladaptors(const string& saport)
|
|||
if(BSPF::startsWithIgnoreCase(_joyptr->name, "Stelladaptor"))
|
||||
{
|
||||
if(saOrder[saCount] == 1)
|
||||
{
|
||||
_joyptr->name += " (emulates left joystick port)";
|
||||
_joyptr->type = PhysicalJoystick::Type::LEFT_STELLADAPTOR;
|
||||
}
|
||||
else if(saOrder[saCount] == 2)
|
||||
{
|
||||
_joyptr->name += " (emulates right joystick port)";
|
||||
_joyptr->type = PhysicalJoystick::Type::RIGHT_STELLADAPTOR;
|
||||
}
|
||||
saCount++;
|
||||
found = true;
|
||||
}
|
||||
else if(BSPF::startsWithIgnoreCase(_joyptr->name, "2600-daptor"))
|
||||
{
|
||||
if(saOrder[saCount] == 1)
|
||||
{
|
||||
_joyptr->name += " (emulates left joystick port)";
|
||||
_joyptr->type = PhysicalJoystick::Type::LEFT_2600DAPTOR;
|
||||
}
|
||||
else if(saOrder[saCount] == 2)
|
||||
{
|
||||
_joyptr->name += " (emulates right joystick port)";
|
||||
_joyptr->type = PhysicalJoystick::Type::RIGHT_2600DAPTOR;
|
||||
}
|
||||
found = true;
|
||||
}
|
||||
if(found)
|
||||
{
|
||||
if(saOrder[saCount] == 1)
|
||||
_joyptr->name += " (emulates left joystick port)";
|
||||
else if(saOrder[saCount] == 2)
|
||||
_joyptr->name += " (emulates right joystick port)";
|
||||
|
||||
saCount++;
|
||||
// always map Stelladaptor/2600-daptor to emulation mode defaults
|
||||
setStickDefaultMapping(_joyptr->ID, Event::NoType, EventMode::kEmulationMode);
|
||||
}
|
||||
}
|
||||
myOSystem.settings().setValue("saport", saport);
|
||||
|
@ -704,75 +715,185 @@ void PhysicalJoystickHandler::handleAxisEvent(int stick, int axis, int value)
|
|||
|
||||
if(j)
|
||||
{
|
||||
int button = j->buttonLast[stick];
|
||||
//int button = j->buttonLast[stick];
|
||||
|
||||
if(myHandler.state() == EventHandlerState::EMULATION)
|
||||
switch(j->type)
|
||||
{
|
||||
Event::Type eventAxisAnalog;
|
||||
// Since the various controller classes deal with Stelladaptor
|
||||
// devices differently, we send the raw X and Y axis data directly,
|
||||
// and let the controller handle it
|
||||
// These events don't have to pass through handleEvent, since
|
||||
// they can never be remapped
|
||||
case PhysicalJoystick::Type::LEFT_STELLADAPTOR:
|
||||
case PhysicalJoystick::Type::LEFT_2600DAPTOR:
|
||||
if(myOSystem.hasConsole()
|
||||
&& myOSystem.console().leftController().type() == Controller::Type::Driving)
|
||||
{
|
||||
if(axis < NUM_SA_AXIS)
|
||||
myEvent.set(SA_Axis[0][axis], value);
|
||||
}
|
||||
else
|
||||
handleRegularAxisEvent(j, stick, axis, value);
|
||||
break; // axis on left controller (0)
|
||||
|
||||
// Check for analog events, which are handled differently
|
||||
// A value change lower than ~90% indicates analog input
|
||||
if((abs(j->axisLastValue[axis] - value) < 30000)
|
||||
&& (eventAxisAnalog = j->joyMap.get(EventMode::kEmulationMode, button, JoyAxis(axis), JoyDir::ANALOG)) != Event::Type::NoType)
|
||||
{
|
||||
myHandler.handleEvent(eventAxisAnalog, value);
|
||||
}
|
||||
case PhysicalJoystick::Type::RIGHT_STELLADAPTOR:
|
||||
case PhysicalJoystick::Type::RIGHT_2600DAPTOR:
|
||||
if(myOSystem.hasConsole()
|
||||
&& myOSystem.console().rightController().type() == Controller::Type::Driving)
|
||||
{
|
||||
if(axis < NUM_SA_AXIS)
|
||||
myEvent.set(SA_Axis[1][axis], value);
|
||||
}
|
||||
else
|
||||
handleRegularAxisEvent(j, stick, axis, value);
|
||||
break; // axis on right controller (1)
|
||||
|
||||
default: // PhysicalJoystick::Type::REGULAR
|
||||
handleRegularAxisEvent(j, stick, axis, value);
|
||||
#if 0
|
||||
// if(myHandler.state() == EventHandlerState::EMULATION)
|
||||
// {
|
||||
// Event::Type eventAxisAnalog;
|
||||
|
||||
// // Check for analog events, which are handled differently
|
||||
// // A value change lower than ~90% indicates analog input
|
||||
// if((abs(j->axisLastValue[axis] - value) < 30000)
|
||||
// && (eventAxisAnalog = j->joyMap.get(EventMode::kEmulationMode, button, JoyAxis(axis), JoyDir::ANALOG)) != Event::Type::NoType)
|
||||
// {
|
||||
// myHandler.handleEvent(eventAxisAnalog, value);
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// // Otherwise, we assume the event is digital
|
||||
// // Every axis event has two associated values, negative and positive
|
||||
// Event::Type eventAxisNeg = j->joyMap.get(EventMode::kEmulationMode, button, JoyAxis(axis), JoyDir::NEG);
|
||||
// Event::Type eventAxisPos = j->joyMap.get(EventMode::kEmulationMode, button, JoyAxis(axis), JoyDir::POS);
|
||||
|
||||
// if(value > Joystick::deadzone())
|
||||
// myHandler.handleEvent(eventAxisPos);
|
||||
// else if(value < -Joystick::deadzone())
|
||||
// myHandler.handleEvent(eventAxisNeg);
|
||||
// else
|
||||
// {
|
||||
// // Treat any deadzone value as zero
|
||||
// value = 0;
|
||||
|
||||
// // Now filter out consecutive, similar values
|
||||
// // (only pass on the event if the state has changed)
|
||||
// if(j->axisLastValue[axis] != value)
|
||||
// {
|
||||
// // Turn off both events, since we don't know exactly which one
|
||||
// // was previously activated.
|
||||
// myHandler.handleEvent(eventAxisNeg, false);
|
||||
// myHandler.handleEvent(eventAxisPos, false);
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// j->axisLastValue[axis] = value;
|
||||
// }
|
||||
// #ifdef GUI_SUPPORT
|
||||
// else if(myHandler.hasOverlay())
|
||||
// {
|
||||
// // A value change lower than Joystick::deadzone indicates analog input which is ignored
|
||||
// if((abs(j->axisLastValue[axis] - value) > Joystick::deadzone()))
|
||||
// {
|
||||
// // First, clamp the values to simulate digital input
|
||||
// // (the only thing that the underlying code understands)
|
||||
// if(value > Joystick::deadzone())
|
||||
// value = 32000;
|
||||
// else if(value < -Joystick::deadzone())
|
||||
// value = -32000;
|
||||
// else
|
||||
// value = 0;
|
||||
|
||||
// // Now filter out consecutive, similar values
|
||||
// // (only pass on the event if the state has changed)
|
||||
// if(value != j->axisLastValue[axis])
|
||||
// {
|
||||
// myHandler.overlay().handleJoyAxisEvent(stick, JoyAxis(axis), convertAxisValue(value), button);
|
||||
|
||||
// }
|
||||
// }
|
||||
// j->axisLastValue[axis] = value;
|
||||
// }
|
||||
// #endif
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void PhysicalJoystickHandler::handleRegularAxisEvent(const PhysicalJoystickPtr j,
|
||||
int stick, int axis, int value)
|
||||
{
|
||||
int button = j->buttonLast[stick];
|
||||
|
||||
if(myHandler.state() == EventHandlerState::EMULATION)
|
||||
{
|
||||
Event::Type eventAxisAnalog;
|
||||
|
||||
// Check for analog events, which are handled differently
|
||||
// A value change lower than ~90% indicates analog input
|
||||
if((abs(j->axisLastValue[axis] - value) < 30000)
|
||||
&& (eventAxisAnalog = j->joyMap.get(EventMode::kEmulationMode, button, JoyAxis(axis), JoyDir::ANALOG)) != Event::Type::NoType)
|
||||
{
|
||||
myHandler.handleEvent(eventAxisAnalog, value);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Otherwise, we assume the event is digital
|
||||
// Every axis event has two associated values, negative and positive
|
||||
Event::Type eventAxisNeg = j->joyMap.get(EventMode::kEmulationMode, button, JoyAxis(axis), JoyDir::NEG);
|
||||
Event::Type eventAxisPos = j->joyMap.get(EventMode::kEmulationMode, button, JoyAxis(axis), JoyDir::POS);
|
||||
|
||||
if(value > Joystick::deadzone())
|
||||
myHandler.handleEvent(eventAxisPos);
|
||||
else if(value < -Joystick::deadzone())
|
||||
myHandler.handleEvent(eventAxisNeg);
|
||||
else
|
||||
{
|
||||
// Otherwise, we assume the event is digital
|
||||
// Every axis event has two associated values, negative and positive
|
||||
Event::Type eventAxisNeg = j->joyMap.get(EventMode::kEmulationMode, button, JoyAxis(axis), JoyDir::NEG);
|
||||
Event::Type eventAxisPos = j->joyMap.get(EventMode::kEmulationMode, button, JoyAxis(axis), JoyDir::POS);
|
||||
|
||||
if(value > Joystick::deadzone())
|
||||
myHandler.handleEvent(eventAxisPos);
|
||||
else if(value < -Joystick::deadzone())
|
||||
myHandler.handleEvent(eventAxisNeg);
|
||||
else
|
||||
{
|
||||
// Treat any deadzone value as zero
|
||||
value = 0;
|
||||
|
||||
// Now filter out consecutive, similar values
|
||||
// (only pass on the event if the state has changed)
|
||||
if(j->axisLastValue[axis] != value)
|
||||
{
|
||||
// Turn off both events, since we don't know exactly which one
|
||||
// was previously activated.
|
||||
myHandler.handleEvent(eventAxisNeg, false);
|
||||
myHandler.handleEvent(eventAxisPos, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
j->axisLastValue[axis] = value;
|
||||
}
|
||||
#ifdef GUI_SUPPORT
|
||||
else if(myHandler.hasOverlay())
|
||||
{
|
||||
// A value change lower than Joystick::deadzone indicates analog input which is ignored
|
||||
if((abs(j->axisLastValue[axis] - value) > Joystick::deadzone()))
|
||||
{
|
||||
// First, clamp the values to simulate digital input
|
||||
// (the only thing that the underlying code understands)
|
||||
if(value > Joystick::deadzone())
|
||||
value = 32000;
|
||||
else if(value < -Joystick::deadzone())
|
||||
value = -32000;
|
||||
else
|
||||
value = 0;
|
||||
// Treat any deadzone value as zero
|
||||
value = 0;
|
||||
|
||||
// Now filter out consecutive, similar values
|
||||
// (only pass on the event if the state has changed)
|
||||
if(value != j->axisLastValue[axis])
|
||||
if(j->axisLastValue[axis] != value)
|
||||
{
|
||||
myHandler.overlay().handleJoyAxisEvent(stick, JoyAxis(axis), convertAxisValue(value), button);
|
||||
|
||||
// Turn off both events, since we don't know exactly which one
|
||||
// was previously activated.
|
||||
myHandler.handleEvent(eventAxisNeg, false);
|
||||
myHandler.handleEvent(eventAxisPos, false);
|
||||
}
|
||||
}
|
||||
j->axisLastValue[axis] = value;
|
||||
}
|
||||
#endif
|
||||
j->axisLastValue[axis] = value;
|
||||
}
|
||||
#ifdef GUI_SUPPORT
|
||||
else if(myHandler.hasOverlay())
|
||||
{
|
||||
// A value change lower than Joystick::deadzone indicates analog input which is ignored
|
||||
if((abs(j->axisLastValue[axis] - value) > Joystick::deadzone()))
|
||||
{
|
||||
// First, clamp the values to simulate digital input
|
||||
// (the only thing that the underlying code understands)
|
||||
if(value > Joystick::deadzone())
|
||||
value = 32000;
|
||||
else if(value < -Joystick::deadzone())
|
||||
value = -32000;
|
||||
else
|
||||
value = 0;
|
||||
|
||||
// Now filter out consecutive, similar values
|
||||
// (only pass on the event if the state has changed)
|
||||
if(value != j->axisLastValue[axis])
|
||||
{
|
||||
myHandler.overlay().handleJoyAxisEvent(stick, JoyAxis(axis), convertAxisValue(value), button);
|
||||
|
||||
}
|
||||
}
|
||||
j->axisLastValue[axis] = value;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
|
@ -1160,3 +1281,10 @@ PhysicalJoystickHandler::DefaultMenuMapping = {
|
|||
{Event::UIUp, JOY_CTRL_NONE, JoyAxis::NONE, JoyDir::NONE, 0, JoyHatDir::UP},
|
||||
{Event::UIDown, JOY_CTRL_NONE, JoyAxis::NONE, JoyDir::NONE, 0, JoyHatDir::DOWN},
|
||||
};
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
// Used by the Stelladaptor to send absolute axis values
|
||||
const Event::Type PhysicalJoystickHandler::SA_Axis[NUM_PORTS][NUM_SA_AXIS] = {
|
||||
{ Event::SALeftAxis0Value, Event::SALeftAxis1Value },
|
||||
{ Event::SARightAxis0Value, Event::SARightAxis1Value }
|
||||
};
|
||||
|
|
|
@ -62,7 +62,7 @@ class PhysicalJoystickHandler
|
|||
};
|
||||
|
||||
public:
|
||||
PhysicalJoystickHandler(OSystem& system, EventHandler& handler);
|
||||
PhysicalJoystickHandler(OSystem& system, EventHandler& handler, Event& event);
|
||||
|
||||
static nlohmann::json convertLegacyMapping(const string& mapping);
|
||||
|
||||
|
@ -125,6 +125,7 @@ class PhysicalJoystickHandler
|
|||
|
||||
OSystem& myOSystem;
|
||||
EventHandler& myHandler;
|
||||
Event& myEvent;
|
||||
|
||||
// Contains all joysticks that Stella knows about, indexed by name
|
||||
StickDatabase myDatabase;
|
||||
|
@ -149,6 +150,10 @@ class PhysicalJoystickHandler
|
|||
return value == int(JoyDir::NONE) ? JoyDir::NONE : value > 0 ? JoyDir::POS : JoyDir::NEG;
|
||||
}
|
||||
|
||||
// Handle regular axis events (besides special Stelladaptor handling)
|
||||
void handleRegularAxisEvent(const PhysicalJoystickPtr j,
|
||||
int stick, int axis, int value);
|
||||
|
||||
// Structures used for action menu items
|
||||
struct EventMapping {
|
||||
Event::Type event{Event::NoType};
|
||||
|
@ -192,6 +197,10 @@ class PhysicalJoystickHandler
|
|||
static EventMappingArray DefaultRightPaddlesMapping;
|
||||
static EventMappingArray DefaultLeftKeypadMapping;
|
||||
static EventMappingArray DefaultRightKeypadMapping;
|
||||
|
||||
static constexpr int NUM_PORTS = 2;
|
||||
static constexpr int NUM_SA_AXIS = 2;
|
||||
static const Event::Type SA_Axis[NUM_PORTS][NUM_SA_AXIS];
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -15,9 +15,6 @@
|
|||
// this file, and for a DISCLAIMER OF ALL WARRANTIES.
|
||||
//============================================================================
|
||||
|
||||
#include "Event.hxx"
|
||||
#include "System.hxx"
|
||||
|
||||
#include "Driving.hxx"
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
|
@ -38,8 +35,8 @@ Driving::Driving(Jack jack, const Event& event, const System& system, bool altma
|
|||
myCWEvent = Event::JoystickTwoRight;
|
||||
myFireEvent = Event::JoystickTwoFire;
|
||||
}
|
||||
myXAxisValue = Event::PaddleZeroAnalog;
|
||||
myYAxisValue = Event::PaddleOneAnalog;
|
||||
myXAxisValue = Event::SALeftAxis0Value; // joystick input
|
||||
myYAxisValue = Event::SALeftAxis1Value; // driving controller input
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -55,8 +52,8 @@ Driving::Driving(Jack jack, const Event& event, const System& system, bool altma
|
|||
myCWEvent = Event::JoystickThreeRight;
|
||||
myFireEvent = Event::JoystickThreeFire;
|
||||
}
|
||||
myXAxisValue = Event::PaddleTwoAnalog;
|
||||
myYAxisValue = Event::PaddleThreeAnalog;
|
||||
myXAxisValue = Event::SARightAxis0Value; // joystick input
|
||||
myYAxisValue = Event::SARightAxis1Value; // driving controller input
|
||||
}
|
||||
|
||||
// Digital pins 3 and 4 are not connected
|
||||
|
@ -67,70 +64,11 @@ Driving::Driving(Jack jack, const Event& event, const System& system, bool altma
|
|||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void Driving::update()
|
||||
{
|
||||
// Digital events (from keyboard or joystick hats & buttons)
|
||||
bool firePressed = myEvent.get(myFireEvent) != 0;
|
||||
updateButtons();
|
||||
|
||||
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;
|
||||
|
||||
// Mouse motion and button events
|
||||
if(myControlID > -1)
|
||||
{
|
||||
int m_axis = myEvent.get(Event::MouseAxisXMove);
|
||||
if(m_axis < -2) --myCounter;
|
||||
else if(m_axis > 2) ++myCounter;
|
||||
firePressed = firePressed
|
||||
|| myEvent.get(Event::MouseButtonLeftValue)
|
||||
|| myEvent.get(Event::MouseButtonRightValue);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Test for 'untied' mouse axis mode, where each axis is potentially
|
||||
// mapped to a separate driving controller
|
||||
if(myControlIDX > -1)
|
||||
{
|
||||
int m_axis = myEvent.get(Event::MouseAxisXMove);
|
||||
if(m_axis < -2) --myCounter;
|
||||
else if(m_axis > 2) ++myCounter;
|
||||
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;
|
||||
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;
|
||||
|
||||
// Stelladaptor is the only controller that should set this
|
||||
int yaxis = myEvent.get(myYAxisValue);
|
||||
|
||||
// Only overwrite gray code when Stelladaptor input has changed
|
||||
// (that means real changes, not just analog signal jitter)
|
||||
if((yaxis < (myLastYaxis - 1024)) || (yaxis > (myLastYaxis + 1024)))
|
||||
{
|
||||
myLastYaxis = yaxis;
|
||||
if(yaxis <= -16384-4096)
|
||||
myGrayIndex = 3; // up
|
||||
else if(yaxis > 16384+4096)
|
||||
myGrayIndex = 1; // down
|
||||
else if(yaxis >= 16384-4096)
|
||||
myGrayIndex = 2; // up + down
|
||||
else /* if(yaxis < 16384-4096) */
|
||||
myGrayIndex = 0; // no movement
|
||||
|
||||
// Make sure direct gray codes from Stelladaptor stay in sync with
|
||||
// simulated gray codes generated by PC keyboard or PC joystick
|
||||
myCounter = myGrayIndex / SENSITIVITY * 4.0F;
|
||||
}
|
||||
updateDigitalAxes();
|
||||
updateMouseAxes();
|
||||
updateStelladaptorAxes();
|
||||
|
||||
// Gray codes for rotation
|
||||
static constexpr std::array<uInt8, 4> graytable = { 0x03, 0x01, 0x00, 0x02 };
|
||||
|
@ -141,6 +79,113 @@ void Driving::update()
|
|||
setPin(DigitalPin::Two, (gray & 0x2) != 0);
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void Driving::updateButtons()
|
||||
{
|
||||
bool firePressed = myEvent.get(myFireEvent) != 0;
|
||||
|
||||
// The joystick uses both mouse buttons for the single joystick button
|
||||
updateMouseButtons(firePressed);
|
||||
|
||||
setPin(DigitalPin::Six, !getAutoFireState(firePressed));
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void Driving::updateMouseButtons(bool& firePressed)
|
||||
{
|
||||
if(myControlID > -1)
|
||||
firePressed |= (myEvent.get(Event::MouseButtonLeftValue) != 0
|
||||
|| myEvent.get(Event::MouseButtonRightValue) != 0);
|
||||
else
|
||||
{
|
||||
// Test for 'untied' mouse axis mode, where each axis is potentially
|
||||
// mapped to a separate driving controller
|
||||
if(myControlIDX > -1)
|
||||
firePressed |= (myEvent.get(Event::MouseButtonLeftValue) != 0);
|
||||
if(myControlIDY > -1)
|
||||
firePressed |= (myEvent.get(Event::MouseButtonRightValue) != 0);
|
||||
}
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void Driving::updateDigitalAxes()
|
||||
{
|
||||
// Digital events (from keyboard or joystick hats & buttons)
|
||||
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;
|
||||
|
||||
// Only consider the lower-most bits (corresponding to pins 1 & 2)
|
||||
myGrayIndex = Int32(myCounter * SENSITIVITY / 4.0F) & 0b11;
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void Driving::updateMouseAxes()
|
||||
{
|
||||
#define MJ_Threshold 2
|
||||
// Mouse motion and button events
|
||||
if(myControlID > -1)
|
||||
{
|
||||
int m_axis = myEvent.get(Event::MouseAxisXMove);
|
||||
if(m_axis < -MJ_Threshold)
|
||||
--myCounter;
|
||||
else if(m_axis > MJ_Threshold)
|
||||
++myCounter;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Test for 'untied' mouse axis mode, where each axis is potentially
|
||||
// mapped to a separate driving controller
|
||||
if(myControlIDX > -1)
|
||||
{
|
||||
int m_axis = myEvent.get(Event::MouseAxisXMove);
|
||||
if(m_axis < -MJ_Threshold)
|
||||
--myCounter;
|
||||
else if(m_axis > MJ_Threshold)
|
||||
++myCounter;
|
||||
}
|
||||
if(myControlIDY > -1)
|
||||
{
|
||||
int m_axis = myEvent.get(Event::MouseAxisYMove);
|
||||
if(m_axis < -MJ_Threshold)
|
||||
--myCounter;
|
||||
else if(m_axis > MJ_Threshold)
|
||||
++myCounter;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void Driving::updateStelladaptorAxes()
|
||||
{
|
||||
#define SA_Threshold 4096
|
||||
// Stelladaptor is the only controller that should set this
|
||||
int yaxis = myEvent.get(myYAxisValue);
|
||||
|
||||
// Only overwrite gray code when Stelladaptor input has changed
|
||||
// (that means real changes, not just analog signal jitter)
|
||||
if((yaxis < (myLastYaxis - 1024)) || (yaxis > (myLastYaxis + 1024)))
|
||||
{
|
||||
myLastYaxis = yaxis;
|
||||
if(yaxis <= -16384 - SA_Threshold)
|
||||
myGrayIndex = 3; // up
|
||||
else if(yaxis > 16384 + SA_Threshold)
|
||||
myGrayIndex = 1; // down
|
||||
else if(yaxis >= 16384 - SA_Threshold)
|
||||
myGrayIndex = 2; // up + down
|
||||
else /* if(yaxis < 16384 - SA_Threshold) */
|
||||
myGrayIndex = 0; // no movement
|
||||
|
||||
// Make sure direct gray codes from Stelladaptor stay in sync with
|
||||
// simulated gray codes generated by PC keyboard or PC joystick
|
||||
// Must be rounded into the middle of the myCounter interval!
|
||||
myCounter = (myGrayIndex + 0.5F) * 4.0F / SENSITIVITY;
|
||||
}
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
bool Driving::setMouseControl(
|
||||
Controller::Type xtype, int xid, Controller::Type ytype, int yid)
|
||||
|
|
|
@ -116,6 +116,35 @@ class Driving : public Controller
|
|||
// speeds
|
||||
static float SENSITIVITY;
|
||||
|
||||
private:
|
||||
/**
|
||||
Update the button pin states.
|
||||
*/
|
||||
void updateButtons();
|
||||
|
||||
/**
|
||||
Update the button states from the mouse button events currently set.
|
||||
*/
|
||||
void updateMouseButtons(bool& firePressed);
|
||||
|
||||
/**
|
||||
Update the axes pin states according to the keyboard
|
||||
or joystick hats & buttons events currently set.
|
||||
*/
|
||||
void updateDigitalAxes();
|
||||
|
||||
/**
|
||||
Update the axes pin states according to the Stelladaptor axes value
|
||||
events currently set.
|
||||
*/
|
||||
void updateStelladaptorAxes();
|
||||
|
||||
/**
|
||||
Update the axes pin states according to mouse events currently set.
|
||||
*/
|
||||
void updateMouseAxes();
|
||||
|
||||
|
||||
private:
|
||||
// Following constructors and assignment operators not supported
|
||||
Driving() = delete;
|
||||
|
|
|
@ -165,6 +165,7 @@ class Event
|
|||
DecreasePaddleCenterY, IncreasePaddleCenterY,
|
||||
PreviousMouseControl,
|
||||
DecreaseMouseAxesRange, IncreaseMouseAxesRange,
|
||||
SALeftAxis0Value, SALeftAxis1Value, SARightAxis0Value, SARightAxis1Value,
|
||||
LastType
|
||||
};
|
||||
|
||||
|
|
|
@ -87,7 +87,7 @@ void EventHandler::initialize()
|
|||
myPKeyHandler = make_unique<PhysicalKeyboardHandler>(myOSystem, *this);
|
||||
|
||||
// Create joystick handler (to handle all physical joystick functionality)
|
||||
myPJoyHandler = make_unique<PhysicalJoystickHandler>(myOSystem, *this);
|
||||
myPJoyHandler = make_unique<PhysicalJoystickHandler>(myOSystem, *this, myEvent);
|
||||
|
||||
// Erase the 'combo' array
|
||||
for(int i = 0; i < COMBO_SIZE; ++i)
|
||||
|
|
|
@ -46,8 +46,8 @@ Joystick::Joystick(Jack jack, const Event& event, const System& system,
|
|||
myRightEvent = Event::JoystickTwoRight;
|
||||
myFireEvent = Event::JoystickTwoFire;
|
||||
}
|
||||
myXAxisValue = Event::PaddleZeroAnalog; // TODO
|
||||
myYAxisValue = Event::PaddleOneAnalog; // TODO
|
||||
//myXAxisValue = Event::SALeftAxis0Value;
|
||||
//myYAxisValue = Event::SALeftAxis1Value;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -67,8 +67,8 @@ Joystick::Joystick(Jack jack, const Event& event, const System& system,
|
|||
myRightEvent = Event::JoystickThreeRight;
|
||||
myFireEvent = Event::JoystickThreeFire;
|
||||
}
|
||||
myXAxisValue = Event::PaddleTwoAnalog; // TODO
|
||||
myYAxisValue = Event::PaddleThreeAnalog; // TODO
|
||||
//myXAxisValue = Event::SARightAxis0Value;
|
||||
//myYAxisValue = Event::SARightAxis1Value;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -78,7 +78,7 @@ void Joystick::update()
|
|||
updateButtons();
|
||||
|
||||
updateDigitalAxes();
|
||||
updateAnalogAxes();
|
||||
//updateStelladaptorAxes();
|
||||
updateMouseAxes();
|
||||
}
|
||||
|
||||
|
@ -110,34 +110,36 @@ void Joystick::updateDigitalAxes()
|
|||
setPin(DigitalPin::One, myEvent.get(myUpEvent) == 0);
|
||||
setPin(DigitalPin::Two, myEvent.get(myDownEvent) == 0);
|
||||
setPin(DigitalPin::Three, myEvent.get(myLeftEvent) == 0);
|
||||
setPin(DigitalPin::Four, myEvent.get(myRightEvent) == 0);
|
||||
setPin(DigitalPin::Four, myEvent.get(myRightEvent) != 1);
|
||||
cerr << myEvent.get(myRightEvent) << endl;
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void Joystick::updateAnalogAxes()
|
||||
{
|
||||
// Axis events (usually generated by the Stelladaptor)
|
||||
int xaxis = myEvent.get(myXAxisValue);
|
||||
int yaxis = myEvent.get(myYAxisValue);
|
||||
if(xaxis > 16384 - 4096)
|
||||
{
|
||||
setPin(DigitalPin::Four, false);
|
||||
// Stelladaptor sends "half moved right" for L+R pushed together
|
||||
if(xaxis < 16384 + 4096)
|
||||
setPin(DigitalPin::Three, false);
|
||||
}
|
||||
else if(xaxis < -16384)
|
||||
setPin(DigitalPin::Three, false);
|
||||
if(yaxis > 16384 - 4096)
|
||||
{
|
||||
setPin(DigitalPin::Two, false);
|
||||
// Stelladaptor sends "half moved down" for U+D pushed together
|
||||
if(yaxis < 16384 + 4096)
|
||||
setPin(DigitalPin::One, false);
|
||||
}
|
||||
else if(yaxis < -16384)
|
||||
setPin(DigitalPin::One, false);
|
||||
}
|
||||
//// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
//void Joystick::updateStelladaptorAxes()
|
||||
//{
|
||||
// #define SA_Threshold 4096
|
||||
// // Axis events (usually generated by the Stelladaptor)
|
||||
// int xaxis = myEvent.get(myXAxisValue);
|
||||
// int yaxis = myEvent.get(myYAxisValue);
|
||||
// if(xaxis > 16384 - SA_Threshold)
|
||||
// {
|
||||
// setPin(DigitalPin::Four, false);
|
||||
// // Stelladaptor sends "half moved right" for L+R pushed together
|
||||
// if(xaxis < 16384 + SA_Threshold)
|
||||
// setPin(DigitalPin::Three, false);
|
||||
// }
|
||||
// else if(xaxis < -16384)
|
||||
// setPin(DigitalPin::Three, false);
|
||||
// if(yaxis > 16384 - SA_Threshold)
|
||||
// {
|
||||
// setPin(DigitalPin::Two, false);
|
||||
// // Stelladaptor sends "half moved down" for U+D pushed together
|
||||
// if(yaxis < 16384 + SA_Threshold)
|
||||
// setPin(DigitalPin::One, false);
|
||||
// }
|
||||
// else if(yaxis < -16384)
|
||||
// setPin(DigitalPin::One, false);
|
||||
//}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void Joystick::updateMouseAxes()
|
||||
|
|
|
@ -18,8 +18,8 @@
|
|||
#ifndef JOYSTICK_HXX
|
||||
#define JOYSTICK_HXX
|
||||
|
||||
#include "Event.hxx"
|
||||
#include "Control.hxx"
|
||||
#include "Event.hxx"
|
||||
|
||||
/**
|
||||
The standard Atari 2600 joystick controller.
|
||||
|
@ -118,8 +118,8 @@ class Joystick : public Controller
|
|||
private:
|
||||
// Pre-compute the events we care about based on given port
|
||||
// This will eliminate test for left or right port in update()
|
||||
Event::Type myUpEvent, myDownEvent, myLeftEvent, myRightEvent,
|
||||
myXAxisValue, myYAxisValue;
|
||||
Event::Type myUpEvent, myDownEvent, myLeftEvent, myRightEvent;
|
||||
//myXAxisValue, myYAxisValue;
|
||||
|
||||
// Controller to emulate in normal mouse axis mode
|
||||
int myControlID{-1};
|
||||
|
@ -133,10 +133,11 @@ class Joystick : public Controller
|
|||
*/
|
||||
void updateDigitalAxes();
|
||||
|
||||
/**
|
||||
Update the axes pin states according to the axes value events currently set.
|
||||
*/
|
||||
void updateAnalogAxes();
|
||||
///**
|
||||
// Update the axes pin states according to the Stelladaptor axes value
|
||||
// events currently set.
|
||||
//*/
|
||||
//void updateStelladaptorAxes();
|
||||
|
||||
/**
|
||||
Update the axes pin states according to mouse events currently set.
|
||||
|
|
Loading…
Reference in New Issue