From fa987e63b66c1ad2f97771925a33b93bc7c25946 Mon Sep 17 00:00:00 2001 From: Thomas Jentzsch Date: Thu, 3 Sep 2020 15:14:55 +0200 Subject: [PATCH] added multiple controller support (joystick, driving, SaveKey, AtariVox) --- Changes.txt | 2 +- docs/index.html | 17 +-- src/emucore/ControllerDetector.cxx | 10 +- src/emucore/QuadTari.cxx | 19 +-- src/gui/GameInfoDialog.cxx | 69 +++++++--- src/gui/GameInfoDialog.hxx | 10 +- src/gui/QuadTariDialog.cxx | 200 +++++++++++++++++++++++++++++ src/gui/QuadTariDialog.hxx | 69 ++++++++++ src/windows/Stella.vcxproj | 2 + src/windows/Stella.vcxproj.filters | 6 + 10 files changed, 351 insertions(+), 53 deletions(-) create mode 100644 src/gui/QuadTariDialog.cxx create mode 100644 src/gui/QuadTariDialog.hxx diff --git a/Changes.txt b/Changes.txt index eb495b099..ac82c7713 100644 --- a/Changes.txt +++ b/Changes.txt @@ -37,7 +37,7 @@ are no longer corrupted/cut off. This includes properly supporting the 2600-daptor II, which is flashable to an AVox-USB converter. - * Added QuadTari controller support for josticks (TODO: doc, settings etc.) + * Added QuadTari controller support for several controllers (TODO: docs) * Added option to select the audio device. diff --git a/docs/index.html b/docs/index.html index 699422419..f466e7413 100644 --- a/docs/index.html +++ b/docs/index.html @@ -268,24 +268,15 @@ Atari 2600 FPGA project, including cycle-exact audio, analog interference from mixing of audio channels, as well as stereo sound support; dynamic sound resampling is also included -
  • Emulates the Atari 2600 Joystick Controllers using your computer's keyboard, +
  • Emulates the Atari 2600 Joystick, Paddle, Driving, CBS BoosterGrip, Sega Genesis, QuadTari controllers using your computer's keyboard, joysticks or mouse
  • -
  • Emulates the Atari 2600 Keyboard Controllers using your computer's keyboard
  • -
  • Emulates the Atari 2600 Paddle Controllers using your computer's mouse, keyboard - or joysticks
  • -
  • Emulates the Atari 2600 Driving Controllers using your computer's keyboard, - joysticks or mouse
  • -
  • Emulates the CBS BoosterGrip Controller using your computer's keyboard, - joysticks or mouse
  • -
  • Emulates the Sega Genesis Controller using your computer's keyboard, - joysticks or mouse
  • -
  • Emulates CX22/CX80 style trackballs and Amiga/Atari Mouse using your +
  • Emulates CX22/CX80 style Trackballs, Amiga/Atari Mouse, Mindlink controller and the Light Gun using your computer's mouse
  • +
  • Emulates the Atari 2600 Keyboard controllers using your computer's keyboard
  • 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 and the Light Gun using your computer's mouse
  • -
  • Supports autodetection for most common controller types
  • +
  • Supports autodetection for most common controller types
  • Support for real Atari 2600 controllers using the Stelladaptor and 2600-daptor/2600-daptor II
  • diff --git a/src/emucore/ControllerDetector.cxx b/src/emucore/ControllerDetector.cxx index 86835f54d..644d4e23b 100644 --- a/src/emucore/ControllerDetector.cxx +++ b/src/emucore/ControllerDetector.cxx @@ -699,6 +699,11 @@ bool ControllerDetector::isProbablyLightGun(const ByteBuffer& image, size_t size bool ControllerDetector::isProbablyQuadTari(const ByteBuffer& image, size_t size, Controller::Jack port) { + uInt8 signatureBoth[] = { 0x1B, 0x1F, 0x0B, 0x0E, 0x1E, 0x0B, 0x1C, 0x13 }; // "QUADTARI" + + if(searchForBytes(image, size, signatureBoth, 8)) + return true; + if(port == Controller::Jack::Left) { uInt8 signature[] = { 'Q', 'U', 'A', 'D', 'L' }; @@ -711,8 +716,5 @@ bool ControllerDetector::isProbablyQuadTari(const ByteBuffer& image, size_t size return searchForBytes(image, size, signature, 5); } - - uInt8 signature[] = { 0x1B, 0x1F, 0x0B, 0x0E, 0x1E, 0x0B, 0x1C, 0x13 }; - - return searchForBytes(image, size, signature, 8); + return false; } diff --git a/src/emucore/QuadTari.cxx b/src/emucore/QuadTari.cxx index afac9294a..9b7b98190 100644 --- a/src/emucore/QuadTari.cxx +++ b/src/emucore/QuadTari.cxx @@ -65,17 +65,18 @@ QuadTari::QuadTari(Jack jack, OSystem& osystem, const System& system, const Prop // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - unique_ptr QuadTari::addController(const Controller::Type type, bool second) { + FilesystemNode nvramfile = myOSystem.nvramDir(); + Controller::onMessageCallback callback = [&os = myOSystem](const string& msg) { + bool devSettings = os.settings().getBool("dev.settings"); + if(os.settings().getBool(devSettings ? "dev.eepromaccess" : "plr.eepromaccess")) + os.frameBuffer().showMessage(msg); + }; + switch(type) { case Controller::Type::AtariVox: { - FilesystemNode nvramfile = myOSystem.nvramDir(); nvramfile /= "atarivox_eeprom.dat"; - Controller::onMessageCallback callback = [&os = myOSystem](const string& msg) { - bool devSettings = os.settings().getBool("dev.settings"); - if(os.settings().getBool(devSettings ? "dev.eepromaccess" : "plr.eepromaccess")) - os.frameBuffer().showMessage(msg); - }; return make_unique(myJack, myEvent, mySystem, myOSystem.settings().getString("avoxport"), nvramfile, callback); // no alternative mapping here @@ -85,13 +86,7 @@ unique_ptr QuadTari::addController(const Controller::Type type, bool case Controller::Type::SaveKey: { - FilesystemNode nvramfile = myOSystem.nvramDir(); nvramfile /= "savekey_eeprom.dat"; - Controller::onMessageCallback callback = [&os = myOSystem](const string& msg) { - bool devSettings = os.settings().getBool("dev.settings"); - if(os.settings().getBool(devSettings ? "dev.eepromaccess" : "plr.eepromaccess")) - os.frameBuffer().showMessage(msg); - }; return make_unique(myJack, myEvent, mySystem, nvramfile, callback); // no alternative mapping here } diff --git a/src/gui/GameInfoDialog.cxx b/src/gui/GameInfoDialog.cxx index 69e485f93..a603a5a2d 100644 --- a/src/gui/GameInfoDialog.cxx +++ b/src/gui/GameInfoDialog.cxx @@ -31,6 +31,7 @@ #include "PopUpWidget.hxx" #include "Props.hxx" #include "PropsSet.hxx" +#include "QuadTariDialog.hxx" #include "TabWidget.hxx" #include "TIAConstants.hxx" #include "Widget.hxx" @@ -236,10 +237,6 @@ GameInfoDialog::GameInfoDialog( myLeftPortLabel->getTop()-1, pwidth, lineHeight, ctrls, "", 0, kLeftCChanged); wid.push_back(myLeftPort); - - myLeftQuadTari = new ButtonWidget(myTab, font, myLeftPort->getRight() + fontWidth * 2, myLeftPort->getTop() - 2, - "QuadTari" + ELLIPSIS, kLeftQTPressed); - wid.push_back(myLeftQuadTari); ypos += lineHeight + VGAP; myLeftPortDetected = new StaticTextWidget(myTab, ifont, myLeftPort->getLeft(), ypos, @@ -252,17 +249,17 @@ GameInfoDialog::GameInfoDialog( pwidth, lineHeight, ctrls, "", 0, kRightCChanged); wid.push_back(myRightPort); - myRightQuadTari = new ButtonWidget(myTab, font, myRightPort->getRight() + fontWidth * 2, myRightPort->getTop() - 2, - "QuadTari" + ELLIPSIS, kRightQTPressed); - wid.push_back(myRightQuadTari); + myQuadTariButton = new ButtonWidget(myTab, font, myRightPort->getRight() + fontWidth * 4, myRightPort->getTop() - 2, + "QuadTari" + ELLIPSIS, kQuadTariPressed); + wid.push_back(myQuadTariButton); ypos += lineHeight + VGAP; myRightPortDetected = new StaticTextWidget(myTab, ifont, myRightPort->getLeft(), ypos, "Sega Genesis detected"); ypos += ifont.getLineHeight() + VGAP + 4; - mySwapPorts = new CheckboxWidget(myTab, font, xpos + fontWidth * 2, - myLeftPortDetected->getTop()-1, "Swap ports"); + mySwapPorts = new CheckboxWidget(myTab, font, myLeftPort->getRight() + fontWidth * 4, + myLeftPort->getTop() + 1, "Swap ports"); wid.push_back(mySwapPorts); // EEPROM erase button for left/right controller @@ -601,8 +598,22 @@ void GameInfoDialog::saveProperties() myGameProperties.set(PropType::Console_RightDiff, myRightDiffGroup->getSelected() ? "B" : "A"); // Controller properties - myGameProperties.set(PropType::Controller_Left, myLeftPort->getSelectedTag().toString()); - myGameProperties.set(PropType::Controller_Right, myRightPort->getSelectedTag().toString()); + string controller = myLeftPort->getSelectedTag().toString(); + myGameProperties.set(PropType::Controller_Left, controller); + if(controller != "AUTO" && controller != "QUADTARI") + { + myGameProperties.set(PropType::Controller_Left1, ""); + myGameProperties.set(PropType::Controller_Left2, ""); + } + + controller = myRightPort->getSelectedTag().toString(); + myGameProperties.set(PropType::Controller_Right, controller); + if(controller != "AUTO" && controller != "QUADTARI") + { + myGameProperties.set(PropType::Controller_Right1, ""); + myGameProperties.set(PropType::Controller_Right2, ""); + } + myGameProperties.set(PropType::Console_SwapPorts, (mySwapPorts->isEnabled() && mySwapPorts->getState()) ? "YES" : "NO"); myGameProperties.set(PropType::Controller_SwapPaddles, mySwapPaddles->getState() ? "YES" : "NO"); @@ -715,8 +726,12 @@ void GameInfoDialog::updateControllerStates() if(type == Controller::Type::Unknown) { if(instance().hasConsole()) + { label = (!swapPorts ? instance().console().leftController().name() - : instance().console().rightController().name()) + " detected"; + : instance().console().rightController().name() + " detected"); + if(BSPF::startsWithIgnoreCase(label, "QUADTARI")) + label = "QuadTari detected"; // remove plugged-in controller names + } else if(autoDetect) label = ControllerDetector::detectName(image, size, type, !swapPorts ? Controller::Jack::Left : Controller::Jack::Right, @@ -730,8 +745,12 @@ void GameInfoDialog::updateControllerStates() if(type == Controller::Type::Unknown) { if(instance().hasConsole()) + { label = (!swapPorts ? instance().console().rightController().name() : instance().console().leftController().name()) + " detected"; + if(BSPF::startsWithIgnoreCase(label, "QUADTARI")) + label = "QuadTari detected"; // remove plugged-in controller names + } else if(autoDetect) label = ControllerDetector::detectName(image, size, type, !swapPorts ? Controller::Jack::Right : Controller::Jack::Left, @@ -770,8 +789,10 @@ void GameInfoDialog::updateControllerStates() myRightPortLabel->setEnabled(enableSelectControl); myLeftPort->setEnabled(enableSelectControl); myRightPort->setEnabled(enableSelectControl); - myLeftQuadTari->setEnabled(BSPF::startsWithIgnoreCase(contrLeft, "QUADTARI")); - myRightQuadTari->setEnabled(BSPF::startsWithIgnoreCase(contrRight, "QUADTARI")); + myQuadTariButton->setEnabled(BSPF::startsWithIgnoreCase(contrLeft, "QUADTARI") || + BSPF::startsWithIgnoreCase(contrRight, "QUADTARI") || + BSPF::startsWithIgnoreCase(myLeftPortDetected->getLabel(), "QUADTARI") || + BSPF::startsWithIgnoreCase(myRightPortDetected->getLabel(), "QUADTARI")); mySwapPorts->setEnabled(enableSelectControl); mySwapPaddles->setEnabled(enablePaddles); @@ -843,7 +864,7 @@ void GameInfoDialog::saveCurrentPropertiesToDisk() void GameInfoDialog::handleCommand(CommandSender* sender, int cmd, int data, int id) { - switch (cmd) + switch(cmd) { case GuiObject::kOKCmd: saveConfig(); @@ -871,12 +892,22 @@ void GameInfoDialog::handleCommand(CommandSender* sender, int cmd, updateControllerStates(); break; - case kLeftQTPressed: - break; + case kQuadTariPressed: + { + bool enableLeft = + BSPF::startsWithIgnoreCase(myLeftPort->getSelectedTag().toString(), "QUADTARI") || + BSPF::startsWithIgnoreCase(myLeftPortDetected->getLabel(), "QUADTARI"); + bool enableRight = + BSPF::startsWithIgnoreCase(myRightPort->getSelectedTag().toString(), "QUADTARI") || + BSPF::startsWithIgnoreCase(myRightPortDetected->getLabel(), "QUADTARI"); - case kRightQTPressed: + if(!myQuadTariDialog) + myQuadTariDialog = make_unique + (this, _font, _font.getMaxCharWidth() * 37, _font.getFontHeight() * 8, + myGameProperties); + myQuadTariDialog->show(enableLeft, enableRight); break; - + } case kEEButtonPressed: eraseEEPROM(); break; diff --git a/src/gui/GameInfoDialog.hxx b/src/gui/GameInfoDialog.hxx index b1b155f7a..19d1c29e3 100644 --- a/src/gui/GameInfoDialog.hxx +++ b/src/gui/GameInfoDialog.hxx @@ -26,6 +26,7 @@ class StaticTextWidget; class RadioButtonGroup; class TabWidget; class SliderWidget; +class QuadTariDialog; #include "Dialog.hxx" #include "Command.hxx" @@ -87,8 +88,7 @@ class GameInfoDialog : public Dialog, public CommandSender StaticTextWidget* myLeftPortDetected{nullptr}; PopUpWidget* myRightPort{nullptr}; StaticTextWidget* myRightPortDetected{nullptr}; - ButtonWidget* myLeftQuadTari{nullptr}; - ButtonWidget* myRightQuadTari{nullptr}; + ButtonWidget* myQuadTariButton{nullptr}; CheckboxWidget* mySwapPorts{nullptr}; CheckboxWidget* mySwapPaddles{nullptr}; StaticTextWidget* myEraseEEPROMLabel{nullptr}; @@ -102,6 +102,9 @@ class GameInfoDialog : public Dialog, public CommandSender PopUpWidget* myMouseY{nullptr}; SliderWidget* myMouseRange{nullptr}; + // Allow assigning the four QuadTari controllers + unique_ptr myQuadTariDialog; + // Cartridge properties EditTextWidget* myName{nullptr}; EditTextWidget* myMD5{nullptr}; @@ -116,8 +119,7 @@ class GameInfoDialog : public Dialog, public CommandSender kPPBlendChanged = 'PBch', kLeftCChanged = 'LCch', kRightCChanged = 'RCch', - kLeftQTPressed = 'LQTp', - kRightQTPressed = 'RQTp', + kQuadTariPressed = 'QTpr', kMCtrlChanged = 'MCch', kEEButtonPressed = 'EEgb', kPXCenterChanged = 'Pxch', diff --git a/src/gui/QuadTariDialog.cxx b/src/gui/QuadTariDialog.cxx new file mode 100644 index 000000000..dda63853b --- /dev/null +++ b/src/gui/QuadTariDialog.cxx @@ -0,0 +1,200 @@ +//============================================================================ +// +// 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-2020 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 "OSystem.hxx" +#include "EventHandler.hxx" +#include "Widget.hxx" +#include "PopUpWidget.hxx" +#include "Font.hxx" +#include "Variant.hxx" +#include "Props.hxx" +#include "PropsSet.hxx" +#include "QuadTariDialog.hxx" + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +QuadTariDialog::QuadTariDialog(GuiObject* boss, const GUI::Font& font, int max_w, int max_h, + Properties& properties) + : Dialog(boss->instance(), boss->parent(), font, "QuadTari controllers", 0, 0, max_w, max_h), + myGameProperties(properties) +{ + const int lineHeight = font.getLineHeight(), + fontHeight = font.getFontHeight(), + fontWidth = font.getMaxCharWidth(), + buttonHeight = font.getLineHeight() * 1.25; + const int VBORDER = fontHeight / 2; + const int HBORDER = fontWidth * 1.25; + const int VGAP = fontHeight / 4; + + int xpos, ypos; + WidgetArray wid; + VariantList ctrls; + + xpos = HBORDER; ypos = VBORDER + _th; + + ctrls.clear(); + //VarList::push_back(ctrls, "Auto-detect", "AUTO"); + VarList::push_back(ctrls, "Joystick", "JOYSTICK"); + //VarList::push_back(ctrls, "Paddles", "PADDLES"); + //VarList::push_back(ctrls, "Paddles_IAxis", "PADDLES_IAXIS"); + //VarList::push_back(ctrls, "Paddles_IAxDr", "PADDLES_IAXDR"); + //VarList::push_back(ctrls, "BoosterGrip", "BOOSTERGRIP"); + VarList::push_back(ctrls, "Driving", "DRIVING"); + //VarList::push_back(ctrls, "Keyboard", "KEYBOARD"); + //VarList::push_back(ctrls, "AmigaMouse", "AMIGAMOUSE"); + //VarList::push_back(ctrls, "AtariMouse", "ATARIMOUSE"); + //VarList::push_back(ctrls, "Trakball", "TRAKBALL"); + VarList::push_back(ctrls, "AtariVox", "ATARIVOX"); + 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"); + //VarList::push_back(ctrls, "QuadTari", "QUADTARI"); + + int pwidth = font.getStringWidth("Joystick12"); // looks better overall + + myLeftPortLabel = new StaticTextWidget(this, font, xpos, ypos + 1, "Left port"); + + ypos += lineHeight + VGAP * 2; + myLeft1Port = new PopUpWidget(this, font, xpos, ypos, + pwidth, lineHeight, ctrls, "P1 "); + wid.push_back(myLeft1Port); + + ypos += lineHeight + VGAP * 2; + myLeft2Port = new PopUpWidget(this, font, xpos, ypos, + pwidth, lineHeight, ctrls, "P2 "); + wid.push_back(myLeft2Port); + + xpos = _w - HBORDER - myLeft1Port->getWidth(); // aligned right + ypos = myLeftPortLabel->getTop() - 1; + myRightPortLabel = new StaticTextWidget(this, font, xpos, ypos + 1, "Right port"); + + ypos += lineHeight + VGAP * 2; + myRight1Port = new PopUpWidget(this, font, xpos, ypos, + pwidth, lineHeight, ctrls, "P3 "); + wid.push_back(myRight1Port); + + ypos += lineHeight + VGAP * 2; + myRight2Port = new PopUpWidget(this, font, xpos, ypos, + pwidth, lineHeight, ctrls, "P4 "); + wid.push_back(myRight2Port); + + addDefaultsOKCancelBGroup(wid, _font); + addBGroupToFocusList(wid); +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +void QuadTariDialog::show(bool enableLeft, bool enableRight) +{ + myLeftPortLabel->setEnabled(enableLeft); + myLeft1Port->setEnabled(enableLeft); + myLeft2Port->setEnabled(enableLeft); + myRightPortLabel->setEnabled(enableRight); + myRight1Port->setEnabled(enableRight); + myRight2Port->setEnabled(enableRight); + + open(); +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +void QuadTariDialog::loadControllerProperties(const Properties& props) +{ + string controller; + + if(myLeftPortLabel->isEnabled()) + { + controller = props.get(PropType::Controller_Left1); + myLeft1Port->setSelected(controller, "Joystick"); + controller = props.get(PropType::Controller_Left2); + myLeft2Port->setSelected(controller, "Joystick"); + } + + if(myRightPortLabel->isEnabled()) + { + controller = props.get(PropType::Controller_Right1); + myRight1Port->setSelected(controller, "Joystick"); + controller = props.get(PropType::Controller_Right2); + myRight2Port->setSelected(controller, "Joystick"); + } +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +void QuadTariDialog::loadConfig() +{ + loadControllerProperties(myGameProperties); +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +void QuadTariDialog::saveConfig() +{ + if(myLeftPortLabel->isEnabled()) + { + string controller = myLeft1Port->getSelectedTag().toString(); + myGameProperties.set(PropType::Controller_Left1, controller); + controller = myLeft2Port->getSelectedTag().toString(); + myGameProperties.set(PropType::Controller_Left2, controller); + } + else + { + myGameProperties.set(PropType::Controller_Left1, ""); + myGameProperties.set(PropType::Controller_Left2, ""); + } + + if(myRightPortLabel->isEnabled()) + { + string controller = myRight1Port->getSelectedTag().toString(); + myGameProperties.set(PropType::Controller_Right1, controller); + controller = myRight2Port->getSelectedTag().toString(); + myGameProperties.set(PropType::Controller_Right2, controller); + } + else + { + myGameProperties.set(PropType::Controller_Right1, ""); + myGameProperties.set(PropType::Controller_Right2, ""); + } +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +void QuadTariDialog::setDefaults() +{ + // Load the default properties + const string& md5 = myGameProperties.get(PropType::Cart_MD5); + Properties defaultProperties; + + instance().propSet().getMD5(md5, defaultProperties, true); + loadControllerProperties(defaultProperties); +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +void QuadTariDialog::handleCommand(CommandSender* sender, int cmd, int data, int id) +{ + switch(cmd) + { + case GuiObject::kOKCmd: + saveConfig(); + close(); + break; + + case GuiObject::kDefaultsCmd: + setDefaults(); + break; + + default: + Dialog::handleCommand(sender, cmd, data, id); + break; + } +} diff --git a/src/gui/QuadTariDialog.hxx b/src/gui/QuadTariDialog.hxx new file mode 100644 index 000000000..070a0bd71 --- /dev/null +++ b/src/gui/QuadTariDialog.hxx @@ -0,0 +1,69 @@ +//============================================================================ +// +// 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-2020 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 JOYSTICK_DIALOG_HXX +#define JOYSTICK_DIALOG_HXX + +class CommandSender; +class PopUpWidget; + +#include "Dialog.hxx" + +/** + * Allow assigning controllers to the four QuadTari ports. + */ +class QuadTariDialog: public Dialog +{ + public: + QuadTariDialog(GuiObject* boss, const GUI::Font& font, int max_w, int max_h, + Properties& properties); + ~QuadTariDialog() override = default; + + /** Place the dialog onscreen */ + void show(bool enableLeft, bool enableRight); + + private: + void loadConfig() override; + void saveConfig() override; + void handleCommand(CommandSender* sender, int cmd, int data, int id) override; + + void setDefaults() override; + + void loadControllerProperties(const Properties& props); + + private: + StaticTextWidget* myLeftPortLabel{nullptr}; + PopUpWidget* myLeft1Port{nullptr}; + PopUpWidget* myLeft2Port{nullptr}; + + StaticTextWidget* myRightPortLabel{nullptr}; + PopUpWidget* myRight1Port{nullptr}; + PopUpWidget* myRight2Port{nullptr}; + + // Game properties for currently loaded ROM + Properties& myGameProperties; + + private: + // Following constructors and assignment operators not supported + QuadTariDialog() = delete; + QuadTariDialog(const QuadTariDialog&) = delete; + QuadTariDialog(QuadTariDialog&&) = delete; + QuadTariDialog& operator=(const QuadTariDialog&) = delete; + QuadTariDialog& operator=(QuadTariDialog&&) = delete; +}; + +#endif diff --git a/src/windows/Stella.vcxproj b/src/windows/Stella.vcxproj index 261ac76b9..f37614cda 100644 --- a/src/windows/Stella.vcxproj +++ b/src/windows/Stella.vcxproj @@ -773,6 +773,7 @@ + @@ -1815,6 +1816,7 @@ + diff --git a/src/windows/Stella.vcxproj.filters b/src/windows/Stella.vcxproj.filters index 6be678998..217dfaecf 100644 --- a/src/windows/Stella.vcxproj.filters +++ b/src/windows/Stella.vcxproj.filters @@ -1023,6 +1023,9 @@ Source Files\debugger + + Source Files\gui + @@ -2102,6 +2105,9 @@ Header Files\debugger + + Header Files\gui +