mirror of https://github.com/stella-emu/stella.git
added multiple controller support (joystick, driving, SaveKey, AtariVox)
This commit is contained in:
parent
36aa23824a
commit
21bc244d97
|
@ -37,7 +37,7 @@
|
||||||
are no longer corrupted/cut off. This includes properly supporting the
|
are no longer corrupted/cut off. This includes properly supporting the
|
||||||
2600-daptor II, which is flashable to an AVox-USB converter.
|
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.
|
* Added option to select the audio device.
|
||||||
|
|
||||||
|
|
|
@ -268,24 +268,15 @@
|
||||||
Atari 2600 FPGA project, including cycle-exact audio, analog interference
|
Atari 2600 FPGA project, including cycle-exact audio, analog interference
|
||||||
from mixing of audio channels, as well as stereo sound support; dynamic
|
from mixing of audio channels, as well as stereo sound support; dynamic
|
||||||
sound resampling is also included</li>
|
sound resampling is also included</li>
|
||||||
<li>Emulates the Atari 2600 Joystick Controllers using your computer's keyboard,
|
<li>Emulates the Atari 2600 Joystick, Paddle, Driving, CBS BoosterGrip, Sega Genesis, QuadTari controllers using your computer's keyboard,
|
||||||
joysticks or mouse</li>
|
joysticks or mouse</li>
|
||||||
<li>Emulates the Atari 2600 Keyboard Controllers using your computer's keyboard</li>
|
<li>Emulates CX22/CX80 style Trackballs, Amiga/Atari Mouse, Mindlink controller and the Light Gun using your
|
||||||
<li>Emulates the Atari 2600 Paddle Controllers using your computer's mouse, keyboard
|
|
||||||
or joysticks</li>
|
|
||||||
<li>Emulates the Atari 2600 Driving Controllers using your computer's keyboard,
|
|
||||||
joysticks or mouse</li>
|
|
||||||
<li>Emulates the CBS BoosterGrip Controller using your computer's keyboard,
|
|
||||||
joysticks or mouse</li>
|
|
||||||
<li>Emulates the Sega Genesis Controller using your computer's keyboard,
|
|
||||||
joysticks or mouse</li>
|
|
||||||
<li>Emulates CX22/CX80 style trackballs and Amiga/Atari Mouse using your
|
|
||||||
computer's mouse</li>
|
computer's mouse</li>
|
||||||
|
<li>Emulates the Atari 2600 Keyboard controllers using your computer's keyboard</li>
|
||||||
<li>Emulates <a href="http://en.wikipedia.org/wiki/CompuMate">Spectravideo CompuMate</a> system using your computer's keyboard,
|
<li>Emulates <a href="http://en.wikipedia.org/wiki/CompuMate">Spectravideo CompuMate</a> system using your computer's keyboard,
|
||||||
including mapping of CompuMate 'Backspace', 'Space' and 'Enter' functionality to
|
including mapping of CompuMate 'Backspace', 'Space' and 'Enter' functionality to
|
||||||
to the actual keys on your keyboard</li>
|
to the actual keys on your keyboard</li>
|
||||||
<li>Emulates the Mindlink Controller and the Light Gun using your computer's mouse</li>
|
<li>Supports autodetection for most common controller types</li>
|
||||||
<li>Supports autodetection for most common controller types</li>
|
|
||||||
<li>Support for real Atari 2600 controllers using the
|
<li>Support for real Atari 2600 controllers using the
|
||||||
<a href="http://www.grandideastudio.com/portfolio/stelladaptor-2600">Stelladaptor</a> and
|
<a href="http://www.grandideastudio.com/portfolio/stelladaptor-2600">Stelladaptor</a> and
|
||||||
<a href="http://2600-daptor.com">2600-daptor/2600-daptor II</a></li>
|
<a href="http://2600-daptor.com">2600-daptor/2600-daptor II</a></li>
|
||||||
|
|
|
@ -699,6 +699,11 @@ bool ControllerDetector::isProbablyLightGun(const ByteBuffer& image, size_t size
|
||||||
bool ControllerDetector::isProbablyQuadTari(const ByteBuffer& image, size_t size,
|
bool ControllerDetector::isProbablyQuadTari(const ByteBuffer& image, size_t size,
|
||||||
Controller::Jack port)
|
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)
|
if(port == Controller::Jack::Left)
|
||||||
{
|
{
|
||||||
uInt8 signature[] = { 'Q', 'U', 'A', 'D', 'L' };
|
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);
|
return searchForBytes(image, size, signature, 5);
|
||||||
}
|
}
|
||||||
|
return false;
|
||||||
uInt8 signature[] = { 0x1B, 0x1F, 0x0B, 0x0E, 0x1E, 0x0B, 0x1C, 0x13 };
|
|
||||||
|
|
||||||
return searchForBytes(image, size, signature, 8);
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -65,17 +65,18 @@ QuadTari::QuadTari(Jack jack, OSystem& osystem, const System& system, const Prop
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
unique_ptr<Controller> QuadTari::addController(const Controller::Type type, bool second)
|
unique_ptr<Controller> 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)
|
switch(type)
|
||||||
{
|
{
|
||||||
case Controller::Type::AtariVox:
|
case Controller::Type::AtariVox:
|
||||||
{
|
{
|
||||||
FilesystemNode nvramfile = myOSystem.nvramDir();
|
|
||||||
nvramfile /= "atarivox_eeprom.dat";
|
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<AtariVox>(myJack, myEvent, mySystem,
|
return make_unique<AtariVox>(myJack, myEvent, mySystem,
|
||||||
myOSystem.settings().getString("avoxport"),
|
myOSystem.settings().getString("avoxport"),
|
||||||
nvramfile, callback); // no alternative mapping here
|
nvramfile, callback); // no alternative mapping here
|
||||||
|
@ -85,13 +86,7 @@ unique_ptr<Controller> QuadTari::addController(const Controller::Type type, bool
|
||||||
|
|
||||||
case Controller::Type::SaveKey:
|
case Controller::Type::SaveKey:
|
||||||
{
|
{
|
||||||
FilesystemNode nvramfile = myOSystem.nvramDir();
|
|
||||||
nvramfile /= "savekey_eeprom.dat";
|
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<SaveKey>(myJack, myEvent, mySystem,
|
return make_unique<SaveKey>(myJack, myEvent, mySystem,
|
||||||
nvramfile, callback); // no alternative mapping here
|
nvramfile, callback); // no alternative mapping here
|
||||||
}
|
}
|
||||||
|
|
|
@ -31,6 +31,7 @@
|
||||||
#include "PopUpWidget.hxx"
|
#include "PopUpWidget.hxx"
|
||||||
#include "Props.hxx"
|
#include "Props.hxx"
|
||||||
#include "PropsSet.hxx"
|
#include "PropsSet.hxx"
|
||||||
|
#include "QuadTariDialog.hxx"
|
||||||
#include "TabWidget.hxx"
|
#include "TabWidget.hxx"
|
||||||
#include "TIAConstants.hxx"
|
#include "TIAConstants.hxx"
|
||||||
#include "Widget.hxx"
|
#include "Widget.hxx"
|
||||||
|
@ -236,10 +237,6 @@ GameInfoDialog::GameInfoDialog(
|
||||||
myLeftPortLabel->getTop()-1,
|
myLeftPortLabel->getTop()-1,
|
||||||
pwidth, lineHeight, ctrls, "", 0, kLeftCChanged);
|
pwidth, lineHeight, ctrls, "", 0, kLeftCChanged);
|
||||||
wid.push_back(myLeftPort);
|
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;
|
ypos += lineHeight + VGAP;
|
||||||
|
|
||||||
myLeftPortDetected = new StaticTextWidget(myTab, ifont, myLeftPort->getLeft(), ypos,
|
myLeftPortDetected = new StaticTextWidget(myTab, ifont, myLeftPort->getLeft(), ypos,
|
||||||
|
@ -252,17 +249,17 @@ GameInfoDialog::GameInfoDialog(
|
||||||
pwidth, lineHeight, ctrls, "", 0, kRightCChanged);
|
pwidth, lineHeight, ctrls, "", 0, kRightCChanged);
|
||||||
wid.push_back(myRightPort);
|
wid.push_back(myRightPort);
|
||||||
|
|
||||||
myRightQuadTari = new ButtonWidget(myTab, font, myRightPort->getRight() + fontWidth * 2, myRightPort->getTop() - 2,
|
myQuadTariButton = new ButtonWidget(myTab, font, myRightPort->getRight() + fontWidth * 4, myRightPort->getTop() - 2,
|
||||||
"QuadTari" + ELLIPSIS, kRightQTPressed);
|
"QuadTari" + ELLIPSIS, kQuadTariPressed);
|
||||||
wid.push_back(myRightQuadTari);
|
wid.push_back(myQuadTariButton);
|
||||||
|
|
||||||
ypos += lineHeight + VGAP;
|
ypos += lineHeight + VGAP;
|
||||||
myRightPortDetected = new StaticTextWidget(myTab, ifont, myRightPort->getLeft(), ypos,
|
myRightPortDetected = new StaticTextWidget(myTab, ifont, myRightPort->getLeft(), ypos,
|
||||||
"Sega Genesis detected");
|
"Sega Genesis detected");
|
||||||
ypos += ifont.getLineHeight() + VGAP + 4;
|
ypos += ifont.getLineHeight() + VGAP + 4;
|
||||||
|
|
||||||
mySwapPorts = new CheckboxWidget(myTab, font, xpos + fontWidth * 2,
|
mySwapPorts = new CheckboxWidget(myTab, font, myLeftPort->getRight() + fontWidth * 4,
|
||||||
myLeftPortDetected->getTop()-1, "Swap ports");
|
myLeftPort->getTop() + 1, "Swap ports");
|
||||||
wid.push_back(mySwapPorts);
|
wid.push_back(mySwapPorts);
|
||||||
|
|
||||||
// EEPROM erase button for left/right controller
|
// EEPROM erase button for left/right controller
|
||||||
|
@ -601,8 +598,22 @@ void GameInfoDialog::saveProperties()
|
||||||
myGameProperties.set(PropType::Console_RightDiff, myRightDiffGroup->getSelected() ? "B" : "A");
|
myGameProperties.set(PropType::Console_RightDiff, myRightDiffGroup->getSelected() ? "B" : "A");
|
||||||
|
|
||||||
// Controller properties
|
// Controller properties
|
||||||
myGameProperties.set(PropType::Controller_Left, myLeftPort->getSelectedTag().toString());
|
string controller = myLeftPort->getSelectedTag().toString();
|
||||||
myGameProperties.set(PropType::Controller_Right, myRightPort->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::Console_SwapPorts, (mySwapPorts->isEnabled() && mySwapPorts->getState()) ? "YES" : "NO");
|
||||||
myGameProperties.set(PropType::Controller_SwapPaddles, mySwapPaddles->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(type == Controller::Type::Unknown)
|
||||||
{
|
{
|
||||||
if(instance().hasConsole())
|
if(instance().hasConsole())
|
||||||
|
{
|
||||||
label = (!swapPorts ? instance().console().leftController().name()
|
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)
|
else if(autoDetect)
|
||||||
label = ControllerDetector::detectName(image, size, type,
|
label = ControllerDetector::detectName(image, size, type,
|
||||||
!swapPorts ? Controller::Jack::Left : Controller::Jack::Right,
|
!swapPorts ? Controller::Jack::Left : Controller::Jack::Right,
|
||||||
|
@ -730,8 +745,12 @@ void GameInfoDialog::updateControllerStates()
|
||||||
if(type == Controller::Type::Unknown)
|
if(type == Controller::Type::Unknown)
|
||||||
{
|
{
|
||||||
if(instance().hasConsole())
|
if(instance().hasConsole())
|
||||||
|
{
|
||||||
label = (!swapPorts ? instance().console().rightController().name()
|
label = (!swapPorts ? instance().console().rightController().name()
|
||||||
: instance().console().leftController().name()) + " detected";
|
: instance().console().leftController().name()) + " detected";
|
||||||
|
if(BSPF::startsWithIgnoreCase(label, "QUADTARI"))
|
||||||
|
label = "QuadTari detected"; // remove plugged-in controller names
|
||||||
|
}
|
||||||
else if(autoDetect)
|
else if(autoDetect)
|
||||||
label = ControllerDetector::detectName(image, size, type,
|
label = ControllerDetector::detectName(image, size, type,
|
||||||
!swapPorts ? Controller::Jack::Right : Controller::Jack::Left,
|
!swapPorts ? Controller::Jack::Right : Controller::Jack::Left,
|
||||||
|
@ -770,8 +789,10 @@ void GameInfoDialog::updateControllerStates()
|
||||||
myRightPortLabel->setEnabled(enableSelectControl);
|
myRightPortLabel->setEnabled(enableSelectControl);
|
||||||
myLeftPort->setEnabled(enableSelectControl);
|
myLeftPort->setEnabled(enableSelectControl);
|
||||||
myRightPort->setEnabled(enableSelectControl);
|
myRightPort->setEnabled(enableSelectControl);
|
||||||
myLeftQuadTari->setEnabled(BSPF::startsWithIgnoreCase(contrLeft, "QUADTARI"));
|
myQuadTariButton->setEnabled(BSPF::startsWithIgnoreCase(contrLeft, "QUADTARI") ||
|
||||||
myRightQuadTari->setEnabled(BSPF::startsWithIgnoreCase(contrRight, "QUADTARI"));
|
BSPF::startsWithIgnoreCase(contrRight, "QUADTARI") ||
|
||||||
|
BSPF::startsWithIgnoreCase(myLeftPortDetected->getLabel(), "QUADTARI") ||
|
||||||
|
BSPF::startsWithIgnoreCase(myRightPortDetected->getLabel(), "QUADTARI"));
|
||||||
|
|
||||||
mySwapPorts->setEnabled(enableSelectControl);
|
mySwapPorts->setEnabled(enableSelectControl);
|
||||||
mySwapPaddles->setEnabled(enablePaddles);
|
mySwapPaddles->setEnabled(enablePaddles);
|
||||||
|
@ -843,7 +864,7 @@ void GameInfoDialog::saveCurrentPropertiesToDisk()
|
||||||
void GameInfoDialog::handleCommand(CommandSender* sender, int cmd,
|
void GameInfoDialog::handleCommand(CommandSender* sender, int cmd,
|
||||||
int data, int id)
|
int data, int id)
|
||||||
{
|
{
|
||||||
switch (cmd)
|
switch(cmd)
|
||||||
{
|
{
|
||||||
case GuiObject::kOKCmd:
|
case GuiObject::kOKCmd:
|
||||||
saveConfig();
|
saveConfig();
|
||||||
|
@ -871,12 +892,22 @@ void GameInfoDialog::handleCommand(CommandSender* sender, int cmd,
|
||||||
updateControllerStates();
|
updateControllerStates();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case kLeftQTPressed:
|
case kQuadTariPressed:
|
||||||
break;
|
{
|
||||||
|
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<QuadTariDialog>
|
||||||
|
(this, _font, _font.getMaxCharWidth() * 37, _font.getFontHeight() * 8,
|
||||||
|
myGameProperties);
|
||||||
|
myQuadTariDialog->show(enableLeft, enableRight);
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
case kEEButtonPressed:
|
case kEEButtonPressed:
|
||||||
eraseEEPROM();
|
eraseEEPROM();
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -26,6 +26,7 @@ class StaticTextWidget;
|
||||||
class RadioButtonGroup;
|
class RadioButtonGroup;
|
||||||
class TabWidget;
|
class TabWidget;
|
||||||
class SliderWidget;
|
class SliderWidget;
|
||||||
|
class QuadTariDialog;
|
||||||
|
|
||||||
#include "Dialog.hxx"
|
#include "Dialog.hxx"
|
||||||
#include "Command.hxx"
|
#include "Command.hxx"
|
||||||
|
@ -87,8 +88,7 @@ class GameInfoDialog : public Dialog, public CommandSender
|
||||||
StaticTextWidget* myLeftPortDetected{nullptr};
|
StaticTextWidget* myLeftPortDetected{nullptr};
|
||||||
PopUpWidget* myRightPort{nullptr};
|
PopUpWidget* myRightPort{nullptr};
|
||||||
StaticTextWidget* myRightPortDetected{nullptr};
|
StaticTextWidget* myRightPortDetected{nullptr};
|
||||||
ButtonWidget* myLeftQuadTari{nullptr};
|
ButtonWidget* myQuadTariButton{nullptr};
|
||||||
ButtonWidget* myRightQuadTari{nullptr};
|
|
||||||
CheckboxWidget* mySwapPorts{nullptr};
|
CheckboxWidget* mySwapPorts{nullptr};
|
||||||
CheckboxWidget* mySwapPaddles{nullptr};
|
CheckboxWidget* mySwapPaddles{nullptr};
|
||||||
StaticTextWidget* myEraseEEPROMLabel{nullptr};
|
StaticTextWidget* myEraseEEPROMLabel{nullptr};
|
||||||
|
@ -102,6 +102,9 @@ class GameInfoDialog : public Dialog, public CommandSender
|
||||||
PopUpWidget* myMouseY{nullptr};
|
PopUpWidget* myMouseY{nullptr};
|
||||||
SliderWidget* myMouseRange{nullptr};
|
SliderWidget* myMouseRange{nullptr};
|
||||||
|
|
||||||
|
// Allow assigning the four QuadTari controllers
|
||||||
|
unique_ptr<QuadTariDialog> myQuadTariDialog;
|
||||||
|
|
||||||
// Cartridge properties
|
// Cartridge properties
|
||||||
EditTextWidget* myName{nullptr};
|
EditTextWidget* myName{nullptr};
|
||||||
EditTextWidget* myMD5{nullptr};
|
EditTextWidget* myMD5{nullptr};
|
||||||
|
@ -116,8 +119,7 @@ class GameInfoDialog : public Dialog, public CommandSender
|
||||||
kPPBlendChanged = 'PBch',
|
kPPBlendChanged = 'PBch',
|
||||||
kLeftCChanged = 'LCch',
|
kLeftCChanged = 'LCch',
|
||||||
kRightCChanged = 'RCch',
|
kRightCChanged = 'RCch',
|
||||||
kLeftQTPressed = 'LQTp',
|
kQuadTariPressed = 'QTpr',
|
||||||
kRightQTPressed = 'RQTp',
|
|
||||||
kMCtrlChanged = 'MCch',
|
kMCtrlChanged = 'MCch',
|
||||||
kEEButtonPressed = 'EEgb',
|
kEEButtonPressed = 'EEgb',
|
||||||
kPXCenterChanged = 'Pxch',
|
kPXCenterChanged = 'Pxch',
|
||||||
|
|
|
@ -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;
|
||||||
|
}
|
||||||
|
}
|
|
@ -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
|
|
@ -773,6 +773,7 @@
|
||||||
<ClCompile Include="..\gui\MessageDialog.cxx" />
|
<ClCompile Include="..\gui\MessageDialog.cxx" />
|
||||||
<ClCompile Include="..\gui\MessageMenu.cxx" />
|
<ClCompile Include="..\gui\MessageMenu.cxx" />
|
||||||
<ClCompile Include="..\gui\MinUICommandDialog.cxx" />
|
<ClCompile Include="..\gui\MinUICommandDialog.cxx" />
|
||||||
|
<ClCompile Include="..\gui\QuadTariDialog.cxx" />
|
||||||
<ClCompile Include="..\gui\R77HelpDialog.cxx" />
|
<ClCompile Include="..\gui\R77HelpDialog.cxx" />
|
||||||
<ClCompile Include="..\gui\RadioButtonWidget.cxx" />
|
<ClCompile Include="..\gui\RadioButtonWidget.cxx" />
|
||||||
<ClCompile Include="..\gui\SnapshotDialog.cxx" />
|
<ClCompile Include="..\gui\SnapshotDialog.cxx" />
|
||||||
|
@ -1815,6 +1816,7 @@
|
||||||
<ClInclude Include="..\gui\MessageDialog.hxx" />
|
<ClInclude Include="..\gui\MessageDialog.hxx" />
|
||||||
<ClInclude Include="..\gui\MessageMenu.hxx" />
|
<ClInclude Include="..\gui\MessageMenu.hxx" />
|
||||||
<ClInclude Include="..\gui\MinUICommandDialog.hxx" />
|
<ClInclude Include="..\gui\MinUICommandDialog.hxx" />
|
||||||
|
<ClInclude Include="..\gui\QuadTariDialog.hxx" />
|
||||||
<ClInclude Include="..\gui\R77HelpDialog.hxx" />
|
<ClInclude Include="..\gui\R77HelpDialog.hxx" />
|
||||||
<ClInclude Include="..\gui\RadioButtonWidget.hxx" />
|
<ClInclude Include="..\gui\RadioButtonWidget.hxx" />
|
||||||
<ClInclude Include="..\gui\SnapshotDialog.hxx" />
|
<ClInclude Include="..\gui\SnapshotDialog.hxx" />
|
||||||
|
|
|
@ -1023,6 +1023,9 @@
|
||||||
<ClCompile Include="..\debugger\gui\QuadTariWidget.cxx">
|
<ClCompile Include="..\debugger\gui\QuadTariWidget.cxx">
|
||||||
<Filter>Source Files\debugger</Filter>
|
<Filter>Source Files\debugger</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
|
<ClCompile Include="..\gui\QuadTariDialog.cxx">
|
||||||
|
<Filter>Source Files\gui</Filter>
|
||||||
|
</ClCompile>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClInclude Include="..\common\bspf.hxx">
|
<ClInclude Include="..\common\bspf.hxx">
|
||||||
|
@ -2102,6 +2105,9 @@
|
||||||
<ClInclude Include="..\debugger\gui\QuadTariWidget.hxx">
|
<ClInclude Include="..\debugger\gui\QuadTariWidget.hxx">
|
||||||
<Filter>Header Files\debugger</Filter>
|
<Filter>Header Files\debugger</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
|
<ClInclude Include="..\gui\QuadTariDialog.hxx">
|
||||||
|
<Filter>Header Files\gui</Filter>
|
||||||
|
</ClInclude>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<None Include="stella.ico">
|
<None Include="stella.ico">
|
||||||
|
|
Loading…
Reference in New Issue