Skip to content

Commit

Permalink
enhancement: added Delete save states button
Browse files Browse the repository at this point in the history
- Refactored the existing Load/Save to indicate they perform their action based on the selected slot
- Added a new Delete State slot button, to help clean up unwanted save states easier
- Added confirmation dialog before deleting
  • Loading branch information
midwan committed Jan 8, 2025
1 parent e4ead70 commit cdc90e9
Show file tree
Hide file tree
Showing 2 changed files with 84 additions and 34 deletions.
7 changes: 4 additions & 3 deletions src/osdep/gui/Navigation.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -578,9 +578,10 @@ static NavigationMap nav_map[] =
{ "State11", "Savestates", "Savestates", "State10", "State12" },
{ "State12", "Savestates", "Savestates", "State11", "State13" },
{ "State13", "Savestates", "Savestates", "State12", "State14" },
{ "State14", "Savestates", "Savestates", "State13", "cmdLoadState" },
{ "cmdLoadState", "Savestates", "cmdSaveState", "State14", "State0" },
{ "cmdSaveState", "cmdLoadState", "Savestates", "State14", "State0" },
{ "State14", "Savestates", "Savestates", "State13", "cmdLoadStateSlot" },
{ "cmdLoadStateSlot", "Savestates", "cmdSaveStateSlot", "State14", "State0" },
{ "cmdSaveStateSlot", "cmdLoadStateSlot", "cmdDeleteStateSlot", "State14", "State0" },
{ "cmdDeleteStateSlot", "cmdSaveStateSlot", "Savestates", "State14", "State0" },

// Virtual Keyboard
{ "chkVkEnabled", "Virtual Keyboard", "Virtual Keyboard", "chkRetroArchVkbd", "chkVkHires"},
Expand Down
111 changes: 80 additions & 31 deletions src/osdep/gui/PanelSavestate.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,13 +18,15 @@ int current_state_num = 0;

static gcn::Window* grpNumber;
static std::vector<gcn::RadioButton*> radioButtons(15);
static gcn::Label* lblFilename;
static gcn::Label* lblTimestamp;

static gcn::Window* grpScreenshot;
static gcn::Icon* icoSavestate = nullptr;
static gcn::Image* imgSavestate = nullptr;
static gcn::Button* cmdLoadState;
static gcn::Button* cmdSaveState;
static gcn::Button* cmdLoadStateSlot;
static gcn::Button* cmdSaveStateSlot;
static gcn::Button* cmdDeleteStateSlot;

static std::string get_file_timestamp(const TCHAR* filename)
{
Expand Down Expand Up @@ -52,10 +54,10 @@ class SavestateActionListener : public gcn::ActionListener
{
current_state_num = static_cast<int>(std::distance(radioButtons.begin(), it));
}
else if (actionEvent.getSource() == cmdLoadState)
else if (actionEvent.getSource() == cmdLoadStateSlot)
{
//------------------------------------------
// Load state
// Load state from selected slot
//------------------------------------------
if (emulating)
{
Expand All @@ -80,9 +82,9 @@ class SavestateActionListener : public gcn::ActionListener
ShowMessage("Loading savestate", "Emulation hasn't started yet.", "", "", "Ok", "");
}

cmdLoadState->requestFocus();
cmdLoadStateSlot->requestFocus();
}
else if (actionEvent.getSource() == cmdSaveState)
else if (actionEvent.getSource() == cmdSaveStateSlot)
{
bool unsafe = false;
bool unsafe_confirmed = false;
Expand All @@ -100,7 +102,7 @@ class SavestateActionListener : public gcn::ActionListener
unsafe_confirmed = ShowMessage("Warning: JIT detected", "JIT is enabled. Savestates might be unsafe! Proceed anyway?", "", "", "Proceed", "Cancel");
}
//------------------------------------------
// Save current state
// Save current state to selected slot
//------------------------------------------
if (emulating)
{
Expand All @@ -117,7 +119,36 @@ class SavestateActionListener : public gcn::ActionListener
ShowMessage("Saving state", "Emulation hasn't started yet.", "", "", "Ok", "");
}

cmdSaveState->requestFocus();
cmdSaveStateSlot->requestFocus();
}
else if (actionEvent.getSource() == cmdDeleteStateSlot)
{
//------------------------------------------
// Delete state from selected slot
//------------------------------------------
if (strlen(savestate_fname) > 0)
{
if (ShowMessage("Delete savestate", "Do you really want to delete the statefile?", "This will also delete the corresponding screenshot.", "", "Yes", "No"))
{
if (remove(savestate_fname) == 0)
{
if (!screenshot_filename.empty())
{
remove(screenshot_filename.c_str());
}
RefreshPanelSavestate();
}
else
{
ShowMessage("Delete savestate", "Failed to delete statefile.", "", "", "Ok", "");
}
}
}
else
{
ShowMessage("Delete savestate", "No statefile selected.", "", "", "Ok", "");
}
cmdDeleteStateSlot->requestFocus();
}

RefreshPanelSavestate();
Expand All @@ -139,6 +170,7 @@ void InitPanelSavestate(const config_category& category)
radioButtons[i]->addActionListener(savestateActionListener);
}

lblFilename = new gcn::Label("Filename: ");
lblTimestamp = new gcn::Label("Thu Aug 23 14:55:02 2001");

grpNumber = new gcn::Window("Slot");
Expand All @@ -160,26 +192,36 @@ void InitPanelSavestate(const config_category& category)
grpScreenshot->setBaseColor(gui_base_color);
grpScreenshot->setForegroundColor(gui_foreground_color);

cmdLoadState = new gcn::Button("Load State");
cmdLoadState->setSize(BUTTON_WIDTH + 10, BUTTON_HEIGHT);
cmdLoadState->setBaseColor(gui_base_color);
cmdLoadState->setForegroundColor(gui_foreground_color);
cmdLoadState->setId("cmdLoadState");
cmdLoadState->addActionListener(savestateActionListener);

cmdSaveState = new gcn::Button("Save State");
cmdSaveState->setSize(BUTTON_WIDTH + 10, BUTTON_HEIGHT);
cmdSaveState->setBaseColor(gui_base_color);
cmdSaveState->setForegroundColor(gui_foreground_color);
cmdSaveState->setId("cmdSaveState");
cmdSaveState->addActionListener(savestateActionListener);
cmdLoadStateSlot = new gcn::Button("Load from Slot");
cmdLoadStateSlot->setSize(BUTTON_WIDTH + 35, BUTTON_HEIGHT);
cmdLoadStateSlot->setBaseColor(gui_base_color);
cmdLoadStateSlot->setForegroundColor(gui_foreground_color);
cmdLoadStateSlot->setId("cmdLoadStateSlot");
cmdLoadStateSlot->addActionListener(savestateActionListener);

cmdSaveStateSlot = new gcn::Button("Save to Slot");
cmdSaveStateSlot->setSize(BUTTON_WIDTH + 35, BUTTON_HEIGHT);
cmdSaveStateSlot->setBaseColor(gui_base_color);
cmdSaveStateSlot->setForegroundColor(gui_foreground_color);
cmdSaveStateSlot->setId("cmdSaveStateSlot");
cmdSaveStateSlot->addActionListener(savestateActionListener);

cmdDeleteStateSlot = new gcn::Button("Delete Slot");
cmdDeleteStateSlot->setSize(BUTTON_WIDTH + 35, BUTTON_HEIGHT);
cmdDeleteStateSlot->setBaseColor(gui_base_color);
cmdDeleteStateSlot->setForegroundColor(gui_foreground_color);
cmdDeleteStateSlot->setId("cmdDeleteStateSlot");
cmdDeleteStateSlot->addActionListener(savestateActionListener);

category.panel->add(grpNumber, DISTANCE_BORDER, DISTANCE_BORDER);
category.panel->add(grpScreenshot, grpNumber->getX() + grpNumber->getWidth() + DISTANCE_NEXT_X, DISTANCE_BORDER);
category.panel->add(lblTimestamp, grpScreenshot->getX(), grpScreenshot->getY() + grpScreenshot->getHeight() + DISTANCE_NEXT_Y);
category.panel->add(lblFilename, grpScreenshot->getX(), grpScreenshot->getY() + grpScreenshot->getHeight() + DISTANCE_NEXT_Y);
category.panel->add(lblTimestamp, grpScreenshot->getX(), lblFilename->getY() + lblFilename->getHeight() + DISTANCE_NEXT_Y);

pos_y = lblTimestamp->getY() + lblTimestamp->getHeight() + DISTANCE_NEXT_Y;
category.panel->add(cmdLoadState, grpScreenshot->getX(), pos_y);
category.panel->add(cmdSaveState, cmdLoadState->getX() + cmdLoadState->getWidth() + DISTANCE_NEXT_X, pos_y);
category.panel->add(cmdLoadStateSlot, grpScreenshot->getX(), pos_y);
category.panel->add(cmdSaveStateSlot, cmdLoadStateSlot->getX() + cmdLoadStateSlot->getWidth() + DISTANCE_NEXT_X, pos_y);
category.panel->add(cmdDeleteStateSlot, cmdSaveStateSlot->getX() + cmdSaveStateSlot->getWidth() + DISTANCE_NEXT_X, pos_y);

RefreshPanelSavestate();
}
Expand All @@ -190,6 +232,7 @@ void ExitPanelSavestate()
delete radioButton;
}
delete grpNumber;
delete lblFilename;
delete lblTimestamp;

delete imgSavestate;
Expand All @@ -198,8 +241,9 @@ void ExitPanelSavestate()
icoSavestate = nullptr;
delete grpScreenshot;

delete cmdLoadState;
delete cmdSaveState;
delete cmdLoadStateSlot;
delete cmdSaveStateSlot;
delete cmdDeleteStateSlot;

delete savestateActionListener;
}
Expand Down Expand Up @@ -229,6 +273,7 @@ void RefreshPanelSavestate()
auto* const f = fopen(savestate_fname, "rbe");
if (f) {
fclose(f);
lblFilename->setCaption("Filename: " + extract_filename(std::string(savestate_fname)));
lblTimestamp->setCaption(get_file_timestamp(savestate_fname));

if (!screenshot_filename.empty())
Expand Down Expand Up @@ -258,22 +303,26 @@ void RefreshPanelSavestate()
}
else
{
lblTimestamp->setCaption("No savestate found: " + extract_filename(std::string(savestate_fname)));
lblFilename->setCaption("No savestate found:");
lblTimestamp->setCaption(extract_filename(std::string(savestate_fname)));
}
}
else
{
lblTimestamp->setCaption("No savestate loaded");
lblFilename->setCaption("No savestate loaded");
lblTimestamp->setCaption("");
}
lblFilename->adjustSize();
lblTimestamp->adjustSize();

for (const auto& radioButton : radioButtons) {
radioButton->setEnabled(true);
}

grpScreenshot->setVisible(true);
cmdLoadState->setEnabled(strlen(savestate_fname) > 0);
cmdSaveState->setEnabled(strlen(savestate_fname) > 0);
cmdLoadStateSlot->setEnabled(strlen(savestate_fname) > 0);
cmdSaveStateSlot->setEnabled(strlen(savestate_fname) > 0);
cmdDeleteStateSlot->setEnabled(strlen(savestate_fname) > 0);
}

bool HelpPanelSavestate(std::vector<std::string>& helptext)
Expand All @@ -286,7 +335,7 @@ bool HelpPanelSavestate(std::vector<std::string>& helptext)
helptext.emplace_back("fail when the JIT/PPC/RTG emulation options are enabled.");
helptext.emplace_back(" ");
helptext.emplace_back("Savestates are stored in a .uss file, with the name being that of the currently loaded");
helptext.emplace_back("floppy disk image or whdload.lha file, or the name of the loaded HDD .uae config.");
helptext.emplace_back("floppy disk image or whdload .lha file, or the name of the loaded HDD .uae config.");
helptext.emplace_back(" ");
helptext.emplace_back("For more information about Savestates, please read the related Amiberry Wiki page.");
helptext.emplace_back(" ");
Expand Down

0 comments on commit cdc90e9

Please sign in to comment.