Skip to content

Commit

Permalink
enhancement: add more features in Savestates panel
Browse files Browse the repository at this point in the history
- Added buttons for loading and saving a custom (non-slot related) save state.
- Updated logic to save the corresponding screenshot based on the selected filename.
- When using custom filenames, no slot is selected. If you select a slot manually, the filename is reset to the default for that slot instead.
  • Loading branch information
midwan committed Jan 8, 2025
1 parent cdc90e9 commit 6aaa82c
Show file tree
Hide file tree
Showing 4 changed files with 128 additions and 43 deletions.
23 changes: 19 additions & 4 deletions src/osdep/amiberry_gui.cpp
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
#include <algorithm>
#include <cstdio>
#include <strings.h>
#include <cstring>
Expand Down Expand Up @@ -313,8 +314,7 @@ static struct romdata* scan_single_rom_2(struct zfile* f)
if (!memcmp(buffer, "KICK", 4))
{
zfile_fseek(f, 512, SEEK_SET);
if (size > 262144)
size = 262144;
size = std::min(size, 262144);
}
else if (!memcmp(buffer, "AMIROMTYPE1", 11))
{
Expand Down Expand Up @@ -814,7 +814,7 @@ void disk_selection(const int shortcut, uae_prefs* prefs)
}
else if (shortcut == 4)
{
// Load Save state
// Load a Save state
TCHAR tmp[MAX_DPATH];
get_savestate_path(tmp, sizeof tmp / sizeof(TCHAR));

Expand All @@ -824,14 +824,20 @@ void disk_selection(const int shortcut, uae_prefs* prefs)
_tcscpy(savestate_fname, selected.c_str());
savestate_initsave(savestate_fname, 1, true, true);
savestate_state = STATE_DORESTORE;

const auto filename = extract_filename(savestate_fname);
screenshot_filename = get_screenshot_path();
screenshot_filename += filename;
screenshot_filename = remove_file_extension(screenshot_filename);
screenshot_filename += ".png";
}
else {
savestate_fname[0] = 0;
}
}
else if (shortcut == 5)
{
// Save state
// Save a state
TCHAR tmp[MAX_DPATH];
get_savestate_path(tmp, sizeof tmp / sizeof(TCHAR));

Expand All @@ -848,7 +854,14 @@ void disk_selection(const int shortcut, uae_prefs* prefs)
_tcscat(tmp, savestate_fname);
save_state(savestate_fname, _T("Description!"));
if (create_screenshot())
{
const auto filename = extract_filename(savestate_fname);
screenshot_filename = get_screenshot_path();
screenshot_filename += filename;
screenshot_filename = remove_file_extension(screenshot_filename);
screenshot_filename += ".png";
save_thumb(screenshot_filename);
}
}
}
// Select CD Image
Expand Down Expand Up @@ -975,6 +988,8 @@ void gui_purge_events()

void gui_update()
{
if (current_state_num == 99) return;

std::string filename;
const std::string suffix = current_state_num >= 1 && current_state_num <= 14 ?
"-" + std::to_string(current_state_num) : "";
Expand Down
8 changes: 5 additions & 3 deletions src/osdep/gui/Navigation.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -579,9 +579,11 @@ static NavigationMap nav_map[] =
{ "State12", "Savestates", "Savestates", "State11", "State13" },
{ "State13", "Savestates", "Savestates", "State12", "State14" },
{ "State14", "Savestates", "Savestates", "State13", "cmdLoadStateSlot" },
{ "cmdLoadStateSlot", "Savestates", "cmdSaveStateSlot", "State14", "State0" },
{ "cmdSaveStateSlot", "cmdLoadStateSlot", "cmdDeleteStateSlot", "State14", "State0" },
{ "cmdDeleteStateSlot", "cmdSaveStateSlot", "Savestates", "State14", "State0" },
{ "cmdLoadStateSlot", "Savestates", "cmdSaveStateSlot", "State14", "cmdLoadState" },
{ "cmdSaveStateSlot", "cmdLoadStateSlot", "cmdDeleteStateSlot", "State14", "cmdSaveState" },
{ "cmdDeleteStateSlot", "cmdSaveStateSlot", "Savestates", "State14", "cmdSaveState" },
{ "cmdLoadState", "Savestates", "cmdSaveState", "cmdLoadStateSlot", "State0" },
{ "cmdSaveState", "cmdLoadState", "Savestates", "cmdSaveStateSlot", "State0" },

// Virtual Keyboard
{ "chkVkEnabled", "Virtual Keyboard", "Virtual Keyboard", "chkRetroArchVkbd", "chkVkHires"},
Expand Down
139 changes: 103 additions & 36 deletions src/osdep/gui/PanelSavestate.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
int current_state_num = 0;

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

Expand All @@ -27,6 +27,8 @@ static gcn::Image* imgSavestate = nullptr;
static gcn::Button* cmdLoadStateSlot;
static gcn::Button* cmdSaveStateSlot;
static gcn::Button* cmdDeleteStateSlot;
static gcn::Button* cmdLoadState;
static gcn::Button* cmdSaveState;

static std::string get_file_timestamp(const TCHAR* filename)
{
Expand All @@ -49,12 +51,18 @@ class SavestateActionListener : public gcn::ActionListener
public:
void action(const gcn::ActionEvent& actionEvent) override
{
const auto it = std::find(radioButtons.begin(), radioButtons.end(), actionEvent.getSource());
if (it != radioButtons.end())
const auto action = actionEvent.getSource();

for (int i = 0; i < 15; ++i)
{
current_state_num = static_cast<int>(std::distance(radioButtons.begin(), it));
if (action == optStateSlot[i])
{
current_state_num = i;
break;
}
}
else if (actionEvent.getSource() == cmdLoadStateSlot)

if (action == cmdLoadStateSlot)
{
//------------------------------------------
// Load state from selected slot
Expand Down Expand Up @@ -84,28 +92,29 @@ class SavestateActionListener : public gcn::ActionListener

cmdLoadStateSlot->requestFocus();
}
else if (actionEvent.getSource() == cmdSaveStateSlot)
else if (action == cmdSaveStateSlot)
{
bool unsafe = false;
bool unsafe_confirmed = false;
const AmigaMonitor* mon = &AMonitors[0];
// Check if we have RTG, then it might fail saving
if (mon->screen_is_picasso)
{
unsafe = true;
unsafe_confirmed = ShowMessage("Warning: P96 detected", "P96 is enabled. Savestates might be unsafe! Proceed anyway?", "", "", "Proceed", "Cancel");
}
// Check if we have JIT enabled
if (changed_prefs.cachesize > 0)
{
unsafe = true;
unsafe_confirmed = ShowMessage("Warning: JIT detected", "JIT is enabled. Savestates might be unsafe! Proceed anyway?", "", "", "Proceed", "Cancel");
}
//------------------------------------------
// Save current state to selected slot
//------------------------------------------
if (emulating)
{
bool unsafe = false;
bool unsafe_confirmed = false;
const AmigaMonitor* mon = &AMonitors[0];
// Check if we have RTG, then it might fail saving
if (mon->screen_is_picasso)
{
unsafe = true;
unsafe_confirmed = ShowMessage("Warning: P96 detected", "P96 is enabled. Savestates might be unsafe! Proceed anyway?", "", "", "Proceed", "Cancel");
}
// Check if we have JIT enabled
if (changed_prefs.cachesize > 0)
{
unsafe = true;
unsafe_confirmed = ShowMessage("Warning: JIT detected", "JIT is enabled. Savestates might be unsafe! Proceed anyway?", "", "", "Proceed", "Cancel");
}

if (!unsafe || unsafe_confirmed)
{
savestate_initsave(savestate_fname, 1, true, true);
Expand All @@ -121,7 +130,7 @@ class SavestateActionListener : public gcn::ActionListener

cmdSaveStateSlot->requestFocus();
}
else if (actionEvent.getSource() == cmdDeleteStateSlot)
else if (action == cmdDeleteStateSlot)
{
//------------------------------------------
// Delete state from selected slot
Expand Down Expand Up @@ -150,6 +159,42 @@ class SavestateActionListener : public gcn::ActionListener
}
cmdDeleteStateSlot->requestFocus();
}
else if (action == cmdLoadState)
{
// Load state from file
disk_selection(4, &changed_prefs);
current_state_num = 99; // Set it to something invalid, so no slot is selected
}
else if (action == cmdSaveState)
{
// Save current state to file
if (emulating)
{
bool unsafe = false;
bool unsafe_confirmed = false;
const AmigaMonitor* mon = &AMonitors[0];
// Check if we have RTG, then it might fail saving
if (mon->screen_is_picasso)
{
unsafe = true;
unsafe_confirmed = ShowMessage("Warning: P96 detected", "P96 is enabled. Savestates might be unsafe! Proceed anyway?", "", "", "Proceed", "Cancel");
}
// Check if we have JIT enabled
if (changed_prefs.cachesize > 0)
{
unsafe = true;
unsafe_confirmed = ShowMessage("Warning: JIT detected", "JIT is enabled. Savestates might be unsafe! Proceed anyway?", "", "", "Proceed", "Cancel");
}
if (!unsafe || unsafe_confirmed)
{
disk_selection(5, &changed_prefs);
}
}
else
{
ShowMessage("Saving state", "Emulation hasn't started yet.", "", "", "Ok", "");
}
}

RefreshPanelSavestate();
}
Expand All @@ -162,20 +207,20 @@ void InitPanelSavestate(const config_category& category)
savestateActionListener = new SavestateActionListener();

for (int i = 0; i < 15; ++i) {
radioButtons[i] = new gcn::RadioButton(std::to_string(i), "radiostategroup");
radioButtons[i]->setId("State" + std::to_string(i));
radioButtons[i]->setBaseColor(gui_base_color);
radioButtons[i]->setBackgroundColor(gui_background_color);
radioButtons[i]->setForegroundColor(gui_foreground_color);
radioButtons[i]->addActionListener(savestateActionListener);
optStateSlot[i] = new gcn::RadioButton(std::to_string(i), "radiostategroup");
optStateSlot[i]->setId("State" + std::to_string(i));
optStateSlot[i]->setBaseColor(gui_base_color);
optStateSlot[i]->setBackgroundColor(gui_background_color);
optStateSlot[i]->setForegroundColor(gui_foreground_color);
optStateSlot[i]->addActionListener(savestateActionListener);
}

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

grpNumber = new gcn::Window("Slot");
int pos_y = 10;
for (const auto& radioButton : radioButtons) {
for (const auto& radioButton : optStateSlot) {
grpNumber->add(radioButton, 10, pos_y);
pos_y += radioButton->getHeight() + DISTANCE_NEXT_Y;
}
Expand Down Expand Up @@ -213,6 +258,20 @@ void InitPanelSavestate(const config_category& category)
cmdDeleteStateSlot->setId("cmdDeleteStateSlot");
cmdDeleteStateSlot->addActionListener(savestateActionListener);

cmdLoadState = new gcn::Button("Load state...");
cmdLoadState->setSize(BUTTON_WIDTH + 35, 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 + 35, BUTTON_HEIGHT);
cmdSaveState->setBaseColor(gui_base_color);
cmdSaveState->setForegroundColor(gui_foreground_color);
cmdSaveState->setId("cmdSaveState");
cmdSaveState->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(lblFilename, grpScreenshot->getX(), grpScreenshot->getY() + grpScreenshot->getHeight() + DISTANCE_NEXT_Y);
Expand All @@ -223,12 +282,16 @@ void InitPanelSavestate(const config_category& category)
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);

pos_y = cmdLoadStateSlot->getY() + cmdLoadStateSlot->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);

RefreshPanelSavestate();
}

void ExitPanelSavestate()
{
for (const auto& radioButton : radioButtons) {
for (const auto& radioButton : optStateSlot) {
delete radioButton;
}
delete grpNumber;
Expand All @@ -244,6 +307,8 @@ void ExitPanelSavestate()
delete cmdLoadStateSlot;
delete cmdSaveStateSlot;
delete cmdDeleteStateSlot;
delete cmdLoadState;
delete cmdSaveState;

delete savestateActionListener;
}
Expand All @@ -262,8 +327,14 @@ void RefreshPanelSavestate()
imgSavestate = nullptr;
}

if (current_state_num >= 0 && current_state_num < static_cast<int>(radioButtons.size())) {
radioButtons[current_state_num]->setSelected(true);
if (current_state_num >= 0 && current_state_num < static_cast<int>(optStateSlot.size())) {
optStateSlot[current_state_num]->setSelected(true);
}
else
{
for (const auto& radio_button : optStateSlot) {
radio_button->setSelected(false);
}
}

gui_update();
Expand Down Expand Up @@ -315,10 +386,6 @@ void RefreshPanelSavestate()
lblFilename->adjustSize();
lblTimestamp->adjustSize();

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

grpScreenshot->setVisible(true);
cmdLoadStateSlot->setEnabled(strlen(savestate_fname) > 0);
cmdSaveStateSlot->setEnabled(strlen(savestate_fname) > 0);
Expand Down
1 change: 1 addition & 0 deletions src/osdep/gui/gui_handling.h
Original file line number Diff line number Diff line change
Expand Up @@ -440,6 +440,7 @@ extern void apply_theme_extras();

extern void SetLastLoadedConfig(const char* filename);
extern void set_last_active_config(const char* filename);
extern void disk_selection(const int shortcut, uae_prefs* prefs);

extern void addromfiles(UAEREG* fkey, gcn::DropDown* d, const TCHAR* path, int type1, int type2);

Expand Down

0 comments on commit 6aaa82c

Please sign in to comment.