mirror of https://github.com/stella-emu/stella.git
Joysticks are now detected dynamically, meaning that they can be added/removed
while the emulator is running. git-svn-id: svn://svn.code.sf.net/p/stella/code/trunk@3002 8b62c5a3-ac7e-4cc8-8f21-d9a121418aba
This commit is contained in:
parent
5959f69405
commit
c21220ce2c
|
@ -14,6 +14,11 @@
|
||||||
|
|
||||||
4.1.1 to 4.2: (xxx xx, 2014)
|
4.1.1 to 4.2: (xxx xx, 2014)
|
||||||
|
|
||||||
|
* Controllers are now detected dynamically by Stella. This means that
|
||||||
|
you can plug/unplug joysticks/paddles/etc while Stella is running,
|
||||||
|
and they will be added and removed automatically. Also fixed is
|
||||||
|
a bug whereby sometimes custom joystick mappings weren't being saved.
|
||||||
|
|
||||||
* Fixed 'MDM' scheme to trigger bankswitching on writes to hotspots
|
* Fixed 'MDM' scheme to trigger bankswitching on writes to hotspots
|
||||||
(previously it only triggered on reads). Also, the scheme has been
|
(previously it only triggered on reads). Also, the scheme has been
|
||||||
modified as originally designed by E. Blink; hotspots are now in the
|
modified as originally designed by E. Blink; hotspots are now in the
|
||||||
|
|
|
@ -10,7 +10,7 @@
|
||||||
<br><br>
|
<br><br>
|
||||||
<center><h2><b>A multi-platform Atari 2600 VCS emulator</b></h2></center>
|
<center><h2><b>A multi-platform Atari 2600 VCS emulator</b></h2></center>
|
||||||
|
|
||||||
<center><h4><b>Release 4.1.1</b></h4></center>
|
<center><h4><b>Release 4.2</b></h4></center>
|
||||||
<br><br>
|
<br><br>
|
||||||
|
|
||||||
<center><h2><b>User's Guide</b></h2></center>
|
<center><h2><b>User's Guide</b></h2></center>
|
||||||
|
@ -54,7 +54,7 @@
|
||||||
|
|
||||||
<br><br><br>
|
<br><br><br>
|
||||||
|
|
||||||
<center><b>February 1999 - September 2014</b></center>
|
<center><b>February 1999 - October 2014</b></center>
|
||||||
<center><b>The Stella Team</b></center>
|
<center><b>The Stella Team</b></center>
|
||||||
<center><b><a href="http://stella.sourceforge.net">Stella Homepage</a></b></center>
|
<center><b><a href="http://stella.sourceforge.net">Stella Homepage</a></b></center>
|
||||||
|
|
||||||
|
@ -2767,10 +2767,9 @@
|
||||||
<a href="http://2600-daptor.com">2600-adaptor</a> devices.</p>
|
<a href="http://2600-daptor.com">2600-adaptor</a> devices.</p>
|
||||||
|
|
||||||
<p>Stella can use up to <b>two</b> adaptors; any extra ones are ignored.
|
<p>Stella can use up to <b>two</b> adaptors; any extra ones are ignored.
|
||||||
Stelladaptor devices will be automatically detected and configured. Stelladaptor
|
Stelladaptor devices will be automatically detected and configured. The
|
||||||
devices must be plugged in before starting the application; actual controllers
|
actual controllers can be plugged/unplugged while the emulator is running,
|
||||||
can be plugged/unplugged while the emulator is running, although you will need
|
although you will need to restart the game currently being emulated.</p>
|
||||||
to restart the game currently being emulated.</p>
|
|
||||||
|
|
||||||
<p>The detection and configuration is as follows:
|
<p>The detection and configuration is as follows:
|
||||||
|
|
||||||
|
|
|
@ -31,29 +31,6 @@ EventHandlerSDL2::~EventHandlerSDL2()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
||||||
void EventHandlerSDL2::initializeJoysticks()
|
|
||||||
{
|
|
||||||
#ifdef JOYSTICK_SUPPORT
|
|
||||||
// Initialize the joystick subsystem
|
|
||||||
if(SDL_WasInit(SDL_INIT_JOYSTICK) != 0)
|
|
||||||
{
|
|
||||||
if(SDL_NumJoysticks() > 0)
|
|
||||||
{
|
|
||||||
int numSticks = SDL_NumJoysticks();
|
|
||||||
for(int i = 0; i < numSticks; ++i)
|
|
||||||
addJoystick(new JoystickSDL2(i), i);
|
|
||||||
|
|
||||||
myOSystem.logMessage("EventHandlerSDL2::initializeJoysticks() +sticks", 2);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
myOSystem.logMessage("EventHandlerSDL2::initializeJoysticks() -sticks", 2);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
myOSystem.logMessage("EventHandlerSDL2::initializeJoysticks() failed!", 2);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
void EventHandlerSDL2::enableTextEvents(bool enable)
|
void EventHandlerSDL2::enableTextEvents(bool enable)
|
||||||
{
|
{
|
||||||
|
@ -157,6 +134,17 @@ void EventHandlerSDL2::pollEvent()
|
||||||
handleJoyHatEvent(myEvent.jhat.which, myEvent.jhat.hat, value);
|
handleJoyHatEvent(myEvent.jhat.which, myEvent.jhat.hat, value);
|
||||||
break; // SDL_JOYHATMOTION
|
break; // SDL_JOYHATMOTION
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case SDL_JOYDEVICEADDED:
|
||||||
|
{
|
||||||
|
addJoystick(new JoystickSDL2(myEvent.jdevice.which));
|
||||||
|
break; // SDL_JOYDEVICEADDED
|
||||||
|
}
|
||||||
|
case SDL_JOYDEVICEREMOVED:
|
||||||
|
{
|
||||||
|
removeJoystick(myEvent.jdevice.which);
|
||||||
|
break; // SDL_JOYDEVICEREMOVED
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
case SDL_QUIT:
|
case SDL_QUIT:
|
||||||
|
@ -216,23 +204,19 @@ void EventHandlerSDL2::pollEvent()
|
||||||
EventHandlerSDL2::JoystickSDL2::JoystickSDL2(int idx)
|
EventHandlerSDL2::JoystickSDL2::JoystickSDL2(int idx)
|
||||||
: myStick(NULL)
|
: myStick(NULL)
|
||||||
{
|
{
|
||||||
#ifdef JOYSTICK_SUPPORT
|
|
||||||
myStick = SDL_JoystickOpen(idx);
|
myStick = SDL_JoystickOpen(idx);
|
||||||
if(myStick)
|
if(myStick)
|
||||||
{
|
{
|
||||||
initialize(SDL_JoystickName(myStick),
|
initialize(idx, SDL_JoystickName(myStick),
|
||||||
SDL_JoystickNumAxes(myStick), SDL_JoystickNumButtons(myStick),
|
SDL_JoystickNumAxes(myStick), SDL_JoystickNumButtons(myStick),
|
||||||
SDL_JoystickNumHats(myStick), SDL_JoystickNumBalls(myStick));
|
SDL_JoystickNumHats(myStick), SDL_JoystickNumBalls(myStick));
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
EventHandlerSDL2::JoystickSDL2::~JoystickSDL2()
|
EventHandlerSDL2::JoystickSDL2::~JoystickSDL2()
|
||||||
{
|
{
|
||||||
#ifdef JOYSTICK_SUPPORT
|
|
||||||
if(myStick)
|
if(myStick)
|
||||||
SDL_JoystickClose(myStick);
|
SDL_JoystickClose(myStick);
|
||||||
myStick = NULL;
|
myStick = NULL;
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -45,11 +45,6 @@ class EventHandlerSDL2 : public EventHandler
|
||||||
virtual ~EventHandlerSDL2();
|
virtual ~EventHandlerSDL2();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
/**
|
|
||||||
Set up any joysticks on the system.
|
|
||||||
*/
|
|
||||||
void initializeJoysticks();
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Enable/disable text events (distinct from single-key events).
|
Enable/disable text events (distinct from single-key events).
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -62,7 +62,8 @@ EventHandler::EventHandler(OSystem& osystem)
|
||||||
myState(S_NONE),
|
myState(S_NONE),
|
||||||
myAllowAllDirectionsFlag(false),
|
myAllowAllDirectionsFlag(false),
|
||||||
myFryingFlag(false),
|
myFryingFlag(false),
|
||||||
mySkipMouseMotion(true)
|
mySkipMouseMotion(true),
|
||||||
|
myJoyHandler(NULL)
|
||||||
{
|
{
|
||||||
// Erase the key mapping array
|
// Erase the key mapping array
|
||||||
for(int i = 0; i < KBDK_LAST; ++i)
|
for(int i = 0; i < KBDK_LAST; ++i)
|
||||||
|
@ -73,6 +74,9 @@ EventHandler::EventHandler(OSystem& osystem)
|
||||||
for(int i = 0; i < kComboSize; ++i)
|
for(int i = 0; i < kComboSize; ++i)
|
||||||
for(int j = 0; j < kEventsPerCombo; ++j)
|
for(int j = 0; j < kEventsPerCombo; ++j)
|
||||||
myComboTable[i][j] = Event::NoType;
|
myComboTable[i][j] = Event::NoType;
|
||||||
|
|
||||||
|
// Create joystick handler (to handle all joystick functionality)
|
||||||
|
myJoyHandler = new JoystickHandler(osystem);
|
||||||
}
|
}
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
@ -86,9 +90,8 @@ EventHandler::~EventHandler()
|
||||||
if(ourMenuActionList[i].key)
|
if(ourMenuActionList[i].key)
|
||||||
free(ourMenuActionList[i].key);
|
free(ourMenuActionList[i].key);
|
||||||
|
|
||||||
delete myMouseControl;
|
delete myMouseControl; myMouseControl = NULL;
|
||||||
for(uInt32 i = 0; i < myJoysticks.size(); ++i)
|
delete myJoyHandler; myJoyHandler = NULL;
|
||||||
delete myJoysticks[i];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
@ -115,31 +118,6 @@ void EventHandler::initialize()
|
||||||
|
|
||||||
// Integer to string conversions (for HEX) use upper or lower-case
|
// Integer to string conversions (for HEX) use upper or lower-case
|
||||||
Common::Base::setHexUppercase(myOSystem.settings().getBool("dbg.uhex"));
|
Common::Base::setHexUppercase(myOSystem.settings().getBool("dbg.uhex"));
|
||||||
|
|
||||||
// Joystick stuff
|
|
||||||
#ifdef JOYSTICK_SUPPORT
|
|
||||||
initializeJoysticks();
|
|
||||||
|
|
||||||
// Map the stelladaptors we've found according to the specified ports
|
|
||||||
mapStelladaptors(myOSystem.settings().getString("saport"));
|
|
||||||
|
|
||||||
setJoymap();
|
|
||||||
setActionMappings(kEmulationMode);
|
|
||||||
setActionMappings(kMenuMode);
|
|
||||||
|
|
||||||
ostringstream buf;
|
|
||||||
buf << "Joystick devices found:" << endl;
|
|
||||||
if(myJoysticks.size() == 0)
|
|
||||||
buf << "No joysticks present." << endl;
|
|
||||||
else
|
|
||||||
{
|
|
||||||
for(uInt32 i = 0; i < myJoysticks.size(); ++i)
|
|
||||||
buf << " " << i << ": " << myJoysticks[i]->about() << endl;
|
|
||||||
}
|
|
||||||
myOSystem.logMessage(buf.str(), 1);
|
|
||||||
#else
|
|
||||||
myOSystem.logMessage("Joystick support disabled.", 1);
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
@ -158,104 +136,20 @@ void EventHandler::reset(State state)
|
||||||
}
|
}
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
void EventHandler::addJoystick(StellaJoystick* stick, int idx)
|
void EventHandler::addJoystick(StellaJoystick* stick)
|
||||||
{
|
{
|
||||||
#ifdef JOYSTICK_SUPPORT
|
#ifdef JOYSTICK_SUPPORT
|
||||||
myJoysticks.insert_at(idx, stick);
|
int idx = myJoyHandler->add(stick);
|
||||||
|
if(idx < 0)
|
||||||
// Skip if we couldn't open it for any reason
|
|
||||||
if(stick->name == "None")
|
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// Figure out what type of joystick this is
|
setActionMappings(kEmulationMode);
|
||||||
if(stick->name.find("2600-daptor", 0) != string::npos)
|
setActionMappings(kMenuMode);
|
||||||
{
|
|
||||||
// 2600-daptorII devices have 3 axes and 12 buttons, and the value of the z-axis
|
|
||||||
// determines how those 12 buttons are used (not all buttons are used in all modes)
|
|
||||||
if(stick->numAxes == 3)
|
|
||||||
{
|
|
||||||
// TODO - stubbed out for now, until we find a way to reliably get info
|
|
||||||
// from the Z axis
|
|
||||||
stick->name = "2600-daptor II";
|
|
||||||
}
|
|
||||||
else
|
|
||||||
stick->name = "2600-daptor";
|
|
||||||
}
|
|
||||||
else if(stick->name.find("Stelladaptor", 0) != string::npos)
|
|
||||||
{
|
|
||||||
stick->name = "Stelladaptor";
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// We need unique names for mappable devices
|
|
||||||
int count = 0;
|
|
||||||
for(uInt32 i = 0; i < myJoysticks.size(); ++i)
|
|
||||||
if(BSPF_startsWithIgnoreCase(myJoysticks[i]->name, stick->name))
|
|
||||||
++count;
|
|
||||||
|
|
||||||
if(count > 1)
|
ostringstream buf;
|
||||||
{
|
buf << "Added joystick " << stick->ID << ":" << endl
|
||||||
ostringstream name;
|
<< " " << stick->about() << endl;
|
||||||
name << stick->name << " " << count;
|
myOSystem.logMessage(buf.str(), 1);
|
||||||
stick->name = name.str();
|
|
||||||
}
|
|
||||||
stick->type = StellaJoystick::JT_REGULAR;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
||||||
void EventHandler::mapStelladaptors(const string& saport)
|
|
||||||
{
|
|
||||||
#ifdef JOYSTICK_SUPPORT
|
|
||||||
// saport will have two values:
|
|
||||||
// 'lr' means treat first valid adaptor as left port, second as right port
|
|
||||||
// 'rl' means treat first valid adaptor as right port, second as left port
|
|
||||||
// We know there will be only two such devices (at most), since the logic
|
|
||||||
// in setupJoysticks take care of that
|
|
||||||
int saCount = 0;
|
|
||||||
int saOrder[2];
|
|
||||||
if(BSPF_equalsIgnoreCase(saport, "lr"))
|
|
||||||
{
|
|
||||||
saOrder[0] = 1; saOrder[1] = 2;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
saOrder[0] = 2; saOrder[1] = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
for(uInt32 i = 0; i < myJoysticks.size(); ++i)
|
|
||||||
{
|
|
||||||
if(BSPF_startsWithIgnoreCase(myJoysticks[i]->name, "Stelladaptor"))
|
|
||||||
{
|
|
||||||
if(saOrder[saCount] == 1)
|
|
||||||
{
|
|
||||||
myJoysticks[i]->name += " (emulates left joystick port)";
|
|
||||||
myJoysticks[i]->type = StellaJoystick::JT_STELLADAPTOR_LEFT;
|
|
||||||
}
|
|
||||||
else if(saOrder[saCount] == 2)
|
|
||||||
{
|
|
||||||
myJoysticks[i]->name += " (emulates right joystick port)";
|
|
||||||
myJoysticks[i]->type = StellaJoystick::JT_STELLADAPTOR_RIGHT;
|
|
||||||
}
|
|
||||||
saCount++;
|
|
||||||
}
|
|
||||||
else if(BSPF_startsWithIgnoreCase(myJoysticks[i]->name, "2600-daptor"))
|
|
||||||
{
|
|
||||||
if(saOrder[saCount] == 1)
|
|
||||||
{
|
|
||||||
myJoysticks[i]->name += " (emulates left joystick port)";
|
|
||||||
myJoysticks[i]->type = StellaJoystick::JT_2600DAPTOR_LEFT;
|
|
||||||
}
|
|
||||||
else if(saOrder[saCount] == 2)
|
|
||||||
{
|
|
||||||
myJoysticks[i]->name += " (emulates right joystick port)";
|
|
||||||
myJoysticks[i]->type = StellaJoystick::JT_2600DAPTOR_RIGHT;
|
|
||||||
}
|
|
||||||
saCount++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
myOSystem.settings().setValue("saport", saport);
|
|
||||||
|
|
||||||
// We're potentially swapping out an input device behind the back of
|
// We're potentially swapping out an input device behind the back of
|
||||||
// the Event system, so we make sure all Stelladaptor-generated events
|
// the Event system, so we make sure all Stelladaptor-generated events
|
||||||
|
@ -272,9 +166,26 @@ void EventHandler::mapStelladaptors(const string& saport)
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
void EventHandler::removeJoystick(int idx)
|
||||||
|
{
|
||||||
|
#ifdef JOYSTICK_SUPPORT
|
||||||
|
myJoyHandler->remove(idx);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
void EventHandler::mapStelladaptors(const string& saport)
|
||||||
|
{
|
||||||
|
#ifdef JOYSTICK_SUPPORT
|
||||||
|
myJoyHandler->mapStelladaptors(saport);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
void EventHandler::toggleSAPortOrder()
|
void EventHandler::toggleSAPortOrder()
|
||||||
{
|
{
|
||||||
|
#ifdef JOYSTICK_SUPPORT
|
||||||
const string& saport = myOSystem.settings().getString("saport");
|
const string& saport = myOSystem.settings().getString("saport");
|
||||||
if(saport == "lr")
|
if(saport == "lr")
|
||||||
{
|
{
|
||||||
|
@ -286,6 +197,7 @@ void EventHandler::toggleSAPortOrder()
|
||||||
mapStelladaptors("lr");
|
mapStelladaptors("lr");
|
||||||
myOSystem.frameBuffer().showMessage("Stelladaptor ports left/right");
|
myOSystem.frameBuffer().showMessage("Stelladaptor ports left/right");
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
@ -690,21 +602,20 @@ void EventHandler::handleMouseButtonEvent(MouseButton b, int x, int y)
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
void EventHandler::handleJoyEvent(int stick, int button, uInt8 state)
|
void EventHandler::handleJoyEvent(int stick, int button, uInt8 state)
|
||||||
{
|
{
|
||||||
if(stick >= (int)myJoysticks.size())
|
const StellaJoystick* joy = myJoyHandler->joy(stick);
|
||||||
return;
|
if(!joy) return;
|
||||||
|
|
||||||
// Stelladaptors handle buttons differently than regular joysticks
|
// Stelladaptors handle buttons differently than regular joysticks
|
||||||
const StellaJoystick& joy = *myJoysticks[stick];
|
switch(joy->type)
|
||||||
switch(joy.type)
|
|
||||||
{
|
{
|
||||||
case StellaJoystick::JT_REGULAR:
|
case StellaJoystick::JT_REGULAR:
|
||||||
// Handle buttons which switch eventhandler state
|
// Handle buttons which switch eventhandler state
|
||||||
if(state && eventStateChange(joy.btnTable[button][kEmulationMode]))
|
if(state && eventStateChange(joy->btnTable[button][kEmulationMode]))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// Determine which mode we're in, then send the event to the appropriate place
|
// Determine which mode we're in, then send the event to the appropriate place
|
||||||
if(myState == S_EMULATE)
|
if(myState == S_EMULATE)
|
||||||
handleEvent(joy.btnTable[button][kEmulationMode], state);
|
handleEvent(joy->btnTable[button][kEmulationMode], state);
|
||||||
else if(myOverlay != NULL)
|
else if(myOverlay != NULL)
|
||||||
myOverlay->handleJoyEvent(stick, button, state);
|
myOverlay->handleJoyEvent(stick, button, state);
|
||||||
break; // Regular button
|
break; // Regular button
|
||||||
|
@ -716,7 +627,7 @@ void EventHandler::handleJoyEvent(int stick, int button, uInt8 state)
|
||||||
// The 'type-2' here refers to the fact that 'StellaJoystick::JT_STELLADAPTOR_LEFT'
|
// The 'type-2' here refers to the fact that 'StellaJoystick::JT_STELLADAPTOR_LEFT'
|
||||||
// and 'StellaJoystick::JT_STELLADAPTOR_RIGHT' are at index 2 and 3 in the JoyType
|
// and 'StellaJoystick::JT_STELLADAPTOR_RIGHT' are at index 2 and 3 in the JoyType
|
||||||
// enum; subtracting two gives us Controller 0 and 1
|
// enum; subtracting two gives us Controller 0 and 1
|
||||||
if(button < 2) myEvent.set(SA_Button[joy.type-2][button], state);
|
if(button < 2) myEvent.set(SA_Button[joy->type-2][button], state);
|
||||||
break; // Stelladaptor button
|
break; // Stelladaptor button
|
||||||
case StellaJoystick::JT_2600DAPTOR_LEFT:
|
case StellaJoystick::JT_2600DAPTOR_LEFT:
|
||||||
case StellaJoystick::JT_2600DAPTOR_RIGHT:
|
case StellaJoystick::JT_2600DAPTOR_RIGHT:
|
||||||
|
@ -728,18 +639,18 @@ void EventHandler::handleJoyEvent(int stick, int button, uInt8 state)
|
||||||
switch(myOSystem.console().controller(Controller::Left).type())
|
switch(myOSystem.console().controller(Controller::Left).type())
|
||||||
{
|
{
|
||||||
case Controller::Keyboard:
|
case Controller::Keyboard:
|
||||||
if(button < 12) myEvent.set(SA_Key[joy.type-4][button], state);
|
if(button < 12) myEvent.set(SA_Key[joy->type-4][button], state);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
if(button < 4) myEvent.set(SA_Button[joy.type-4][button], state);
|
if(button < 4) myEvent.set(SA_Button[joy->type-4][button], state);
|
||||||
}
|
}
|
||||||
switch(myOSystem.console().controller(Controller::Right).type())
|
switch(myOSystem.console().controller(Controller::Right).type())
|
||||||
{
|
{
|
||||||
case Controller::Keyboard:
|
case Controller::Keyboard:
|
||||||
if(button < 12) myEvent.set(SA_Key[joy.type-4][button], state);
|
if(button < 12) myEvent.set(SA_Key[joy->type-4][button], state);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
if(button < 4) myEvent.set(SA_Button[joy.type-4][button], state);
|
if(button < 4) myEvent.set(SA_Button[joy->type-4][button], state);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break; // 2600DAPTOR button
|
break; // 2600DAPTOR button
|
||||||
|
@ -751,19 +662,18 @@ void EventHandler::handleJoyEvent(int stick, int button, uInt8 state)
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
void EventHandler::handleJoyAxisEvent(int stick, int axis, int value)
|
void EventHandler::handleJoyAxisEvent(int stick, int axis, int value)
|
||||||
{
|
{
|
||||||
if(stick >= (int)myJoysticks.size())
|
const StellaJoystick* joy = myJoyHandler->joy(stick);
|
||||||
return;
|
if(!joy) return;
|
||||||
|
|
||||||
// Stelladaptors handle axis differently than regular joysticks
|
// Stelladaptors handle axis differently than regular joysticks
|
||||||
const StellaJoystick& joy = *myJoysticks[stick];
|
switch(joy->type)
|
||||||
switch(joy.type)
|
|
||||||
{
|
{
|
||||||
case StellaJoystick::JT_REGULAR:
|
case StellaJoystick::JT_REGULAR:
|
||||||
if(myState == S_EMULATE)
|
if(myState == S_EMULATE)
|
||||||
{
|
{
|
||||||
// Every axis event has two associated values, negative and positive
|
// Every axis event has two associated values, negative and positive
|
||||||
Event::Type eventAxisNeg = joy.axisTable[axis][0][kEmulationMode];
|
Event::Type eventAxisNeg = joy->axisTable[axis][0][kEmulationMode];
|
||||||
Event::Type eventAxisPos = joy.axisTable[axis][1][kEmulationMode];
|
Event::Type eventAxisPos = joy->axisTable[axis][1][kEmulationMode];
|
||||||
|
|
||||||
// Check for analog events, which are handled differently
|
// Check for analog events, which are handled differently
|
||||||
// We'll pass them off as Stelladaptor events, and let the controllers
|
// We'll pass them off as Stelladaptor events, and let the controllers
|
||||||
|
@ -796,7 +706,7 @@ void EventHandler::handleJoyAxisEvent(int stick, int axis, int value)
|
||||||
|
|
||||||
// Now filter out consecutive, similar values
|
// Now filter out consecutive, similar values
|
||||||
// (only pass on the event if the state has changed)
|
// (only pass on the event if the state has changed)
|
||||||
if(joy.axisLastValue[axis] != value)
|
if(joy->axisLastValue[axis] != value)
|
||||||
{
|
{
|
||||||
// Turn off both events, since we don't know exactly which one
|
// Turn off both events, since we don't know exactly which one
|
||||||
// was previously activated.
|
// was previously activated.
|
||||||
|
@ -804,7 +714,7 @@ void EventHandler::handleJoyAxisEvent(int stick, int axis, int value)
|
||||||
handleEvent(eventAxisPos, 0);
|
handleEvent(eventAxisPos, 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
joy.axisLastValue[axis] = value;
|
joy->axisLastValue[axis] = value;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -822,10 +732,10 @@ void EventHandler::handleJoyAxisEvent(int stick, int axis, int value)
|
||||||
|
|
||||||
// Now filter out consecutive, similar values
|
// Now filter out consecutive, similar values
|
||||||
// (only pass on the event if the state has changed)
|
// (only pass on the event if the state has changed)
|
||||||
if(value != joy.axisLastValue[axis])
|
if(value != joy->axisLastValue[axis])
|
||||||
{
|
{
|
||||||
myOverlay->handleJoyAxisEvent(stick, axis, value);
|
myOverlay->handleJoyAxisEvent(stick, axis, value);
|
||||||
joy.axisLastValue[axis] = value;
|
joy->axisLastValue[axis] = value;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break; // Regular joystick axis
|
break; // Regular joystick axis
|
||||||
|
@ -841,7 +751,7 @@ void EventHandler::handleJoyAxisEvent(int stick, int axis, int value)
|
||||||
// and 'StellaJoystick::JT_STELLADAPTOR_RIGHT' are at index 2 and 3 in the JoyType
|
// and 'StellaJoystick::JT_STELLADAPTOR_RIGHT' are at index 2 and 3 in the JoyType
|
||||||
// enum; subtracting two gives us Controller 0 and 1
|
// enum; subtracting two gives us Controller 0 and 1
|
||||||
if(axis < 2)
|
if(axis < 2)
|
||||||
myEvent.set(SA_Axis[joy.type-2][axis], value);
|
myEvent.set(SA_Axis[joy->type-2][axis], value);
|
||||||
break; // Stelladaptor axis
|
break; // Stelladaptor axis
|
||||||
case StellaJoystick::JT_2600DAPTOR_LEFT:
|
case StellaJoystick::JT_2600DAPTOR_LEFT:
|
||||||
case StellaJoystick::JT_2600DAPTOR_RIGHT:
|
case StellaJoystick::JT_2600DAPTOR_RIGHT:
|
||||||
|
@ -849,7 +759,7 @@ void EventHandler::handleJoyAxisEvent(int stick, int axis, int value)
|
||||||
// and 'StellaJoystick::JT_2600DAPTOR_RIGHT' are at index 4 and 5 in the JoyType
|
// and 'StellaJoystick::JT_2600DAPTOR_RIGHT' are at index 4 and 5 in the JoyType
|
||||||
// enum; subtracting four gives us Controller 0 and 1
|
// enum; subtracting four gives us Controller 0 and 1
|
||||||
if(axis < 2)
|
if(axis < 2)
|
||||||
myEvent.set(SA_Axis[joy.type-4][axis], value);
|
myEvent.set(SA_Axis[joy->type-4][axis], value);
|
||||||
break; // 26000daptor axis
|
break; // 26000daptor axis
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
|
@ -859,23 +769,21 @@ void EventHandler::handleJoyAxisEvent(int stick, int axis, int value)
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
void EventHandler::handleJoyHatEvent(int stick, int hat, int value)
|
void EventHandler::handleJoyHatEvent(int stick, int hat, int value)
|
||||||
{
|
{
|
||||||
if(stick >= (int)myJoysticks.size())
|
const StellaJoystick* joy = myJoyHandler->joy(stick);
|
||||||
return;
|
if(!joy) return;
|
||||||
|
|
||||||
const StellaJoystick& joy = *myJoysticks[stick];
|
|
||||||
|
|
||||||
// Preprocess all hat events, converting to Stella JoyHat type
|
// Preprocess all hat events, converting to Stella JoyHat type
|
||||||
// Generate multiple equivalent hat events representing combined direction
|
// Generate multiple equivalent hat events representing combined direction
|
||||||
// when we get a diagonal hat event
|
// when we get a diagonal hat event
|
||||||
if(myState == S_EMULATE)
|
if(myState == S_EMULATE)
|
||||||
{
|
{
|
||||||
handleEvent(joy.hatTable[hat][EVENT_HATUP][kEmulationMode],
|
handleEvent(joy->hatTable[hat][EVENT_HATUP][kEmulationMode],
|
||||||
value & EVENT_HATUP_M);
|
value & EVENT_HATUP_M);
|
||||||
handleEvent(joy.hatTable[hat][EVENT_HATRIGHT][kEmulationMode],
|
handleEvent(joy->hatTable[hat][EVENT_HATRIGHT][kEmulationMode],
|
||||||
value & EVENT_HATRIGHT_M);
|
value & EVENT_HATRIGHT_M);
|
||||||
handleEvent(joy.hatTable[hat][EVENT_HATDOWN][kEmulationMode],
|
handleEvent(joy->hatTable[hat][EVENT_HATDOWN][kEmulationMode],
|
||||||
value & EVENT_HATDOWN_M);
|
value & EVENT_HATDOWN_M);
|
||||||
handleEvent(joy.hatTable[hat][EVENT_HATLEFT][kEmulationMode],
|
handleEvent(joy->hatTable[hat][EVENT_HATLEFT][kEmulationMode],
|
||||||
value & EVENT_HATLEFT_M);
|
value & EVENT_HATLEFT_M);
|
||||||
}
|
}
|
||||||
else if(myOverlay != NULL)
|
else if(myOverlay != NULL)
|
||||||
|
@ -1164,14 +1072,15 @@ void EventHandler::setActionMappings(EventMode mode)
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef JOYSTICK_SUPPORT
|
#ifdef JOYSTICK_SUPPORT
|
||||||
for(uInt32 stick = 0; stick < myJoysticks.size(); ++stick)
|
for(uInt32 stick = 0; stick < myJoyHandler->numSticks(); ++stick)
|
||||||
{
|
{
|
||||||
const StellaJoystick& joy = *myJoysticks[stick];
|
const StellaJoystick* joy = myJoyHandler->joy(stick);
|
||||||
|
if(!joy) continue;
|
||||||
|
|
||||||
// Joystick button mapping/labeling
|
// Joystick button mapping/labeling
|
||||||
for(int button = 0; button < joy.numButtons; ++button)
|
for(int button = 0; button < joy->numButtons; ++button)
|
||||||
{
|
{
|
||||||
if(joy.btnTable[button][mode] == event)
|
if(joy->btnTable[button][mode] == event)
|
||||||
{
|
{
|
||||||
buf.str("");
|
buf.str("");
|
||||||
buf << "J" << stick << "/B" << button;
|
buf << "J" << stick << "/B" << button;
|
||||||
|
@ -1183,11 +1092,11 @@ void EventHandler::setActionMappings(EventMode mode)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Joystick axis mapping/labeling
|
// Joystick axis mapping/labeling
|
||||||
for(int axis = 0; axis < joy.numAxes; ++axis)
|
for(int axis = 0; axis < joy->numAxes; ++axis)
|
||||||
{
|
{
|
||||||
for(int dir = 0; dir < 2; ++dir)
|
for(int dir = 0; dir < 2; ++dir)
|
||||||
{
|
{
|
||||||
if(joy.axisTable[axis][dir][mode] == event)
|
if(joy->axisTable[axis][dir][mode] == event)
|
||||||
{
|
{
|
||||||
buf.str("");
|
buf.str("");
|
||||||
buf << "J" << stick << "/A" << axis;
|
buf << "J" << stick << "/A" << axis;
|
||||||
|
@ -1210,11 +1119,11 @@ void EventHandler::setActionMappings(EventMode mode)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Joystick hat mapping/labeling
|
// Joystick hat mapping/labeling
|
||||||
for(int hat = 0; hat < joy.numHats; ++hat)
|
for(int hat = 0; hat < joy->numHats; ++hat)
|
||||||
{
|
{
|
||||||
for(int dir = 0; dir < 4; ++dir)
|
for(int dir = 0; dir < 4; ++dir)
|
||||||
{
|
{
|
||||||
if(joy.hatTable[hat][dir][mode] == event)
|
if(joy->hatTable[hat][dir][mode] == event)
|
||||||
{
|
{
|
||||||
buf.str("");
|
buf.str("");
|
||||||
buf << "J" << stick << "/H" << hat;
|
buf << "J" << stick << "/H" << hat;
|
||||||
|
@ -1298,48 +1207,6 @@ void EventHandler::setKeymap()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
||||||
void EventHandler::setJoymap()
|
|
||||||
{
|
|
||||||
#ifdef JOYSTICK_SUPPORT
|
|
||||||
setDefaultJoymap(Event::NoType, kEmulationMode);
|
|
||||||
setDefaultJoymap(Event::NoType, kMenuMode);
|
|
||||||
|
|
||||||
// Get all mappings from the settings
|
|
||||||
istringstream buf(myOSystem.settings().getString("joymap"));
|
|
||||||
string joymap;
|
|
||||||
|
|
||||||
// First check the event type, and disregard the entire mapping if it's invalid
|
|
||||||
getline(buf, joymap, '^');
|
|
||||||
if(atoi(joymap.c_str()) != Event::LastType)
|
|
||||||
return;
|
|
||||||
|
|
||||||
// Otherwise, put each joystick mapping entry into a hashmap
|
|
||||||
while(getline(buf, joymap, '^'))
|
|
||||||
{
|
|
||||||
istringstream namebuf(joymap);
|
|
||||||
string joyname;
|
|
||||||
getline(namebuf, joyname, '|');
|
|
||||||
if(joyname.length() != 0)
|
|
||||||
myJoystickMap.insert(make_pair(joyname, joymap));
|
|
||||||
}
|
|
||||||
|
|
||||||
// Next try to match the mappings to the specific joystick (by name)
|
|
||||||
// We do it this way since a joystick may be unplugged and replugged,
|
|
||||||
// but it's settings should stay the same
|
|
||||||
for(uInt32 i = 0; i < myJoysticks.size(); ++i)
|
|
||||||
{
|
|
||||||
StellaJoystick& joy = *myJoysticks[i];
|
|
||||||
if(joy.type == StellaJoystick::JT_REGULAR)
|
|
||||||
{
|
|
||||||
map<string,string>::const_iterator iter = myJoystickMap.find(joy.name);
|
|
||||||
if(iter != myJoystickMap.end())
|
|
||||||
joy.setMap(iter->second);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
void EventHandler::setComboMap()
|
void EventHandler::setComboMap()
|
||||||
{
|
{
|
||||||
|
@ -1404,36 +1271,34 @@ bool EventHandler::addJoyAxisMapping(Event::Type event, EventMode mode,
|
||||||
bool updateMenus)
|
bool updateMenus)
|
||||||
{
|
{
|
||||||
#ifdef JOYSTICK_SUPPORT
|
#ifdef JOYSTICK_SUPPORT
|
||||||
if(stick >= 0 && stick < (int)myJoysticks.size())
|
const StellaJoystick* joy = myJoyHandler->joy(stick);
|
||||||
|
if(joy)
|
||||||
{
|
{
|
||||||
const StellaJoystick& joy = *myJoysticks[stick];
|
if(axis >= 0 && axis < joy->numAxes &&
|
||||||
if(axis >= 0 && axis < joy.numAxes &&
|
|
||||||
event >= 0 && event < Event::LastType)
|
event >= 0 && event < Event::LastType)
|
||||||
{
|
{
|
||||||
// This confusing code is because each axis has two associated values,
|
// This confusing code is because each axis has two associated values,
|
||||||
// but analog events only affect one of the axis.
|
// but analog events only affect one of the axis.
|
||||||
if(eventIsAnalog(event))
|
if(eventIsAnalog(event))
|
||||||
joy.axisTable[axis][0][mode] =
|
joy->axisTable[axis][0][mode] =
|
||||||
joy.axisTable[axis][1][mode] = event;
|
joy->axisTable[axis][1][mode] = event;
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// Otherwise, turn off the analog event(s) for this axis
|
// Otherwise, turn off the analog event(s) for this axis
|
||||||
if(eventIsAnalog(joy.axisTable[axis][0][mode]))
|
if(eventIsAnalog(joy->axisTable[axis][0][mode]))
|
||||||
joy.axisTable[axis][0][mode] = Event::NoType;
|
joy->axisTable[axis][0][mode] = Event::NoType;
|
||||||
if(eventIsAnalog(joy.axisTable[axis][1][mode]))
|
if(eventIsAnalog(joy->axisTable[axis][1][mode]))
|
||||||
joy.axisTable[axis][1][mode] = Event::NoType;
|
joy->axisTable[axis][1][mode] = Event::NoType;
|
||||||
|
|
||||||
joy.axisTable[axis][(value > 0)][mode] = event;
|
joy->axisTable[axis][(value > 0)][mode] = event;
|
||||||
}
|
}
|
||||||
if(updateMenus)
|
if(updateMenus)
|
||||||
setActionMappings(mode);
|
setActionMappings(mode);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return false;
|
|
||||||
#else
|
|
||||||
return false;
|
|
||||||
#endif
|
#endif
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
@ -1442,22 +1307,20 @@ bool EventHandler::addJoyButtonMapping(Event::Type event, EventMode mode,
|
||||||
bool updateMenus)
|
bool updateMenus)
|
||||||
{
|
{
|
||||||
#ifdef JOYSTICK_SUPPORT
|
#ifdef JOYSTICK_SUPPORT
|
||||||
if(stick >= 0 && stick < (int)myJoysticks.size() && !eventIsAnalog(event))
|
const StellaJoystick* joy = myJoyHandler->joy(stick);
|
||||||
|
if(joy)
|
||||||
{
|
{
|
||||||
const StellaJoystick& joy = *myJoysticks[stick];
|
if(button >= 0 && button < joy->numButtons &&
|
||||||
if(button >= 0 && button < joy.numButtons &&
|
|
||||||
event >= 0 && event < Event::LastType)
|
event >= 0 && event < Event::LastType)
|
||||||
{
|
{
|
||||||
joy.btnTable[button][mode] = event;
|
joy->btnTable[button][mode] = event;
|
||||||
if(updateMenus)
|
if(updateMenus)
|
||||||
setActionMappings(mode);
|
setActionMappings(mode);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return false;
|
|
||||||
#else
|
|
||||||
return false;
|
|
||||||
#endif
|
#endif
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
@ -1466,22 +1329,20 @@ bool EventHandler::addJoyHatMapping(Event::Type event, EventMode mode,
|
||||||
bool updateMenus)
|
bool updateMenus)
|
||||||
{
|
{
|
||||||
#ifdef JOYSTICK_SUPPORT
|
#ifdef JOYSTICK_SUPPORT
|
||||||
if(stick >= 0 && stick < (int)myJoysticks.size() && !eventIsAnalog(event))
|
const StellaJoystick* joy = myJoyHandler->joy(stick);
|
||||||
|
if(joy)
|
||||||
{
|
{
|
||||||
const StellaJoystick& joy = *myJoysticks[stick];
|
if(hat >= 0 && hat < joy->numHats &&
|
||||||
if(hat >= 0 && hat < joy.numHats &&
|
|
||||||
event >= 0 && event < Event::LastType && value != EVENT_HATCENTER)
|
event >= 0 && event < Event::LastType && value != EVENT_HATCENTER)
|
||||||
{
|
{
|
||||||
joy.hatTable[hat][value][mode] = event;
|
joy->hatTable[hat][value][mode] = event;
|
||||||
if(updateMenus)
|
if(updateMenus)
|
||||||
setActionMappings(mode);
|
setActionMappings(mode);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return false;
|
|
||||||
#else
|
|
||||||
return false;
|
|
||||||
#endif
|
#endif
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
@ -1494,8 +1355,7 @@ void EventHandler::eraseMapping(Event::Type event, EventMode mode)
|
||||||
|
|
||||||
#ifdef JOYSTICK_SUPPORT
|
#ifdef JOYSTICK_SUPPORT
|
||||||
// Erase the joystick mapping arrays
|
// Erase the joystick mapping arrays
|
||||||
for(uInt32 i = 0; i < myJoysticks.size(); ++i)
|
myJoyHandler->eraseMapping(event, mode);
|
||||||
myJoysticks[i]->eraseMap(mode);
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
setActionMappings(mode);
|
setActionMappings(mode);
|
||||||
|
@ -1619,19 +1479,8 @@ void EventHandler::setDefaultKeymap(Event::Type event, EventMode mode)
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
void EventHandler::setDefaultJoymap(Event::Type event, EventMode mode)
|
void EventHandler::setDefaultJoymap(Event::Type event, EventMode mode)
|
||||||
{
|
{
|
||||||
#ifdef JOYSTICK_SUPPORT
|
myJoyHandler->setDefaultMapping(event, mode);
|
||||||
// If event is 'NoType', erase and reset all mappings
|
|
||||||
// Otherwise, only reset the given event
|
|
||||||
for(uInt32 i = 0; i < myJoysticks.size(); ++i)
|
|
||||||
{
|
|
||||||
if(event == Event::NoType)
|
|
||||||
myJoysticks[i]->eraseMap(mode); // erase *all* mappings
|
|
||||||
else
|
|
||||||
myJoysticks[i]->eraseEvent(event, mode); // only reset the specific event
|
|
||||||
}
|
|
||||||
myOSystem.setDefaultJoymap(event, mode);
|
|
||||||
setActionMappings(mode);
|
setActionMappings(mode);
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
@ -1651,37 +1500,7 @@ void EventHandler::saveKeyMapping()
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
void EventHandler::saveJoyMapping()
|
void EventHandler::saveJoyMapping()
|
||||||
{
|
{
|
||||||
#ifdef JOYSTICK_SUPPORT
|
myJoyHandler->saveMapping();
|
||||||
// Don't update the joymap at all if it hasn't been modified during the
|
|
||||||
// program run
|
|
||||||
if(myJoysticks.size() == 0)
|
|
||||||
return;
|
|
||||||
|
|
||||||
// Save the joystick mapping hash table, making sure to update it with
|
|
||||||
// any changes that have been made during the program run
|
|
||||||
for(uInt32 i = 0; i < myJoysticks.size(); ++i)
|
|
||||||
{
|
|
||||||
const StellaJoystick& joy = *myJoysticks[i];
|
|
||||||
if(joy.type == StellaJoystick::JT_REGULAR)
|
|
||||||
{
|
|
||||||
// Update hashmap, removing the joystick entry (if it exists)
|
|
||||||
// and adding the most recent mapping from the joystick itself
|
|
||||||
map<string,string>::iterator iter = myJoystickMap.find(joy.name);
|
|
||||||
if(iter != myJoystickMap.end())
|
|
||||||
myJoystickMap.erase(iter);
|
|
||||||
myJoystickMap.insert(make_pair(joy.name, joy.getMap()));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Now save the contents of the hashmap
|
|
||||||
ostringstream joybuf;
|
|
||||||
joybuf << Event::LastType;
|
|
||||||
map<string,string>::const_iterator iter;
|
|
||||||
for(iter = myJoystickMap.begin(); iter != myJoystickMap.end(); ++iter)
|
|
||||||
joybuf << "^" << iter->second;
|
|
||||||
|
|
||||||
myOSystem.settings().setValue("joymap", joybuf.str());
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
@ -2316,208 +2135,3 @@ const Event::Type EventHandler::SA_Key[2][12] = {
|
||||||
Event::KeyboardOne7, Event::KeyboardOne8, Event::KeyboardOne9,
|
Event::KeyboardOne7, Event::KeyboardOne8, Event::KeyboardOne9,
|
||||||
Event::KeyboardOneStar, Event::KeyboardOne0, Event::KeyboardOnePound }
|
Event::KeyboardOneStar, Event::KeyboardOne0, Event::KeyboardOnePound }
|
||||||
};
|
};
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
||||||
EventHandler::StellaJoystick::StellaJoystick()
|
|
||||||
: type(JT_NONE),
|
|
||||||
name("None"),
|
|
||||||
numAxes(0),
|
|
||||||
numButtons(0),
|
|
||||||
numHats(0),
|
|
||||||
axisTable(NULL),
|
|
||||||
btnTable(NULL),
|
|
||||||
hatTable(NULL),
|
|
||||||
axisLastValue(NULL)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
||||||
EventHandler::StellaJoystick::~StellaJoystick()
|
|
||||||
{
|
|
||||||
delete[] axisTable; axisTable = NULL;
|
|
||||||
delete[] btnTable; btnTable = NULL;
|
|
||||||
delete[] hatTable; hatTable = NULL;
|
|
||||||
delete[] axisLastValue; axisLastValue = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
||||||
void EventHandler::StellaJoystick::initialize(const string& desc,
|
|
||||||
int axes, int buttons, int hats, int /*balls*/)
|
|
||||||
{
|
|
||||||
name = desc;
|
|
||||||
|
|
||||||
// Dynamically create the various mapping arrays for this joystick,
|
|
||||||
// based on its specific attributes
|
|
||||||
numAxes = axes;
|
|
||||||
numButtons = buttons;
|
|
||||||
numHats = hats;
|
|
||||||
if(numAxes)
|
|
||||||
axisTable = new Event::Type[numAxes][2][kNumModes];
|
|
||||||
if(numButtons)
|
|
||||||
btnTable = new Event::Type[numButtons][kNumModes];
|
|
||||||
if(numHats)
|
|
||||||
hatTable = new Event::Type[numHats][4][kNumModes];
|
|
||||||
axisLastValue = new int[numAxes];
|
|
||||||
|
|
||||||
// Erase the joystick axis mapping array and last axis value
|
|
||||||
for(int a = 0; a < numAxes; ++a)
|
|
||||||
{
|
|
||||||
axisLastValue[a] = 0;
|
|
||||||
for(int m = 0; m < kNumModes; ++m)
|
|
||||||
axisTable[a][0][m] = axisTable[a][1][m] = Event::NoType;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Erase the joystick button mapping array
|
|
||||||
for(int b = 0; b < numButtons; ++b)
|
|
||||||
for(int m = 0; m < kNumModes; ++m)
|
|
||||||
btnTable[b][m] = Event::NoType;
|
|
||||||
|
|
||||||
// Erase the joystick hat mapping array
|
|
||||||
for(int h = 0; h < numHats; ++h)
|
|
||||||
for(int m = 0; m < kNumModes; ++m)
|
|
||||||
hatTable[h][0][m] = hatTable[h][1][m] =
|
|
||||||
hatTable[h][2][m] = hatTable[h][3][m] = Event::NoType;
|
|
||||||
}
|
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
||||||
string EventHandler::StellaJoystick::getMap() const
|
|
||||||
{
|
|
||||||
// The mapping structure (for remappable devices) is defined as follows:
|
|
||||||
// NAME | AXIS # + values | BUTTON # + values | HAT # + values,
|
|
||||||
// where each subsection of values is separated by ':'
|
|
||||||
if(type == JT_REGULAR)
|
|
||||||
{
|
|
||||||
ostringstream joybuf;
|
|
||||||
joybuf << name << "|" << numAxes;
|
|
||||||
for(int m = 0; m < kNumModes; ++m)
|
|
||||||
for(int a = 0; a < numAxes; ++a)
|
|
||||||
for(int k = 0; k < 2; ++k)
|
|
||||||
joybuf << " " << axisTable[a][k][m];
|
|
||||||
joybuf << "|" << numButtons;
|
|
||||||
for(int m = 0; m < kNumModes; ++m)
|
|
||||||
for(int b = 0; b < numButtons; ++b)
|
|
||||||
joybuf << " " << btnTable[b][m];
|
|
||||||
joybuf << "|" << numHats;
|
|
||||||
for(int m = 0; m < kNumModes; ++m)
|
|
||||||
for(int h = 0; h < numHats; ++h)
|
|
||||||
for(int k = 0; k < 4; ++k)
|
|
||||||
joybuf << " " << hatTable[h][k][m];
|
|
||||||
|
|
||||||
return joybuf.str();
|
|
||||||
}
|
|
||||||
return EmptyString;
|
|
||||||
}
|
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
||||||
bool EventHandler::StellaJoystick::setMap(const string& m)
|
|
||||||
{
|
|
||||||
istringstream buf(m);
|
|
||||||
StringList items;
|
|
||||||
string item;
|
|
||||||
while(getline(buf, item, '|'))
|
|
||||||
items.push_back(item);
|
|
||||||
|
|
||||||
// Error checking
|
|
||||||
if(items.size() != 4)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
IntArray map;
|
|
||||||
|
|
||||||
// Parse axis/button/hat values
|
|
||||||
getValues(items[1], map);
|
|
||||||
if((int)map.size() == numAxes * 2 * kNumModes)
|
|
||||||
{
|
|
||||||
// Fill the axes table with events
|
|
||||||
IntArray::const_iterator event = map.begin();
|
|
||||||
for(int m = 0; m < kNumModes; ++m)
|
|
||||||
for(int a = 0; a < numAxes; ++a)
|
|
||||||
for(int k = 0; k < 2; ++k)
|
|
||||||
axisTable[a][k][m] = (Event::Type) *event++;
|
|
||||||
}
|
|
||||||
getValues(items[2], map);
|
|
||||||
if((int)map.size() == numButtons * kNumModes)
|
|
||||||
{
|
|
||||||
IntArray::const_iterator event = map.begin();
|
|
||||||
for(int m = 0; m < kNumModes; ++m)
|
|
||||||
for(int b = 0; b < numButtons; ++b)
|
|
||||||
btnTable[b][m] = (Event::Type) *event++;
|
|
||||||
}
|
|
||||||
getValues(items[3], map);
|
|
||||||
if((int)map.size() == numHats * 4 * kNumModes)
|
|
||||||
{
|
|
||||||
IntArray::const_iterator event = map.begin();
|
|
||||||
for(int m = 0; m < kNumModes; ++m)
|
|
||||||
for(int h = 0; h < numHats; ++h)
|
|
||||||
for(int k = 0; k < 4; ++k)
|
|
||||||
hatTable[h][k][m] = (Event::Type) *event++;
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
||||||
void EventHandler::StellaJoystick::eraseMap(EventMode mode)
|
|
||||||
{
|
|
||||||
// Erase axis mappings
|
|
||||||
for(int a = 0; a < numAxes; ++a)
|
|
||||||
axisTable[a][0][mode] = axisTable[a][1][mode] = Event::NoType;
|
|
||||||
|
|
||||||
// Erase button mappings
|
|
||||||
for(int b = 0; b < numButtons; ++b)
|
|
||||||
btnTable[b][mode] = Event::NoType;
|
|
||||||
|
|
||||||
// Erase hat mappings
|
|
||||||
for(int h = 0; h < numHats; ++h)
|
|
||||||
hatTable[h][0][mode] = hatTable[h][1][mode] =
|
|
||||||
hatTable[h][2][mode] = hatTable[h][3][mode] = Event::NoType;
|
|
||||||
}
|
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
||||||
void EventHandler::StellaJoystick::eraseEvent(Event::Type event, EventMode mode)
|
|
||||||
{
|
|
||||||
// Erase axis mappings
|
|
||||||
for(int a = 0; a < numAxes; ++a)
|
|
||||||
{
|
|
||||||
if(axisTable[a][0][mode] == event) axisTable[a][0][mode] = Event::NoType;
|
|
||||||
if(axisTable[a][1][mode] == event) axisTable[a][1][mode] = Event::NoType;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Erase button mappings
|
|
||||||
for(int b = 0; b < numButtons; ++b)
|
|
||||||
if(btnTable[b][mode] == event) btnTable[b][mode] = Event::NoType;
|
|
||||||
|
|
||||||
// Erase hat mappings
|
|
||||||
for(int h = 0; h < numHats; ++h)
|
|
||||||
{
|
|
||||||
if(hatTable[h][0][mode] == event) hatTable[h][0][mode] = Event::NoType;
|
|
||||||
if(hatTable[h][1][mode] == event) hatTable[h][1][mode] = Event::NoType;
|
|
||||||
if(hatTable[h][2][mode] == event) hatTable[h][2][mode] = Event::NoType;
|
|
||||||
if(hatTable[h][3][mode] == event) hatTable[h][3][mode] = Event::NoType;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
||||||
void EventHandler::StellaJoystick::getValues(const string& list, IntArray& map)
|
|
||||||
{
|
|
||||||
map.clear();
|
|
||||||
istringstream buf(list);
|
|
||||||
|
|
||||||
int value;
|
|
||||||
buf >> value; // we don't need to know the # of items at this point
|
|
||||||
while(buf >> value)
|
|
||||||
map.push_back(value);
|
|
||||||
}
|
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
||||||
string EventHandler::StellaJoystick::about() const
|
|
||||||
{
|
|
||||||
ostringstream buf;
|
|
||||||
buf << name;
|
|
||||||
if(type == JT_REGULAR)
|
|
||||||
buf << " with:" << endl << " "
|
|
||||||
<< numAxes << " axes, "
|
|
||||||
<< numButtons << " buttons, "
|
|
||||||
<< numHats << " hats";
|
|
||||||
|
|
||||||
return buf.str();
|
|
||||||
}
|
|
||||||
|
|
|
@ -219,12 +219,18 @@ class EventHandler
|
||||||
|
|
||||||
Event::Type eventForKey(StellaKey key, EventMode mode) const
|
Event::Type eventForKey(StellaKey key, EventMode mode) const
|
||||||
{ return myKeyTable[key][mode]; }
|
{ return myKeyTable[key][mode]; }
|
||||||
Event::Type eventForJoyAxis(int stick, int axis, int value, EventMode mode) const
|
Event::Type eventForJoyAxis(int stick, int axis, int value, EventMode mode) const {
|
||||||
{ return myJoysticks[stick]->axisTable[axis][(value > 0)][mode]; }
|
const StellaJoystick* joy = myJoyHandler->joy(stick);
|
||||||
Event::Type eventForJoyButton(int stick, int button, EventMode mode) const
|
return joy ? joy->axisTable[axis][(value > 0)][mode] : Event::NoType;
|
||||||
{ return myJoysticks[stick]->btnTable[button][mode]; }
|
}
|
||||||
Event::Type eventForJoyHat(int stick, int hat, int value, EventMode mode) const
|
Event::Type eventForJoyButton(int stick, int button, EventMode mode) const {
|
||||||
{ return myJoysticks[stick]->hatTable[hat][value][mode]; }
|
const StellaJoystick* joy = myJoyHandler->joy(stick);
|
||||||
|
return joy ? joy->btnTable[button][mode] : Event::NoType;
|
||||||
|
}
|
||||||
|
Event::Type eventForJoyHat(int stick, int hat, int value, EventMode mode) const {
|
||||||
|
const StellaJoystick* joy = myJoyHandler->joy(stick);
|
||||||
|
return joy ? joy->hatTable[hat][value][mode] : Event::NoType;
|
||||||
|
}
|
||||||
|
|
||||||
Event::Type eventAtIndex(int idx, EventMode mode) const;
|
Event::Type eventAtIndex(int idx, EventMode mode) const;
|
||||||
string actionAtIndex(int idx, EventMode mode) const;
|
string actionAtIndex(int idx, EventMode mode) const;
|
||||||
|
@ -333,11 +339,6 @@ class EventHandler
|
||||||
void handleJoyAxisEvent(int stick, int axis, int value);
|
void handleJoyAxisEvent(int stick, int axis, int value);
|
||||||
void handleJoyHatEvent(int stick, int hat, int value);
|
void handleJoyHatEvent(int stick, int hat, int value);
|
||||||
|
|
||||||
/**
|
|
||||||
Set up any joysticks on the system.
|
|
||||||
*/
|
|
||||||
virtual void initializeJoysticks() = 0;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Enable/disable text events (distinct from single-key events).
|
Enable/disable text events (distinct from single-key events).
|
||||||
*/
|
*/
|
||||||
|
@ -391,7 +392,8 @@ class EventHandler
|
||||||
string about() const;
|
string about() const;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void initialize(const string& desc, int axes, int buttons, int hats, int balls);
|
void initialize(int index, const string& desc,
|
||||||
|
int axes, int buttons, int hats, int balls);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
enum JoyType {
|
enum JoyType {
|
||||||
|
@ -404,6 +406,7 @@ class EventHandler
|
||||||
};
|
};
|
||||||
|
|
||||||
JoyType type;
|
JoyType type;
|
||||||
|
int ID;
|
||||||
string name;
|
string name;
|
||||||
int numAxes, numButtons, numHats;
|
int numAxes, numButtons, numHats;
|
||||||
Event::Type (*axisTable)[2][kNumModes];
|
Event::Type (*axisTable)[2][kNumModes];
|
||||||
|
@ -413,12 +416,67 @@ class EventHandler
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void getValues(const string& list, IntArray& map);
|
void getValues(const string& list, IntArray& map);
|
||||||
|
|
||||||
|
friend ostream& operator<<(ostream& os, const StellaJoystick& s) {
|
||||||
|
os << " ID: " << s.ID << ", name: " << s.name << ", numaxis: " << s.numAxes
|
||||||
|
<< ", numbtns: " << s.numButtons << ", numhats: " << s.numHats;
|
||||||
|
return os;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
class JoystickHandler
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
JoystickHandler(OSystem& system);
|
||||||
|
~JoystickHandler();
|
||||||
|
|
||||||
|
int add(StellaJoystick* stick);
|
||||||
|
int remove(int id);
|
||||||
|
uInt32 numSticks() const { return mySticks.size(); }
|
||||||
|
void mapStelladaptors(const string& saport);
|
||||||
|
void setDefaultMapping(Event::Type type, EventMode mode);
|
||||||
|
void eraseMapping(Event::Type event, EventMode mode);
|
||||||
|
void saveMapping();
|
||||||
|
|
||||||
|
const StellaJoystick* joy(int id) const {
|
||||||
|
return id < mySticks.size() ? mySticks[id] : NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
OSystem& myOSystem;
|
||||||
|
|
||||||
|
struct StickInfo
|
||||||
|
{
|
||||||
|
StickInfo(const string& map = EmptyString, StellaJoystick* stick = NULL)
|
||||||
|
: mapping(map), joy(stick) {}
|
||||||
|
|
||||||
|
string mapping;
|
||||||
|
StellaJoystick* joy;
|
||||||
|
|
||||||
|
friend ostream& operator<<(ostream& os, const StickInfo& si) {
|
||||||
|
os << " joy: " << si.joy << endl << " map: " << si.mapping;
|
||||||
|
return os;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
// Contains all joysticks that Stella knows about, indexed by name
|
||||||
|
map<string,StickInfo> myDatabase;
|
||||||
|
|
||||||
|
// Contains only joysticks that are currently available, indexed by id
|
||||||
|
Common::Array<StellaJoystick*> mySticks;
|
||||||
|
|
||||||
|
void setStickDefaultMapping(int stick, Event::Type type, EventMode mode);
|
||||||
|
void printDatabase();
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Add the given joystick to the list of sticks available to the handler.
|
Add the given joystick to the list of sticks available to the handler.
|
||||||
*/
|
*/
|
||||||
void addJoystick(StellaJoystick* stick, int idx);
|
void addJoystick(StellaJoystick* stick);
|
||||||
|
|
||||||
|
/**
|
||||||
|
Remove joystick at the current index.
|
||||||
|
*/
|
||||||
|
void removeJoystick(int index);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
enum {
|
enum {
|
||||||
|
@ -442,7 +500,6 @@ class EventHandler
|
||||||
void setActionMappings(EventMode mode);
|
void setActionMappings(EventMode mode);
|
||||||
void setKeyNames();
|
void setKeyNames();
|
||||||
void setKeymap();
|
void setKeymap();
|
||||||
void setJoymap();
|
|
||||||
void setDefaultKeymap(Event::Type, EventMode mode);
|
void setDefaultKeymap(Event::Type, EventMode mode);
|
||||||
void setDefaultJoymap(Event::Type, EventMode mode);
|
void setDefaultJoymap(Event::Type, EventMode mode);
|
||||||
void saveKeyMapping();
|
void saveKeyMapping();
|
||||||
|
@ -519,8 +576,8 @@ class EventHandler
|
||||||
static const Event::Type SA_Button[2][4];
|
static const Event::Type SA_Button[2][4];
|
||||||
static const Event::Type SA_Key[2][12];
|
static const Event::Type SA_Key[2][12];
|
||||||
|
|
||||||
Common::Array<StellaJoystick*> myJoysticks;
|
// Handler for all joystick addition/removal/mapping
|
||||||
map<string,string> myJoystickMap;
|
JoystickHandler* myJoyHandler;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -0,0 +1,562 @@
|
||||||
|
//============================================================================
|
||||||
|
//
|
||||||
|
// SSSS tt lll lll
|
||||||
|
// SS SS tt ll ll
|
||||||
|
// SS tttttt eeee ll ll aaaa
|
||||||
|
// SSSS tt ee ee ll ll aa
|
||||||
|
// SS tt eeeeee ll ll aaaaa -- "An Atari 2600 VCS Emulator"
|
||||||
|
// SS SS tt ee ll ll aa aa
|
||||||
|
// SSSS ttt eeeee llll llll aaaaa
|
||||||
|
//
|
||||||
|
// Copyright (c) 1995-2014 by Bradford W. Mott, Stephen Anthony
|
||||||
|
// and the Stella Team
|
||||||
|
//
|
||||||
|
// See the file "License.txt" for information on usage and redistribution of
|
||||||
|
// this file, and for a DISCLAIMER OF ALL WARRANTIES.
|
||||||
|
//
|
||||||
|
// $Id$
|
||||||
|
//============================================================================
|
||||||
|
|
||||||
|
#include <sstream>
|
||||||
|
#include <map>
|
||||||
|
|
||||||
|
#include "OSystem.hxx"
|
||||||
|
#include "Settings.hxx"
|
||||||
|
#include "bspf.hxx"
|
||||||
|
|
||||||
|
#include "EventHandler.hxx"
|
||||||
|
|
||||||
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
EventHandler::StellaJoystick::StellaJoystick()
|
||||||
|
: type(JT_NONE),
|
||||||
|
ID(-1),
|
||||||
|
name("None"),
|
||||||
|
numAxes(0),
|
||||||
|
numButtons(0),
|
||||||
|
numHats(0),
|
||||||
|
axisTable(NULL),
|
||||||
|
btnTable(NULL),
|
||||||
|
hatTable(NULL),
|
||||||
|
axisLastValue(NULL)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
EventHandler::StellaJoystick::~StellaJoystick()
|
||||||
|
{
|
||||||
|
delete[] axisTable; axisTable = NULL;
|
||||||
|
delete[] btnTable; btnTable = NULL;
|
||||||
|
delete[] hatTable; hatTable = NULL;
|
||||||
|
delete[] axisLastValue; axisLastValue = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
void EventHandler::StellaJoystick::initialize(int index, const string& desc,
|
||||||
|
int axes, int buttons, int hats, int /*balls*/)
|
||||||
|
{
|
||||||
|
ID = index;
|
||||||
|
name = desc;
|
||||||
|
|
||||||
|
// Dynamically create the various mapping arrays for this joystick,
|
||||||
|
// based on its specific attributes
|
||||||
|
numAxes = axes;
|
||||||
|
numButtons = buttons;
|
||||||
|
numHats = hats;
|
||||||
|
if(numAxes)
|
||||||
|
axisTable = new Event::Type[numAxes][2][kNumModes];
|
||||||
|
if(numButtons)
|
||||||
|
btnTable = new Event::Type[numButtons][kNumModes];
|
||||||
|
if(numHats)
|
||||||
|
hatTable = new Event::Type[numHats][4][kNumModes];
|
||||||
|
axisLastValue = new int[numAxes];
|
||||||
|
|
||||||
|
// Erase the joystick axis mapping array and last axis value
|
||||||
|
for(int a = 0; a < numAxes; ++a)
|
||||||
|
{
|
||||||
|
axisLastValue[a] = 0;
|
||||||
|
for(int m = 0; m < kNumModes; ++m)
|
||||||
|
axisTable[a][0][m] = axisTable[a][1][m] = Event::NoType;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Erase the joystick button mapping array
|
||||||
|
for(int b = 0; b < numButtons; ++b)
|
||||||
|
for(int m = 0; m < kNumModes; ++m)
|
||||||
|
btnTable[b][m] = Event::NoType;
|
||||||
|
|
||||||
|
// Erase the joystick hat mapping array
|
||||||
|
for(int h = 0; h < numHats; ++h)
|
||||||
|
for(int m = 0; m < kNumModes; ++m)
|
||||||
|
hatTable[h][0][m] = hatTable[h][1][m] =
|
||||||
|
hatTable[h][2][m] = hatTable[h][3][m] = Event::NoType;
|
||||||
|
}
|
||||||
|
|
||||||
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
string EventHandler::StellaJoystick::getMap() const
|
||||||
|
{
|
||||||
|
// The mapping structure (for remappable devices) is defined as follows:
|
||||||
|
// NAME | AXIS # + values | BUTTON # + values | HAT # + values,
|
||||||
|
// where each subsection of values is separated by ':'
|
||||||
|
if(type == JT_REGULAR)
|
||||||
|
{
|
||||||
|
ostringstream joybuf;
|
||||||
|
joybuf << name << "|" << numAxes;
|
||||||
|
for(int m = 0; m < kNumModes; ++m)
|
||||||
|
for(int a = 0; a < numAxes; ++a)
|
||||||
|
for(int k = 0; k < 2; ++k)
|
||||||
|
joybuf << " " << axisTable[a][k][m];
|
||||||
|
joybuf << "|" << numButtons;
|
||||||
|
for(int m = 0; m < kNumModes; ++m)
|
||||||
|
for(int b = 0; b < numButtons; ++b)
|
||||||
|
joybuf << " " << btnTable[b][m];
|
||||||
|
joybuf << "|" << numHats;
|
||||||
|
for(int m = 0; m < kNumModes; ++m)
|
||||||
|
for(int h = 0; h < numHats; ++h)
|
||||||
|
for(int k = 0; k < 4; ++k)
|
||||||
|
joybuf << " " << hatTable[h][k][m];
|
||||||
|
|
||||||
|
return joybuf.str();
|
||||||
|
}
|
||||||
|
return EmptyString;
|
||||||
|
}
|
||||||
|
|
||||||
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
bool EventHandler::StellaJoystick::setMap(const string& m)
|
||||||
|
{
|
||||||
|
istringstream buf(m);
|
||||||
|
StringList items;
|
||||||
|
string item;
|
||||||
|
while(getline(buf, item, '|'))
|
||||||
|
items.push_back(item);
|
||||||
|
|
||||||
|
// Error checking
|
||||||
|
if(items.size() != 4)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
IntArray map;
|
||||||
|
|
||||||
|
// Parse axis/button/hat values
|
||||||
|
getValues(items[1], map);
|
||||||
|
if((int)map.size() == numAxes * 2 * kNumModes)
|
||||||
|
{
|
||||||
|
// Fill the axes table with events
|
||||||
|
IntArray::const_iterator event = map.begin();
|
||||||
|
for(int m = 0; m < kNumModes; ++m)
|
||||||
|
for(int a = 0; a < numAxes; ++a)
|
||||||
|
for(int k = 0; k < 2; ++k)
|
||||||
|
axisTable[a][k][m] = (Event::Type) *event++;
|
||||||
|
}
|
||||||
|
getValues(items[2], map);
|
||||||
|
if((int)map.size() == numButtons * kNumModes)
|
||||||
|
{
|
||||||
|
IntArray::const_iterator event = map.begin();
|
||||||
|
for(int m = 0; m < kNumModes; ++m)
|
||||||
|
for(int b = 0; b < numButtons; ++b)
|
||||||
|
btnTable[b][m] = (Event::Type) *event++;
|
||||||
|
}
|
||||||
|
getValues(items[3], map);
|
||||||
|
if((int)map.size() == numHats * 4 * kNumModes)
|
||||||
|
{
|
||||||
|
IntArray::const_iterator event = map.begin();
|
||||||
|
for(int m = 0; m < kNumModes; ++m)
|
||||||
|
for(int h = 0; h < numHats; ++h)
|
||||||
|
for(int k = 0; k < 4; ++k)
|
||||||
|
hatTable[h][k][m] = (Event::Type) *event++;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
void EventHandler::StellaJoystick::eraseMap(EventMode mode)
|
||||||
|
{
|
||||||
|
// Erase axis mappings
|
||||||
|
for(int a = 0; a < numAxes; ++a)
|
||||||
|
axisTable[a][0][mode] = axisTable[a][1][mode] = Event::NoType;
|
||||||
|
|
||||||
|
// Erase button mappings
|
||||||
|
for(int b = 0; b < numButtons; ++b)
|
||||||
|
btnTable[b][mode] = Event::NoType;
|
||||||
|
|
||||||
|
// Erase hat mappings
|
||||||
|
for(int h = 0; h < numHats; ++h)
|
||||||
|
hatTable[h][0][mode] = hatTable[h][1][mode] =
|
||||||
|
hatTable[h][2][mode] = hatTable[h][3][mode] = Event::NoType;
|
||||||
|
}
|
||||||
|
|
||||||
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
void EventHandler::StellaJoystick::eraseEvent(Event::Type event, EventMode mode)
|
||||||
|
{
|
||||||
|
// Erase axis mappings
|
||||||
|
for(int a = 0; a < numAxes; ++a)
|
||||||
|
{
|
||||||
|
if(axisTable[a][0][mode] == event) axisTable[a][0][mode] = Event::NoType;
|
||||||
|
if(axisTable[a][1][mode] == event) axisTable[a][1][mode] = Event::NoType;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Erase button mappings
|
||||||
|
for(int b = 0; b < numButtons; ++b)
|
||||||
|
if(btnTable[b][mode] == event) btnTable[b][mode] = Event::NoType;
|
||||||
|
|
||||||
|
// Erase hat mappings
|
||||||
|
for(int h = 0; h < numHats; ++h)
|
||||||
|
{
|
||||||
|
if(hatTable[h][0][mode] == event) hatTable[h][0][mode] = Event::NoType;
|
||||||
|
if(hatTable[h][1][mode] == event) hatTable[h][1][mode] = Event::NoType;
|
||||||
|
if(hatTable[h][2][mode] == event) hatTable[h][2][mode] = Event::NoType;
|
||||||
|
if(hatTable[h][3][mode] == event) hatTable[h][3][mode] = Event::NoType;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
void EventHandler::StellaJoystick::getValues(const string& list, IntArray& map)
|
||||||
|
{
|
||||||
|
map.clear();
|
||||||
|
istringstream buf(list);
|
||||||
|
|
||||||
|
int value;
|
||||||
|
buf >> value; // we don't need to know the # of items at this point
|
||||||
|
while(buf >> value)
|
||||||
|
map.push_back(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
string EventHandler::StellaJoystick::about() const
|
||||||
|
{
|
||||||
|
ostringstream buf;
|
||||||
|
buf << name;
|
||||||
|
if(type == JT_REGULAR)
|
||||||
|
buf << " with: " << numAxes << " axes, " << numButtons << " buttons, "
|
||||||
|
<< numHats << " hats";
|
||||||
|
|
||||||
|
return buf.str();
|
||||||
|
}
|
||||||
|
|
||||||
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
EventHandler::JoystickHandler::JoystickHandler(OSystem& system)
|
||||||
|
: myOSystem(system)
|
||||||
|
{
|
||||||
|
// Load previously saved joystick mapping (if any) from settings
|
||||||
|
istringstream buf(myOSystem.settings().getString("joymap"));
|
||||||
|
string joymap, joyname;
|
||||||
|
|
||||||
|
// First check the event type, and disregard the entire mapping if it's invalid
|
||||||
|
getline(buf, joymap, '^');
|
||||||
|
if(atoi(joymap.c_str()) == Event::LastType)
|
||||||
|
{
|
||||||
|
// Otherwise, put each joystick mapping entry into the database
|
||||||
|
while(getline(buf, joymap, '^'))
|
||||||
|
{
|
||||||
|
istringstream namebuf(joymap);
|
||||||
|
getline(namebuf, joyname, '|');
|
||||||
|
if(joyname.length() != 0)
|
||||||
|
{
|
||||||
|
StickInfo info(joymap);
|
||||||
|
myDatabase.insert(make_pair(joyname, info));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
EventHandler::JoystickHandler::~JoystickHandler()
|
||||||
|
{
|
||||||
|
map<string,StickInfo>::const_iterator it;
|
||||||
|
for(it = myDatabase.begin(); it != myDatabase.end(); ++it)
|
||||||
|
delete it->second.joy;
|
||||||
|
}
|
||||||
|
|
||||||
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
void EventHandler::JoystickHandler::printDatabase()
|
||||||
|
{
|
||||||
|
cerr << "---------------------------------------------------------" << endl
|
||||||
|
<< "joy database:" << endl;
|
||||||
|
map<string,StickInfo>::const_iterator it;
|
||||||
|
for(it = myDatabase.begin(); it != myDatabase.end(); ++it)
|
||||||
|
cerr << it->first << endl << it->second << endl << endl;
|
||||||
|
|
||||||
|
cerr << "---------------------------------------------------------" << endl
|
||||||
|
<< "joy active:" << endl;
|
||||||
|
for(uInt32 i = 0; i < mySticks.size(); ++i)
|
||||||
|
cerr << *mySticks[i] << endl;
|
||||||
|
cerr << endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
int EventHandler::JoystickHandler::add(StellaJoystick* stick)
|
||||||
|
{
|
||||||
|
// Skip if we couldn't open it for any reason
|
||||||
|
if(stick->ID < 0)
|
||||||
|
return stick->ID;
|
||||||
|
|
||||||
|
// Figure out what type of joystick this is
|
||||||
|
bool specialAdaptor = false;
|
||||||
|
|
||||||
|
if(stick->name.find("2600-daptor", 0) != string::npos)
|
||||||
|
{
|
||||||
|
// 2600-daptorII devices have 3 axes and 12 buttons, and the value of the z-axis
|
||||||
|
// determines how those 12 buttons are used (not all buttons are used in all modes)
|
||||||
|
if(stick->numAxes == 3)
|
||||||
|
{
|
||||||
|
// TODO - stubbed out for now, until we find a way to reliably get info
|
||||||
|
// from the Z axis
|
||||||
|
stick->name = "2600-daptor II";
|
||||||
|
}
|
||||||
|
else
|
||||||
|
stick->name = "2600-daptor";
|
||||||
|
|
||||||
|
specialAdaptor = true;
|
||||||
|
}
|
||||||
|
else if(stick->name.find("Stelladaptor", 0) != string::npos)
|
||||||
|
{
|
||||||
|
stick->name = "Stelladaptor";
|
||||||
|
specialAdaptor = true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// We need unique names for mappable devices
|
||||||
|
int count = 0;
|
||||||
|
map<string,StickInfo>::const_iterator c_it;
|
||||||
|
for(c_it = myDatabase.begin(); c_it != myDatabase.end(); ++c_it)
|
||||||
|
if(BSPF_startsWithIgnoreCase(c_it->first, stick->name))
|
||||||
|
++count;
|
||||||
|
|
||||||
|
if(count > 1)
|
||||||
|
{
|
||||||
|
ostringstream name;
|
||||||
|
name << stick->name << " " << count;
|
||||||
|
stick->name = name.str();
|
||||||
|
}
|
||||||
|
stick->type = StellaJoystick::JT_REGULAR;
|
||||||
|
}
|
||||||
|
mySticks.insert_at(stick->ID, stick);
|
||||||
|
|
||||||
|
// Map the stelladaptors we've found according to the specified ports
|
||||||
|
if(specialAdaptor)
|
||||||
|
mapStelladaptors(myOSystem.settings().getString("saport"));
|
||||||
|
|
||||||
|
// Add stick to database
|
||||||
|
map<string,StickInfo>::iterator it = myDatabase.find(stick->name);
|
||||||
|
if(it != myDatabase.end()) // already present
|
||||||
|
{
|
||||||
|
it->second.joy = stick;
|
||||||
|
stick->setMap(it->second.mapping);
|
||||||
|
}
|
||||||
|
else // adding for the first time
|
||||||
|
{
|
||||||
|
StickInfo info("", stick);
|
||||||
|
myDatabase.insert(make_pair(stick->name, info));
|
||||||
|
setStickDefaultMapping(stick->ID, Event::NoType, kEmulationMode);
|
||||||
|
setStickDefaultMapping(stick->ID, Event::NoType, kMenuMode);
|
||||||
|
}
|
||||||
|
|
||||||
|
return stick->ID;
|
||||||
|
}
|
||||||
|
|
||||||
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
int EventHandler::JoystickHandler::remove(int index)
|
||||||
|
{
|
||||||
|
// When a joystick is removed, we delete the actual joystick object but
|
||||||
|
// remember its mapping, since it will eventually be saved to settings
|
||||||
|
|
||||||
|
// Sticks that are removed must have initially been added
|
||||||
|
// So we use the 'active' joystick list to access them
|
||||||
|
if(index >= 0 && index < mySticks.size() && mySticks[index] != NULL)
|
||||||
|
{
|
||||||
|
StellaJoystick* stick = mySticks[index];
|
||||||
|
|
||||||
|
map<string,StickInfo>::iterator it = myDatabase.find(stick->name);
|
||||||
|
if(it != myDatabase.end() && it->second.joy == stick)
|
||||||
|
{
|
||||||
|
ostringstream buf;
|
||||||
|
buf << "Removed joystick " << mySticks[index]->ID << ":" << endl
|
||||||
|
<< " " << mySticks[index]->about() << endl;
|
||||||
|
myOSystem.logMessage(buf.str(), 1);
|
||||||
|
|
||||||
|
// Remove joystick, but remember mapping
|
||||||
|
it->second.mapping = stick->getMap();
|
||||||
|
delete it->second.joy; it->second.joy = NULL;
|
||||||
|
mySticks[index] = NULL;
|
||||||
|
|
||||||
|
return index;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
void EventHandler::JoystickHandler::mapStelladaptors(const string& saport)
|
||||||
|
{
|
||||||
|
// saport will have two values:
|
||||||
|
// 'lr' means treat first valid adaptor as left port, second as right port
|
||||||
|
// 'rl' means treat first valid adaptor as right port, second as left port
|
||||||
|
// We know there will be only two such devices (at most), since the logic
|
||||||
|
// in setupJoysticks take care of that
|
||||||
|
int saCount = 0;
|
||||||
|
int saOrder[2] = { 1, 2 };
|
||||||
|
if(BSPF_equalsIgnoreCase(saport, "rl"))
|
||||||
|
{
|
||||||
|
saOrder[0] = 2; saOrder[1] = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
for(uInt32 i = 0; i < mySticks.size(); ++i)
|
||||||
|
{
|
||||||
|
if(BSPF_startsWithIgnoreCase(mySticks[i]->name, "Stelladaptor"))
|
||||||
|
{
|
||||||
|
if(saOrder[saCount] == 1)
|
||||||
|
{
|
||||||
|
mySticks[i]->name += " (emulates left joystick port)";
|
||||||
|
mySticks[i]->type = StellaJoystick::JT_STELLADAPTOR_LEFT;
|
||||||
|
}
|
||||||
|
else if(saOrder[saCount] == 2)
|
||||||
|
{
|
||||||
|
mySticks[i]->name += " (emulates right joystick port)";
|
||||||
|
mySticks[i]->type = StellaJoystick::JT_STELLADAPTOR_RIGHT;
|
||||||
|
}
|
||||||
|
saCount++;
|
||||||
|
}
|
||||||
|
else if(BSPF_startsWithIgnoreCase(mySticks[i]->name, "2600-daptor"))
|
||||||
|
{
|
||||||
|
if(saOrder[saCount] == 1)
|
||||||
|
{
|
||||||
|
mySticks[i]->name += " (emulates left joystick port)";
|
||||||
|
mySticks[i]->type = StellaJoystick::JT_2600DAPTOR_LEFT;
|
||||||
|
}
|
||||||
|
else if(saOrder[saCount] == 2)
|
||||||
|
{
|
||||||
|
mySticks[i]->name += " (emulates right joystick port)";
|
||||||
|
mySticks[i]->type = StellaJoystick::JT_2600DAPTOR_RIGHT;
|
||||||
|
}
|
||||||
|
saCount++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
myOSystem.settings().setValue("saport", saport);
|
||||||
|
}
|
||||||
|
|
||||||
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
void EventHandler::JoystickHandler::setDefaultMapping(Event::Type event, EventMode mode)
|
||||||
|
{
|
||||||
|
eraseMapping(event, mode);
|
||||||
|
setStickDefaultMapping(0, event, mode);
|
||||||
|
setStickDefaultMapping(1, event, mode);
|
||||||
|
}
|
||||||
|
|
||||||
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
void EventHandler::JoystickHandler::setStickDefaultMapping(int stick,
|
||||||
|
Event::Type event, EventMode mode)
|
||||||
|
{
|
||||||
|
#define SET_DEFAULT_AXIS(sda_event, sda_mode, sda_stick, sda_axis, sda_val, sda_cmp_event) \
|
||||||
|
if(eraseAll || sda_cmp_event == sda_event) \
|
||||||
|
handler.addJoyAxisMapping(sda_event, sda_mode, sda_stick, sda_axis, sda_val, false);
|
||||||
|
|
||||||
|
#define SET_DEFAULT_BTN(sdb_event, sdb_mode, sdb_stick, sdb_button, sdb_cmp_event) \
|
||||||
|
if(eraseAll || sdb_cmp_event == sdb_event) \
|
||||||
|
handler.addJoyButtonMapping(sdb_event, sdb_mode, sdb_stick, sdb_button, false);
|
||||||
|
|
||||||
|
#define SET_DEFAULT_HAT(sdh_event, sdh_mode, sdh_stick, sdh_hat, sdh_dir, sdh_cmp_event) \
|
||||||
|
if(eraseAll || sdh_cmp_event == sdh_event) \
|
||||||
|
handler.addJoyHatMapping(sdh_event, sdh_mode, sdh_stick, sdh_hat, sdh_dir, false);
|
||||||
|
|
||||||
|
EventHandler& handler = myOSystem.eventHandler();
|
||||||
|
bool eraseAll = (event == Event::NoType);
|
||||||
|
|
||||||
|
switch(mode)
|
||||||
|
{
|
||||||
|
case kEmulationMode: // Default emulation events
|
||||||
|
if(stick == 0)
|
||||||
|
{
|
||||||
|
// Left joystick left/right directions (assume joystick zero)
|
||||||
|
SET_DEFAULT_AXIS(Event::JoystickZeroLeft, mode, 0, 0, 0, event);
|
||||||
|
SET_DEFAULT_AXIS(Event::JoystickZeroRight, mode, 0, 0, 1, event);
|
||||||
|
// Left joystick up/down directions (assume joystick zero)
|
||||||
|
SET_DEFAULT_AXIS(Event::JoystickZeroUp, mode, 0, 1, 0, event);
|
||||||
|
SET_DEFAULT_AXIS(Event::JoystickZeroDown, mode, 0, 1, 1, event);
|
||||||
|
// Left joystick (assume joystick zero, button zero)
|
||||||
|
SET_DEFAULT_BTN(Event::JoystickZeroFire, mode, 0, 0, event);
|
||||||
|
// Left joystick left/right directions (assume joystick zero and hat 0)
|
||||||
|
SET_DEFAULT_HAT(Event::JoystickZeroLeft, mode, 0, 0, EVENT_HATLEFT, event);
|
||||||
|
SET_DEFAULT_HAT(Event::JoystickZeroRight, mode, 0, 0, EVENT_HATRIGHT, event);
|
||||||
|
// Left joystick up/down directions (assume joystick zero and hat 0)
|
||||||
|
SET_DEFAULT_HAT(Event::JoystickZeroUp, mode, 0, 0, EVENT_HATUP, event);
|
||||||
|
SET_DEFAULT_HAT(Event::JoystickZeroDown, mode, 0, 0, EVENT_HATDOWN, event);
|
||||||
|
}
|
||||||
|
else if(stick == 1)
|
||||||
|
{
|
||||||
|
// Right joystick left/right directions (assume joystick one)
|
||||||
|
SET_DEFAULT_AXIS(Event::JoystickOneLeft, mode, 1, 0, 0, event);
|
||||||
|
SET_DEFAULT_AXIS(Event::JoystickOneRight, mode, 1, 0, 1, event);
|
||||||
|
// Right joystick left/right directions (assume joystick one)
|
||||||
|
SET_DEFAULT_AXIS(Event::JoystickOneUp, mode, 1, 1, 0, event);
|
||||||
|
SET_DEFAULT_AXIS(Event::JoystickOneDown, mode, 1, 1, 1, event);
|
||||||
|
// Right joystick (assume joystick one, button zero)
|
||||||
|
SET_DEFAULT_BTN(Event::JoystickOneFire, mode, 1, 0, event);
|
||||||
|
// Right joystick left/right directions (assume joystick one and hat 0)
|
||||||
|
SET_DEFAULT_HAT(Event::JoystickOneLeft, mode, 1, 0, EVENT_HATLEFT, event);
|
||||||
|
SET_DEFAULT_HAT(Event::JoystickOneRight, mode, 1, 0, EVENT_HATRIGHT, event);
|
||||||
|
// Right joystick up/down directions (assume joystick one and hat 0)
|
||||||
|
SET_DEFAULT_HAT(Event::JoystickOneUp, mode, 1, 0, EVENT_HATUP, event);
|
||||||
|
SET_DEFAULT_HAT(Event::JoystickOneDown, mode, 1, 0, EVENT_HATDOWN, event);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case kMenuMode: // Default menu/UI events
|
||||||
|
if(stick == 0)
|
||||||
|
{
|
||||||
|
SET_DEFAULT_AXIS(Event::UILeft, mode, 0, 0, 0, event);
|
||||||
|
SET_DEFAULT_AXIS(Event::UIRight, mode, 0, 0, 1, event);
|
||||||
|
SET_DEFAULT_AXIS(Event::UIUp, mode, 0, 1, 0, event);
|
||||||
|
SET_DEFAULT_AXIS(Event::UIDown, mode, 0, 1, 1, event);
|
||||||
|
|
||||||
|
// Left joystick (assume joystick zero, button zero)
|
||||||
|
SET_DEFAULT_BTN(Event::UISelect, mode, 0, 0, event);
|
||||||
|
// Right joystick (assume joystick one, button zero)
|
||||||
|
SET_DEFAULT_BTN(Event::UISelect, mode, 1, 0, event);
|
||||||
|
|
||||||
|
SET_DEFAULT_HAT(Event::UILeft, mode, 0, 0, EVENT_HATLEFT, event);
|
||||||
|
SET_DEFAULT_HAT(Event::UIRight, mode, 0, 0, EVENT_HATRIGHT, event);
|
||||||
|
SET_DEFAULT_HAT(Event::UIUp, mode, 0, 0, EVENT_HATUP, event);
|
||||||
|
SET_DEFAULT_HAT(Event::UIDown, mode, 0, 0, EVENT_HATDOWN, event);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
void EventHandler::JoystickHandler::eraseMapping(Event::Type event, EventMode mode)
|
||||||
|
{
|
||||||
|
// If event is 'NoType', erase and reset all mappings
|
||||||
|
// Otherwise, only reset the given event
|
||||||
|
if(event == Event::NoType)
|
||||||
|
{
|
||||||
|
for(uInt32 i = 0; i < mySticks.size(); ++i)
|
||||||
|
mySticks[i]->eraseMap(mode); // erase all events
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
for(uInt32 i = 0; i < mySticks.size(); ++i)
|
||||||
|
mySticks[i]->eraseEvent(event, mode); // only reset the specific event
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
void EventHandler::JoystickHandler::saveMapping()
|
||||||
|
{
|
||||||
|
// Save the joystick mapping hash table, making sure to update it with
|
||||||
|
// any changes that have been made during the program run
|
||||||
|
ostringstream joybuf;
|
||||||
|
joybuf << Event::LastType;
|
||||||
|
|
||||||
|
map<string,StickInfo>::const_iterator it;
|
||||||
|
for(it = myDatabase.begin(); it != myDatabase.end(); ++it)
|
||||||
|
{
|
||||||
|
const string& map = it->second.joy ?
|
||||||
|
it->second.joy->getMap() : it->second.mapping;
|
||||||
|
|
||||||
|
if(map != "")
|
||||||
|
joybuf << "^" << map;
|
||||||
|
}
|
||||||
|
myOSystem.settings().setValue("joymap", joybuf.str());
|
||||||
|
}
|
|
@ -705,81 +705,6 @@ void OSystem::validatePath(string& path, const string& setting,
|
||||||
mySettings->setValue(setting, node.getShortPath());
|
mySettings->setValue(setting, node.getShortPath());
|
||||||
}
|
}
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
||||||
void OSystem::setDefaultJoymap(Event::Type event, EventMode mode)
|
|
||||||
{
|
|
||||||
#define SET_DEFAULT_AXIS(sda_event, sda_mode, sda_stick, sda_axis, sda_val, sda_cmp_event) \
|
|
||||||
if(eraseAll || sda_cmp_event == sda_event) \
|
|
||||||
myEventHandler->addJoyAxisMapping(sda_event, sda_mode, sda_stick, sda_axis, sda_val, false);
|
|
||||||
|
|
||||||
#define SET_DEFAULT_BTN(sdb_event, sdb_mode, sdb_stick, sdb_button, sdb_cmp_event) \
|
|
||||||
if(eraseAll || sdb_cmp_event == sdb_event) \
|
|
||||||
myEventHandler->addJoyButtonMapping(sdb_event, sdb_mode, sdb_stick, sdb_button, false);
|
|
||||||
|
|
||||||
#define SET_DEFAULT_HAT(sdh_event, sdh_mode, sdh_stick, sdh_hat, sdh_dir, sdh_cmp_event) \
|
|
||||||
if(eraseAll || sdh_cmp_event == sdh_event) \
|
|
||||||
myEventHandler->addJoyHatMapping(sdh_event, sdh_mode, sdh_stick, sdh_hat, sdh_dir, false);
|
|
||||||
|
|
||||||
bool eraseAll = (event == Event::NoType);
|
|
||||||
switch(mode)
|
|
||||||
{
|
|
||||||
case kEmulationMode: // Default emulation events
|
|
||||||
// Left joystick left/right directions (assume joystick zero)
|
|
||||||
SET_DEFAULT_AXIS(Event::JoystickZeroLeft, mode, 0, 0, 0, event);
|
|
||||||
SET_DEFAULT_AXIS(Event::JoystickZeroRight, mode, 0, 0, 1, event);
|
|
||||||
// Left joystick up/down directions (assume joystick zero)
|
|
||||||
SET_DEFAULT_AXIS(Event::JoystickZeroUp, mode, 0, 1, 0, event);
|
|
||||||
SET_DEFAULT_AXIS(Event::JoystickZeroDown, mode, 0, 1, 1, event);
|
|
||||||
// Right joystick left/right directions (assume joystick one)
|
|
||||||
SET_DEFAULT_AXIS(Event::JoystickOneLeft, mode, 1, 0, 0, event);
|
|
||||||
SET_DEFAULT_AXIS(Event::JoystickOneRight, mode, 1, 0, 1, event);
|
|
||||||
// Right joystick left/right directions (assume joystick one)
|
|
||||||
SET_DEFAULT_AXIS(Event::JoystickOneUp, mode, 1, 1, 0, event);
|
|
||||||
SET_DEFAULT_AXIS(Event::JoystickOneDown, mode, 1, 1, 1, event);
|
|
||||||
|
|
||||||
// Left joystick (assume joystick zero, button zero)
|
|
||||||
SET_DEFAULT_BTN(Event::JoystickZeroFire, mode, 0, 0, event);
|
|
||||||
// Right joystick (assume joystick one, button zero)
|
|
||||||
SET_DEFAULT_BTN(Event::JoystickOneFire, mode, 1, 0, event);
|
|
||||||
|
|
||||||
// Left joystick left/right directions (assume joystick zero and hat 0)
|
|
||||||
SET_DEFAULT_HAT(Event::JoystickZeroLeft, mode, 0, 0, EVENT_HATLEFT, event);
|
|
||||||
SET_DEFAULT_HAT(Event::JoystickZeroRight, mode, 0, 0, EVENT_HATRIGHT, event);
|
|
||||||
// Left joystick up/down directions (assume joystick zero and hat 0)
|
|
||||||
SET_DEFAULT_HAT(Event::JoystickZeroUp, mode, 0, 0, EVENT_HATUP, event);
|
|
||||||
SET_DEFAULT_HAT(Event::JoystickZeroDown, mode, 0, 0, EVENT_HATDOWN, event);
|
|
||||||
// Right joystick left/right directions (assume joystick one and hat 0)
|
|
||||||
SET_DEFAULT_HAT(Event::JoystickOneLeft, mode, 1, 0, EVENT_HATLEFT, event);
|
|
||||||
SET_DEFAULT_HAT(Event::JoystickOneRight, mode, 1, 0, EVENT_HATRIGHT, event);
|
|
||||||
// Right joystick up/down directions (assume joystick one and hat 0)
|
|
||||||
SET_DEFAULT_HAT(Event::JoystickOneUp, mode, 1, 0, EVENT_HATUP, event);
|
|
||||||
SET_DEFAULT_HAT(Event::JoystickOneDown, mode, 1, 0, EVENT_HATDOWN, event);
|
|
||||||
|
|
||||||
break;
|
|
||||||
|
|
||||||
case kMenuMode: // Default menu/UI events
|
|
||||||
SET_DEFAULT_AXIS(Event::UILeft, mode, 0, 0, 0, event);
|
|
||||||
SET_DEFAULT_AXIS(Event::UIRight, mode, 0, 0, 1, event);
|
|
||||||
SET_DEFAULT_AXIS(Event::UIUp, mode, 0, 1, 0, event);
|
|
||||||
SET_DEFAULT_AXIS(Event::UIDown, mode, 0, 1, 1, event);
|
|
||||||
|
|
||||||
// Left joystick (assume joystick zero, button zero)
|
|
||||||
SET_DEFAULT_BTN(Event::UISelect, mode, 0, 0, event);
|
|
||||||
// Right joystick (assume joystick one, button zero)
|
|
||||||
SET_DEFAULT_BTN(Event::UISelect, mode, 1, 0, event);
|
|
||||||
|
|
||||||
SET_DEFAULT_HAT(Event::UILeft, mode, 0, 0, EVENT_HATLEFT, event);
|
|
||||||
SET_DEFAULT_HAT(Event::UIRight, mode, 0, 0, EVENT_HATRIGHT, event);
|
|
||||||
SET_DEFAULT_HAT(Event::UIUp, mode, 0, 0, EVENT_HATUP, event);
|
|
||||||
SET_DEFAULT_HAT(Event::UIDown, mode, 0, 0, EVENT_HATDOWN, event);
|
|
||||||
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
uInt64 OSystem::getTicks() const
|
uInt64 OSystem::getTicks() const
|
||||||
{
|
{
|
||||||
|
|
|
@ -419,15 +419,6 @@ class OSystem
|
||||||
*/
|
*/
|
||||||
virtual void mainLoop();
|
virtual void mainLoop();
|
||||||
|
|
||||||
/**
|
|
||||||
This method determines the default mapping of joystick actions to
|
|
||||||
Stella events for a specific system/platform.
|
|
||||||
|
|
||||||
@param event The event which to (re)set (Event::NoType resets all)
|
|
||||||
@param mode The mode for which the defaults are set
|
|
||||||
*/
|
|
||||||
virtual void setDefaultJoymap(Event::Type event, EventMode mode);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Informs the OSystem of a change in EventHandler state.
|
Informs the OSystem of a change in EventHandler state.
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -46,6 +46,7 @@ MODULE_OBJS := \
|
||||||
src/emucore/Control.o \
|
src/emucore/Control.o \
|
||||||
src/emucore/Driving.o \
|
src/emucore/Driving.o \
|
||||||
src/emucore/EventHandler.o \
|
src/emucore/EventHandler.o \
|
||||||
|
src/emucore/EventJoyHandler.o \
|
||||||
src/emucore/FrameBuffer.o \
|
src/emucore/FrameBuffer.o \
|
||||||
src/emucore/FBSurface.o \
|
src/emucore/FBSurface.o \
|
||||||
src/emucore/FSNode.o \
|
src/emucore/FSNode.o \
|
||||||
|
|
|
@ -48,8 +48,8 @@ LoggerDialog::LoggerDialog(OSystem* osystem, DialogContainer* parent,
|
||||||
|
|
||||||
// Set real dimensions
|
// Set real dimensions
|
||||||
// This is one dialog that can take as much space as is available
|
// This is one dialog that can take as much space as is available
|
||||||
_w = BSPF_min(max_w, 480);
|
_w = max_w;
|
||||||
_h = BSPF_min(max_h, 380);
|
_h = max_h;
|
||||||
|
|
||||||
// Test listing of the log output
|
// Test listing of the log output
|
||||||
xpos = 10; ypos = 10;
|
xpos = 10; ypos = 10;
|
||||||
|
|
|
@ -29,7 +29,8 @@ class Properties;
|
||||||
Menu::Menu(OSystem* osystem)
|
Menu::Menu(OSystem* osystem)
|
||||||
: DialogContainer(osystem)
|
: DialogContainer(osystem)
|
||||||
{
|
{
|
||||||
myBaseDialog = new OptionsDialog(myOSystem, this, 0, 480, 380, false);
|
myBaseDialog = new OptionsDialog(myOSystem, this, 0,
|
||||||
|
FrameBuffer::kFBMinW, FrameBuffer::kFBMinH, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
|
Loading…
Reference in New Issue