controller bindings for load and save state

Issue #615
This commit is contained in:
Flyinghead 2023-02-28 20:21:29 +01:00
parent 885a0508c0
commit 803f4cd298
5 changed files with 61 additions and 3 deletions

View File

@ -47,6 +47,8 @@ enum DreamcastKey
EMU_BTN_FFORWARD,
EMU_BTN_ESCAPE,
EMU_BTN_INSERT_CARD,
EMU_BTN_LOADSTATE,
EMU_BTN_SAVESTATE,
// Real axes
DC_AXIS_TRIGGERS = 0x1000000,

View File

@ -91,6 +91,14 @@ bool GamepadDevice::handleButtonInput(int port, DreamcastKey key, bool pressed)
if (pressed && settings.platform.isNaomi())
card_reader::insertCard();
break;
case EMU_BTN_LOADSTATE:
if (pressed)
gui_loadState();
break;
case EMU_BTN_SAVESTATE:
if (pressed)
gui_saveState();
break;
case DC_AXIS_LT:
if (port >= 0)
lt[port] = pressed ? 255 : 0;

View File

@ -56,6 +56,8 @@ button_list[] =
{ DC_AXIS_RIGHT, "compat", "btn_analog_right" },
{ DC_BTN_RELOAD, "dreamcast", "reload" },
{ EMU_BTN_INSERT_CARD, "emulator", "insert_card" },
{ EMU_BTN_LOADSTATE, "emulator", "btn_jump_state" },
{ EMU_BTN_SAVESTATE, "emulator", "btn_quick_save" },
};
static struct

View File

@ -517,6 +517,11 @@ void gui_stop_game(const std::string& message)
}
}
static bool savestateAllowed()
{
return !settings.content.path.empty() && !settings.network.online && !settings.naomi.multiboard;
}
static void gui_display_commands()
{
imguiDriver->displayVmus();
@ -527,10 +532,10 @@ static void gui_display_commands()
ImGui::Begin("##commands", NULL, ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoMove | ImGuiWindowFlags_AlwaysAutoResize);
{
DisabledScope scope(settings.content.path.empty() || settings.network.online || settings.naomi.multiboard);
DisabledScope scope(!savestateAllowed());
// Load State
if (ImGui::Button("Load State", ScaledVec2(110, 50)) && !scope.isDisabled())
if (ImGui::Button("Load State", ScaledVec2(110, 50)) && savestateAllowed())
{
gui_state = GuiState::Closed;
dc_loadstate(config::SavestateSlot);
@ -554,7 +559,7 @@ static void gui_display_commands()
ImGui::SameLine();
// Save State
if (ImGui::Button("Save State", ScaledVec2(110, 50)) && !scope.isDisabled())
if (ImGui::Button("Save State", ScaledVec2(110, 50)) && savestateAllowed())
{
gui_state = GuiState::Closed;
dc_savestate(config::SavestateSlot);
@ -727,6 +732,8 @@ const Mapping dcButtons[] = {
{ EMU_BTN_MENU, "Menu" },
{ EMU_BTN_ESCAPE, "Exit" },
{ EMU_BTN_FFORWARD, "Fast-forward" },
{ EMU_BTN_LOADSTATE, "Load State" },
{ EMU_BTN_SAVESTATE, "Save State" },
{ EMU_BTN_NONE, nullptr }
};
@ -774,6 +781,8 @@ const Mapping arcadeButtons[] = {
{ EMU_BTN_MENU, "Menu" },
{ EMU_BTN_ESCAPE, "Exit" },
{ EMU_BTN_FFORWARD, "Fast-forward" },
{ EMU_BTN_LOADSTATE, "Load State" },
{ EMU_BTN_SAVESTATE, "Save State" },
{ EMU_BTN_INSERT_CARD, "Insert Card" },
{ EMU_BTN_NONE, nullptr }
@ -1034,6 +1043,10 @@ static void controller_mapping_popup(const std::shared_ptr<GamepadDevice>& gamep
const char* items[] = { "Dreamcast Controls", "Arcade Controls" };
if (last_item_current_map_idx == 2 && game_started)
// Select the right mappings for the current game
item_current_map_idx = settings.platform.isArcade() ? 1 : 0;
// Here our selection data is an index.
ImGui::SetNextItemWidth(comboWidth);
@ -2998,6 +3011,37 @@ void gui_save()
boxart.saveDatabase();
}
void gui_loadState()
{
const LockGuard lock(guiMutex);
if (gui_state == GuiState::Closed && savestateAllowed())
{
try {
emu.stop();
dc_loadstate(config::SavestateSlot);
emu.start();
} catch (const FlycastException& e) {
gui_stop_game(e.what());
}
}
}
void gui_saveState()
{
const LockGuard lock(guiMutex);
if (gui_state == GuiState::Closed && savestateAllowed())
{
try {
emu.stop();
dc_savestate(config::SavestateSlot);
emu.start();
} catch (const FlycastException& e) {
gui_stop_game(e.what());
}
}
}
#ifdef TARGET_UWP
// Ugly but a good workaround for MS stupidity
// UWP doesn't allow the UI thread to wait on a thread/task. When an std::future is ready, it is possible

View File

@ -48,6 +48,8 @@ void gui_start_game(const std::string& path);
void gui_error(const std::string& what);
void gui_setOnScreenKeyboardCallback(void (*callback)(bool show));
void gui_save();
void gui_loadState();
void gui_saveState();
enum class GuiState {
Closed,