diff --git a/src/gui/CommandMenu.cxx b/src/gui/CommandMenu.cxx index ae6f8197f..131ab1924 100644 --- a/src/gui/CommandMenu.cxx +++ b/src/gui/CommandMenu.cxx @@ -17,11 +17,15 @@ #include "Dialog.hxx" #include "CommandDialog.hxx" +#include "MinUICommandDialog.hxx" #include "CommandMenu.hxx" // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - CommandMenu::CommandMenu(OSystem& osystem) : DialogContainer(osystem) { - myBaseDialog = new CommandDialog(myOSystem, *this); + if (osystem.settings().getBool("minimal_ui")) + myBaseDialog = new MinUICommandDialog(myOSystem, *this); + else + myBaseDialog = new CommandDialog(myOSystem, *this); } diff --git a/src/gui/MinUICommandDialog.cxx b/src/gui/MinUICommandDialog.cxx new file mode 100644 index 000000000..d17d607f1 --- /dev/null +++ b/src/gui/MinUICommandDialog.cxx @@ -0,0 +1,255 @@ +//============================================================================ +// +// 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 "Console.hxx" +#include "TIA.hxx" +#include "Switches.hxx" +#include "Dialog.hxx" +#include "Font.hxx" +#include "EventHandler.hxx" +#include "StateManager.hxx" +#include "OSystem.hxx" +#include "Widget.hxx" +#include "StellaSettingsDialog.hxx" +#include "TIASurface.hxx" +#include "MinUICommandDialog.hxx" + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +MinUICommandDialog::MinUICommandDialog(OSystem& osystem, DialogContainer& parent) + : Dialog(osystem, parent, osystem.frameBuffer().font(), "Commands") +{ + const int HBORDER = 10; + const int VBORDER = 10; + const int HGAP = 8; + const int VGAP = 5; + const int buttonWidth = _font.getStringWidth(" Load State 0") + 20, + buttonHeight = _font.getLineHeight() + 8, + rowHeight = buttonHeight + VGAP; + + // Set real dimensions + _w = 3 * (buttonWidth + 5) + HBORDER * 2; + _h = 6 * rowHeight - VGAP + VBORDER * 2 + _th; + ButtonWidget* bw = nullptr; + WidgetArray wid; + int xoffset = HBORDER, yoffset = VBORDER + _th; + + auto ADD_CD_BUTTON = [&](const string& label, int cmd) + { + ButtonWidget* b = new ButtonWidget(this, _font, xoffset, yoffset, + buttonWidth, buttonHeight, label, cmd); + yoffset += buttonHeight + VGAP; + return b; + }; + + // Column 1 + bw = ADD_CD_BUTTON("Select", kSelectCmd); + wid.push_back(bw); + bw = ADD_CD_BUTTON("Reset", kResetCmd); + wid.push_back(bw); + myColorButton = ADD_CD_BUTTON("", kColorCmd); + wid.push_back(myColorButton); + myLeftDiffButton = ADD_CD_BUTTON("", kLeftDiffCmd); + wid.push_back(myLeftDiffButton); + myRightDiffButton = ADD_CD_BUTTON("", kLeftDiffCmd); + wid.push_back(myRightDiffButton); + + // Column 2 + xoffset += buttonWidth + HGAP; + yoffset = VBORDER + _th; + + mySaveStateButton = ADD_CD_BUTTON("", kSaveStateCmd); + wid.push_back(mySaveStateButton); + myStateSlotButton = ADD_CD_BUTTON("", kStateSlotCmd); + wid.push_back(myStateSlotButton); + myLoadStateButton = ADD_CD_BUTTON("", kLoadStateCmd); + wid.push_back(myLoadStateButton); + bw = ADD_CD_BUTTON("Rewind", kRewindCmd); + wid.push_back(bw); + bw = ADD_CD_BUTTON("Unwind", kUnwindCmd); + wid.push_back(bw); + bw = ADD_CD_BUTTON("Close", kCloseCmd); + wid.push_back(bw); + + // Column 3 + xoffset += buttonWidth + HGAP; + yoffset = VBORDER + _th; + + myTVFormatButton = ADD_CD_BUTTON("", kFormatCmd); + wid.push_back(myTVFormatButton); + myStretchButton = ADD_CD_BUTTON("", kStretchCmd); + wid.push_back(myStretchButton); + myPhosphorButton = ADD_CD_BUTTON("", kPhosphorCmd); + wid.push_back(myPhosphorButton); + bw = ADD_CD_BUTTON("Settings"+ ELLIPSIS, kSettings); + wid.push_back(bw); + bw = ADD_CD_BUTTON("Exit Game", kExitGameCmd); + wid.push_back(bw); + + addToFocusList(wid); + + myStellaSettingsDialog = make_unique(osystem, parent, _font, + FBMinimum::Width, FBMinimum::Height); +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +void MinUICommandDialog::loadConfig() +{ + // Column 1 + myColorButton->setLabel(instance().console().switches().tvColor() ? "Color Mode" : "B/W Mode"); + myLeftDiffButton->setLabel(instance().console().switches().leftDifficultyA() ? "P1 Skill A" : "P1 Skill B"); + myRightDiffButton->setLabel(instance().console().switches().rightDifficultyA() ? "P2 Skill A" : "P2 Skill B"); + // Column 2 + updateSlot(instance().state().currentSlot()); + + // Column 3 + updateTVFormat(); + myStretchButton->setLabel(instance().settings().getBool("tia.fs_stretch") ? "Stretched" : "4:3 Format"); + myPhosphorButton->setLabel(instance().frameBuffer().tiaSurface().phosphorEnabled() ? "Phosphor On" : "Phosphor Off"); +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +void MinUICommandDialog::handleCommand(CommandSender* sender, int cmd, + int data, int id) +{ + bool consoleCmd = false, stateCmd = false; + Event::Type event = Event::NoType; + + switch(cmd) + { + // Column 1 + case kSelectCmd: + event = Event::ConsoleSelect; + consoleCmd = true; + break; + + case kResetCmd: + event = Event::ConsoleReset; + consoleCmd = true; + break; + + case kColorCmd: + event = Event::ConsoleColorToggle; + consoleCmd = true; + break; + + case kLeftDiffCmd: + event = Event::ConsoleLeftDiffToggle; + consoleCmd = true; + break; + + case kRightDiffCmd: + event = Event::ConsoleRightDiffToggle; + consoleCmd = true; + break; + + // Column 2 + case kSaveStateCmd: + event = Event::SaveState; + consoleCmd = true; + break; + + case kStateSlotCmd: + { + event = Event::ChangeState; + stateCmd = true; + int slot = (instance().state().currentSlot() + 1) % 10; + updateSlot(slot); + break; + } + case kLoadStateCmd: + event = Event::LoadState; + consoleCmd = true; + break; + + case kRewindCmd: + instance().state().toggleTimeMachine(); // TODO + break; + + case kUnwindCmd: + instance().state().toggleTimeMachine(); // TODO + break; + + case kCloseCmd: + instance().eventHandler().leaveMenuMode(); + break; + + // Column 3 + case kFormatCmd: + instance().console().toggleFormat(); + updateTVFormat(); + break; + + case kStretchCmd: + instance().settings().setValue("tia.fs_stretch", !instance().settings().getBool("tia.fs_stretch")); + instance().eventHandler().leaveMenuMode(); + break; + + case kPhosphorCmd: + instance().eventHandler().leaveMenuMode(); + instance().console().togglePhosphor(); + break; + + case kSettings: + { + // This dialog is resizable under certain conditions, so we need + // to re-create it as necessary + uInt32 w = 0, h = 0; + + if(myStellaSettingsDialog == nullptr || myStellaSettingsDialog->shouldResize(w, h)) + { + myStellaSettingsDialog = make_unique(instance(), parent(), + instance().frameBuffer().font(), w, h); + } + myStellaSettingsDialog->open(); + break; + } + + case kExitGameCmd: + instance().eventHandler().handleEvent(Event::LauncherMode); + break; + } + + // Console commands should be performed right away, after leaving the menu + // State commands require you to exit the menu manually + if(consoleCmd) + { + instance().eventHandler().leaveMenuMode(); + instance().eventHandler().handleEvent(event); + instance().console().switches().update(); + instance().console().tia().update(); + instance().eventHandler().handleEvent(event, false); + } + else if(stateCmd) + instance().eventHandler().handleEvent(event); +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +void MinUICommandDialog::updateSlot(int slot) +{ + ostringstream buf; + buf << " " << slot; + + mySaveStateButton->setLabel("Save State" + buf.str()); + myStateSlotButton->setLabel("State Slot" + buf.str()); + myLoadStateButton->setLabel("Load State" + buf.str()); +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +void MinUICommandDialog::updateTVFormat() +{ + myTVFormatButton->setLabel(instance().console().getFormatString() + " Mode"); +} diff --git a/src/gui/MinUICommandDialog.hxx b/src/gui/MinUICommandDialog.hxx new file mode 100644 index 000000000..e95553ee6 --- /dev/null +++ b/src/gui/MinUICommandDialog.hxx @@ -0,0 +1,87 @@ +//============================================================================ +// +// 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 MIN_UI_COMMAND_DIALOG_HXX +#define MIN_UI_COMMAND_DIALOG_HXX + +class Properties; +class CommandSender; +class DialogContainer; +class OSystem; + +#include "Dialog.hxx" + +class MinUICommandDialog : public Dialog +{ + public: + MinUICommandDialog(OSystem& osystem, DialogContainer& parent); + virtual ~MinUICommandDialog() = default; + + protected: + void loadConfig() override; + void handleCommand(CommandSender* sender, int cmd, int data, int id) override; + void updateSlot(int slot); + void updateTVFormat(); + + // column 0 + ButtonWidget* myColorButton; + ButtonWidget* myLeftDiffButton; + ButtonWidget* myRightDiffButton; + // column 1 + ButtonWidget* mySaveStateButton; + ButtonWidget* myStateSlotButton; + ButtonWidget* myLoadStateButton; + ButtonWidget* myRewindButton; + ButtonWidget* myUnwindButton; + // column 2 + ButtonWidget* myTVFormatButton; + ButtonWidget* myStretchButton; + ButtonWidget* myPhosphorButton; + + unique_ptr myStellaSettingsDialog; + + enum + { + kSelectCmd = 'Csel', + kResetCmd = 'Cres', + kColorCmd = 'Ccol', + kLeftDiffCmd = 'Cldf', + kRightDiffCmd = 'Crdf', + kSaveStateCmd = 'Csst', + kStateSlotCmd = 'Ccst', + kLoadStateCmd = 'Clst', + kSnapshotCmd = 'Csnp', + kRewindCmd = 'Crew', + kUnwindCmd = 'Cunw', + kFormatCmd = 'Cfmt', + kStretchCmd = 'Cstr', + kPhosphorCmd = 'Cpho', + kSettings = 'Cscn', + kExitGameCmd = 'Cext', + kCloseCmd = 'Ccls' + }; + + private: + // Following constructors and assignment operators not supported + MinUICommandDialog() = delete; + MinUICommandDialog(const MinUICommandDialog&) = delete; + MinUICommandDialog(MinUICommandDialog&&) = delete; + MinUICommandDialog& operator=(const MinUICommandDialog&) = delete; + MinUICommandDialog& operator=(MinUICommandDialog&&) = delete; +}; + +#endif diff --git a/src/gui/StellaSettingsDialog.cxx b/src/gui/StellaSettingsDialog.cxx index bf52a908d..468d3e324 100644 --- a/src/gui/StellaSettingsDialog.cxx +++ b/src/gui/StellaSettingsDialog.cxx @@ -30,19 +30,19 @@ StellaSettingsDialog::StellaSettingsDialog(OSystem& osystem, DialogContainer& pa const GUI::Font& font, int max_w, int max_h) : Dialog(osystem, parent, font, "Stella settings") { - const int VGAP = 4; const int VBORDER = 8; const int HBORDER = 10; const int INDENT = 20; const int lineHeight = font.getLineHeight(), fontWidth = font.getMaxCharWidth(); + const int VGAP = 5; int xpos, ypos; WidgetArray wid; VariantList items; // Set real dimensions - setSize(33 * fontWidth + HBORDER * 2, 15 * (lineHeight + VGAP) + _th, max_w, max_h); + setSize(33 * fontWidth + HBORDER * 2, 13 * (lineHeight + VGAP) + VGAP * 8 + 6 + _th, max_w, max_h); xpos = HBORDER; ypos = VBORDER + _th; @@ -321,6 +321,7 @@ void StellaSettingsDialog::loadControllerProperties(const Properties& props) switch (instance().eventHandler().state()) { case EventHandlerState::OPTIONSMENU: // game is running! + case EventHandlerState::CMDMENU: // game is running! enable = true; break; case EventHandlerState::LAUNCHER: diff --git a/src/gui/module.mk b/src/gui/module.mk index 466ad3670..68bf66af8 100644 --- a/src/gui/module.mk +++ b/src/gui/module.mk @@ -31,6 +31,7 @@ MODULE_OBJS := \ src/gui/LoggerDialog.o \ src/gui/Menu.o \ src/gui/MessageBox.o \ + src/gui/MinUICommandDialog.o\ src/gui/OptionsDialog.o \ src/gui/PopUpWidget.o \ src/gui/ProgressDialog.o \ diff --git a/src/windows/Stella.vcxproj b/src/windows/Stella.vcxproj index 49f4672bf..39a8f8db1 100644 --- a/src/windows/Stella.vcxproj +++ b/src/windows/Stella.vcxproj @@ -501,6 +501,7 @@ + @@ -1220,6 +1221,7 @@ + diff --git a/src/windows/Stella.vcxproj.filters b/src/windows/Stella.vcxproj.filters index 679abdc30..632cfb678 100644 --- a/src/windows/Stella.vcxproj.filters +++ b/src/windows/Stella.vcxproj.filters @@ -960,6 +960,9 @@ Source Files\gui + + Source Files\gui + @@ -1964,6 +1967,9 @@ Header Files\emucore + + Header Files\gui +