mirror of https://github.com/stella-emu/stella.git
Second pass at joystick hat support. It seems to be working fine in
emulation mode, but it's somewhat sensitive in GUI navigation (could be my cheap gamepad). Remapping is mostly complete, except for assignment of hats to analog events. Some more thought is required for this one. git-svn-id: svn://svn.code.sf.net/p/stella/code/trunk@946 8b62c5a3-ac7e-4cc8-8f21-d9a121418aba
This commit is contained in:
parent
34e281d1b7
commit
24aa8c782f
|
@ -13,7 +13,7 @@
|
|||
// See the file "license" for information on usage and redistribution of
|
||||
// this file, and for a DISCLAIMER OF ALL WARRANTIES.
|
||||
//
|
||||
// $Id: EventHandler.cxx,v 1.144 2006-01-09 16:50:01 stephena Exp $
|
||||
// $Id: EventHandler.cxx,v 1.145 2006-01-09 19:30:04 stephena Exp $
|
||||
//============================================================================
|
||||
|
||||
#include <sstream>
|
||||
|
@ -673,6 +673,7 @@ void EventHandler::poll(uInt32 time)
|
|||
handleJoyEvent(stick, button, state);
|
||||
break;
|
||||
}
|
||||
break; // Regular button
|
||||
}
|
||||
|
||||
case JT_STELLADAPTOR_LEFT:
|
||||
|
@ -783,10 +784,22 @@ void EventHandler::poll(uInt32 time)
|
|||
if(stick >= kNumJoysticks || hat >= kNumJoyHats)
|
||||
break;
|
||||
|
||||
if(myState == S_EMULATE)
|
||||
handleJoyHatEvent(stick, hat, value);
|
||||
else if(myOverlay != NULL)
|
||||
myOverlay->handleJoyHatEvent(stick, hat, value);
|
||||
// Preprocess all hat events, converting to Stella JoyHat type
|
||||
// Generate two equivalent hat events representing combined direction
|
||||
// when we get a diagonal hat event
|
||||
if(value == SDL_HAT_CENTERED)
|
||||
handleJoyHatEvent(stick, hat, kJHatCentered);
|
||||
else
|
||||
{
|
||||
if(value & SDL_HAT_UP)
|
||||
handleJoyHatEvent(stick, hat, kJHatUp);
|
||||
if(value & SDL_HAT_RIGHT)
|
||||
handleJoyHatEvent(stick, hat, kJHatRight);
|
||||
if(value & SDL_HAT_DOWN)
|
||||
handleJoyHatEvent(stick, hat, kJHatDown);
|
||||
if(value & SDL_HAT_LEFT)
|
||||
handleJoyHatEvent(stick, hat, kJHatLeft);
|
||||
}
|
||||
break; // SDL_JOYHATMOTION
|
||||
}
|
||||
#endif // JOYSTICK_SUPPORT
|
||||
|
@ -950,7 +963,72 @@ void EventHandler::handleJoyAxisEvent(int stick, int axis, int value)
|
|||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void EventHandler::handleJoyHatEvent(int stick, int hat, int value)
|
||||
{
|
||||
cerr << "stick = " << stick << ", hat = " << hat << ", value = " << value << endl;
|
||||
if(myState == S_EMULATE)
|
||||
{
|
||||
cerr << "stick = " << stick << ", hat = " << hat;
|
||||
switch(value) {
|
||||
case kJHatCentered: cerr << " centered\n"; break;
|
||||
case kJHatUp: cerr << " up\n"; break;
|
||||
case kJHatDown: cerr << " down\n"; break;
|
||||
case kJHatLeft: cerr << " left\n"; break;
|
||||
case kJHatRight: cerr << " right\n"; break;
|
||||
}
|
||||
|
||||
// Treat hats as pairs of directions, similar to joystick axes
|
||||
// Every hat pair has two associated values, negative and positive
|
||||
// Analog events are stored in the negative portion
|
||||
Event::Type eventHatAnalog;
|
||||
switch(value)
|
||||
{
|
||||
case kJHatUp:
|
||||
case kJHatDown:
|
||||
eventHatAnalog = myJoyHatTable[stick][hat][0];
|
||||
break;
|
||||
case kJHatLeft:
|
||||
case kJHatRight:
|
||||
eventHatAnalog = myJoyHatTable[stick][hat][2];
|
||||
break;
|
||||
default:
|
||||
eventHatAnalog = Event::NoType;
|
||||
break;
|
||||
}
|
||||
// Check for analog events, which are handled differently
|
||||
switch((int)eventHatAnalog)
|
||||
{
|
||||
case Event::PaddleZeroAnalog:
|
||||
myEvent->set(Event::PaddleZeroResistance,
|
||||
(int)(1000000.0 * (32767 - value) / 65534));
|
||||
break;
|
||||
case Event::PaddleOneAnalog:
|
||||
myEvent->set(Event::PaddleOneResistance,
|
||||
(int)(1000000.0 * (32767 - value) / 65534));
|
||||
break;
|
||||
case Event::PaddleTwoAnalog:
|
||||
myEvent->set(Event::PaddleTwoResistance,
|
||||
(int)(1000000.0 * (32767 - value) / 65534));
|
||||
break;
|
||||
case Event::PaddleThreeAnalog:
|
||||
myEvent->set(Event::PaddleThreeResistance,
|
||||
(int)(1000000.0 * (32767 - value) / 65534));
|
||||
break;
|
||||
default:
|
||||
// Otherwise, we know the event is digital
|
||||
if(value == kJHatCentered)
|
||||
{
|
||||
// Turn off all associated events, since we don't know exactly
|
||||
// which one was previously activated.
|
||||
handleEvent(myJoyHatTable[stick][hat][0], 0);
|
||||
handleEvent(myJoyHatTable[stick][hat][1], 0);
|
||||
handleEvent(myJoyHatTable[stick][hat][2], 0);
|
||||
handleEvent(myJoyHatTable[stick][hat][3], 0);
|
||||
}
|
||||
else
|
||||
handleEvent(myJoyHatTable[stick][hat][value] , 1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if(myOverlay != NULL)
|
||||
myOverlay->handleJoyHatEvent(stick, hat, value);
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
|
@ -1241,7 +1319,7 @@ void EventHandler::createMouseButtonEvent(int x, int y, int state)
|
|||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void EventHandler::setActionMappings()
|
||||
{
|
||||
int i, j, stick, button, axis, dir;
|
||||
int i, j, stick, button, axis, hat, dir;
|
||||
ostringstream buf;
|
||||
|
||||
// Fill the ActionList with the current key and joystick mappings
|
||||
|
@ -1305,8 +1383,43 @@ void EventHandler::setActionMappings()
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
// FIXME - add joy hat labeling
|
||||
// Joystick hat mapping/labeling
|
||||
for(stick = 0; stick < kNumJoysticks; ++stick)
|
||||
{
|
||||
for(hat = 0; hat < kNumJoyHats; ++hat)
|
||||
{
|
||||
for(dir = 0; dir < 4; ++dir)
|
||||
{
|
||||
if(myJoyHatTable[stick][hat][dir] == event)
|
||||
{
|
||||
buf.str("");
|
||||
buf << "J" << stick << " hat " << hat;
|
||||
switch(dir)
|
||||
{
|
||||
case kJHatUp: buf << " up"; break;
|
||||
case kJHatDown: buf << " down"; break;
|
||||
case kJHatLeft: buf << " left"; break;
|
||||
case kJHatRight: buf << " right"; break;
|
||||
}
|
||||
/* FIXME - figure out how to combine analog & hats
|
||||
if(eventIsAnalog(event))
|
||||
{
|
||||
dir = 2; // Immediately exit the inner loop after this iteration
|
||||
buf << " abs";
|
||||
}
|
||||
else if(dir == 0)
|
||||
buf << " neg";
|
||||
else
|
||||
buf << " pos";
|
||||
*/
|
||||
if(key == "")
|
||||
key = key + buf.str();
|
||||
else
|
||||
key = key + ", " + buf.str();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// There are some keys which are hardcoded. These should be represented too.
|
||||
string prepend = "";
|
||||
|
@ -1474,8 +1587,17 @@ void EventHandler::setDefaultJoyHatMapping(Event::Type event, int stick,
|
|||
hat >= 0 && hat < kNumJoyHats &&
|
||||
event >= 0 && event < Event::LastType)
|
||||
{
|
||||
cerr << "add mapping for stick = " << stick << ", hat = " << hat << ", value = " << value << endl;
|
||||
/*
|
||||
switch(value)
|
||||
{
|
||||
case kJHatUp:
|
||||
case kJHatDown:
|
||||
case kJHatLeft:
|
||||
case kJHatRight:
|
||||
myJoyHatTable[stick][hat][value] = event;
|
||||
break;
|
||||
}
|
||||
|
||||
/* FIXME - deal with assignment of analog events
|
||||
// This confusing code is because each axis has two associated values,
|
||||
// but analog events only affect one of the axis.
|
||||
if(eventIsAnalog(event))
|
||||
|
|
|
@ -13,7 +13,7 @@
|
|||
// See the file "license" for information on usage and redistribution of
|
||||
// this file, and for a DISCLAIMER OF ALL WARRANTIES.
|
||||
//
|
||||
// $Id: EventHandler.hxx,v 1.74 2006-01-09 16:50:01 stephena Exp $
|
||||
// $Id: EventHandler.hxx,v 1.75 2006-01-09 19:30:04 stephena Exp $
|
||||
//============================================================================
|
||||
|
||||
#ifndef EVENTHANDLER_HXX
|
||||
|
@ -60,6 +60,16 @@ enum {
|
|||
#endif
|
||||
};
|
||||
|
||||
// A wrapper around SDL hat events, so we don't drag SDL
|
||||
// through all the child classes
|
||||
enum JoyHat {
|
||||
kJHatUp,
|
||||
kJHatDown,
|
||||
kJHatLeft,
|
||||
kJHatRight,
|
||||
kJHatCentered
|
||||
};
|
||||
|
||||
enum MouseButton {
|
||||
EVENT_LBUTTONDOWN,
|
||||
EVENT_LBUTTONUP,
|
||||
|
@ -123,7 +133,7 @@ struct JoyMouse {
|
|||
mapping can take place.
|
||||
|
||||
@author Stephen Anthony
|
||||
@version $Id: EventHandler.hxx,v 1.74 2006-01-09 16:50:01 stephena Exp $
|
||||
@version $Id: EventHandler.hxx,v 1.75 2006-01-09 19:30:04 stephena Exp $
|
||||
*/
|
||||
class EventHandler
|
||||
{
|
||||
|
|
|
@ -13,7 +13,7 @@
|
|||
// See the file "license" for information on usage and redistribution of
|
||||
// this file, and for a DISCLAIMER OF ALL WARRANTIES.
|
||||
//
|
||||
// $Id: DialogContainer.cxx,v 1.29 2006-01-09 16:50:01 stephena Exp $
|
||||
// $Id: DialogContainer.cxx,v 1.30 2006-01-09 19:30:04 stephena Exp $
|
||||
//============================================================================
|
||||
|
||||
#include "OSystem.hxx"
|
||||
|
@ -389,8 +389,44 @@ void DialogContainer::handleJoyAxisEvent(int stick, int axis, int value)
|
|||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void DialogContainer::handleJoyHatEvent(int stick, int hat, int value)
|
||||
{
|
||||
cerr << "received hat event in dialogcontainer:" << endl
|
||||
<< "stick = " << stick << ", hat = " << hat << ", value = " << value << endl;
|
||||
if(myDialogStack.empty())
|
||||
return;
|
||||
|
||||
// Send the event to the dialog box on the top of the stack
|
||||
Dialog* activeDialog = myDialogStack.top();
|
||||
|
||||
// Only preprocess hat events if the dialog absolutely doesn't want them
|
||||
// Translate to axis events for movement
|
||||
if(!activeDialog->wantsAllEvents())
|
||||
{
|
||||
bool handled = true;
|
||||
switch(value)
|
||||
{
|
||||
case kJHatCentered:
|
||||
handleJoyAxisEvent(stick, 0, 0);
|
||||
handleJoyAxisEvent(stick, 1, 0); // axis 0 & 1, 0 ==> OFF
|
||||
break;
|
||||
case kJHatUp:
|
||||
handleJoyAxisEvent(stick, 1, -32767); // axis 1, -value ==> UP
|
||||
break;
|
||||
case kJHatLeft:
|
||||
handleJoyAxisEvent(stick, 0, -32767); // axis 0, -value ==> LEFT
|
||||
break;
|
||||
case kJHatDown:
|
||||
handleJoyAxisEvent(stick, 1, 32767); // axis 1, +value ==> DOWN
|
||||
break;
|
||||
case kJHatRight:
|
||||
handleJoyAxisEvent(stick, 0, 32767); // axis 0, +value ==> RIGHT
|
||||
break;
|
||||
default:
|
||||
handled = false;
|
||||
}
|
||||
if(handled)
|
||||
return;
|
||||
}
|
||||
|
||||
if(activeDialog->wantsEvents())
|
||||
activeDialog->handleJoyHat(stick, hat, value);
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
|
|
|
@ -13,7 +13,7 @@
|
|||
// See the file "license" for information on usage and redistribution of
|
||||
// this file, and for a DISCLAIMER OF ALL WARRANTIES.
|
||||
//
|
||||
// $Id: EventMappingWidget.cxx,v 1.8 2006-01-08 02:28:03 stephena Exp $
|
||||
// $Id: EventMappingWidget.cxx,v 1.9 2006-01-09 19:30:04 stephena Exp $
|
||||
//
|
||||
// Based on code from ScummVM - Scumm Interpreter
|
||||
// Copyright (C) 2002-2004 The ScummVM project
|
||||
|
@ -208,7 +208,7 @@ void EventMappingWidget::handleJoyDown(int stick, int button)
|
|||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void EventMappingWidget::handleJoyAxis(int stick, int axis, int value)
|
||||
{
|
||||
// Remap joystick buttons in remap mode
|
||||
// Remap joystick axes in remap mode
|
||||
if(myRemapStatus && myActionSelected >= 0)
|
||||
{
|
||||
Event::Type event = EventHandler::ourActionList[ myActionSelected ].event;
|
||||
|
@ -218,6 +218,19 @@ void EventMappingWidget::handleJoyAxis(int stick, int axis, int value)
|
|||
}
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void EventMappingWidget::handleJoyHat(int stick, int hat, int value)
|
||||
{
|
||||
// Remap joystick hats in remap mode
|
||||
if(myRemapStatus && myActionSelected >= 0)
|
||||
{
|
||||
Event::Type event = EventHandler::ourActionList[ myActionSelected ].event;
|
||||
instance()->eventHandler().addJoyHatMapping(event, stick, hat, value);
|
||||
|
||||
stopRemapping();
|
||||
}
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void EventMappingWidget::handleCommand(CommandSender* sender, int cmd,
|
||||
int data, int id)
|
||||
|
|
|
@ -13,7 +13,7 @@
|
|||
// See the file "license" for information on usage and redistribution of
|
||||
// this file, and for a DISCLAIMER OF ALL WARRANTIES.
|
||||
//
|
||||
// $Id: EventMappingWidget.hxx,v 1.4 2005-12-24 22:09:36 stephena Exp $
|
||||
// $Id: EventMappingWidget.hxx,v 1.5 2006-01-09 19:30:04 stephena Exp $
|
||||
//
|
||||
// Based on code from ScummVM - Scumm Interpreter
|
||||
// Copyright (C) 2002-2004 The ScummVM project
|
||||
|
@ -47,6 +47,7 @@ class EventMappingWidget : public Widget, public CommandSender
|
|||
virtual bool handleKeyDown(int ascii, int keycode, int modifiers);
|
||||
virtual void handleJoyDown(int stick, int button);
|
||||
virtual void handleJoyAxis(int stick, int axis, int value);
|
||||
virtual void handleJoyHat(int stick, int hat, int value);
|
||||
|
||||
bool remapMode() { return myRemapStatus; }
|
||||
|
||||
|
|
|
@ -13,7 +13,7 @@
|
|||
// See the file "license" for information on usage and redistribution of
|
||||
// this file, and for a DISCLAIMER OF ALL WARRANTIES.
|
||||
//
|
||||
// $Id: InputDialog.cxx,v 1.8 2005-12-21 01:50:16 stephena Exp $
|
||||
// $Id: InputDialog.cxx,v 1.9 2006-01-09 19:30:04 stephena Exp $
|
||||
//============================================================================
|
||||
|
||||
#include "OSystem.hxx"
|
||||
|
@ -250,6 +250,16 @@ void InputDialog::handleJoyAxis(int stick, int axis, int value)
|
|||
Dialog::handleJoyAxis(stick, axis, value);
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void InputDialog::handleJoyHat(int stick, int hat, int value)
|
||||
{
|
||||
// Remap joystick hat in remap mode, otherwise pass to listwidget
|
||||
if(myEventMapper->remapMode())
|
||||
myEventMapper->handleJoyHat(stick, hat, value);
|
||||
else
|
||||
Dialog::handleJoyHat(stick, hat, value);
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void InputDialog::handleCommand(CommandSender* sender, int cmd,
|
||||
int data, int id)
|
||||
|
|
|
@ -13,7 +13,7 @@
|
|||
// See the file "license" for information on usage and redistribution of
|
||||
// this file, and for a DISCLAIMER OF ALL WARRANTIES.
|
||||
//
|
||||
// $Id: InputDialog.hxx,v 1.4 2005-12-16 14:41:15 stephena Exp $
|
||||
// $Id: InputDialog.hxx,v 1.5 2006-01-09 19:30:04 stephena Exp $
|
||||
//============================================================================
|
||||
|
||||
#ifndef INPUT_DIALOG_HXX
|
||||
|
@ -42,6 +42,7 @@ class InputDialog : public Dialog
|
|||
virtual void handleKeyDown(int ascii, int keycode, int modifiers);
|
||||
virtual void handleJoyDown(int stick, int button);
|
||||
virtual void handleJoyAxis(int stick, int axis, int value);
|
||||
virtual void handleJoyHat(int stick, int hat, int value);
|
||||
virtual void handleCommand(CommandSender* sender, int cmd, int data, int id);
|
||||
|
||||
void loadConfig();
|
||||
|
|
Loading…
Reference in New Issue