added multiple controller support (joystick, driving, SaveKey, AtariVox)

This commit is contained in:
Thomas Jentzsch 2020-09-03 15:14:55 +02:00
parent f1b1936a73
commit fa987e63b6
10 changed files with 351 additions and 53 deletions

View File

@ -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.

View File

@ -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</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>
<li>Emulates the Atari 2600 Keyboard Controllers using your computer's keyboard</li>
<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
<li>Emulates CX22/CX80 style Trackballs, Amiga/Atari Mouse, Mindlink controller and the Light Gun using your
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,
including mapping of CompuMate 'Backspace', 'Space' and 'Enter' functionality to
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
<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>

View File

@ -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;
}

View File

@ -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)
{
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<AtariVox>(myJack, myEvent, mySystem,
myOSystem.settings().getString("avoxport"),
nvramfile, callback); // no alternative mapping here
@ -85,13 +86,7 @@ unique_ptr<Controller> 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<SaveKey>(myJack, myEvent, mySystem,
nvramfile, callback); // no alternative mapping here
}

View File

@ -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<QuadTariDialog>
(this, _font, _font.getMaxCharWidth() * 37, _font.getFontHeight() * 8,
myGameProperties);
myQuadTariDialog->show(enableLeft, enableRight);
break;
}
case kEEButtonPressed:
eraseEEPROM();
break;

View File

@ -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<QuadTariDialog> 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',

200
src/gui/QuadTariDialog.cxx Normal file
View File

@ -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;
}
}

View File

@ -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

View File

@ -773,6 +773,7 @@
<ClCompile Include="..\gui\MessageDialog.cxx" />
<ClCompile Include="..\gui\MessageMenu.cxx" />
<ClCompile Include="..\gui\MinUICommandDialog.cxx" />
<ClCompile Include="..\gui\QuadTariDialog.cxx" />
<ClCompile Include="..\gui\R77HelpDialog.cxx" />
<ClCompile Include="..\gui\RadioButtonWidget.cxx" />
<ClCompile Include="..\gui\SnapshotDialog.cxx" />
@ -1815,6 +1816,7 @@
<ClInclude Include="..\gui\MessageDialog.hxx" />
<ClInclude Include="..\gui\MessageMenu.hxx" />
<ClInclude Include="..\gui\MinUICommandDialog.hxx" />
<ClInclude Include="..\gui\QuadTariDialog.hxx" />
<ClInclude Include="..\gui\R77HelpDialog.hxx" />
<ClInclude Include="..\gui\RadioButtonWidget.hxx" />
<ClInclude Include="..\gui\SnapshotDialog.hxx" />

View File

@ -1023,6 +1023,9 @@
<ClCompile Include="..\debugger\gui\QuadTariWidget.cxx">
<Filter>Source Files\debugger</Filter>
</ClCompile>
<ClCompile Include="..\gui\QuadTariDialog.cxx">
<Filter>Source Files\gui</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="..\common\bspf.hxx">
@ -2102,6 +2105,9 @@
<ClInclude Include="..\debugger\gui\QuadTariWidget.hxx">
<Filter>Header Files\debugger</Filter>
</ClInclude>
<ClInclude Include="..\gui\QuadTariDialog.hxx">
<Filter>Header Files\gui</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<None Include="stella.ico">