diff --git a/src/emucore/Console.cxx b/src/emucore/Console.cxx index 9387509be..fb9bf6d2b 100644 --- a/src/emucore/Console.cxx +++ b/src/emucore/Console.cxx @@ -47,6 +47,7 @@ #include "AmigaMouse.hxx" #include "AtariMouse.hxx" #include "TrakBall.hxx" +#include "Lightgun.hxx" #include "FrameBuffer.hxx" #include "TIASurface.hxx" #include "OSystem.hxx" @@ -876,6 +877,10 @@ unique_ptr Console::getControllerPort(const Controller::Type type, controller = make_unique(port, myEvent, *mySystem); break; + case Controller::Type::Lightgun: + controller = make_unique(port, myEvent, *mySystem); + break; + default: // What else can we do? // always create because it may have been changed by user dialog diff --git a/src/emucore/Control.cxx b/src/emucore/Control.cxx index 569177f1f..de0edf85f 100644 --- a/src/emucore/Control.cxx +++ b/src/emucore/Control.cxx @@ -112,7 +112,8 @@ string Controller::getName(const Type type) "Unknown", "AmigaMouse", "AtariMouse", "AtariVox", "BoosterGrip", "CompuMate", "Driving", "Sega Genesis", "Joystick", "Keyboard", "KidVid", "MindLink", - "Paddles", "Paddles_IAxis", "Paddles_IAxDr", "SaveKey", "TrakBall" + "Paddles", "Paddles_IAxis", "Paddles_IAxDr", "SaveKey", "TrakBall", + "Lightgun" }; return NAMES[int(type)]; @@ -126,7 +127,8 @@ string Controller::getPropName(const Type type) "AUTO", "AMIGAMOUSE", "ATARIMOUSE", "ATARIVOX", "BOOSTERGRIP", "COMPUMATE", "DRIVING", "GENESIS", "JOYSTICK", "KEYBOARD", "KIDVID", "MINDLINK", - "PADDLES", "PADDLES_IAXIS", "PADDLES_IAXDR", "SAVEKEY", "TRAKBALL" + "PADDLES", "PADDLES_IAXIS", "PADDLES_IAXDR", "SAVEKEY", "TRAKBALL", + "LIGHTGUN" }; return PROP_NAMES[int(type)]; diff --git a/src/emucore/Control.hxx b/src/emucore/Control.hxx index 8b26f8588..28440deb5 100644 --- a/src/emucore/Control.hxx +++ b/src/emucore/Control.hxx @@ -94,6 +94,7 @@ class Controller : public Serializable AmigaMouse, AtariMouse, AtariVox, BoosterGrip, CompuMate, Driving, Genesis, Joystick, Keyboard, KidVid, MindLink, Paddles, PaddlesIAxis, PaddlesIAxDr, SaveKey, TrakBall, + Lightgun, LastType }; diff --git a/src/emucore/ControllerDetector.cxx b/src/emucore/ControllerDetector.cxx index 0a78d700e..298f24e20 100644 --- a/src/emucore/ControllerDetector.cxx +++ b/src/emucore/ControllerDetector.cxx @@ -70,8 +70,9 @@ Controller::Type ControllerDetector::autodetectPort(const uInt8* image, size_t s else if(usesKeyboard(image, size, port)) type = Controller::Type::Keyboard; else if(usesGenesisButton(image, size, port)) - type = Controller::Type::Genesis; + else if(isProbablyLightGun(image, size, port)) + type = Controller::Type::Lightgun; } else { @@ -643,3 +644,41 @@ bool ControllerDetector::isProbablySaveKey(const uInt8* image, size_t size, return false; } + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +bool ControllerDetector::isProbablyLightGun(const uInt8* image, size_t size, + Controller::Jack port) +{ + if (port == Controller::Jack::Left) + { + // check for INPT4 after NOPs access + const int NUM_SIGS = 2; + const int SIG_SIZE = 6; + uInt8 signature[NUM_SIGS][SIG_SIZE] = { + { 0xea, 0xea, 0xea, 0x24, 0x0c, 0x10 }, + { 0xea, 0xea, 0xea, 0x24, 0x3c, 0x10 } + }; // all pattern checked, only 'Sentinel' and 'Shooting Arcade' match + + for (uInt32 i = 0; i < NUM_SIGS; ++i) + if (searchForBytes(image, size, signature[i], SIG_SIZE)) + return true; + + return false; + } + else if(port == Controller::Jack::Right) + { + // check for INPT5 after NOPs access + const int NUM_SIGS = 2; + const int SIG_SIZE = 6; + uInt8 signature[NUM_SIGS][SIG_SIZE] = { + { 0xea, 0xea, 0xea, 0x24, 0x0d, 0x10 }, + { 0xea, 0xea, 0xea, 0x24, 0x3d, 0x10 } + }; // all pattern checked, only 'Bobby is Hungry' matches + + for (uInt32 i = 0; i < NUM_SIGS; ++i) + if (searchForBytes(image, size, signature[i], SIG_SIZE)) + return true; + } + + return false; +} diff --git a/src/emucore/ControllerDetector.hxx b/src/emucore/ControllerDetector.hxx index 16374569f..f28482e04 100644 --- a/src/emucore/ControllerDetector.hxx +++ b/src/emucore/ControllerDetector.hxx @@ -111,6 +111,10 @@ class ControllerDetector // Returns true if a SaveKey code pattern is found. static bool isProbablySaveKey(const uInt8* image, size_t size, Controller::Jack port); + // Returns true if a Lightgun code pattern is found + static bool isProbablyLightGun(const uInt8* image, size_t size, Controller::Jack port); + + private: // Following constructors and assignment operators not supported ControllerDetector() = delete; diff --git a/src/emucore/Event.hxx b/src/emucore/Event.hxx index 2fea72dd8..41cbf7997 100644 --- a/src/emucore/Event.hxx +++ b/src/emucore/Event.hxx @@ -121,6 +121,7 @@ class Event CompuMateSlash, ToggleInter, + LightgunZeroFire, LightgunZeroPos, LightgunOneFire, LightgunOnePos, LastType }; diff --git a/src/emucore/EventHandler.cxx b/src/emucore/EventHandler.cxx index dcb2cf696..3aa30d136 100644 --- a/src/emucore/EventHandler.cxx +++ b/src/emucore/EventHandler.cxx @@ -27,6 +27,7 @@ #include "OSystem.hxx" #include "Joystick.hxx" #include "Paddles.hxx" +#include "Lightgun.hxx" #include "PointingDevice.hxx" #include "PropsSet.hxx" #include "Settings.hxx" @@ -100,6 +101,7 @@ void EventHandler::initialize() Paddles::setDejitterDiff(myOSystem.settings().getInt("dejitter.diff")); Paddles::setDigitalSensitivity(myOSystem.settings().getInt("dsense")); Paddles::setMouseSensitivity(myOSystem.settings().getInt("msense")); + Lightgun::setMouseSensitivity(myOSystem.settings().getInt("msense")); PointingDevice::setSensitivity(myOSystem.settings().getInt("tsense")); #ifdef GUI_SUPPORT diff --git a/src/emucore/FrameBuffer.cxx b/src/emucore/FrameBuffer.cxx index 922c694dd..46368f5d9 100644 --- a/src/emucore/FrameBuffer.cxx +++ b/src/emucore/FrameBuffer.cxx @@ -841,6 +841,9 @@ void FrameBuffer::setCursorState() bool analog = myOSystem.hasConsole() ? (myOSystem.console().leftController().isAnalog() || myOSystem.console().rightController().isAnalog()) : false; + bool lightgun = emulation && myOSystem.hasConsole() ? + myOSystem.console().leftController().type() == Controller::Type::Lightgun || + myOSystem.console().rightController().type() == Controller::Type::Lightgun : false; bool alwaysUseMouse = BSPF::equalsIgnoreCase("always", myOSystem.settings().getString("usemouse")); grabMouse(emulation && (analog || alwaysUseMouse) && myGrabMouse); diff --git a/src/gui/GameInfoDialog.cxx b/src/gui/GameInfoDialog.cxx index 7b2e213ea..28006e760 100644 --- a/src/gui/GameInfoDialog.cxx +++ b/src/gui/GameInfoDialog.cxx @@ -220,8 +220,9 @@ GameInfoDialog::GameInfoDialog( VarList::push_back(ctrls, "SaveKey", "SAVEKEY"); VarList::push_back(ctrls, "Sega Genesis", "GENESIS"); VarList::push_back(ctrls, "KidVid", "KIDVID"); + VarList::push_back(ctrls, "Lightgun", "LIGHTGUN"); VarList::push_back(ctrls, "MindLink", "MINDLINK"); - + ypos = VBORDER; pwidth = font.getStringWidth("Paddles_IAxis"); myLeftPortLabel = new StaticTextWidget(myTab, font, HBORDER, ypos+1, "Left port "); diff --git a/src/gui/InputDialog.cxx b/src/gui/InputDialog.cxx index 476633e98..de192a18d 100644 --- a/src/gui/InputDialog.cxx +++ b/src/gui/InputDialog.cxx @@ -21,6 +21,7 @@ #include "EventHandler.hxx" #include "Joystick.hxx" #include "Paddles.hxx" +#include "Lightgun.hxx" #include "PointingDevice.hxx" #include "SaveKey.hxx" #include "AtariVox.hxx" @@ -349,6 +350,8 @@ void InputDialog::saveConfig() sensitivity = myMPaddleSpeed->getValue(); instance().settings().setValue("msense", sensitivity); Paddles::setMouseSensitivity(sensitivity); + Lightgun::setMouseSensitivity(sensitivity); + // Trackball speed sensitivity = myTrackBallSpeed->getValue(); diff --git a/src/windows/Stella.vcxproj b/src/windows/Stella.vcxproj index 7bd655b92..a3f520dbb 100644 --- a/src/windows/Stella.vcxproj +++ b/src/windows/Stella.vcxproj @@ -487,6 +487,7 @@ + @@ -1210,6 +1211,7 @@ + diff --git a/src/windows/Stella.vcxproj.filters b/src/windows/Stella.vcxproj.filters index 37ae6f984..4d0d3964f 100644 --- a/src/windows/Stella.vcxproj.filters +++ b/src/windows/Stella.vcxproj.filters @@ -996,6 +996,9 @@ Source Files + + Source Files\emucore + @@ -2036,6 +2039,9 @@ Header Files + + Header Files\emucore +