diff --git a/docs/index.html b/docs/index.html
index 5ed085294..fd07a52f6 100644
--- a/docs/index.html
+++ b/docs/index.html
@@ -275,7 +275,7 @@
Emulates Spectravideo CompuMate system using your computer's keyboard,
including mapping of CompuMate 'Backspace', 'Space' and 'Enter' functionality to
to the actual keys on your keyboard
- Emulates the Mindlink Controller using your computer's mouse
+ Emulates the Mindlink Controller and the Light Gun using your computer's mouse
Supports autodetection for most common controller types
Support for real Atari 2600 controllers using the
Stelladaptor and
@@ -1784,6 +1784,14 @@
✕ |
✕ |
+
+ Light Gun |
+ ✕ |
+ ✕ |
+ ✓ |
+ ✕ |
+ ✕ |
+
Mindlink |
✕ |
@@ -3817,6 +3825,7 @@ Ms Pac-Man (Stella extended codes):
SaveKey | A 32K EEPROM for saving high scores, etc. (the EEPROM portion of an AtariVox). |
Genesis | Sega Genesis controller, which can be used similar to a BoosterGrip, giving an extra button. |
CompuMate ¹ | Spectravideo CompuMate (if either left or right is set, CompuMate is used for both). |
+ Lightgun | Atari XG-1 compatible Light Gun |
Mindlink ¹ | Mindlink controller. |
diff --git a/src/emucore/Booster.cxx b/src/emucore/Booster.cxx
index 3e931547c..26b6e276a 100644
--- a/src/emucore/Booster.cxx
+++ b/src/emucore/Booster.cxx
@@ -99,8 +99,8 @@ void BoosterGrip::update()
{
// The following code was taken from z26
#define MJ_Threshold 2
- int mousex = myEvent.get(Event::MouseAxisXValue),
- mousey = myEvent.get(Event::MouseAxisYValue);
+ int mousex = myEvent.get(Event::MouseAxisXMove),
+ mousey = myEvent.get(Event::MouseAxisYMove);
if(mousex || mousey)
{
if((!(abs(mousey) > abs(mousex) << 1)) && (abs(mousex) >= MJ_Threshold))
diff --git a/src/emucore/Console.cxx b/src/emucore/Console.cxx
index 5ac2a1479..cc0d7157b 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"
@@ -871,6 +872,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, myOSystem.frameBuffer());
+ 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 09b291471..570512614 100644
--- a/src/emucore/Control.cxx
+++ b/src/emucore/Control.cxx
@@ -109,7 +109,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)];
@@ -123,7 +124,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 aa85b9552..8fff9dea6 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/Driving.cxx b/src/emucore/Driving.cxx
index 5b634b15d..bb24b9cb8 100644
--- a/src/emucore/Driving.cxx
+++ b/src/emucore/Driving.cxx
@@ -62,7 +62,7 @@ void Driving::update()
// Mouse motion and button events
if(myControlID > -1)
{
- int m_axis = myEvent.get(Event::MouseAxisXValue);
+ int m_axis = myEvent.get(Event::MouseAxisXMove);
if(m_axis < -2) --myCounter;
else if(m_axis > 2) ++myCounter;
if(myEvent.get(Event::MouseButtonLeftValue) ||
@@ -75,7 +75,7 @@ void Driving::update()
// mapped to a separate driving controller
if(myControlIDX > -1)
{
- int m_axis = myEvent.get(Event::MouseAxisXValue);
+ int m_axis = myEvent.get(Event::MouseAxisXMove);
if(m_axis < -2) --myCounter;
else if(m_axis > 2) ++myCounter;
if(myEvent.get(Event::MouseButtonLeftValue))
@@ -83,7 +83,7 @@ void Driving::update()
}
if(myControlIDY > -1)
{
- int m_axis = myEvent.get(Event::MouseAxisYValue);
+ int m_axis = myEvent.get(Event::MouseAxisYMove);
if(m_axis < -2) --myCounter;
else if(m_axis > 2) ++myCounter;
if(myEvent.get(Event::MouseButtonRightValue))
diff --git a/src/emucore/Event.hxx b/src/emucore/Event.hxx
index 2fea72dd8..481689fab 100644
--- a/src/emucore/Event.hxx
+++ b/src/emucore/Event.hxx
@@ -68,7 +68,7 @@ class Event
Combo1, Combo2, Combo3, Combo4, Combo5, Combo6, Combo7, Combo8,
Combo9, Combo10, Combo11, Combo12, Combo13, Combo14, Combo15, Combo16,
- MouseAxisXValue, MouseAxisYValue,
+ MouseAxisXMove, MouseAxisYMove,
MouseButtonLeftValue, MouseButtonRightValue,
ChangeState, LoadState, SaveState, TakeSnapshot, Quit,
@@ -121,6 +121,7 @@ class Event
CompuMateSlash,
ToggleInter,
+ MouseAxisXValue, MouseAxisYValue,
LastType
};
diff --git a/src/emucore/EventHandler.cxx b/src/emucore/EventHandler.cxx
index 3b8ffe6eb..3e26c3692 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"
@@ -247,8 +248,8 @@ void EventHandler::poll(uInt64 time)
// Turn off all mouse-related items; if they haven't been taken care of
// in the previous ::update() methods, they're now invalid
- myEvent.set(Event::MouseAxisXValue, 0);
- myEvent.set(Event::MouseAxisYValue, 0);
+ myEvent.set(Event::MouseAxisXMove, 0);
+ myEvent.set(Event::MouseAxisYMove, 0);
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@@ -269,8 +270,10 @@ void EventHandler::handleMouseMotionEvent(int x, int y, int xrel, int yrel)
{
if(!mySkipMouseMotion)
{
- myEvent.set(Event::MouseAxisXValue, xrel);
- myEvent.set(Event::MouseAxisYValue, yrel);
+ myEvent.set(Event::MouseAxisXValue, x); // required for Lightgun controller
+ myEvent.set(Event::MouseAxisYValue, y); // required for Lightgun controller
+ myEvent.set(Event::MouseAxisXMove, xrel);
+ myEvent.set(Event::MouseAxisYMove, yrel);
}
mySkipMouseMotion = false;
}
@@ -1952,7 +1955,7 @@ const Event::EventSet EventHandler::MiscEvents = {
Event::Quit, Event::ReloadConsole, Event::Fry, Event::StartPauseMode,
Event::TogglePauseMode, Event::OptionsMenuMode, Event::CmdMenuMode, Event::ExitMode,
Event::TakeSnapshot, Event::ToggleContSnapshots, Event::ToggleContSnapshotsFrame,
- // Event::MouseAxisXValue, Event::MouseAxisYValue,
+ // Event::MouseAxisXMove, Event::MouseAxisYMove,
// Event::MouseButtonLeftValue, Event::MouseButtonRightValue,
Event::HandleMouseControl, Event::ToggleGrabMouse,
Event::ToggleSAPortOrder,
diff --git a/src/emucore/FrameBuffer.cxx b/src/emucore/FrameBuffer.cxx
index e4e6bf480..5ed99d6fb 100644
--- a/src/emucore/FrameBuffer.cxx
+++ b/src/emucore/FrameBuffer.cxx
@@ -841,10 +841,17 @@ void FrameBuffer::setCursorState()
bool analog = myOSystem.hasConsole() ?
(myOSystem.console().leftController().isAnalog() ||
myOSystem.console().rightController().isAnalog()) : false;
+ bool usesLightgun = 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"));
// Show/hide cursor in UI/emulation mode based on 'cursor' setting
int cursor = myOSystem.settings().getInt("cursor");
+ // always enable cursor in lightgun games
+ if (usesLightgun)
+ cursor |= 1;
+
switch(cursor)
{
case 0:
diff --git a/src/emucore/Genesis.cxx b/src/emucore/Genesis.cxx
index 30e4055db..8623b0ea6 100644
--- a/src/emucore/Genesis.cxx
+++ b/src/emucore/Genesis.cxx
@@ -67,8 +67,8 @@ void Genesis::update()
{
// The following code was taken from z26
#define MJ_Threshold 2
- int mousex = myEvent.get(Event::MouseAxisXValue),
- mousey = myEvent.get(Event::MouseAxisYValue);
+ int mousex = myEvent.get(Event::MouseAxisXMove),
+ mousey = myEvent.get(Event::MouseAxisYMove);
if(mousex || mousey)
{
if((!(abs(mousey) > abs(mousex) << 1)) && (abs(mousex) >= MJ_Threshold))
diff --git a/src/emucore/Joystick.cxx b/src/emucore/Joystick.cxx
index 0a988eb73..4b08e843d 100644
--- a/src/emucore/Joystick.cxx
+++ b/src/emucore/Joystick.cxx
@@ -81,8 +81,8 @@ void Joystick::update()
{
// The following code was taken from z26
#define MJ_Threshold 2
- int mousex = myEvent.get(Event::MouseAxisXValue),
- mousey = myEvent.get(Event::MouseAxisYValue);
+ int mousex = myEvent.get(Event::MouseAxisXMove),
+ mousey = myEvent.get(Event::MouseAxisYMove);
if(mousex || mousey)
{
if((!(abs(mousey) > abs(mousex) << 1)) && (abs(mousex) >= MJ_Threshold))
diff --git a/src/emucore/Lightgun.cxx b/src/emucore/Lightgun.cxx
new file mode 100644
index 000000000..41fc5a882
--- /dev/null
+++ b/src/emucore/Lightgun.cxx
@@ -0,0 +1,75 @@
+//============================================================================
+//
+// SSSS tt lll lll
+// SS SS tt ll ll
+// SS tttttt eeee ll ll aaaa
+// SSSS tt ee ee ll ll aa
+// SS tt eeeeee ll ll aaaaa -- "An Atari 2600 VCS Emulator"
+// SS SS tt ee ll ll aa aa
+// SSSS ttt eeeee llll llll aaaaa
+//
+// Copyright (c) 1995-2019 by Bradford W. Mott, Stephen Anthony
+// and the Stella Team
+//
+// See the file "License.txt" for information on usage and redistribution of
+// this file, and for a DISCLAIMER OF ALL WARRANTIES.
+//============================================================================
+
+
+#include "Event.hxx"
+#include "TIA.hxx"
+#include "FrameBuffer.hxx"
+
+#include "Lightgun.hxx"
+
+// | | Left port | Right port |
+// | Fire button | SWCHA bit 4 | SWCHA bit 0 | DP:1
+// | Detect light | INPT4 bit 7 | INPT5 bit 7 | DP:6
+
+// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+Lightgun::Lightgun(Jack jack, const Event& event, const System& system, const FrameBuffer& frameBuffer)
+ : Controller(jack, event, system, Controller::Type::Lightgun),
+ myFrameBuffer(frameBuffer)
+{
+}
+
+// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+bool Lightgun::read(DigitalPin pin)
+{
+ // We need to override the Controller::read() method, since the lightgun
+ // checks this multiple times per frame
+ // (we can't just read 60 times per second in the ::update() method)
+ switch (pin)
+ {
+ case DigitalPin::Six: // INPT4/5
+ {
+ const Common::Rect& rect = myFrameBuffer.imageRect();
+ // scale mouse coordinates into TIA coordinates
+ Int32 xMouse = (myEvent.get(Event::MouseAxisXValue) - rect.x())
+ * TIAConstants::H_PIXEL / rect.w();
+ Int32 yMouse = (myEvent.get(Event::MouseAxisYValue) - rect.y())
+ * 210 / rect.h(); // TODO: replace "magic number"
+ // get adjusted TIA coordinates
+ Int32 xTia = mySystem.tia().clocksThisLine() - TIAConstants::H_BLANK_CLOCKS + X_OFS;
+ Int32 yTia = mySystem.tia().scanlines() - mySystem.tia().startLine() + Y_OFS;
+
+ if (xTia < 0)
+ xTia += TIAConstants::H_CLOCKS;
+
+ bool enable = !((xTia - xMouse) >= 0 && (xTia - xMouse) < 15 && (yTia - yMouse) >= 0);
+
+ return enable;
+ }
+ default:
+ return Controller::read(pin);
+ }
+}
+
+// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+void Lightgun::update()
+{
+ // we allow left and right mouse buttons for fire button
+ setPin(DigitalPin::One, myEvent.get(Event::MouseButtonLeftValue)
+ || myEvent.get(Event::MouseButtonRightValue));
+}
+
diff --git a/src/emucore/Lightgun.hxx b/src/emucore/Lightgun.hxx
new file mode 100644
index 000000000..928f705b0
--- /dev/null
+++ b/src/emucore/Lightgun.hxx
@@ -0,0 +1,77 @@
+//============================================================================
+//
+// SSSS tt lll lll
+// SS SS tt ll ll
+// SS tttttt eeee ll ll aaaa
+// SSSS tt ee ee ll ll aa
+// SS tt eeeeee ll ll aaaaa -- "An Atari 2600 VCS Emulator"
+// SS SS tt ee ll ll aa aa
+// SSSS ttt eeeee llll llll aaaaa
+//
+// Copyright (c) 1995-2019 by Bradford W. Mott, Stephen Anthony
+// and the Stella Team
+//
+// See the file "License.txt" for information on usage and redistribution of
+// this file, and for a DISCLAIMER OF ALL WARRANTIES.
+//============================================================================
+
+#ifndef LIGHTGUN_HXX
+#define LIGHTGUN_HXX
+
+/**
+ This class handles the lightgun controller
+
+ @author Thomas Jentzsch
+*/
+
+class Lightgun : public Controller
+{
+public:
+ /**
+ Create a new pair of paddle controllers plugged into the specified jack
+
+ @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
+ */
+ Lightgun(Jack jack, const Event& event, const System& system, const FrameBuffer& frameBuffer);
+ virtual ~Lightgun() = default;
+
+public:
+ using Controller::read;
+
+ /**
+ Read the value of the specified digital pin for this controller.
+
+ @param pin The pin of the controller jack to read
+ @return The state of the pin
+ */
+ bool read(DigitalPin pin) override;
+
+ /**
+ Update the entire digital and analog pin state according to the
+ events currently set.
+ */
+ void update() override;
+
+ /**
+ Returns the name of this controller.
+ */
+ string name() const override { return "Lightgun"; }
+
+private:
+ const FrameBuffer& myFrameBuffer;
+
+ static constexpr Int32 X_OFS = -21;
+ static constexpr Int32 Y_OFS = 5;
+
+private:
+ // Following constructors and assignment operators not supported
+ Lightgun() = delete;
+ Lightgun(const Lightgun&) = delete;
+ Lightgun(Lightgun&&) = delete;
+ Lightgun& operator=(const Lightgun&) = delete;
+ Lightgun& operator=(Lightgun&&) = delete;
+};
+
+#endif
diff --git a/src/emucore/MindLink.cxx b/src/emucore/MindLink.cxx
index bca8c92f1..50d43785a 100644
--- a/src/emucore/MindLink.cxx
+++ b/src/emucore/MindLink.cxx
@@ -40,7 +40,7 @@ void MindLink::update()
return;
myMindlinkPos = (myMindlinkPos & 0x3fffffff) +
- (myEvent.get(Event::MouseAxisXValue) << 3);
+ (myEvent.get(Event::MouseAxisXMove) << 3);
if(myMindlinkPos < 0x2800)
myMindlinkPos = 0x2800;
if(myMindlinkPos >= 0x3800)
diff --git a/src/emucore/Paddles.cxx b/src/emucore/Paddles.cxx
index 601850018..45e1398b6 100644
--- a/src/emucore/Paddles.cxx
+++ b/src/emucore/Paddles.cxx
@@ -162,13 +162,13 @@ Paddles::Paddles(Jack jack, const Event& event, const System& system,
abs(MOUSE_SENSITIVITY);
if(!swapaxis)
{
- myAxisMouseMotion = Event::MouseAxisXValue;
+ myAxisMouseMotion = Event::MouseAxisXMove;
myAxisDigitalZero = 0;
myAxisDigitalOne = 1;
}
else
{
- myAxisMouseMotion = Event::MouseAxisYValue;
+ myAxisMouseMotion = Event::MouseAxisYMove;
myAxisDigitalZero = 1;
myAxisDigitalOne = 0;
}
@@ -277,7 +277,7 @@ void Paddles::update()
if(myMPaddleIDX > -1)
{
myCharge[myMPaddleIDX] = BSPF::clamp(myCharge[myMPaddleIDX] -
- (myEvent.get(Event::MouseAxisXValue) * MOUSE_SENSITIVITY),
+ (myEvent.get(Event::MouseAxisXMove) * MOUSE_SENSITIVITY),
TRIGMIN, TRIGRANGE);
if(myEvent.get(Event::MouseButtonLeftValue))
setPin(ourButtonPin[myMPaddleIDX], false);
@@ -285,7 +285,7 @@ void Paddles::update()
if(myMPaddleIDY > -1)
{
myCharge[myMPaddleIDY] = BSPF::clamp(myCharge[myMPaddleIDY] -
- (myEvent.get(Event::MouseAxisYValue) * MOUSE_SENSITIVITY),
+ (myEvent.get(Event::MouseAxisYMove) * MOUSE_SENSITIVITY),
TRIGMIN, TRIGRANGE);
if(myEvent.get(Event::MouseButtonRightValue))
setPin(ourButtonPin[myMPaddleIDY], false);
diff --git a/src/emucore/PointingDevice.cxx b/src/emucore/PointingDevice.cxx
index 507998730..e23a4399e 100644
--- a/src/emucore/PointingDevice.cxx
+++ b/src/emucore/PointingDevice.cxx
@@ -79,11 +79,11 @@ void PointingDevice::update()
return;
// Update horizontal direction
- updateDirection( myEvent.get(Event::MouseAxisXValue), myHCounterRemainder,
+ updateDirection( myEvent.get(Event::MouseAxisXMove), myHCounterRemainder,
myTrackBallLeft, myTrackBallLinesH, myScanCountH, myFirstScanOffsetH);
// Update vertical direction
- updateDirection(-myEvent.get(Event::MouseAxisYValue), myVCounterRemainder,
+ updateDirection(-myEvent.get(Event::MouseAxisYMove), myVCounterRemainder,
myTrackBallDown, myTrackBallLinesV, myScanCountV, myFirstScanOffsetV);
// Get mouse button state
diff --git a/src/emucore/module.mk b/src/emucore/module.mk
index 7fd311126..e02fcdc2d 100644
--- a/src/emucore/module.mk
+++ b/src/emucore/module.mk
@@ -66,6 +66,7 @@ MODULE_OBJS := \
src/emucore/Joystick.o \
src/emucore/Keyboard.o \
src/emucore/KidVid.o \
+ src/emucore/Lightgun.o \
src/emucore/MindLink.o \
src/emucore/M6502.o \
src/emucore/M6532.o \
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/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
+