mirror of https://github.com/stella-emu/stella.git
derived Genesis and Booster from Joystick controller class
This commit is contained in:
parent
b6e0b8fdcd
commit
a7bde4603e
|
@ -15,36 +15,21 @@
|
||||||
// this file, and for a DISCLAIMER OF ALL WARRANTIES.
|
// this file, and for a DISCLAIMER OF ALL WARRANTIES.
|
||||||
//============================================================================
|
//============================================================================
|
||||||
|
|
||||||
#include "Event.hxx"
|
|
||||||
#include "Booster.hxx"
|
#include "Booster.hxx"
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
BoosterGrip::BoosterGrip(Jack jack, const Event& event, const System& system)
|
BoosterGrip::BoosterGrip(Jack jack, const Event& event, const System& system)
|
||||||
: Controller(jack, event, system, Controller::Type::BoosterGrip)
|
: Joystick(jack, event, system, Controller::Type::BoosterGrip)
|
||||||
{
|
{
|
||||||
if(myJack == Jack::Left)
|
if(myJack == Jack::Left)
|
||||||
{
|
{
|
||||||
myUpEvent = Event::JoystickZeroUp;
|
|
||||||
myDownEvent = Event::JoystickZeroDown;
|
|
||||||
myLeftEvent = Event::JoystickZeroLeft;
|
|
||||||
myRightEvent = Event::JoystickZeroRight;
|
|
||||||
myFireEvent = Event::JoystickZeroFire;
|
|
||||||
myTriggerEvent = Event::JoystickZeroFire5;
|
myTriggerEvent = Event::JoystickZeroFire5;
|
||||||
myBoosterEvent = Event::JoystickZeroFire9;
|
myBoosterEvent = Event::JoystickZeroFire9;
|
||||||
myXAxisValue = Event::PaddleZeroAnalog;
|
|
||||||
myYAxisValue = Event::PaddleOneAnalog;
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
myUpEvent = Event::JoystickOneUp;
|
|
||||||
myDownEvent = Event::JoystickOneDown;
|
|
||||||
myLeftEvent = Event::JoystickOneLeft;
|
|
||||||
myRightEvent = Event::JoystickOneRight;
|
|
||||||
myFireEvent = Event::JoystickOneFire;
|
|
||||||
myTriggerEvent = Event::JoystickOneFire5;
|
myTriggerEvent = Event::JoystickOneFire5;
|
||||||
myBoosterEvent = Event::JoystickOneFire9;
|
myBoosterEvent = Event::JoystickOneFire9;
|
||||||
myXAxisValue = Event::PaddleTwoAnalog;
|
|
||||||
myYAxisValue = Event::PaddleThreeAnalog;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
setPin(AnalogPin::Five, MAX_RESISTANCE);
|
setPin(AnalogPin::Five, MAX_RESISTANCE);
|
||||||
|
@ -52,98 +37,17 @@ BoosterGrip::BoosterGrip(Jack jack, const Event& event, const System& system)
|
||||||
}
|
}
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
void BoosterGrip::update()
|
void BoosterGrip::updateButtons()
|
||||||
{
|
{
|
||||||
// Digital events (from keyboard or joystick hats & buttons)
|
|
||||||
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);
|
|
||||||
bool firePressed = myEvent.get(myFireEvent) != 0;
|
bool firePressed = myEvent.get(myFireEvent) != 0;
|
||||||
|
|
||||||
// The CBS Booster-grip has two more buttons on it. These buttons are
|
// The CBS Booster-grip has two more buttons on it. These buttons are
|
||||||
// connected to the inputs usually used by paddles.
|
// connected to the inputs usually used by paddles.
|
||||||
setPin(
|
bool triggerPressed = myEvent.get(myTriggerEvent) != 0;
|
||||||
AnalogPin::Five,
|
bool boosterPressed = myEvent.get(myBoosterEvent) != 0;
|
||||||
(myEvent.get(myTriggerEvent) != 0) ? MIN_RESISTANCE : MAX_RESISTANCE
|
|
||||||
);
|
|
||||||
setPin(
|
|
||||||
AnalogPin::Nine,
|
|
||||||
(myEvent.get(myBoosterEvent) != 0) ? MIN_RESISTANCE : MAX_RESISTANCE
|
|
||||||
);
|
|
||||||
|
|
||||||
// Axis events (usually generated by the Stelladaptor)
|
updateMouseButtons(firePressed, boosterPressed);
|
||||||
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);
|
|
||||||
|
|
||||||
// Mouse motion and button events
|
|
||||||
if(myControlID > -1)
|
|
||||||
{
|
|
||||||
// The following code was taken from z26
|
|
||||||
#define MJ_Threshold 2
|
|
||||||
int mousex = myEvent.get(Event::MouseAxisXMove),
|
|
||||||
mousey = myEvent.get(Event::MouseAxisYMove);
|
|
||||||
if(mousex || mousey)
|
|
||||||
{
|
|
||||||
if((!(abs(mousey) > abs(mousex) << 1)) && (abs(mousex) >= MJ_Threshold))
|
|
||||||
{
|
|
||||||
if(mousex < 0)
|
|
||||||
setPin(DigitalPin::Three, false);
|
|
||||||
else if (mousex > 0)
|
|
||||||
setPin(DigitalPin::Four, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
if((!(abs(mousex) > abs(mousey) << 1)) && (abs(mousey) >= MJ_Threshold))
|
|
||||||
{
|
|
||||||
if(mousey < 0)
|
|
||||||
setPin(DigitalPin::One, false);
|
|
||||||
else if(mousey > 0)
|
|
||||||
setPin(DigitalPin::Two, false);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// Get mouse button state
|
|
||||||
firePressed = firePressed
|
|
||||||
|| myEvent.get(Event::MouseButtonLeftValue);
|
|
||||||
if(myEvent.get(Event::MouseButtonRightValue))
|
|
||||||
setPin(AnalogPin::Nine, MIN_RESISTANCE);
|
|
||||||
}
|
|
||||||
setPin(DigitalPin::Six, !getAutoFireState(firePressed));
|
setPin(DigitalPin::Six, !getAutoFireState(firePressed));
|
||||||
}
|
setPin(AnalogPin::Five, triggerPressed ? MIN_RESISTANCE : MAX_RESISTANCE);
|
||||||
|
setPin(AnalogPin::Nine, boosterPressed ? MIN_RESISTANCE : MAX_RESISTANCE);
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
||||||
bool BoosterGrip::setMouseControl(
|
|
||||||
Controller::Type xtype, int xid, Controller::Type ytype, int yid)
|
|
||||||
{
|
|
||||||
// Currently, the booster-grip takes full control of the mouse, using both
|
|
||||||
// axes for its two degrees of movement, and the left/right buttons for
|
|
||||||
// fire and booster, respectively
|
|
||||||
if(xtype == Controller::Type::BoosterGrip && ytype == Controller::Type::BoosterGrip &&
|
|
||||||
xid == yid)
|
|
||||||
{
|
|
||||||
myControlID = ((myJack == Jack::Left && xid == 0) ||
|
|
||||||
(myJack == Jack::Right && xid == 1)
|
|
||||||
) ? xid : -1;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
myControlID = -1;
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,8 +18,7 @@
|
||||||
#ifndef BOOSTERGRIP_HXX
|
#ifndef BOOSTERGRIP_HXX
|
||||||
#define BOOSTERGRIP_HXX
|
#define BOOSTERGRIP_HXX
|
||||||
|
|
||||||
#include "Control.hxx"
|
#include "Joystick.hxx"
|
||||||
#include "Event.hxx"
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
The standard Atari 2600 joystick controller fitted with the
|
The standard Atari 2600 joystick controller fitted with the
|
||||||
|
@ -28,7 +27,7 @@
|
||||||
|
|
||||||
@author Bradford W. Mott
|
@author Bradford W. Mott
|
||||||
*/
|
*/
|
||||||
class BoosterGrip : public Controller
|
class BoosterGrip : public Joystick
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
/**
|
/**
|
||||||
|
@ -42,45 +41,21 @@ class BoosterGrip : public Controller
|
||||||
~BoosterGrip() override = default;
|
~BoosterGrip() override = default;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
/**
|
|
||||||
Update the entire digital and analog pin state according to the
|
|
||||||
events currently set.
|
|
||||||
*/
|
|
||||||
void update() override;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Returns the name of this controller.
|
Returns the name of this controller.
|
||||||
*/
|
*/
|
||||||
string name() const override { return "BoosterGrip"; }
|
string name() const override { return "BoosterGrip"; }
|
||||||
|
|
||||||
|
private:
|
||||||
/**
|
/**
|
||||||
Determines how this controller will treat values received from the
|
Update the button pin states.
|
||||||
X/Y axis and left/right buttons of the mouse. Since not all controllers
|
|
||||||
use the mouse the same way (or at all), it's up to the specific class to
|
|
||||||
decide how to use this data.
|
|
||||||
|
|
||||||
In the current implementation, the left button is tied to the X axis,
|
|
||||||
and the right one tied to the Y axis.
|
|
||||||
|
|
||||||
@param xtype The controller to use for x-axis data
|
|
||||||
@param xid The controller ID to use for x-axis data (-1 for no id)
|
|
||||||
@param ytype The controller to use for y-axis data
|
|
||||||
@param yid The controller ID to use for y-axis data (-1 for no id)
|
|
||||||
|
|
||||||
@return Whether the controller supports using the mouse
|
|
||||||
*/
|
*/
|
||||||
bool setMouseControl(
|
void updateButtons() override;
|
||||||
Controller::Type xtype, int xid, Controller::Type ytype, int yid) override;
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// Pre-compute the events we care about based on given port
|
// Pre-compute the events we care about based on given port
|
||||||
// This will eliminate test for left or right port in update()
|
// This will eliminate test for left or right port in update()
|
||||||
Event::Type myUpEvent, myDownEvent, myLeftEvent, myRightEvent,
|
Event::Type myBoosterEvent, myTriggerEvent;
|
||||||
myFireEvent, myBoosterEvent, myTriggerEvent,
|
|
||||||
myXAxisValue, myYAxisValue;
|
|
||||||
|
|
||||||
// Controller to emulate in normal mouse axis mode
|
|
||||||
int myControlID{-1};
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// Following constructors and assignment operators not supported
|
// Following constructors and assignment operators not supported
|
||||||
|
|
|
@ -15,102 +15,31 @@
|
||||||
// this file, and for a DISCLAIMER OF ALL WARRANTIES.
|
// this file, and for a DISCLAIMER OF ALL WARRANTIES.
|
||||||
//============================================================================
|
//============================================================================
|
||||||
|
|
||||||
#include "Event.hxx"
|
|
||||||
#include "Genesis.hxx"
|
#include "Genesis.hxx"
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
Genesis::Genesis(Jack jack, const Event& event, const System& system)
|
Genesis::Genesis(Jack jack, const Event& event, const System& system)
|
||||||
: Controller(jack, event, system, Controller::Type::Genesis)
|
: Joystick(jack, event, system, Controller::Type::Genesis)
|
||||||
{
|
{
|
||||||
if(myJack == Jack::Left)
|
if(myJack == Jack::Left)
|
||||||
{
|
myButtonCEvent = Event::JoystickZeroFire5;
|
||||||
myUpEvent = Event::JoystickZeroUp;
|
|
||||||
myDownEvent = Event::JoystickZeroDown;
|
|
||||||
myLeftEvent = Event::JoystickZeroLeft;
|
|
||||||
myRightEvent = Event::JoystickZeroRight;
|
|
||||||
myFire1Event = Event::JoystickZeroFire;
|
|
||||||
myFire2Event = Event::JoystickZeroFire5;
|
|
||||||
}
|
|
||||||
else
|
else
|
||||||
{
|
myButtonCEvent = Event::JoystickOneFire5;
|
||||||
myUpEvent = Event::JoystickOneUp;
|
|
||||||
myDownEvent = Event::JoystickOneDown;
|
|
||||||
myLeftEvent = Event::JoystickOneLeft;
|
|
||||||
myRightEvent = Event::JoystickOneRight;
|
|
||||||
myFire1Event = Event::JoystickOneFire;
|
|
||||||
myFire2Event = Event::JoystickOneFire5;
|
|
||||||
}
|
|
||||||
|
|
||||||
setPin(AnalogPin::Five, MIN_RESISTANCE);
|
setPin(AnalogPin::Five, MIN_RESISTANCE);
|
||||||
setPin(AnalogPin::Nine, MIN_RESISTANCE);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
void Genesis::update()
|
void Genesis::updateButtons()
|
||||||
{
|
{
|
||||||
// Digital events (from keyboard or joystick hats & buttons)
|
bool firePressed = myEvent.get(myFireEvent) != 0;
|
||||||
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);
|
|
||||||
bool firePressed = myEvent.get(myFire1Event) != 0;
|
|
||||||
|
|
||||||
// The Genesis has one more button (C) that can be read by the 2600
|
// The Genesis has one more button (C) that can be read by the 2600
|
||||||
// However, it seems to work opposite to the BoosterGrip controller,
|
// However, it seems to work opposite to the BoosterGrip controller,
|
||||||
// in that the logic is inverted
|
// in that the logic is inverted
|
||||||
setPin(AnalogPin::Five,
|
bool buttonCPressed = myEvent.get(myButtonCEvent) != 0;
|
||||||
(myEvent.get(myFire2Event) == 0) ? MIN_RESISTANCE : MAX_RESISTANCE
|
|
||||||
);
|
|
||||||
|
|
||||||
// Mouse motion and button events
|
updateMouseButtons(firePressed, buttonCPressed);
|
||||||
if(myControlID > -1)
|
|
||||||
{
|
|
||||||
// The following code was taken from z26
|
|
||||||
#define MJ_Threshold 2
|
|
||||||
int mousex = myEvent.get(Event::MouseAxisXMove),
|
|
||||||
mousey = myEvent.get(Event::MouseAxisYMove);
|
|
||||||
if(mousex || mousey)
|
|
||||||
{
|
|
||||||
if((!(abs(mousey) > abs(mousex) << 1)) && (abs(mousex) >= MJ_Threshold))
|
|
||||||
{
|
|
||||||
if(mousex < 0)
|
|
||||||
setPin(DigitalPin::Three, false);
|
|
||||||
else if(mousex > 0)
|
|
||||||
setPin(DigitalPin::Four, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
if((!(abs(mousex) > abs(mousey) << 1)) && (abs(mousey) >= MJ_Threshold))
|
|
||||||
{
|
|
||||||
if(mousey < 0)
|
|
||||||
setPin(DigitalPin::One, false);
|
|
||||||
else if(mousey > 0)
|
|
||||||
setPin(DigitalPin::Two, false);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// Get mouse button state
|
|
||||||
firePressed = firePressed
|
|
||||||
|| myEvent.get(Event::MouseButtonLeftValue);
|
|
||||||
if(myEvent.get(Event::MouseButtonRightValue))
|
|
||||||
setPin(AnalogPin::Five, MAX_RESISTANCE);
|
|
||||||
}
|
|
||||||
setPin(DigitalPin::Six, !getAutoFireState(firePressed));
|
setPin(DigitalPin::Six, !getAutoFireState(firePressed));
|
||||||
}
|
setPin(AnalogPin::Five, buttonCPressed ? MAX_RESISTANCE : MIN_RESISTANCE);
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
||||||
bool Genesis::setMouseControl(
|
|
||||||
Controller::Type xtype, int xid, Controller::Type ytype, int yid)
|
|
||||||
{
|
|
||||||
// Currently, the Genesis controller takes full control of the mouse, using
|
|
||||||
// both axes for its two degrees of movement, and the left/right buttons for
|
|
||||||
// 'B' and 'C', respectively
|
|
||||||
if(xtype == Controller::Type::Genesis && ytype == Controller::Type::Genesis && xid == yid)
|
|
||||||
{
|
|
||||||
myControlID = ((myJack == Jack::Left && xid == 0) ||
|
|
||||||
(myJack == Jack::Right && xid == 1)
|
|
||||||
) ? xid : -1;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
myControlID = -1;
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,9 +18,7 @@
|
||||||
#ifndef GENESIS_HXX
|
#ifndef GENESIS_HXX
|
||||||
#define GENESIS_HXX
|
#define GENESIS_HXX
|
||||||
|
|
||||||
#include "bspf.hxx"
|
#include "Joystick.hxx"
|
||||||
#include "Control.hxx"
|
|
||||||
#include "Event.hxx"
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
The standard Sega Genesis controller works with the 2600 console for
|
The standard Sega Genesis controller works with the 2600 console for
|
||||||
|
@ -30,7 +28,7 @@
|
||||||
|
|
||||||
@author Stephen Anthony
|
@author Stephen Anthony
|
||||||
*/
|
*/
|
||||||
class Genesis : public Controller
|
class Genesis : public Joystick
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
/**
|
/**
|
||||||
|
@ -44,44 +42,21 @@ class Genesis : public Controller
|
||||||
~Genesis() override = default;
|
~Genesis() override = default;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
/**
|
|
||||||
Update the entire digital and analog pin state according to the
|
|
||||||
events currently set.
|
|
||||||
*/
|
|
||||||
void update() override;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Returns the name of this controller.
|
Returns the name of this controller.
|
||||||
*/
|
*/
|
||||||
string name() const override { return "Genesis"; }
|
string name() const override { return "Genesis"; }
|
||||||
|
|
||||||
|
private:
|
||||||
/**
|
/**
|
||||||
Determines how this controller will treat values received from the
|
Update the button pin states.
|
||||||
X/Y axis and left/right buttons of the mouse. Since not all controllers
|
|
||||||
use the mouse the same way (or at all), it's up to the specific class to
|
|
||||||
decide how to use this data.
|
|
||||||
|
|
||||||
In the current implementation, the left button is tied to the X axis,
|
|
||||||
and the right one tied to the Y axis.
|
|
||||||
|
|
||||||
@param xtype The controller to use for x-axis data
|
|
||||||
@param xid The controller ID to use for x-axis data (-1 for no id)
|
|
||||||
@param ytype The controller to use for y-axis data
|
|
||||||
@param yid The controller ID to use for y-axis data (-1 for no id)
|
|
||||||
|
|
||||||
@return Whether the controller supports using the mouse
|
|
||||||
*/
|
*/
|
||||||
bool setMouseControl(
|
void updateButtons() override;
|
||||||
Controller::Type xtype, int xid, Controller::Type ytype, int yid) override;
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// Pre-compute the events we care about based on given port
|
// Pre-compute the events we care about based on given port
|
||||||
// This will eliminate test for left or right port in update()
|
// This will eliminate test for left or right port in update()
|
||||||
Event::Type myUpEvent, myDownEvent, myLeftEvent, myRightEvent,
|
Event::Type myButtonCEvent;
|
||||||
myFire1Event, myFire2Event;
|
|
||||||
|
|
||||||
// Controller to emulate in normal mouse axis mode
|
|
||||||
int myControlID{-1};
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// Following constructors and assignment operators not supported
|
// Following constructors and assignment operators not supported
|
||||||
|
|
|
@ -15,89 +15,133 @@
|
||||||
// this file, and for a DISCLAIMER OF ALL WARRANTIES.
|
// this file, and for a DISCLAIMER OF ALL WARRANTIES.
|
||||||
//============================================================================
|
//============================================================================
|
||||||
|
|
||||||
#include "Event.hxx"
|
|
||||||
#include "Joystick.hxx"
|
#include "Joystick.hxx"
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
Joystick::Joystick(Jack jack, const Event& event, const System& system, bool altmap)
|
Joystick::Joystick(Jack jack, const Event& event, const System& system, bool altmap)
|
||||||
: Controller(jack, event, system, Controller::Type::Joystick)
|
: Joystick(jack, event, system, Controller::Type::Joystick, altmap)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
Joystick::Joystick(Jack jack, const Event& event, const System& system,
|
||||||
|
Controller::Type type, bool altmap)
|
||||||
|
: Controller(jack, event, system, type)
|
||||||
{
|
{
|
||||||
if(myJack == Jack::Left)
|
if(myJack == Jack::Left)
|
||||||
{
|
{
|
||||||
if(!altmap)
|
if(!altmap)
|
||||||
{
|
{
|
||||||
myUpEvent = Event::JoystickZeroUp;
|
myUpEvent = Event::JoystickZeroUp;
|
||||||
myDownEvent = Event::JoystickZeroDown;
|
myDownEvent = Event::JoystickZeroDown;
|
||||||
myLeftEvent = Event::JoystickZeroLeft;
|
myLeftEvent = Event::JoystickZeroLeft;
|
||||||
myRightEvent = Event::JoystickZeroRight;
|
myRightEvent = Event::JoystickZeroRight;
|
||||||
myFireEvent = Event::JoystickZeroFire;
|
myFireEvent = Event::JoystickZeroFire;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
myUpEvent = Event::JoystickTwoUp;
|
myUpEvent = Event::JoystickTwoUp;
|
||||||
myDownEvent = Event::JoystickTwoDown;
|
myDownEvent = Event::JoystickTwoDown;
|
||||||
myLeftEvent = Event::JoystickTwoLeft;
|
myLeftEvent = Event::JoystickTwoLeft;
|
||||||
myRightEvent = Event::JoystickTwoRight;
|
myRightEvent = Event::JoystickTwoRight;
|
||||||
myFireEvent = Event::JoystickTwoFire;
|
myFireEvent = Event::JoystickTwoFire;
|
||||||
}
|
}
|
||||||
myXAxisValue = Event::PaddleZeroAnalog;
|
myXAxisValue = Event::PaddleZeroAnalog; // TODO
|
||||||
myYAxisValue = Event::PaddleOneAnalog;
|
myYAxisValue = Event::PaddleOneAnalog; // TODO
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if(!altmap)
|
if(!altmap)
|
||||||
{
|
{
|
||||||
myUpEvent = Event::JoystickOneUp;
|
myUpEvent = Event::JoystickOneUp;
|
||||||
myDownEvent = Event::JoystickOneDown;
|
myDownEvent = Event::JoystickOneDown;
|
||||||
myLeftEvent = Event::JoystickOneLeft;
|
myLeftEvent = Event::JoystickOneLeft;
|
||||||
myRightEvent = Event::JoystickOneRight;
|
myRightEvent = Event::JoystickOneRight;
|
||||||
myFireEvent = Event::JoystickOneFire;
|
myFireEvent = Event::JoystickOneFire;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
myUpEvent = Event::JoystickThreeUp;
|
myUpEvent = Event::JoystickThreeUp;
|
||||||
myDownEvent = Event::JoystickThreeDown;
|
myDownEvent = Event::JoystickThreeDown;
|
||||||
myLeftEvent = Event::JoystickThreeLeft;
|
myLeftEvent = Event::JoystickThreeLeft;
|
||||||
myRightEvent = Event::JoystickThreeRight;
|
myRightEvent = Event::JoystickThreeRight;
|
||||||
myFireEvent = Event::JoystickThreeFire;
|
myFireEvent = Event::JoystickThreeFire;
|
||||||
}
|
}
|
||||||
myXAxisValue = Event::PaddleTwoAnalog;
|
myXAxisValue = Event::PaddleTwoAnalog; // TODO
|
||||||
myYAxisValue = Event::PaddleThreeAnalog;
|
myYAxisValue = Event::PaddleThreeAnalog; // TODO
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
void Joystick::update()
|
void Joystick::update()
|
||||||
|
{
|
||||||
|
updateButtons();
|
||||||
|
|
||||||
|
updateDigitalAxes();
|
||||||
|
updateAnalogAxes();
|
||||||
|
updateMouseAxes();
|
||||||
|
}
|
||||||
|
|
||||||
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
void Joystick::updateButtons()
|
||||||
|
{
|
||||||
|
bool firePressed = myEvent.get(myFireEvent) != 0;
|
||||||
|
|
||||||
|
// The joystick uses both mouse buttons for the single joystick button
|
||||||
|
updateMouseButtons(firePressed, firePressed);
|
||||||
|
|
||||||
|
setPin(DigitalPin::Six, !getAutoFireState(firePressed));
|
||||||
|
}
|
||||||
|
|
||||||
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
void Joystick::updateMouseButtons(bool& pressedLeft, bool& pressedRight)
|
||||||
|
{
|
||||||
|
if(myControlID > -1)
|
||||||
|
{
|
||||||
|
pressedLeft |= (myEvent.get(Event::MouseButtonLeftValue) != 0);
|
||||||
|
pressedRight |= (pressedRight || myEvent.get(Event::MouseButtonRightValue) != 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
void Joystick::updateDigitalAxes()
|
||||||
{
|
{
|
||||||
// Digital events (from keyboard or joystick hats & buttons)
|
// Digital events (from keyboard or joystick hats & buttons)
|
||||||
setPin(DigitalPin::One, myEvent.get(myUpEvent) == 0);
|
setPin(DigitalPin::One, myEvent.get(myUpEvent) == 0);
|
||||||
setPin(DigitalPin::Two, myEvent.get(myDownEvent) == 0);
|
setPin(DigitalPin::Two, myEvent.get(myDownEvent) == 0);
|
||||||
setPin(DigitalPin::Three, myEvent.get(myLeftEvent) == 0);
|
setPin(DigitalPin::Three, myEvent.get(myLeftEvent) == 0);
|
||||||
setPin(DigitalPin::Four, myEvent.get(myRightEvent) == 0);
|
setPin(DigitalPin::Four, myEvent.get(myRightEvent) == 0);
|
||||||
bool firePressed = myEvent.get(myFireEvent) != 0;
|
}
|
||||||
|
|
||||||
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
void Joystick::updateAnalogAxes()
|
||||||
|
{
|
||||||
// Axis events (usually generated by the Stelladaptor)
|
// Axis events (usually generated by the Stelladaptor)
|
||||||
int xaxis = myEvent.get(myXAxisValue);
|
int xaxis = myEvent.get(myXAxisValue);
|
||||||
int yaxis = myEvent.get(myYAxisValue);
|
int yaxis = myEvent.get(myYAxisValue);
|
||||||
if(xaxis > 16384-4096)
|
if(xaxis > 16384 - 4096)
|
||||||
{
|
{
|
||||||
setPin(DigitalPin::Four, false);
|
setPin(DigitalPin::Four, false);
|
||||||
// Stelladaptor sends "half moved right" for L+R pushed together
|
// Stelladaptor sends "half moved right" for L+R pushed together
|
||||||
if(xaxis < 16384+4096)
|
if(xaxis < 16384 + 4096)
|
||||||
setPin(DigitalPin::Three, false);
|
setPin(DigitalPin::Three, false);
|
||||||
}
|
}
|
||||||
else if(xaxis < -16384)
|
else if(xaxis < -16384)
|
||||||
setPin(DigitalPin::Three, false);
|
setPin(DigitalPin::Three, false);
|
||||||
if(yaxis > 16384-4096)
|
if(yaxis > 16384 - 4096)
|
||||||
{
|
{
|
||||||
setPin(DigitalPin::Two, false);
|
setPin(DigitalPin::Two, false);
|
||||||
// Stelladaptor sends "half moved down" for U+D pushed together
|
// Stelladaptor sends "half moved down" for U+D pushed together
|
||||||
if(yaxis < 16384+4096)
|
if(yaxis < 16384 + 4096)
|
||||||
setPin(DigitalPin::One, false);
|
setPin(DigitalPin::One, false);
|
||||||
}
|
}
|
||||||
else if(yaxis < -16384)
|
else if(yaxis < -16384)
|
||||||
setPin(DigitalPin::One, false);
|
setPin(DigitalPin::One, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
void Joystick::updateMouseAxes()
|
||||||
|
{
|
||||||
// Mouse motion and button events
|
// Mouse motion and button events
|
||||||
if(myControlID > -1)
|
if(myControlID > -1)
|
||||||
{
|
{
|
||||||
|
@ -105,6 +149,7 @@ void Joystick::update()
|
||||||
#define MJ_Threshold 2
|
#define MJ_Threshold 2
|
||||||
int mousex = myEvent.get(Event::MouseAxisXMove),
|
int mousex = myEvent.get(Event::MouseAxisXMove),
|
||||||
mousey = myEvent.get(Event::MouseAxisYMove);
|
mousey = myEvent.get(Event::MouseAxisYMove);
|
||||||
|
|
||||||
if(mousex || mousey)
|
if(mousex || mousey)
|
||||||
{
|
{
|
||||||
if((!(abs(mousey) > abs(mousex) << 1)) && (abs(mousex) >= MJ_Threshold))
|
if((!(abs(mousey) > abs(mousex) << 1)) && (abs(mousex) >= MJ_Threshold))
|
||||||
|
@ -123,12 +168,7 @@ void Joystick::update()
|
||||||
setPin(DigitalPin::Two, false);
|
setPin(DigitalPin::Two, false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Get mouse button state
|
|
||||||
firePressed = firePressed
|
|
||||||
|| myEvent.get(Event::MouseButtonLeftValue)
|
|
||||||
|| myEvent.get(Event::MouseButtonRightValue);
|
|
||||||
}
|
}
|
||||||
setPin(DigitalPin::Six, !getAutoFireState(firePressed));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
@ -136,9 +176,8 @@ bool Joystick::setMouseControl(
|
||||||
Controller::Type xtype, int xid, Controller::Type ytype, int yid)
|
Controller::Type xtype, int xid, Controller::Type ytype, int yid)
|
||||||
{
|
{
|
||||||
// Currently, the joystick takes full control of the mouse, using both
|
// Currently, the joystick takes full control of the mouse, using both
|
||||||
// axes for its two degrees of movement, and both mouse buttons for the
|
// axes for its two degrees of movement
|
||||||
// single joystick button
|
if(xtype == myType && ytype == myType && xid == yid)
|
||||||
if(xtype == Controller::Type::Joystick && ytype == Controller::Type::Joystick && xid == yid)
|
|
||||||
{
|
{
|
||||||
myControlID = ((myJack == Jack::Left && xid == 0) ||
|
myControlID = ((myJack == Jack::Left && xid == 0) ||
|
||||||
(myJack == Jack::Right && xid == 1)
|
(myJack == Jack::Right && xid == 1)
|
||||||
|
|
|
@ -18,7 +18,6 @@
|
||||||
#ifndef JOYSTICK_HXX
|
#ifndef JOYSTICK_HXX
|
||||||
#define JOYSTICK_HXX
|
#define JOYSTICK_HXX
|
||||||
|
|
||||||
#include "bspf.hxx"
|
|
||||||
#include "Event.hxx"
|
#include "Event.hxx"
|
||||||
#include "Control.hxx"
|
#include "Control.hxx"
|
||||||
|
|
||||||
|
@ -41,9 +40,23 @@ class Joystick : public Controller
|
||||||
@param system The system using this controller
|
@param system The system using this controller
|
||||||
@param altmap If true, use alternative mapping
|
@param altmap If true, use alternative mapping
|
||||||
*/
|
*/
|
||||||
Joystick(Jack jack, const Event& event, const System& system, bool altmap = false);
|
Joystick(Jack jack, const Event& event, const System& system,
|
||||||
|
bool altmap = false);
|
||||||
|
|
||||||
~Joystick() override = default;
|
~Joystick() override = default;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
/**
|
||||||
|
Create a new controller plugged into the specified jack
|
||||||
|
|
||||||
|
@param jack The jack the controller is plugged into
|
||||||
|
@param event The event object to use for events
|
||||||
|
@param system The system using this controller
|
||||||
|
@param type The controller type
|
||||||
|
*/
|
||||||
|
Joystick(Jack jack, const Event& event, const System& system,
|
||||||
|
Controller::Type type, bool altmap = false);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
/**
|
/**
|
||||||
Update the entire digital and analog pin state according to the
|
Update the entire digital and analog pin state according to the
|
||||||
|
@ -88,17 +101,48 @@ class Joystick : public Controller
|
||||||
static int deadZoneValue(int deadzone);
|
static int deadZoneValue(int deadzone);
|
||||||
inline static int deadzone() { return _DEAD_ZONE; }
|
inline static int deadzone() { return _DEAD_ZONE; }
|
||||||
|
|
||||||
|
protected:
|
||||||
|
/**
|
||||||
|
Update the button pin states.
|
||||||
|
*/
|
||||||
|
virtual void updateButtons();
|
||||||
|
|
||||||
|
/**
|
||||||
|
Update the button states from the mouse button events currently set.
|
||||||
|
*/
|
||||||
|
void updateMouseButtons(bool& pressedLeft, bool& pressedRight);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
Event::Type myFireEvent;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// Pre-compute the events we care about based on given port
|
// Pre-compute the events we care about based on given port
|
||||||
// This will eliminate test for left or right port in update()
|
// This will eliminate test for left or right port in update()
|
||||||
Event::Type myUpEvent, myDownEvent, myLeftEvent, myRightEvent,
|
Event::Type myUpEvent, myDownEvent, myLeftEvent, myRightEvent,
|
||||||
myXAxisValue, myYAxisValue, myFireEvent;
|
myXAxisValue, myYAxisValue;
|
||||||
|
|
||||||
// Controller to emulate in normal mouse axis mode
|
// Controller to emulate in normal mouse axis mode
|
||||||
int myControlID{-1};
|
int myControlID{-1};
|
||||||
|
|
||||||
static int _DEAD_ZONE;
|
static int _DEAD_ZONE;
|
||||||
|
|
||||||
|
private:
|
||||||
|
/**
|
||||||
|
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 axes value events currently set.
|
||||||
|
*/
|
||||||
|
void updateAnalogAxes();
|
||||||
|
|
||||||
|
/**
|
||||||
|
Update the axes pin states according to mouse events currently set.
|
||||||
|
*/
|
||||||
|
void updateMouseAxes();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// Following constructors and assignment operators not supported
|
// Following constructors and assignment operators not supported
|
||||||
Joystick() = delete;
|
Joystick() = delete;
|
||||||
|
|
Loading…
Reference in New Issue