diff --git a/Changes.txt b/Changes.txt
index 510182428..3061022c7 100644
--- a/Changes.txt
+++ b/Changes.txt
@@ -12,11 +12,23 @@
Release History
===========================================================================
-3.3 to 3.4: (xx. xx, 2011)
+3.3 to 3.4: (May. xx, 2011)
- * The mouse can now be used in joystick games (ie, moving the mouse
- emulates joystick directions, and pressing a mouse button emulates
- the joystick fire button).
+ * Many improvements to input handling, particularly with the mouse and
+ paddles:
+ - The mouse can now be used to emulate a joystick, booster-grip or
+ driving controller.
+
+ - The mouse now controls only one device at a time (1 of 4 paddles,
+ 1 of 2 joysticks, etc), instead of devices from both virtual ports.
+
+ - The sensitivity for digital and mouse input (for paddles) can now
+ be set separately with the 'dsense' and 'msense' commandline
+ arguments, and from within the Input Settings UI.
+
+ * Added support for the 2600-daptor device, which is similar to a
+ Stelladaptor but improves handling of paddles. Thanks go to XXX
+ for a complimentary test sample of this device.
* Added preliminary support for emulating ARM code to the DPC+
bankswitching scheme (thanks to Batari).
@@ -28,6 +40,9 @@
directory in the ROM launcher, and reloads the directory after
the audit is complete.
+ * Removed the 'grabmouse' functionality; the mouse is now always
+ grabbed while playing a game, and released otherwise.
+
* Updated built-in version of the PNG library to the latest version.
-Have fun!
diff --git a/docs/graphics/eventmapping_devsports.png b/docs/graphics/eventmapping_devsports.png
index c61389f5b..8df806245 100644
Binary files a/docs/graphics/eventmapping_devsports.png and b/docs/graphics/eventmapping_devsports.png differ
diff --git a/docs/graphics/options_video.png b/docs/graphics/options_video.png
index 4bf3dbb59..d517184c8 100644
Binary files a/docs/graphics/options_video.png and b/docs/graphics/options_video.png differ
diff --git a/docs/index.html b/docs/index.html
index 2787c87ec..5b76375d7 100644
--- a/docs/index.html
+++ b/docs/index.html
@@ -1689,11 +1689,6 @@
Centers game window (if possible). |
-
- -grabmouse <1|0> |
- Keeps the mouse in the game window. |
-
-
-palette <standard|z26|user> |
Set the palette to either normal Stella, the one used in the z26
@@ -1800,8 +1795,18 @@
|
- -pspeed <number> |
- Speed for digital emulation of paddles (1-15). |
+ -dsense <number> |
+ Sensitivity for emulation of paddles when using a digital device
+ (ie, joystick digital axis or button, keyboard key, etc).
+ Valid range of values is from 1 to 10, with larger numbers causing
+ faster movement. |
+
+
+
+ -msense <number> |
+ Sensitivity for emulation of paddles when using a mouse.
+ Valid range of values is from 1 to 10, with larger numbers causing
+ faster movement. |
@@ -2172,7 +2177,6 @@
PAL color-loss | use PAL color-loss effect | -colorloss |
GL FS Stretch | stretch fullscreen OpenGL in emulation mode | -gl_fsmax |
GL VSync | enable OpenGL vertical synchronization | -gl_vsync |
- Grab mouse | keep mouse in SDL window | -grabmouse |
Show UI messages | overlay UI messages onscreen | -uimessages |
Center window | attempt to center application window | -center |
Fast SC/AR BIOS | Skip progress loading bars for SuperCharger ROMs | -fastscbios |
@@ -2367,8 +2371,9 @@
Item | Brief description | For more information, see CommandLine |
Stelladaptor X is | Specifies which virtual port each Stelladaptor uses (See Advanced Configuration - Stelladaptor Support) | -sa1 & -sa2 |
AVox serial port | Described in further detail in Advanced Configuration - AtariVox/SaveKey Support | -avoxport |
- Joy deadzone | Deadzone area for axes on joysticks/gamepads | -joydeadzone |
- Paddle speed | Speed used when emulating a paddle using a digital device | -pspeed |
+ Joy deadzone size | Deadzone area for axes on joysticks/gamepads | -joydeadzone |
+ Digital paddle sensitivity | Sensitvity used when emulating a paddle using a digital device | -dsense |
+ Mouse paddle sensitivity | Sensitivity used when emulating a paddle using a mouse | -msense |
Allow all 4 ... | Allow all 4 joystick directions to be pressed simultaneously | -joyallow4 |
Use mouse as ... | Use the mouse for various controllers (paddles, driving, etc) | -usemouse |
diff --git a/src/common/Version.hxx b/src/common/Version.hxx
index 06a9bd527..593850402 100644
--- a/src/common/Version.hxx
+++ b/src/common/Version.hxx
@@ -22,7 +22,7 @@
#include
-#define STELLA_VERSION "3.3.05"
+#define STELLA_VERSION "3.4_svn1"
#define STELLA_BUILD atoi("$Rev$" + 6)
#endif
diff --git a/src/emucore/Booster.cxx b/src/emucore/Booster.cxx
index 92e493fc3..06f729bb9 100644
--- a/src/emucore/Booster.cxx
+++ b/src/emucore/Booster.cxx
@@ -82,7 +82,7 @@ void BoosterGrip::update()
if(xaxis < 16384+4096)
myDigitalPinState[Three] = false;
}
- if(xaxis < -16384)
+ else if(xaxis < -16384)
myDigitalPinState[Three] = false;
if(yaxis > 16384-4096)
{
@@ -91,6 +91,39 @@ void BoosterGrip::update()
if(yaxis < 16384+4096)
myDigitalPinState[One] = false;
}
- if(yaxis < -16384)
+ else if(yaxis < -16384)
myDigitalPinState[One] = false;
+
+ // Mouse motion and button events
+ // Since there are 4 possible controller numbers, we use 0 & 2
+ // for the left jack, and 1 & 3 for the right jack
+ if((myJack == Left && !(ourControlNum & 0x1)) ||
+ (myJack == Right && ourControlNum & 0x1))
+ {
+ // The following code was taken from z26
+ #define MJ_Threshold 2
+ int mousex = myEvent.get(Event::MouseAxisXValue),
+ mousey = myEvent.get(Event::MouseAxisYValue);
+ if(mousex || mousey)
+ {
+ if((!(abs(mousey) > abs(mousex) << 1)) && (abs(mousex) >= MJ_Threshold))
+ {
+ if(mousex < 0)
+ myDigitalPinState[Three] = false;
+ else if (mousex > 0)
+ myDigitalPinState[Four] = false;
+ }
+
+ if((!(abs(mousex) > abs(mousey) << 1)) && (abs(mousey) >= MJ_Threshold))
+ {
+ if(mousey < 0)
+ myDigitalPinState[One] = false;
+ else if(mousey > 0)
+ myDigitalPinState[Two] = false;
+ }
+ }
+ // Get mouse button state
+ if(myEvent.get(Event::MouseButtonValue))
+ myDigitalPinState[Six] = false;
+ }
}
diff --git a/src/emucore/Console.cxx b/src/emucore/Console.cxx
index 5452fb7f9..58704fe32 100644
--- a/src/emucore/Console.cxx
+++ b/src/emucore/Console.cxx
@@ -619,7 +619,8 @@ void Console::setControllers(const string& rommd5)
// Also check if we should swap the paddles plugged into a jack
bool swapPaddles = myProperties.get(Controller_SwapPaddles) == "YES";
- Paddles::setMouseIsPaddle(-1); // Reset to defaults
+ // Set default controller for mouse
+ Controller::setMouseIsController(0);
// Construct left controller
if(left == "BOOSTERGRIP")
@@ -636,7 +637,10 @@ void Console::setControllers(const string& rommd5)
}
else if(left == "PADDLES")
{
- myControllers[leftPort] = new Paddles(Controller::Left, *myEvent, *mySystem, swapPaddles);
+ Controller::setMouseIsController(swapPaddles ? 1 : 0);
+ myControllers[leftPort] =
+ new Paddles(Controller::Left, *myEvent, *mySystem,
+ swapPaddles, false, false);
}
else if(left == "TRACKBALL22")
{
@@ -677,7 +681,11 @@ void Console::setControllers(const string& rommd5)
}
else if(right == "PADDLES")
{
- myControllers[rightPort] = new Paddles(Controller::Right, *myEvent, *mySystem, swapPaddles);
+ if(left != "PADDLES")
+ Controller::setMouseIsController(swapPaddles ? 3 : 2);
+ myControllers[rightPort] =
+ new Paddles(Controller::Right, *myEvent, *mySystem,
+ swapPaddles, false, false);
}
else if(right == "TRACKBALL22")
{
diff --git a/src/emucore/Control.cxx b/src/emucore/Control.cxx
index 3d815dd95..5e1788f54 100644
--- a/src/emucore/Control.cxx
+++ b/src/emucore/Control.cxx
@@ -182,12 +182,23 @@ string Controller::about() const
return name() + " in " + (myJack == Left ? "left port" : "right port");
}
+// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+void Controller::setMouseIsController(int number)
+{
+ ourControlNum = number;
+ if(ourControlNum < 0) ourControlNum = 0;
+ else if (ourControlNum > 3) ourControlNum = 3;
+}
+
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
const Int32 Controller::maximumResistance = 0x7FFFFFFF;
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
const Int32 Controller::minimumResistance = 0x00000000;
+// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+Int32 Controller::ourControlNum = 0;
+
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Controller::Controller(const Controller& c)
: myJack(c.myJack),
diff --git a/src/emucore/Control.hxx b/src/emucore/Control.hxx
index 671a4fcd3..41798be14 100644
--- a/src/emucore/Control.hxx
+++ b/src/emucore/Control.hxx
@@ -192,6 +192,17 @@ class Controller : public Serializable
*/
bool load(Serializer& in);
+ /**
+ Sets the mouse to emulate controller number 'X'. Note that this
+ can accept values 0 to 3, since there can be up to four possible
+ controllers (when using paddles). In all other cases when only
+ two controllers are present, it's up to the specific class to
+ decide how to use this data.
+
+ @param number The controller number (0, 1, 2, 3)
+ */
+ static void setMouseIsController(int number);
+
public:
/// Constant which represents maximum resistance for analog pins
static const Int32 maximumResistance;
@@ -221,6 +232,9 @@ class Controller : public Serializable
/// The analog value on each analog pin
Int32 myAnalogPinValue[2];
+ /// The controller number
+ static Int32 ourControlNum;
+
protected:
// Copy constructor isn't supported by controllers so make it private
Controller(const Controller&);
diff --git a/src/emucore/Driving.cxx b/src/emucore/Driving.cxx
index 98c241904..9345a2ffc 100644
--- a/src/emucore/Driving.cxx
+++ b/src/emucore/Driving.cxx
@@ -65,10 +65,22 @@ void Driving::update()
// Digital events (from keyboard or joystick hats & buttons)
myDigitalPinState[Six] = (myEvent.get(myFireEvent) == 0);
+ int d_axis = myEvent.get(myXAxisValue);
+ if(myEvent.get(myCCWEvent) != 0 || d_axis < -16384) myCounter--;
+ else if(myEvent.get(myCWEvent) != 0 || d_axis > 16384) myCounter++;
- int xaxis = myEvent.get(myXAxisValue);
- if(myEvent.get(myCCWEvent) != 0 || xaxis < -16384) myCounter--;
- else if(myEvent.get(myCWEvent) != 0 || xaxis > 16384) myCounter++;
+ // Mouse motion and button events
+ // Since there are 4 possible controller numbers, we use 0 & 2
+ // for the left jack, and 1 & 3 for the right jack
+ if((myJack == Left && !(ourControlNum & 0x1)) ||
+ (myJack == Right && ourControlNum & 0x1))
+ {
+ int m_axis = myEvent.get(Event::MouseAxisXValue);
+ if(m_axis < -2) myCounter--;
+ else if(m_axis > 2) myCounter++;
+ if(myEvent.get(Event::MouseButtonValue))
+ myDigitalPinState[Six] = false;
+ }
// Only consider the lower-most bits (corresponding to pins 1 & 2)
myCounter &= 0x0f;
diff --git a/src/emucore/Driving.hxx b/src/emucore/Driving.hxx
index b09aba229..88a0739c5 100644
--- a/src/emucore/Driving.hxx
+++ b/src/emucore/Driving.hxx
@@ -68,7 +68,8 @@ class Driving : public Controller
// Pre-compute the events we care about based on given port
// This will eliminate test for left or right port in update()
- Event::Type myCWEvent, myCCWEvent, myFireEvent, myXAxisValue, myYAxisValue;
+ Event::Type myCWEvent, myCCWEvent, myFireEvent,
+ myXAxisValue, myYAxisValue, myAxisMouseMotion;
};
#endif
diff --git a/src/emucore/Event.hxx b/src/emucore/Event.hxx
index 0d568b4e3..906a770d8 100644
--- a/src/emucore/Event.hxx
+++ b/src/emucore/Event.hxx
@@ -40,8 +40,8 @@ class Event
{
NoType,
ConsoleOn, ConsoleOff, ConsoleColor, ConsoleBlackWhite,
- ConsoleLeftDifficultyA, ConsoleLeftDifficultyB,
- ConsoleRightDifficultyA, ConsoleRightDifficultyB,
+ ConsoleLeftDiffA, ConsoleLeftDiffB,
+ ConsoleRightDiffA, ConsoleRightDiffB,
ConsoleSelect, ConsoleReset,
JoystickZeroUp, JoystickZeroDown, JoystickZeroLeft, JoystickZeroRight,
diff --git a/src/emucore/EventHandler.cxx b/src/emucore/EventHandler.cxx
index b98575f80..9a3be40b4 100644
--- a/src/emucore/EventHandler.cxx
+++ b/src/emucore/EventHandler.cxx
@@ -64,7 +64,6 @@ EventHandler::EventHandler(OSystem* osystem)
myEvent(NULL),
myOverlay(NULL),
myState(S_NONE),
- myGrabMouseFlag(false),
myAllowAllDirectionsFlag(false),
myFryingFlag(false)
{
@@ -113,12 +112,12 @@ EventHandler::EventHandler(OSystem* osystem)
ourMessageTable[i] = "";
// Set unchanging messages
- ourMessageTable[Event::ConsoleColor] = "Color Mode";
- ourMessageTable[Event::ConsoleBlackWhite] = "BW Mode";
- ourMessageTable[Event::ConsoleLeftDifficultyA] = "Left Difficulty A";
- ourMessageTable[Event::ConsoleLeftDifficultyB] = "Left Difficulty B";
- ourMessageTable[Event::ConsoleRightDifficultyA] = "Right Difficulty A";
- ourMessageTable[Event::ConsoleRightDifficultyB] = "Right Difficulty B";
+ ourMessageTable[Event::ConsoleColor] = "Color Mode";
+ ourMessageTable[Event::ConsoleBlackWhite] = "BW Mode";
+ ourMessageTable[Event::ConsoleLeftDiffA] = "Left Difficulty A";
+ ourMessageTable[Event::ConsoleLeftDiffB] = "Left Difficulty B";
+ ourMessageTable[Event::ConsoleRightDiffA] = "Right Difficulty A";
+ ourMessageTable[Event::ConsoleRightDiffB] = "Right Difficulty B";
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@@ -160,12 +159,12 @@ void EventHandler::initialize()
setActionMappings(kEmulationMode);
setActionMappings(kMenuMode);
- myGrabMouseFlag = myOSystem->settings().getBool("grabmouse");
myUseCtrlKeyFlag = myOSystem->settings().getBool("ctrlcombo");
Joystick::setDeadZone(myOSystem->settings().getInt("joydeadzone"));
- Paddles::setDigitalSpeed(myOSystem->settings().getInt("pspeed"));
- setPaddleMode(myOSystem->settings().getBool("usemouse") ? 0 : -1, false);
+ Paddles::setDigitalSensitivity(myOSystem->settings().getInt("dsense"));
+ Paddles::setMouseSensitivity(myOSystem->settings().getInt("msense"));
+ setMouseControllerMode(myOSystem->settings().getBool("usemouse") ? 0 : -1, false);
// Set quick select delay when typing characters in listwidgets
ListWidget::setQuickSelectDelay(myOSystem->settings().getInt("listdelay"));
@@ -230,7 +229,20 @@ void EventHandler::setupJoysticks()
// Figure out what type of joystick this is
ostringstream buf;
- if(name.find("Stelladaptor", 0) != string::npos)
+ if(name.find("2600-daptor", 0) != string::npos)
+ {
+ saCount++;
+ if(saCount > 2) // Ignore more than 2 Stelladaptors
+ continue;
+ else if(saCount == 1) // Type will be set by mapStelladaptors()
+ ourJoysticks[i].name = "2600-daptor 1";
+ else if(saCount == 2)
+ ourJoysticks[i].name = "2600-daptor 2";
+
+ buf << " " << i << ": " << ourJoysticks[i].name << endl;
+ myOSystem->logMessage(buf.str(), 1);
+ }
+ else if(name.find("Stelladaptor", 0) != string::npos)
{
saCount++;
if(saCount > 2) // Ignore more than 2 Stelladaptors
@@ -300,6 +312,32 @@ void EventHandler::mapStelladaptors(const string& sa1, const string& sa2)
myOSystem->logMessage(" Stelladaptor 2 emulates right joystick port\n", 1);
}
}
+ else if(ourJoysticks[i].name == "2600-daptor 1")
+ {
+ if(sa1 == "left")
+ {
+ ourJoysticks[i].type = JT_2600DAPTOR_LEFT;
+ myOSystem->logMessage(" 2600-daptor 1 emulates left joystick port\n", 1);
+ }
+ else if(sa1 == "right")
+ {
+ ourJoysticks[i].type = JT_2600DAPTOR_RIGHT;
+ myOSystem->logMessage(" 2600-daptor 1 emulates right joystick port\n", 1);
+ }
+ }
+ else if(ourJoysticks[i].name == "2600-daptor 2")
+ {
+ if(sa2 == "left")
+ {
+ ourJoysticks[i].type = JT_2600DAPTOR_LEFT;
+ myOSystem->logMessage(" 2600-daptor 2 emulates left joystick port\n", 1);
+ }
+ else if(sa2 == "right")
+ {
+ ourJoysticks[i].type = JT_2600DAPTOR_RIGHT;
+ myOSystem->logMessage(" 2600-daptor 2 emulates right joystick port\n", 1);
+ }
+ }
}
myOSystem->logMessage("\n", 1);
@@ -508,16 +546,6 @@ void EventHandler::poll(uInt64 time)
{
handleEvent(Event::Quit, 1);
}
- else if(key == SDLK_g)
- {
- // don't change grabmouse in fullscreen mode
- if(!myOSystem->frameBuffer().fullScreen())
- {
- myGrabMouseFlag = !myGrabMouseFlag;
- myOSystem->settings().setBool("grabmouse", myGrabMouseFlag);
- myOSystem->frameBuffer().grabMouse(myGrabMouseFlag);
- }
- }
// These only work when in emulation mode
else if(myState == S_EMULATE)
{
@@ -530,20 +558,20 @@ void EventHandler::poll(uInt64 time)
handleMacOSXKeypress(int(key));
break;
#endif
- case SDLK_0: // Ctrl-0 sets the mouse to paddle 0
- setPaddleMode(0, true);
+ case SDLK_0: // Ctrl-0 sets the mouse to controller 0
+ setMouseControllerMode(0, true);
break;
- case SDLK_1: // Ctrl-1 sets the mouse to paddle 1
- setPaddleMode(1, true);
+ case SDLK_1: // Ctrl-1 sets the mouse to controller 1
+ setMouseControllerMode(1, true);
break;
- case SDLK_2: // Ctrl-2 sets the mouse to paddle 2
- setPaddleMode(2, true);
+ case SDLK_2: // Ctrl-2 sets the mouse to controller 2
+ setMouseControllerMode(2, true);
break;
- case SDLK_3: // Ctrl-3 sets the mouse to paddle 3
- setPaddleMode(3, true);
+ case SDLK_3: // Ctrl-3 sets the mouse to controller 3
+ setMouseControllerMode(3, true);
break;
case SDLK_f: // Ctrl-f toggles NTSC/PAL mode
@@ -730,16 +758,22 @@ void EventHandler::poll(uInt64 time)
}
break; // Regular button
+ // These events don't have to pass through handleEvent, since
+ // they can never be remapped
case JT_STELLADAPTOR_LEFT:
case JT_STELLADAPTOR_RIGHT:
// The 'type-2' here refers to the fact that 'JT_STELLADAPTOR_LEFT'
// and 'JT_STELLADAPTOR_RIGHT' are at index 2 and 3 in the JoyType
// enum; subtracting two gives us Controller 0 and 1
-
- // These events don't have to pass through handleEvent, since
- // they can never be remapped
if(button < 2) myEvent->set(SA_Button[type-2][button], state);
break; // Stelladaptor button
+ case JT_2600DAPTOR_LEFT:
+ case JT_2600DAPTOR_RIGHT:
+ // The 'type-4' here refers to the fact that 'JT_2600DAPTOR_LEFT'
+ // and 'JT_2600DAPTOR_RIGHT' are at index 4 and 5 in the JoyType
+ // enum; subtracting four gives us Controller 0 and 1
+ if(button < 2) myEvent->set(SA_Button[type-4][button], state);
+ break; // 2600DAPTOR button
}
break; // SDL_JOYBUTTONUP, SDL_JOYBUTTONDOWN
}
@@ -820,19 +854,27 @@ void EventHandler::poll(uInt64 time)
}
break; // Regular joystick axis
+ // Since the various controller classes deal with Stelladaptor
+ // devices differently, we send the raw X and Y axis data directly,
+ // and let the controller handle it
+ // These events don't have to pass through handleEvent, since
+ // they can never be remapped
case JT_STELLADAPTOR_LEFT:
case JT_STELLADAPTOR_RIGHT:
- // Since the various controller classes deal with the
- // Stelladaptor differently, we send the raw X and Y axis
- // data directly, and let the controller handle it
// The 'type-2' here refers to the fact that 'JT_STELLADAPTOR_LEFT'
// and 'JT_STELLADAPTOR_RIGHT' are at index 2 and 3 in the JoyType
// enum; subtracting two gives us Controller 0 and 1
-
- // These events don't have to pass through handleEvent, since
- // they can never be remapped
- if(axis < 2) myEvent->set(SA_Axis[type-2][axis], value);
+ if(axis < 2)
+ myEvent->set(SA_Axis[type-2][axis], value);
break; // Stelladaptor axis
+ case JT_2600DAPTOR_LEFT:
+ case JT_2600DAPTOR_RIGHT:
+ // The 'type-4' here refers to the fact that 'JT_2600DAPTOR_LEFT'
+ // and 'JT_2600DAPTOR_RIGHT' are at index 4 and 5 in the JoyType
+ // enum; subtracting four gives us Controller 0 and 1
+ if(axis < 2)
+ myEvent->set(SA_Axis[type-4][axis], value);
+ break; // 26000daptor axis
}
break; // SDL_JOYAXISMOTION
}
@@ -1621,10 +1663,10 @@ void EventHandler::setDefaultKeymap(Event::Type event, EventMode mode)
SET_DEFAULT_KEY(SDLK_F2, mode, Event::ConsoleReset, event);
SET_DEFAULT_KEY(SDLK_F3, mode, Event::ConsoleColor, event);
SET_DEFAULT_KEY(SDLK_F4, mode, Event::ConsoleBlackWhite, event);
- SET_DEFAULT_KEY(SDLK_F5, mode, Event::ConsoleLeftDifficultyA, event);
- SET_DEFAULT_KEY(SDLK_F6, mode, Event::ConsoleLeftDifficultyB, event);
- SET_DEFAULT_KEY(SDLK_F7, mode, Event::ConsoleRightDifficultyA, event);
- SET_DEFAULT_KEY(SDLK_F8, mode, Event::ConsoleRightDifficultyB, event);
+ SET_DEFAULT_KEY(SDLK_F5, mode, Event::ConsoleLeftDiffA, event);
+ SET_DEFAULT_KEY(SDLK_F6, mode, Event::ConsoleLeftDiffB, event);
+ SET_DEFAULT_KEY(SDLK_F7, mode, Event::ConsoleRightDiffA, event);
+ SET_DEFAULT_KEY(SDLK_F8, mode, Event::ConsoleRightDiffB, event);
SET_DEFAULT_KEY(SDLK_F9, mode, Event::SaveState, event);
SET_DEFAULT_KEY(SDLK_F10, mode, Event::ChangeState, event);
SET_DEFAULT_KEY(SDLK_F11, mode, Event::LoadState, event);
@@ -2052,16 +2094,16 @@ void EventHandler::takeSnapshot(uInt32 number)
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-void EventHandler::setPaddleMode(int num, bool showmessage)
+void EventHandler::setMouseControllerMode(int num, bool showmessage)
{
if(num >= 0 && num <= 3)
{
myMouseEnabled = true;
- Paddles::setMouseIsPaddle(num);
+ Controller::setMouseIsController(num);
if(showmessage)
{
ostringstream buf;
- buf << "Mouse is paddle " << num;
+ buf << "Mouse is controller " << num;
myOSystem->frameBuffer().showMessage(buf.str());
}
}
@@ -2081,9 +2123,6 @@ void EventHandler::enterMenuMode(State state)
{
setEventState(state);
myOverlay->reStack();
-
- myOSystem->frameBuffer().setCursorState();
-
myOSystem->sound().mute(true);
}
@@ -2091,9 +2130,6 @@ void EventHandler::enterMenuMode(State state)
void EventHandler::leaveMenuMode()
{
setEventState(S_EMULATE);
-
- myOSystem->frameBuffer().setCursorState();
-
myOSystem->sound().mute(false);
}
@@ -2122,7 +2158,6 @@ bool EventHandler::enterDebugMode()
return false;
}
myOverlay->reStack();
- myOSystem->frameBuffer().setCursorState();
myOSystem->sound().mute(true);
#else
myOSystem->frameBuffer().showMessage("Debugger support not included",
@@ -2145,7 +2180,6 @@ void EventHandler::leaveDebugMode()
setEventState(S_EMULATE);
myOSystem->createFrameBuffer();
- myOSystem->frameBuffer().setCursorState();
myOSystem->sound().mute(false);
#endif
}
@@ -2192,7 +2226,10 @@ void EventHandler::setEventState(State state)
// Inform various subsystems about the new state
myOSystem->stateChanged(myState);
if(&myOSystem->frameBuffer())
+ {
myOSystem->frameBuffer().stateChanged(myState);
+ myOSystem->frameBuffer().setCursorState();
+ }
// Always clear any pending events when changing states
myEvent->clear();
@@ -2436,106 +2473,106 @@ void EventHandler::setSDLMappings()
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
EventHandler::ActionList EventHandler::ourEmulActionList[kEmulActionListSize] = {
- { Event::ConsoleSelect, "Select", 0, true },
- { Event::ConsoleReset, "Reset", 0, true },
- { Event::ConsoleColor, "Color TV", 0, true },
- { Event::ConsoleBlackWhite, "Black & White TV", 0, true },
- { Event::ConsoleLeftDifficultyA, "P0 Difficulty A", 0, true },
- { Event::ConsoleLeftDifficultyB, "P0 Difficulty B", 0, true },
- { Event::ConsoleRightDifficultyA, "P1 Difficulty A", 0, true },
- { Event::ConsoleRightDifficultyB, "P1 Difficulty B", 0, true },
- { Event::SaveState, "Save State", 0, false },
- { Event::ChangeState, "Change State", 0, false },
- { Event::LoadState, "Load State", 0, false },
- { Event::TakeSnapshot, "Snapshot", 0, false },
- { Event::Fry, "Fry cartridge", 0, false },
- { Event::VolumeDecrease, "Decrease volume", 0, false },
- { Event::VolumeIncrease, "Increase volume", 0, false },
- { Event::PauseMode, "Pause", 0, false },
- { Event::MenuMode, "Enter options menu mode", 0, false },
- { Event::CmdMenuMode, "Toggle command menu mode", 0, false },
- { Event::DebuggerMode, "Toggle debugger mode", 0, false },
- { Event::LauncherMode, "Enter ROM launcher", 0, false },
- { Event::Quit, "Quit", 0, false },
+ { Event::ConsoleSelect, "Select", 0, true },
+ { Event::ConsoleReset, "Reset", 0, true },
+ { Event::ConsoleColor, "Color TV", 0, true },
+ { Event::ConsoleBlackWhite, "Black & White TV", 0, true },
+ { Event::ConsoleLeftDiffA, "P0 Difficulty A", 0, true },
+ { Event::ConsoleLeftDiffB, "P0 Difficulty B", 0, true },
+ { Event::ConsoleRightDiffA, "P1 Difficulty A", 0, true },
+ { Event::ConsoleRightDiffB, "P1 Difficulty B", 0, true },
+ { Event::SaveState, "Save State", 0, false },
+ { Event::ChangeState, "Change State", 0, false },
+ { Event::LoadState, "Load State", 0, false },
+ { Event::TakeSnapshot, "Snapshot", 0, false },
+ { Event::Fry, "Fry cartridge", 0, false },
+ { Event::VolumeDecrease, "Decrease volume", 0, false },
+ { Event::VolumeIncrease, "Increase volume", 0, false },
+ { Event::PauseMode, "Pause", 0, false },
+ { Event::MenuMode, "Enter options menu mode", 0, false },
+ { Event::CmdMenuMode, "Toggle command menu mode", 0, false },
+ { Event::DebuggerMode, "Toggle debugger mode", 0, false },
+ { Event::LauncherMode, "Enter ROM launcher", 0, false },
+ { Event::Quit, "Quit", 0, false },
- { Event::JoystickZeroUp, "P0 Joystick Up", 0, true },
- { Event::JoystickZeroDown, "P0 Joystick Down", 0, true },
- { Event::JoystickZeroLeft, "P0 Joystick Left", 0, true },
- { Event::JoystickZeroRight, "P0 Joystick Right", 0, true },
- { Event::JoystickZeroFire1, "P0 Joystick Fire", 0, true },
- { Event::JoystickZeroFire2, "P0 BoosterGrip Trigger", 0, true },
- { Event::JoystickZeroFire3, "P0 BoosterGrip Booster", 0, true },
+ { Event::JoystickZeroUp, "P0 Joystick Up", 0, true },
+ { Event::JoystickZeroDown, "P0 Joystick Down", 0, true },
+ { Event::JoystickZeroLeft, "P0 Joystick Left", 0, true },
+ { Event::JoystickZeroRight, "P0 Joystick Right", 0, true },
+ { Event::JoystickZeroFire1, "P0 Joystick Fire", 0, true },
+ { Event::JoystickZeroFire2, "P0 BoosterGrip Trigger", 0, true },
+ { Event::JoystickZeroFire3, "P0 BoosterGrip Booster", 0, true },
- { Event::JoystickOneUp, "P1 Joystick Up", 0, true },
- { Event::JoystickOneDown, "P1 Joystick Down", 0, true },
- { Event::JoystickOneLeft, "P1 Joystick Left", 0, true },
- { Event::JoystickOneRight, "P1 Joystick Right", 0, true },
- { Event::JoystickOneFire1, "P1 Joystick Fire", 0, true },
- { Event::JoystickOneFire2, "P1 BoosterGrip Trigger", 0, true },
- { Event::JoystickOneFire3, "P1 BoosterGrip Booster", 0, true },
+ { Event::JoystickOneUp, "P1 Joystick Up", 0, true },
+ { Event::JoystickOneDown, "P1 Joystick Down", 0, true },
+ { Event::JoystickOneLeft, "P1 Joystick Left", 0, true },
+ { Event::JoystickOneRight, "P1 Joystick Right", 0, true },
+ { Event::JoystickOneFire1, "P1 Joystick Fire", 0, true },
+ { Event::JoystickOneFire2, "P1 BoosterGrip Trigger", 0, true },
+ { Event::JoystickOneFire3, "P1 BoosterGrip Booster", 0, true },
- { Event::PaddleZeroAnalog, "Paddle 0 Analog", 0, true },
- { Event::PaddleZeroDecrease, "Paddle 0 Decrease", 0, true },
- { Event::PaddleZeroIncrease, "Paddle 0 Increase", 0, true },
- { Event::PaddleZeroFire, "Paddle 0 Fire", 0, true },
+ { Event::PaddleZeroAnalog, "Paddle 0 Analog", 0, true },
+ { Event::PaddleZeroDecrease, "Paddle 0 Decrease", 0, true },
+ { Event::PaddleZeroIncrease, "Paddle 0 Increase", 0, true },
+ { Event::PaddleZeroFire, "Paddle 0 Fire", 0, true },
- { Event::PaddleOneAnalog, "Paddle 1 Analog", 0, true },
- { Event::PaddleOneDecrease, "Paddle 1 Decrease", 0, true },
- { Event::PaddleOneIncrease, "Paddle 1 Increase", 0, true },
- { Event::PaddleOneFire, "Paddle 1 Fire", 0, true },
+ { Event::PaddleOneAnalog, "Paddle 1 Analog", 0, true },
+ { Event::PaddleOneDecrease, "Paddle 1 Decrease", 0, true },
+ { Event::PaddleOneIncrease, "Paddle 1 Increase", 0, true },
+ { Event::PaddleOneFire, "Paddle 1 Fire", 0, true },
- { Event::PaddleTwoAnalog, "Paddle 2 Analog", 0, true },
- { Event::PaddleTwoDecrease, "Paddle 2 Decrease", 0, true },
- { Event::PaddleTwoIncrease, "Paddle 2 Increase", 0, true },
- { Event::PaddleTwoFire, "Paddle 2 Fire", 0, true },
+ { Event::PaddleTwoAnalog, "Paddle 2 Analog", 0, true },
+ { Event::PaddleTwoDecrease, "Paddle 2 Decrease", 0, true },
+ { Event::PaddleTwoIncrease, "Paddle 2 Increase", 0, true },
+ { Event::PaddleTwoFire, "Paddle 2 Fire", 0, true },
- { Event::PaddleThreeAnalog, "Paddle 3 Analog", 0, true },
- { Event::PaddleThreeDecrease, "Paddle 3 Decrease", 0, true },
- { Event::PaddleThreeIncrease, "Paddle 3 Increase", 0, true },
- { Event::PaddleThreeFire, "Paddle 3 Fire", 0, true },
+ { Event::PaddleThreeAnalog, "Paddle 3 Analog", 0, true },
+ { Event::PaddleThreeDecrease, "Paddle 3 Decrease", 0, true },
+ { Event::PaddleThreeIncrease, "Paddle 3 Increase", 0, true },
+ { Event::PaddleThreeFire, "Paddle 3 Fire", 0, true },
- { Event::KeyboardZero1, "P0 Keyboard 1", 0, true },
- { Event::KeyboardZero2, "P0 Keyboard 2", 0, true },
- { Event::KeyboardZero3, "P0 Keyboard 3", 0, true },
- { Event::KeyboardZero4, "P0 Keyboard 4", 0, true },
- { Event::KeyboardZero5, "P0 Keyboard 5", 0, true },
- { Event::KeyboardZero6, "P0 Keyboard 6", 0, true },
- { Event::KeyboardZero7, "P0 Keyboard 7", 0, true },
- { Event::KeyboardZero8, "P0 Keyboard 8", 0, true },
- { Event::KeyboardZero9, "P0 Keyboard 9", 0, true },
- { Event::KeyboardZeroStar, "P0 Keyboard *", 0, true },
- { Event::KeyboardZero0, "P0 Keyboard 0", 0, true },
- { Event::KeyboardZeroPound, "P0 Keyboard #", 0, true },
+ { Event::KeyboardZero1, "P0 Keyboard 1", 0, true },
+ { Event::KeyboardZero2, "P0 Keyboard 2", 0, true },
+ { Event::KeyboardZero3, "P0 Keyboard 3", 0, true },
+ { Event::KeyboardZero4, "P0 Keyboard 4", 0, true },
+ { Event::KeyboardZero5, "P0 Keyboard 5", 0, true },
+ { Event::KeyboardZero6, "P0 Keyboard 6", 0, true },
+ { Event::KeyboardZero7, "P0 Keyboard 7", 0, true },
+ { Event::KeyboardZero8, "P0 Keyboard 8", 0, true },
+ { Event::KeyboardZero9, "P0 Keyboard 9", 0, true },
+ { Event::KeyboardZeroStar, "P0 Keyboard *", 0, true },
+ { Event::KeyboardZero0, "P0 Keyboard 0", 0, true },
+ { Event::KeyboardZeroPound, "P0 Keyboard #", 0, true },
- { Event::KeyboardOne1, "P1 Keyboard 1", 0, true },
- { Event::KeyboardOne2, "P1 Keyboard 2", 0, true },
- { Event::KeyboardOne3, "P1 Keyboard 3", 0, true },
- { Event::KeyboardOne4, "P1 Keyboard 4", 0, true },
- { Event::KeyboardOne5, "P1 Keyboard 5", 0, true },
- { Event::KeyboardOne6, "P1 Keyboard 6", 0, true },
- { Event::KeyboardOne7, "P1 Keyboard 7", 0, true },
- { Event::KeyboardOne8, "P1 Keyboard 8", 0, true },
- { Event::KeyboardOne9, "P1 Keyboard 9", 0, true },
- { Event::KeyboardOneStar, "P1 Keyboard *", 0, true },
- { Event::KeyboardOne0, "P1 Keyboard 0", 0, true },
- { Event::KeyboardOnePound, "P1 Keyboard #", 0, true },
+ { Event::KeyboardOne1, "P1 Keyboard 1", 0, true },
+ { Event::KeyboardOne2, "P1 Keyboard 2", 0, true },
+ { Event::KeyboardOne3, "P1 Keyboard 3", 0, true },
+ { Event::KeyboardOne4, "P1 Keyboard 4", 0, true },
+ { Event::KeyboardOne5, "P1 Keyboard 5", 0, true },
+ { Event::KeyboardOne6, "P1 Keyboard 6", 0, true },
+ { Event::KeyboardOne7, "P1 Keyboard 7", 0, true },
+ { Event::KeyboardOne8, "P1 Keyboard 8", 0, true },
+ { Event::KeyboardOne9, "P1 Keyboard 9", 0, true },
+ { Event::KeyboardOneStar, "P1 Keyboard *", 0, true },
+ { Event::KeyboardOne0, "P1 Keyboard 0", 0, true },
+ { Event::KeyboardOnePound, "P1 Keyboard #", 0, true },
- { Event::Combo1, "Combo 1", 0, false },
- { Event::Combo2, "Combo 2", 0, false },
- { Event::Combo3, "Combo 3", 0, false },
- { Event::Combo4, "Combo 4", 0, false },
- { Event::Combo5, "Combo 5", 0, false },
- { Event::Combo6, "Combo 6", 0, false },
- { Event::Combo7, "Combo 7", 0, false },
- { Event::Combo8, "Combo 8", 0, false },
- { Event::Combo9, "Combo 9", 0, false },
- { Event::Combo10, "Combo 10", 0, false },
- { Event::Combo11, "Combo 11", 0, false },
- { Event::Combo12, "Combo 12", 0, false },
- { Event::Combo13, "Combo 13", 0, false },
- { Event::Combo14, "Combo 14", 0, false },
- { Event::Combo15, "Combo 15", 0, false },
- { Event::Combo16, "Combo 16", 0, false }
+ { Event::Combo1, "Combo 1", 0, false },
+ { Event::Combo2, "Combo 2", 0, false },
+ { Event::Combo3, "Combo 3", 0, false },
+ { Event::Combo4, "Combo 4", 0, false },
+ { Event::Combo5, "Combo 5", 0, false },
+ { Event::Combo6, "Combo 6", 0, false },
+ { Event::Combo7, "Combo 7", 0, false },
+ { Event::Combo8, "Combo 8", 0, false },
+ { Event::Combo9, "Combo 9", 0, false },
+ { Event::Combo10, "Combo 10", 0, false },
+ { Event::Combo11, "Combo 11", 0, false },
+ { Event::Combo12, "Combo 12", 0, false },
+ { Event::Combo13, "Combo 13", 0, false },
+ { Event::Combo14, "Combo 14", 0, false },
+ { Event::Combo15, "Combo 15", 0, false },
+ { Event::Combo16, "Combo 16", 0, false }
};
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
diff --git a/src/emucore/EventHandler.hxx b/src/emucore/EventHandler.hxx
index 78d8fd881..77fbc4d4a 100644
--- a/src/emucore/EventHandler.hxx
+++ b/src/emucore/EventHandler.hxx
@@ -185,12 +185,12 @@ class EventHandler
void quit() { handleEvent(Event::Quit, 1); }
/**
- Sets the mouse to act as paddle 'num'
+ Sets the mouse to act as controller 'num'
- @param num The paddle which the mouse should emulate
+ @param num The controller which the mouse should emulate
@param showmessage Print a message to the framebuffer
*/
- void setPaddleMode(int num, bool showmessage = false);
+ void setMouseControllerMode(int num, bool showmessage = false);
/**
Set the number of seconds between taking a snapshot in
@@ -407,10 +407,12 @@ class EventHandler
kNumJoyHats = 16
};
enum JoyType {
- JT_NONE,
- JT_REGULAR,
- JT_STELLADAPTOR_LEFT,
- JT_STELLADAPTOR_RIGHT
+ JT_NONE = 0,
+ JT_REGULAR = 1,
+ JT_STELLADAPTOR_LEFT = 2,
+ JT_STELLADAPTOR_RIGHT = 3,
+ JT_2600DAPTOR_LEFT = 4,
+ JT_2600DAPTOR_RIGHT = 5
};
struct Stella_Joystick {
SDL_Joystick* stick;
@@ -460,9 +462,6 @@ class EventHandler
// Indicates the current state of the system (ie, which mode is current)
State myState;
- // Indicates whether the mouse cursor is grabbed
- bool myGrabMouseFlag;
-
// Indicates whether the mouse is enabled for game controller actions
bool myMouseEnabled;
diff --git a/src/emucore/FrameBuffer.cxx b/src/emucore/FrameBuffer.cxx
index eb066c622..ac1e9f659 100644
--- a/src/emucore/FrameBuffer.cxx
+++ b/src/emucore/FrameBuffer.cxx
@@ -743,21 +743,12 @@ cerr << "New mode:" << endl
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void FrameBuffer::setCursorState()
{
- if(fullScreen())
- grabMouse(true);
- else
- grabMouse(myOSystem->settings().getBool("grabmouse"));
-
- switch(myOSystem->eventHandler().state())
- {
- case EventHandler::S_EMULATE:
- case EventHandler::S_PAUSE:
- showCursor(false);
- break;
- default:
- showCursor(true);
- break;
- }
+ // Always grab mouse in fullscreen or during emulation,
+ // and don't show the cursor during emulation
+ bool emulation =
+ myOSystem->eventHandler().state() == EventHandler::S_EMULATE;
+ grabMouse(fullScreen() || emulation);
+ showCursor(!emulation);
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
diff --git a/src/emucore/FrameBuffer.hxx b/src/emucore/FrameBuffer.hxx
index eadfc2858..4ed1d823c 100644
--- a/src/emucore/FrameBuffer.hxx
+++ b/src/emucore/FrameBuffer.hxx
@@ -240,11 +240,6 @@ class FrameBuffer
*/
virtual void showCursor(bool show);
- /**
- Grabs or ungrabs the mouse based on the given boolean value.
- */
- void grabMouse(bool grab);
-
/**
Answers if the display is currently in fullscreen mode.
*/
@@ -470,6 +465,11 @@ class FrameBuffer
uInt32 myZoomLevel;
private:
+ /**
+ Grabs or ungrabs the mouse based on the given boolean value.
+ */
+ void grabMouse(bool grab);
+
/**
Set the icon for the main SDL window.
*/
diff --git a/src/emucore/Joystick.cxx b/src/emucore/Joystick.cxx
index b4d19315d..90dc7ea52 100644
--- a/src/emucore/Joystick.cxx
+++ b/src/emucore/Joystick.cxx
@@ -74,7 +74,7 @@ void Joystick::update()
if(xaxis < 16384+4096)
myDigitalPinState[Three] = false;
}
- if(xaxis < -16384)
+ else if(xaxis < -16384)
myDigitalPinState[Three] = false;
if(yaxis > 16384-4096)
{
@@ -83,35 +83,41 @@ void Joystick::update()
if(yaxis < 16384+4096)
myDigitalPinState[One] = false;
}
- if(yaxis < -16384)
+ else if(yaxis < -16384)
myDigitalPinState[One] = false;
- // The following code was taken from z26
- // Mouse events
-#define MJ_Threshold 2
- int mousex = myEvent.get(Event::MouseAxisXValue),
- mousey = myEvent.get(Event::MouseAxisYValue);
- if(mousex || mousey)
+ // Mouse motion and button events
+ // Since there are 4 possible controller numbers, we use 0 & 2
+ // for the left jack, and 1 & 3 for the right jack
+ if((myJack == Left && !(ourControlNum & 0x1)) ||
+ (myJack == Right && ourControlNum & 0x1))
{
- if((!(abs(mousey) > abs(mousex) << 1)) && (abs(mousex) >= MJ_Threshold))
+ // The following code was taken from z26
+ #define MJ_Threshold 2
+ int mousex = myEvent.get(Event::MouseAxisXValue),
+ mousey = myEvent.get(Event::MouseAxisYValue);
+ if(mousex || mousey)
{
- if(mousex < 0)
- myDigitalPinState[Three] = false;
- else if (mousex > 0)
- myDigitalPinState[Four] = false;
- }
+ if((!(abs(mousey) > abs(mousex) << 1)) && (abs(mousex) >= MJ_Threshold))
+ {
+ if(mousex < 0)
+ myDigitalPinState[Three] = false;
+ else if (mousex > 0)
+ myDigitalPinState[Four] = false;
+ }
- if((!(abs(mousex) > abs(mousey) << 1)) && (abs(mousey) >= MJ_Threshold))
- {
- if(mousey < 0)
- myDigitalPinState[One] = false;
- else if(mousey > 0)
- myDigitalPinState[Two] = false;
+ if((!(abs(mousex) > abs(mousey) << 1)) && (abs(mousey) >= MJ_Threshold))
+ {
+ if(mousey < 0)
+ myDigitalPinState[One] = false;
+ else if(mousey > 0)
+ myDigitalPinState[Two] = false;
+ }
}
+ // Get mouse button state
+ if(myEvent.get(Event::MouseButtonValue))
+ myDigitalPinState[Six] = false;
}
- // Get mouse button state
- if(myEvent.get(Event::MouseButtonValue))
- myDigitalPinState[Six] = false;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
diff --git a/src/emucore/Paddles.cxx b/src/emucore/Paddles.cxx
index 6d71914df..89fc169e7 100644
--- a/src/emucore/Paddles.cxx
+++ b/src/emucore/Paddles.cxx
@@ -17,116 +17,212 @@
// $Id$
//============================================================================
-#define TRIGMAX 240
-#define TRIGMIN 1
+#include
#include "Event.hxx"
#include "Paddles.hxx"
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-Paddles::Paddles(Jack jack, const Event& event, const System& system, bool swap)
+Paddles::Paddles(Jack jack, const Event& event, const System& system,
+ bool swapport, bool swapaxis, bool swapdir)
: Controller(jack, event, system, Controller::Paddles)
{
- // Swap the paddle events, from paddle 0 <=> 1 and paddle 2 <=> 3
- // Also consider whether this is the left or right port
+ // The following logic reflects that mapping paddles to different
+ // devices can be extremely complex
+ // As well, while many paddle games have horizontal movement of
+ // objects (which maps nicely to horizontal movement of the joystick
+ // or mouse), others have vertical movement
+ // This vertical handling is taken care of by swapping the axes
+ // On the other hand, some games treat paddle resistance differently,
+ // (ie, increasing resistance can move an object right instead of left)
+ // This is taken care of by swapping the direction of movement
+ // Arrgh, did I mention that paddles are complex ...
+
+ // As much as possible, precompute which events we care about for
+ // a given port; this will speed up processing in update()
+ // Consider whether this is the left or right port
if(myJack == Left)
{
- if(!swap)
+ if(!swapport) // First paddle is 0, second is 1
{
+ // These aren't affected by changes in axis orientation
myP0AxisValue = Event::SALeftAxis0Value;
- myP0DecEvent1 = Event::PaddleZeroDecrease;
- myP0DecEvent2 = Event::JoystickZeroRight;
- myP0IncEvent1 = Event::PaddleZeroIncrease;
- myP0IncEvent2 = Event::JoystickZeroLeft;
+ myP1AxisValue = Event::SALeftAxis1Value;
myP0FireEvent1 = Event::PaddleZeroFire;
myP0FireEvent2 = Event::JoystickZeroFire1;
-
- myP1AxisValue = Event::SALeftAxis1Value;
- myP1DecEvent1 = Event::PaddleOneDecrease;
- myP1DecEvent2 = Event::JoystickZeroUp;
- myP1IncEvent1 = Event::PaddleOneIncrease;
- myP1IncEvent2 = Event::JoystickZeroDown;
myP1FireEvent1 = Event::PaddleOneFire;
myP1FireEvent2 = Event::JoystickZeroFire3;
- if(_MOUSEX_PADDLE < 0) _MOUSEX_PADDLE = 0;
+ // Direction of movement is swapped
+ // That is, moving in a certain direction on an axis can
+ // result in either increasing or decreasing paddle movement
+ if(!swapdir)
+ {
+ myP0DecEvent1 = Event::PaddleZeroDecrease;
+ myP0DecEvent2 = Event::JoystickZeroRight;
+ myP0IncEvent1 = Event::PaddleZeroIncrease;
+ myP0IncEvent2 = Event::JoystickZeroLeft;
+ myP1DecEvent1 = Event::PaddleOneDecrease;
+ myP1DecEvent2 = Event::JoystickZeroDown;
+ myP1IncEvent1 = Event::PaddleOneIncrease;
+ myP1IncEvent2 = Event::JoystickZeroUp;
+ }
+ else
+ {
+ myP0DecEvent1 = Event::PaddleZeroIncrease;
+ myP0DecEvent2 = Event::JoystickZeroLeft;
+ myP0IncEvent1 = Event::PaddleZeroDecrease;
+ myP0IncEvent2 = Event::JoystickZeroRight;
+ myP1DecEvent1 = Event::PaddleOneIncrease;
+ myP1DecEvent2 = Event::JoystickZeroUp;
+ myP1IncEvent1 = Event::PaddleOneDecrease;
+ myP1IncEvent2 = Event::JoystickZeroDown;
+ }
}
- else
+ else // First paddle is 1, second is 0
{
+ // These aren't affected by changes in axis orientation
myP0AxisValue = Event::SALeftAxis1Value;
- myP0DecEvent1 = Event::PaddleOneDecrease;
- myP0DecEvent2 = Event::JoystickZeroUp;
- myP0IncEvent1 = Event::PaddleOneIncrease;
- myP0IncEvent2 = Event::JoystickZeroDown;
+ myP1AxisValue = Event::SALeftAxis0Value;
myP0FireEvent1 = Event::PaddleOneFire;
myP0FireEvent2 = Event::JoystickZeroFire3;
-
- myP1AxisValue = Event::SALeftAxis0Value;
- myP1DecEvent1 = Event::PaddleZeroDecrease;
- myP1DecEvent2 = Event::JoystickZeroRight;
- myP1IncEvent1 = Event::PaddleZeroIncrease;
- myP1IncEvent2 = Event::JoystickZeroLeft;
myP1FireEvent1 = Event::PaddleZeroFire;
myP1FireEvent2 = Event::JoystickZeroFire1;
- if(_MOUSEX_PADDLE < 0) _MOUSEX_PADDLE = 1;
+ // Direction of movement is swapped
+ // That is, moving in a certain direction on an axis can
+ // result in either increasing or decreasing paddle movement
+ if(!swapdir)
+ {
+ myP0DecEvent1 = Event::PaddleOneDecrease;
+ myP0DecEvent2 = Event::JoystickZeroDown;
+ myP0IncEvent1 = Event::PaddleOneIncrease;
+ myP0IncEvent2 = Event::JoystickZeroUp;
+ myP1DecEvent1 = Event::PaddleZeroDecrease;
+ myP1DecEvent2 = Event::JoystickZeroRight;
+ myP1IncEvent1 = Event::PaddleZeroIncrease;
+ myP1IncEvent2 = Event::JoystickZeroLeft;
+ }
+ else
+ {
+ myP0DecEvent1 = Event::PaddleOneIncrease;
+ myP0DecEvent2 = Event::JoystickZeroUp;
+ myP0IncEvent1 = Event::PaddleOneDecrease;
+ myP0IncEvent2 = Event::JoystickZeroDown;
+ myP1DecEvent1 = Event::PaddleZeroIncrease;
+ myP1DecEvent2 = Event::JoystickZeroLeft;
+ myP1IncEvent1 = Event::PaddleZeroDecrease;
+ myP1IncEvent2 = Event::JoystickZeroRight;
+ }
}
}
- else
+ else // Jack is right port
{
- if(!swap)
+ if(!swapport) // First paddle is 2, second is 3
{
+ // These aren't affected by changes in axis orientation
myP0AxisValue = Event::SARightAxis0Value;
- myP0DecEvent1 = Event::PaddleTwoDecrease;
- myP0DecEvent2 = Event::JoystickOneRight;
- myP0IncEvent1 = Event::PaddleTwoIncrease;
- myP0IncEvent2 = Event::JoystickOneLeft;
+ myP1AxisValue = Event::SARightAxis1Value;
myP0FireEvent1 = Event::PaddleTwoFire;
myP0FireEvent2 = Event::JoystickOneFire1;
-
- myP1AxisValue = Event::SARightAxis1Value;
- myP1DecEvent1 = Event::PaddleThreeDecrease;
- myP1DecEvent2 = Event::JoystickOneUp;
- myP1IncEvent1 = Event::PaddleThreeIncrease;
- myP1IncEvent2 = Event::JoystickOneDown;
myP1FireEvent1 = Event::PaddleThreeFire;
myP1FireEvent2 = Event::JoystickOneFire3;
- if(_MOUSEX_PADDLE < 0) _MOUSEX_PADDLE = 0;
+ // Direction of movement is swapped
+ // That is, moving in a certain direction on an axis can
+ // result in either increasing or decreasing paddle movement
+ if(!swapdir)
+ {
+ myP0DecEvent1 = Event::PaddleTwoDecrease;
+ myP0DecEvent2 = Event::JoystickOneRight;
+ myP0IncEvent1 = Event::PaddleTwoIncrease;
+ myP0IncEvent2 = Event::JoystickOneLeft;
+ myP1DecEvent1 = Event::PaddleThreeDecrease;
+ myP1DecEvent2 = Event::JoystickOneDown;
+ myP1IncEvent1 = Event::PaddleThreeIncrease;
+ myP1IncEvent2 = Event::JoystickOneUp;
+ }
+ else
+ {
+ myP0DecEvent1 = Event::PaddleTwoIncrease;
+ myP0DecEvent2 = Event::JoystickOneLeft;
+ myP0IncEvent1 = Event::PaddleTwoDecrease;
+ myP0IncEvent2 = Event::JoystickOneRight;
+ myP1DecEvent1 = Event::PaddleThreeIncrease;
+ myP1DecEvent2 = Event::JoystickOneUp;
+ myP1IncEvent1 = Event::PaddleThreeDecrease;
+ myP1IncEvent2 = Event::JoystickOneDown;
+ }
}
- else
+ else // First paddle is 3, second is 2
{
+ // These aren't affected by changes in axis orientation
myP0AxisValue = Event::SARightAxis1Value;
- myP0DecEvent1 = Event::PaddleThreeDecrease;
- myP0DecEvent2 = Event::JoystickOneUp;
- myP0IncEvent1 = Event::PaddleThreeIncrease;
- myP0IncEvent2 = Event::JoystickOneDown;
+ myP1AxisValue = Event::SARightAxis0Value;
myP0FireEvent1 = Event::PaddleThreeFire;
myP0FireEvent2 = Event::JoystickOneFire3;
-
- myP1AxisValue = Event::SARightAxis0Value;
- myP1DecEvent1 = Event::PaddleTwoDecrease;
- myP1DecEvent2 = Event::JoystickOneRight;
- myP1IncEvent1 = Event::PaddleTwoIncrease;
- myP1IncEvent2 = Event::JoystickOneLeft;
myP1FireEvent1 = Event::PaddleTwoFire;
myP1FireEvent2 = Event::JoystickOneFire1;
- if(_MOUSEX_PADDLE < 0) _MOUSEX_PADDLE = 1;
+ // Direction of movement is swapped
+ // That is, moving in a certain direction on an axis can
+ // result in either increasing or decreasing paddle movement
+ if(!swapdir)
+ {
+ myP0DecEvent1 = Event::PaddleThreeDecrease;
+ myP0DecEvent2 = Event::JoystickOneDown;
+ myP0IncEvent1 = Event::PaddleThreeIncrease;
+ myP0IncEvent2 = Event::JoystickOneUp;
+ myP1DecEvent1 = Event::PaddleTwoDecrease;
+ myP1DecEvent2 = Event::JoystickOneRight;
+ myP1IncEvent1 = Event::PaddleTwoIncrease;
+ myP1IncEvent2 = Event::JoystickOneLeft;
+ }
+ else
+ {
+ myP0DecEvent1 = Event::PaddleThreeIncrease;
+ myP0DecEvent2 = Event::JoystickOneUp;
+ myP0IncEvent1 = Event::PaddleThreeDecrease;
+ myP0IncEvent2 = Event::JoystickOneDown;
+ myP1DecEvent1 = Event::PaddleTwoIncrease;
+ myP1DecEvent2 = Event::JoystickOneLeft;
+ myP1IncEvent1 = Event::PaddleTwoDecrease;
+ myP1IncEvent2 = Event::JoystickOneRight;
+ }
}
}
+ // The following are independent of whether or not the port
+ // is left or right
+ _MOUSE_SENSITIVITY = swapdir ? -abs(_MOUSE_SENSITIVITY) :
+ abs(_MOUSE_SENSITIVITY);
+ if(!swapaxis)
+ {
+ myAxisMouseMotion = Event::MouseAxisXValue;
+ myAxisDigitalZero = 0;
+ myAxisDigitalOne = 1;
+ }
+ else
+ {
+ myAxisMouseMotion = Event::MouseAxisYValue;
+ myAxisDigitalZero = 1;
+ myAxisDigitalOne = 0;
+ }
+
// Digital pins 1, 2 and 6 are not connected
myDigitalPinState[One] =
myDigitalPinState[Two] =
myDigitalPinState[Six] = true;
// Digital emulation of analog paddle movement
- myKeyRepeat0 = myPaddleRepeat0 = myKeyRepeat1 = myPaddleRepeat1 = 0;
+ myKeyRepeat0 = myKeyRepeat1 = false;
+ myPaddleRepeat0 = myPaddleRepeat1 = myLastAxisX = myLastAxisY = 0;
- myCharge[0] = myCharge[1] =
- myLastCharge[0] = myLastCharge[1] = TRIGMAX/2; // half of maximum paddle charge
- myLeftMotion[0] = myLeftMotion[1] = 0;
+ myCharge[0] = myCharge[1] = myLastCharge[0] = myLastCharge[1] = 0;
+
+ // Paranoid mode: defaults for the global variables should be set
+ // before the first instance of this class is instantiated
+ assert(_DIGITAL_SENSITIVITY != -1 && _MOUSE_SENSITIVITY != -1);
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@@ -145,179 +241,138 @@ void Paddles::update()
myDigitalPinState[Four] =
(myEvent.get(myP0FireEvent1) == 0 && myEvent.get(myP0FireEvent2) == 0);
+ // Paddle movement is a very difficult thing to accurately emulate,
+ // since it originally came from an analog device that had very
+ // peculiar behaviour
+ // Compounding the problem is the fact that we'd like to emulate
+ // movement with 'digital' data (like from a keyboard or a digital
+ // joystick axis), but also from a mouse (relative values)
+ // and Stelladaptor-like devices (absolute analog values clamped to
+ // a certain range)
+ // And to top it all off, we don't want one devices input to conflict
+ // with the others ...
+
+ // Analog axis events from Stelladaptor-like devices
+ // These devices generate data in the range -32768 to 32767,
+ // so we have to scale appropriately
+ // Since these events are generated and stored indefinitely,
+ // we only process the first one we see (when it differs from
+ // previous values by a pre-defined amount)
+ // Otherwise, it would always override input from digital and mouse
+ bool sa_changed = false;
+ int sa_xaxis = myEvent.get(myP0AxisValue);
+ int sa_yaxis = myEvent.get(myP1AxisValue);
+ if(abs(myLastAxisX - sa_xaxis) > 10)
+ {
+ myAnalogPinValue[Nine] = (Int32)(1400000 *
+ (float)(32767 - (Int16)sa_xaxis) / 65536.0);
+ sa_changed = true;
+ }
+ if(abs(myLastAxisY - sa_yaxis) > 10)
+ {
+ myAnalogPinValue[Five] = (Int32)(1400000 *
+ (float)(32767 - (Int16)sa_yaxis) / 65536.0);
+ sa_changed = true;
+ }
+ myLastAxisX = sa_xaxis;
+ myLastAxisY = sa_yaxis;
+ if(sa_changed)
+ return;
+
+ // Mouse motion events give relative movement
+ // That is, they're only relevant if they're non-zero
+ if((myJack == Left && ourControlNum <= 1) ||
+ (myJack == Right && ourControlNum > 1))
+ {
+ int num = ourControlNum & 0x01;
+ myCharge[num] -=
+ ((myEvent.get(myAxisMouseMotion) >> 1) * _MOUSE_SENSITIVITY);
+ if(myCharge[num] < TRIGMIN)
+ myCharge[num] = TRIGMIN;
+ if(myCharge[num] > TRIGMAX)
+ myCharge[num] = TRIGMAX;
+ if(myEvent.get(Event::MouseButtonValue))
+ myDigitalPinState[ourButtonPin[num]] = false;
+ }
+
+ // Finally, consider digital input, where movement happens
+ // until a digital event is released
if(myKeyRepeat0)
{
myPaddleRepeat0++;
- if(myPaddleRepeat0 > _PADDLE_SPEED) myPaddleRepeat0 = 2;
+ if(myPaddleRepeat0 > _DIGITAL_SENSITIVITY)
+ myPaddleRepeat0 = _DIGITAL_DISTANCE;
}
if(myKeyRepeat1)
{
myPaddleRepeat1++;
- if(myPaddleRepeat1 > _PADDLE_SPEED) myPaddleRepeat1 = 2;
+ if(myPaddleRepeat1 > _DIGITAL_SENSITIVITY)
+ myPaddleRepeat1 = _DIGITAL_DISTANCE;
}
- myKeyRepeat0 = 0;
- myKeyRepeat1 = 0;
+ myKeyRepeat0 = false;
+ myKeyRepeat1 = false;
if(myEvent.get(myP0DecEvent1) || myEvent.get(myP0DecEvent2))
{
- myKeyRepeat0 = 1;
- if(myCharge[0] > myPaddleRepeat0)
- myCharge[0] -= myPaddleRepeat0;
+ myKeyRepeat0 = true;
+ if(myCharge[myAxisDigitalZero] > myPaddleRepeat0)
+ myCharge[myAxisDigitalZero] -= myPaddleRepeat0;
}
if(myEvent.get(myP0IncEvent1) || myEvent.get(myP0IncEvent2))
{
- myKeyRepeat0 = 1;
- if((myCharge[0] + myPaddleRepeat0) < TRIGMAX)
- myCharge[0] += myPaddleRepeat0;
+ myKeyRepeat0 = true;
+ if((myCharge[myAxisDigitalZero] + myPaddleRepeat0) < TRIGMAX)
+ myCharge[myAxisDigitalZero] += myPaddleRepeat0;
}
if(myEvent.get(myP1DecEvent1) || myEvent.get(myP1DecEvent2))
{
- myKeyRepeat1 = 1;
- if(myCharge[1] > myPaddleRepeat1)
- myCharge[1] -= myPaddleRepeat1;
+ myKeyRepeat1 = true;
+ if(myCharge[myAxisDigitalOne] > myPaddleRepeat1)
+ myCharge[myAxisDigitalOne] -= myPaddleRepeat1;
}
if(myEvent.get(myP1IncEvent1) || myEvent.get(myP1IncEvent2))
{
- myKeyRepeat1 = 1;
- if((myCharge[1] + myPaddleRepeat1) < TRIGMAX)
- myCharge[1] += myPaddleRepeat1;
+ myKeyRepeat1 = true;
+ if((myCharge[myAxisDigitalOne] + myPaddleRepeat1) < TRIGMAX)
+ myCharge[myAxisDigitalOne] += myPaddleRepeat1;
}
- // Mouse events
- if(myJack == Left && (_MOUSEX_PADDLE == 0 || _MOUSEX_PADDLE == 1))
- {
- // TODO - add infrastructure to map mouse direction to increase or decrease charge
- myCharge[_MOUSEX_PADDLE] -= myEvent.get(Event::MouseAxisXValue);
- if(myCharge[_MOUSEX_PADDLE] < TRIGMIN) myCharge[_MOUSEX_PADDLE] = TRIGMIN;
- if(myCharge[_MOUSEX_PADDLE] > TRIGMAX) myCharge[_MOUSEX_PADDLE] = TRIGMAX;
- if(myEvent.get(Event::MouseButtonValue))
- myDigitalPinState[ourButtonPin[_MOUSEX_PADDLE]] = false;
- }
- else if(myJack == Right && (_MOUSEX_PADDLE == 2 || _MOUSEX_PADDLE == 3))
- {
- // TODO - add infrastructure to map mouse direction to increase or decrease charge
- myCharge[_MOUSEX_PADDLE-2] -= myEvent.get(Event::MouseAxisXValue);
- if(myCharge[_MOUSEX_PADDLE-2] < TRIGMIN) myCharge[_MOUSEX_PADDLE-2] = TRIGMIN;
- if(myCharge[_MOUSEX_PADDLE-2] > TRIGMAX) myCharge[_MOUSEX_PADDLE-2] = TRIGMAX;
- if(myEvent.get(Event::MouseButtonValue))
- myDigitalPinState[ourButtonPin[_MOUSEX_PADDLE-2]] = false;
- }
+ // Only change state if the charge has actually changed
+ if(myCharge[1] != myLastCharge[1])
+ myAnalogPinValue[Five] =
+ (Int32)(1400000 * (myCharge[1] / float(TRIGRANGE)));
+ if(myCharge[0] != myLastCharge[0])
+ myAnalogPinValue[Nine] =
+ (Int32)(1400000 * (myCharge[0] / float(TRIGRANGE)));
- // Axis events (possibly use analog values)
- int xaxis = myEvent.get(myP0AxisValue);
- int yaxis = myEvent.get(myP1AxisValue);
-
- // Filter out jitter by not allowing rapid direction changes
- int charge0 = ((32767 - xaxis) >> 8) & 0xff;
- if(charge0 - myLastCharge[0] > 0) // we are moving left
- {
- if(!myLeftMotion[0]) // moving right before?
- {
- if(charge0 - myLastCharge[0] <= 4)
- {
- myCharge[0] = myLastCharge[0];
- }
- else
- {
- myCharge[0] = (charge0 + myLastCharge[0]) >> 1;
- myLastCharge[0] = charge0;
- myLeftMotion[0] = 1;
- }
- }
- else
- {
- myCharge[0] = (charge0 + myLastCharge[0]) >> 1;
- myLastCharge[0] = charge0;
- }
- }
- // Filter out jitter by not allowing rapid direction changes
- else if(charge0 - myLastCharge[0] < 0) // we are moving right
- {
- if(myLeftMotion[0]) // moving left before?
- {
- if(myLastCharge[0] - charge0 <= 4)
- {
- myCharge[0] = myLastCharge[0];
- }
- else
- {
- myCharge[0] = (charge0 + myLastCharge[0]) >> 1;
- myLastCharge[0] = charge0;
- myLeftMotion[0] = 0;
- }
- }
- else
- {
- myCharge[0] = (charge0 + myLastCharge[0]) >> 1;
- myLastCharge[0] = charge0;
- }
- }
-
- // Filter out jitter by not allowing rapid direction changes
- int charge1 = ((32767 - yaxis) >> 8) & 0xff;
- if(charge1 - myLastCharge[1] > 0) // we are moving left
- {
- if(!myLeftMotion[1]) // moving right before?
- {
- if(charge1 - myLastCharge[1] <= 4)
- {
- myCharge[1] = myLastCharge[1];
- }
- else
- {
- myCharge[1] = (charge1 + myLastCharge[1]) >> 1;
- myLastCharge[1] = charge1;
- myLeftMotion[1] = 1;
- }
- }
- else
- {
- myCharge[1] = (charge1 + myLastCharge[1]) >> 1;
- myLastCharge[1] = charge1;
- }
- }
- // Filter out jitter by not allowing rapid direction changes
- else if(charge1 - myLastCharge[1] < 0) // we are moving right
- {
- if(myLeftMotion[1]) // moving left before?
- {
- if(myLastCharge[1] - charge1 <= 4)
- {
- myCharge[1] = myLastCharge[1];
- }
- else
- {
- myCharge[1] = (charge1 + myLastCharge[1]) >> 1;
- myLastCharge[1] = charge1;
- myLeftMotion[1] = 0;
- }
- }
- else
- {
- myCharge[1] = (charge1 + myLastCharge[1]) >> 1;
- myLastCharge[1] = charge1;
- }
- }
-
- myAnalogPinValue[Five] = (Int32)(1400000 * (myCharge[1] / 255.0));
- myAnalogPinValue[Nine] = (Int32)(1400000 * (myCharge[0] / 255.0));
+ myLastCharge[1] = myCharge[1];
+ myLastCharge[0] = myCharge[0];
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-void Paddles::setMouseIsPaddle(int number, int dir)
+void Paddles::setDigitalSensitivity(int sensitivity)
{
- // TODO - make mouse Y axis be actually used in the code above
- if(dir == 0)
- _MOUSEX_PADDLE = number;
- else
- _MOUSEY_PADDLE = number;
+ if(sensitivity < 1) sensitivity = 1;
+ else if(sensitivity > 10) sensitivity = 10;
+
+ _DIGITAL_SENSITIVITY = sensitivity;
+ _DIGITAL_DISTANCE = 20 + (sensitivity << 3);
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-int Paddles::_PADDLE_SPEED = 6;
-int Paddles::_MOUSEX_PADDLE = -1;
-int Paddles::_MOUSEY_PADDLE = -1;
+void Paddles::setMouseSensitivity(int sensitivity)
+{
+ if(sensitivity < 1) sensitivity = 1;
+ else if(sensitivity > 15) sensitivity = 15;
+
+ _MOUSE_SENSITIVITY = sensitivity;
+}
+
+// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+int Paddles::_DIGITAL_SENSITIVITY = -1;
+int Paddles::_DIGITAL_DISTANCE = -1;
+int Paddles::_MOUSE_SENSITIVITY = -1;
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
const Controller::DigitalPin Paddles::ourButtonPin[2] = { Four, Three };
diff --git a/src/emucore/Paddles.hxx b/src/emucore/Paddles.hxx
index 392ac05c2..34440ce43 100644
--- a/src/emucore/Paddles.hxx
+++ b/src/emucore/Paddles.hxx
@@ -39,9 +39,15 @@ class Paddles : public Controller
@param jack The jack the controller is plugged into
@param event The event object to use for events
@param system The system using this controller
- @param swap Whether to swap the paddles plugged into this jack
+
+ @param swapport Whether to swap the paddles plugged into this jack
+ @param swapaxis Whether to swap the axis on the paddle (x <-> y)
+ @param swapdir Whether to swap the direction for which an axis
+ causes movement (lesser axis values cause paddle
+ resistance to decrease instead of increase)
*/
- Paddles(Jack jack, const Event& event, const System& system, bool swap);
+ Paddles(Jack jack, const Event& event, const System& system,
+ bool swapport, bool swapaxis, bool swapdir);
/**
Destructor
@@ -56,39 +62,50 @@ class Paddles : public Controller
virtual void update();
/**
- Sets the speed for digital emulation of paddle movement.
- This is only used for *digital* events (ie, buttons or keys
- generating paddle movement events); axis events from joysticks,
- Stelladaptors or the mouse are not modified.
+ Sets the sensitivity for digital emulation of paddle movement.
+ This is only used for *digital* events (ie, buttons or keys,
+ or digital joystick axis events); Stelladaptors or the mouse are
+ not modified.
+
+ @param sensitivity Value from 1 to 10, with larger values
+ causing more movement
*/
- static void setDigitalSpeed(int speed) { _PADDLE_SPEED = speed; }
+ static void setDigitalSensitivity(int sensitivity);
/**
- Sets the mouse to emulate the paddle 'number' in the X or Y
- axis. X -> dir 0, Y -> dir 1
+ Sets the sensitivity for analog emulation of paddle movement
+ using a mouse.
+
+ @param sensitivity Value from 1 to 10, with larger values
+ causing more movement
*/
- static void setMouseIsPaddle(int number, int dir = 0);
+ static void setMouseSensitivity(int sensitivity);
private:
+ // Range of values over which digital and mouse movement is scaled
+ // to paddle resistance
+ enum {
+ TRIGRANGE = 4096,
+ TRIGMAX = 3856,
+ TRIGMIN = 1
+ };
+
// Pre-compute the events we care about based on given port
// This will eliminate test for left or right port in update()
Event::Type myP0AxisValue, myP1AxisValue,
myP0DecEvent1, myP0DecEvent2, myP0IncEvent1, myP0IncEvent2,
myP1DecEvent1, myP1DecEvent2, myP1IncEvent1, myP1IncEvent2,
- myP0FireEvent1, myP0FireEvent2, myP1FireEvent1, myP1FireEvent2;
+ myP0FireEvent1, myP0FireEvent2, myP1FireEvent1, myP1FireEvent2,
+ myAxisMouseMotion;
- int myKeyRepeat0;
- int myPaddleRepeat0;
- int myKeyRepeat1;
- int myPaddleRepeat1;
+ bool myKeyRepeat0, myKeyRepeat1;
+ int myPaddleRepeat0, myPaddleRepeat1;
+ int myCharge[2], myLastCharge[2];
+ int myLastAxisX, myLastAxisY;
+ int myAxisDigitalZero, myAxisDigitalOne;
- int myCharge[2];
- int myLastCharge[2];
- int myLeftMotion[2];
-
- static int _PADDLE_SPEED;
- static int _MOUSEX_PADDLE;
- static int _MOUSEY_PADDLE;
+ static int _DIGITAL_SENSITIVITY, _DIGITAL_DISTANCE;
+ static int _MOUSE_SENSITIVITY;
// Lookup table for associating paddle buttons with controller pins
// Yes, this is hideously complex
diff --git a/src/emucore/Settings.cxx b/src/emucore/Settings.cxx
index 282c40e7d..e7b844b87 100644
--- a/src/emucore/Settings.cxx
+++ b/src/emucore/Settings.cxx
@@ -54,7 +54,6 @@ Settings::Settings(OSystem* osystem)
setInternal("fullscreen", "0");
setInternal("fullres", "auto");
setInternal("center", "false");
- setInternal("grabmouse", "false");
setInternal("palette", "standard");
setInternal("colorloss", "false");
setInternal("timing", "sleep");
@@ -84,7 +83,8 @@ Settings::Settings(OSystem* osystem)
setInternal("joydeadzone", "13");
setInternal("joyallow4", "false");
setInternal("usemouse", "true");
- setInternal("pspeed", "6");
+ setInternal("dsense", "5");
+ setInternal("msense", "7");
setInternal("sa1", "left");
setInternal("sa2", "right");
setInternal("ctrlcombo", "true");
@@ -284,9 +284,13 @@ void Settings::validate()
if(i < 0) setInternal("joydeadzone", "0");
else if(i > 29) setInternal("joydeadzone", "29");
- i = getInt("pspeed");
- if(i < 1) setInternal("pspeed", "1");
- else if(i > 15) setInternal("pspeed", "15");
+ i = getInt("dsense");
+ if(i < 1) setInternal("dsense", "1");
+ else if(i > 10) setInternal("dsense", "10");
+
+ i = getInt("msense");
+ if(i < 1) setInternal("msense", "1");
+ else if(i > 15) setInternal("msense", "15");
i = getInt("ssinterval");
if(i < 1) setInternal("ssinterval", "2");
@@ -366,7 +370,6 @@ void Settings::usage()
<< " -fullscreen <1|0|-1> Use fullscreen mode (1 or 0), or disable switching to fullscreen entirely\n"
<< " -fullres The resolution to use in fullscreen mode\n"
<< " -center <1|0> Centers game window (if possible)\n"
- << " -grabmouse <1|0> Keeps the mouse in the game window\n"
<< " -palette \n"
@@ -389,7 +392,8 @@ void Settings::usage()
<< " -joydeadzone Sets 'deadzone' area for analog joysticks (0-29)\n"
<< " -joyallow4 <1|0> Allow all 4 directions on a joystick to be pressed simultaneously\n"
<< " -usemouse <1|0> Use mouse for various controllers (paddle, driving, etc)\n"
- << " -pspeed Speed of digital emulated paddle movement (1-15)\n"
+ << " -dsense Sensitivity of digital emulated paddle movement (1-10)\n"
+ << " -msense Sensitivity of mouse emulated paddle movement (1-15)\n"
<< " -sa1 Stelladaptor 1 emulates specified joystick port\n"
<< " -sa2 Stelladaptor 2 emulates specified joystick port\n"
<< " -ctrlcombo <1|0> Use key combos involving the Control key (Control-Q for quit may be disabled!)\n"
diff --git a/src/emucore/Switches.cxx b/src/emucore/Switches.cxx
index 7a2222f79..6a4a42886 100644
--- a/src/emucore/Switches.cxx
+++ b/src/emucore/Switches.cxx
@@ -71,20 +71,20 @@ void Switches::update()
mySwitches &= ~0x08;
}
- if(myEvent.get(Event::ConsoleRightDifficultyA) != 0)
+ if(myEvent.get(Event::ConsoleRightDiffA) != 0)
{
mySwitches |= 0x80;
}
- else if(myEvent.get(Event::ConsoleRightDifficultyB) != 0)
+ else if(myEvent.get(Event::ConsoleRightDiffB) != 0)
{
mySwitches &= ~0x80;
}
- if(myEvent.get(Event::ConsoleLeftDifficultyA) != 0)
+ if(myEvent.get(Event::ConsoleLeftDiffA) != 0)
{
mySwitches |= 0x40;
}
- else if(myEvent.get(Event::ConsoleLeftDifficultyB) != 0)
+ else if(myEvent.get(Event::ConsoleLeftDiffB) != 0)
{
mySwitches &= ~0x40;
}
diff --git a/src/gui/CommandDialog.cxx b/src/gui/CommandDialog.cxx
index a42dd1b7c..29654dc9f 100644
--- a/src/gui/CommandDialog.cxx
+++ b/src/gui/CommandDialog.cxx
@@ -126,22 +126,22 @@ void CommandDialog::handleCommand(CommandSender* sender, int cmd,
break;
case kLeftDiffACmd:
- event = Event::ConsoleLeftDifficultyA;
+ event = Event::ConsoleLeftDiffA;
consoleCmd = true;
break;
case kLeftDiffBCmd:
- event = Event::ConsoleLeftDifficultyB;
+ event = Event::ConsoleLeftDiffB;
consoleCmd = true;
break;
case kRightDiffACmd:
- event = Event::ConsoleRightDifficultyA;
+ event = Event::ConsoleRightDiffA;
consoleCmd = true;
break;
case kRightDiffBCmd:
- event = Event::ConsoleRightDifficultyB;
+ event = Event::ConsoleRightDiffB;
consoleCmd = true;
break;
diff --git a/src/gui/InputDialog.cxx b/src/gui/InputDialog.cxx
index babe77d7d..d2fad3cd8 100644
--- a/src/gui/InputDialog.cxx
+++ b/src/gui/InputDialog.cxx
@@ -140,13 +140,13 @@ void InputDialog::addDevicePortTab(const GUI::Font& font)
fwidth, fontHeight, "");
wid.push_back(myAVoxPort);
- lwidth = font.getStringWidth("Digital paddle speed: ");
+ lwidth = font.getStringWidth("Digital paddle sensitivity: ");
pwidth = font.getMaxCharWidth() * 8;
// Add joystick deadzone setting
- ypos += 2*lineHeight;
+ ypos += lineHeight + 5;
myDeadzone = new SliderWidget(myTab, font, xpos, ypos, pwidth, lineHeight,
- "Joystick deadzone: ", lwidth, kDeadzoneChanged);
+ "Joystick deadzone size: ", lwidth, kDeadzoneChanged);
myDeadzone->setMinValue(0); myDeadzone->setMaxValue(29);
xpos += myDeadzone->getWidth() + 5;
myDeadzoneLabel = new StaticTextWidget(myTab, font, xpos, ypos+1, 5*fontWidth,
@@ -154,17 +154,29 @@ void InputDialog::addDevicePortTab(const GUI::Font& font)
myDeadzoneLabel->setFlags(WIDGET_CLEARBG);
wid.push_back(myDeadzone);
- // Add paddle speed
+ // Add paddle speed (digital emulation)
xpos = 5; ypos += lineHeight + 3;
- myPaddleSpeed = new SliderWidget(myTab, font, xpos, ypos, pwidth, lineHeight,
- "Digital paddle speed: ",
- lwidth, kPSpeedChanged);
- myPaddleSpeed->setMinValue(1); myPaddleSpeed->setMaxValue(15);
- xpos += myPaddleSpeed->getWidth() + 5;
- myPaddleLabel = new StaticTextWidget(myTab, font, xpos, ypos+1, 24, lineHeight,
- "", kTextAlignLeft);
- myPaddleLabel->setFlags(WIDGET_CLEARBG);
- wid.push_back(myPaddleSpeed);
+ myDPaddleSpeed = new SliderWidget(myTab, font, xpos, ypos, pwidth, lineHeight,
+ "Digital paddle sensitivity: ",
+ lwidth, kDPSpeedChanged);
+ myDPaddleSpeed->setMinValue(1); myDPaddleSpeed->setMaxValue(10);
+ xpos += myDPaddleSpeed->getWidth() + 5;
+ myDPaddleLabel = new StaticTextWidget(myTab, font, xpos, ypos+1, 24, lineHeight,
+ "", kTextAlignLeft);
+ myDPaddleLabel->setFlags(WIDGET_CLEARBG);
+ wid.push_back(myDPaddleSpeed);
+
+ // Add paddle speed (mouse emulation)
+ xpos = 5; ypos += lineHeight + 3;
+ myMPaddleSpeed = new SliderWidget(myTab, font, xpos, ypos, pwidth, lineHeight,
+ "Mouse paddle sensitivity: ",
+ lwidth, kMPSpeedChanged);
+ myMPaddleSpeed->setMinValue(1); myMPaddleSpeed->setMaxValue(15);
+ xpos += myMPaddleSpeed->getWidth() + 5;
+ myMPaddleLabel = new StaticTextWidget(myTab, font, xpos, ypos+1, 24, lineHeight,
+ "", kTextAlignLeft);
+ myMPaddleSpeed->setFlags(WIDGET_CLEARBG);
+ wid.push_back(myMPaddleSpeed);
// Add 'allow all 4 directions' for joystick
xpos = 10; ypos += 2*lineHeight;
@@ -201,9 +213,11 @@ void InputDialog::loadConfig()
bool usemouse = instance().settings().getBool("usemouse");
myMouseEnabled->setState(usemouse);
- // Paddle speed
- myPaddleSpeed->setValue(instance().settings().getInt("pspeed"));
- myPaddleLabel->setLabel(instance().settings().getString("pspeed"));
+ // Paddle speed (digital and mouse)
+ myDPaddleSpeed->setValue(instance().settings().getInt("dsense"));
+ myDPaddleLabel->setLabel(instance().settings().getString("dsense"));
+ myMPaddleSpeed->setValue(instance().settings().getInt("msense"));
+ myMPaddleLabel->setLabel(instance().settings().getString("msense"));
// AtariVox serial port
myAVoxPort->setEditString(instance().settings().getString("avoxport"));
@@ -230,12 +244,15 @@ void InputDialog::saveConfig()
// Mouse/paddle enabled
bool usemouse = myMouseEnabled->getState();
instance().settings().setBool("usemouse", usemouse);
- instance().eventHandler().setPaddleMode(usemouse ? 0 : -1);
+ instance().eventHandler().setMouseControllerMode(usemouse ? 0 : -1);
- // Paddle speed
- int speed = myPaddleSpeed->getValue();
- instance().settings().setInt("pspeed", speed);
- Paddles::setDigitalSpeed(speed);
+ // Paddle speed (digital and mouse)
+ int sensitivity = myDPaddleSpeed->getValue();
+ instance().settings().setInt("dsense", sensitivity);
+ Paddles::setDigitalSensitivity(sensitivity);
+ sensitivity = myMPaddleSpeed->getValue();
+ instance().settings().setInt("msense", sensitivity);
+ Paddles::setMouseSensitivity(sensitivity);
// AtariVox serial port
instance().settings().setString("avoxport", myAVoxPort->getEditString());
@@ -272,9 +289,11 @@ void InputDialog::setDefaults()
// Mouse/paddle enabled
myMouseEnabled->setState(true);
- // Paddle speed
- myPaddleSpeed->setValue(6);
- myPaddleLabel->setLabel("6");
+ // Paddle speed (digital and mouse)
+ myDPaddleSpeed->setValue(5);
+ myDPaddleLabel->setLabel("5");
+ myMPaddleSpeed->setValue(6);
+ myMPaddleLabel->setLabel("6");
// AtariVox serial port
myAVoxPort->setEditString("");
@@ -373,8 +392,12 @@ void InputDialog::handleCommand(CommandSender* sender, int cmd,
myDeadzoneLabel->setValue(3200 + 1000*myDeadzone->getValue());
break;
- case kPSpeedChanged:
- myPaddleLabel->setValue(myPaddleSpeed->getValue());
+ case kDPSpeedChanged:
+ myDPaddleLabel->setValue(myDPaddleSpeed->getValue());
+ break;
+
+ case kMPSpeedChanged:
+ myMPaddleLabel->setValue(myMPaddleSpeed->getValue());
break;
default:
diff --git a/src/gui/InputDialog.hxx b/src/gui/InputDialog.hxx
index 44c8db8f0..fd8058fa3 100644
--- a/src/gui/InputDialog.hxx
+++ b/src/gui/InputDialog.hxx
@@ -59,7 +59,8 @@ class InputDialog : public Dialog
kLeftChanged = 'LCch',
kRightChanged = 'RCch',
kDeadzoneChanged = 'DZch',
- kPSpeedChanged = 'PSch'
+ kDPSpeedChanged = 'PDch',
+ kMPSpeedChanged = 'PMch'
};
TabWidget* myTab;
@@ -74,8 +75,10 @@ class InputDialog : public Dialog
SliderWidget* myDeadzone;
StaticTextWidget* myDeadzoneLabel;
- SliderWidget* myPaddleSpeed;
- StaticTextWidget* myPaddleLabel;
+ SliderWidget* myDPaddleSpeed;
+ SliderWidget* myMPaddleSpeed;
+ StaticTextWidget* myDPaddleLabel;
+ StaticTextWidget* myMPaddleLabel;
CheckboxWidget* myAllowAll4;
CheckboxWidget* myMouseEnabled;
};
diff --git a/src/gui/VideoDialog.cxx b/src/gui/VideoDialog.cxx
index d10e67258..884421ee3 100644
--- a/src/gui/VideoDialog.cxx
+++ b/src/gui/VideoDialog.cxx
@@ -213,12 +213,6 @@ VideoDialog::VideoDialog(OSystem* osystem, DialogContainer* parent,
wid.push_back(myUseVSyncCheckbox);
ypos += lineHeight + 4;
- // Grab mouse (in windowed mode)
- myGrabmouseCheckbox = new CheckboxWidget(myTab, font, xpos, ypos,
- "Grab mouse");
- wid.push_back(myGrabmouseCheckbox);
- ypos += lineHeight + 4;
-
// Show UI messages onscreen
myUIMessagesCheckbox = new CheckboxWidget(myTab, font, xpos, ypos,
"Show UI messages");
@@ -344,7 +338,6 @@ VideoDialog::VideoDialog(OSystem* osystem, DialogContainer* parent,
#endif
#ifndef WINDOWED_SUPPORT
myFullscreenCheckbox->clearFlags(WIDGET_ENABLED);
- myGrabmouseCheckbox->clearFlags(WIDGET_ENABLED);
myCenterCheckbox->clearFlags(WIDGET_ENABLED);
#endif
#if !(defined(BSPF_WIN32) || (defined(BSPF_UNIX) && defined(HAVE_X11)))
@@ -425,9 +418,6 @@ void VideoDialog::loadConfig()
myUseVSyncCheckbox->setState(instance().settings().getBool("gl_vsync"));
myUseVSyncCheckbox->setEnabled(gl);
- // Grab mouse
- myGrabmouseCheckbox->setState(instance().settings().getBool("grabmouse"));
-
// Show UI messages
myUIMessagesCheckbox->setState(instance().settings().getBool("uimessages"));
@@ -522,10 +512,6 @@ void VideoDialog::saveConfig()
// Use sync to vertical blank (GL mode only)
instance().settings().setBool("gl_vsync", myUseVSyncCheckbox->getState());
- // Grab mouse
- instance().settings().setBool("grabmouse", myGrabmouseCheckbox->getState());
- instance().frameBuffer().setCursorState();
-
// Show UI messages
instance().settings().setBool("uimessages", myUIMessagesCheckbox->getState());
@@ -572,7 +558,6 @@ void VideoDialog::setDefaults()
myColorLossCheckbox->setState(false);
myGLStretchCheckbox->setState(false);
myUseVSyncCheckbox->setState(true);
- myGrabmouseCheckbox->setState(false);
myUIMessagesCheckbox->setState(true);
myCenterCheckbox->setState(false);
myFastSCBiosCheckbox->setState(false);
diff --git a/src/gui/VideoDialog.hxx b/src/gui/VideoDialog.hxx
index d5a11e6f3..67f475934 100644
--- a/src/gui/VideoDialog.hxx
+++ b/src/gui/VideoDialog.hxx
@@ -75,11 +75,10 @@ class VideoDialog : public Dialog
CheckboxWidget* myUseVSyncCheckbox;
CheckboxWidget* myUIMessagesCheckbox;
CheckboxWidget* myCenterCheckbox;
- CheckboxWidget* myGrabmouseCheckbox;
CheckboxWidget* myFastSCBiosCheckbox;
// TV effects options
- PopUpWidget* myTexturePopup;
+ PopUpWidget* myTexturePopup;
PopUpWidget* myBleedPopup;
PopUpWidget* myNoisePopup;
CheckboxWidget* myPhosphorCheckbox;
diff --git a/src/macosx/Menus.h b/src/macosx/Menus.h
index 3157fede1..abfe7a0e8 100644
--- a/src/macosx/Menus.h
+++ b/src/macosx/Menus.h
@@ -37,7 +37,6 @@
IBOutlet id mousePaddle1MenuItem;
IBOutlet id mousePaddle2MenuItem;
IBOutlet id mousePaddle3MenuItem;
- IBOutlet id grabMouseMenuItem;
IBOutlet id increaseVolumeMenuItem;
IBOutlet id decreaseVolumeMenuItem;
}
@@ -50,7 +49,6 @@
- (IBAction)fullScreen:(id)sender;
- (IBAction)openCart:(id)sender;
- (IBAction)restartGame:(id)sender;
-- (IBAction)grabMouse:(id)sender;
- (IBAction)doPrefs:(id)sender;
- (IBAction)volumePlus:(id)sender;
- (IBAction)volumeMinus:(id)sender;
diff --git a/src/macosx/Menus.m b/src/macosx/Menus.m
index 45eec4f09..11715288b 100644
--- a/src/macosx/Menus.m
+++ b/src/macosx/Menus.m
@@ -197,11 +197,6 @@ static Menus *sharedInstance = nil;
[self pushKeyEvent:SDLK_r:NO:NO:YES];
}
-- (IBAction)grabMouse:(id)sender
-{
- [self pushKeyEvent:SDLK_g:NO:NO:YES];
-}
-
- (IBAction)doPrefs:(id)sender
{
[self pushKeyEvent:SDLK_TAB:NO:NO:NO];
@@ -229,7 +224,6 @@ static Menus *sharedInstance = nil;
[mousePaddle1MenuItem setTarget:self];
[mousePaddle2MenuItem setTarget:self];
[mousePaddle3MenuItem setTarget:self];
- [grabMouseMenuItem setTarget:self];
[increaseVolumeMenuItem setTarget:self];
[decreaseVolumeMenuItem setTarget:self];
}
@@ -246,7 +240,6 @@ static Menus *sharedInstance = nil;
[mousePaddle1MenuItem setTarget:nil];
[mousePaddle2MenuItem setTarget:nil];
[mousePaddle3MenuItem setTarget:nil];
- [grabMouseMenuItem setTarget:nil];
[increaseVolumeMenuItem setTarget:nil];
[decreaseVolumeMenuItem setTarget:nil];
}
@@ -263,7 +256,6 @@ static Menus *sharedInstance = nil;
[mousePaddle1MenuItem setTarget:nil];
[mousePaddle2MenuItem setTarget:nil];
[mousePaddle3MenuItem setTarget:nil];
- [grabMouseMenuItem setTarget:nil];
[increaseVolumeMenuItem setTarget:nil];
[decreaseVolumeMenuItem setTarget:nil];
}
@@ -280,7 +272,6 @@ static Menus *sharedInstance = nil;
[mousePaddle1MenuItem setTarget:nil];
[mousePaddle2MenuItem setTarget:nil];
[mousePaddle3MenuItem setTarget:nil];
- [grabMouseMenuItem setTarget:nil];
[increaseVolumeMenuItem setTarget:nil];
[decreaseVolumeMenuItem setTarget:nil];
}
@@ -297,7 +288,6 @@ static Menus *sharedInstance = nil;
[mousePaddle1MenuItem setTarget:nil];
[mousePaddle2MenuItem setTarget:nil];
[mousePaddle3MenuItem setTarget:nil];
- [grabMouseMenuItem setTarget:nil];
[increaseVolumeMenuItem setTarget:nil];
[decreaseVolumeMenuItem setTarget:nil];
}