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-lossuse PAL color-loss effect-colorloss GL FS Stretchstretch fullscreen OpenGL in emulation mode-gl_fsmax GL VSyncenable OpenGL vertical synchronization-gl_vsync - Grab mousekeep mouse in SDL window-grabmouse Show UI messagesoverlay UI messages onscreen-uimessages Center windowattempt to center application window-center Fast SC/AR BIOSSkip progress loading bars for SuperCharger ROMs-fastscbios @@ -2367,8 +2371,9 @@ ItemBrief descriptionFor more information,
see CommandLine Stelladaptor X isSpecifies which virtual port each Stelladaptor uses (See Advanced Configuration - Stelladaptor Support)-sa1 & -sa2 AVox serial portDescribed in further detail in Advanced Configuration - AtariVox/SaveKey Support -avoxport - Joy deadzoneDeadzone area for axes on joysticks/gamepads-joydeadzone - Paddle speedSpeed used when emulating a paddle using a digital device-pspeed + Joy deadzone sizeDeadzone area for axes on joysticks/gamepads-joydeadzone + Digital paddle sensitivitySensitvity used when emulating a paddle using a digital device-dsense + Mouse paddle sensitivitySensitivity 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]; }