parent
885a0508c0
commit
803f4cd298
|
@ -47,6 +47,8 @@ enum DreamcastKey
|
||||||
EMU_BTN_FFORWARD,
|
EMU_BTN_FFORWARD,
|
||||||
EMU_BTN_ESCAPE,
|
EMU_BTN_ESCAPE,
|
||||||
EMU_BTN_INSERT_CARD,
|
EMU_BTN_INSERT_CARD,
|
||||||
|
EMU_BTN_LOADSTATE,
|
||||||
|
EMU_BTN_SAVESTATE,
|
||||||
|
|
||||||
// Real axes
|
// Real axes
|
||||||
DC_AXIS_TRIGGERS = 0x1000000,
|
DC_AXIS_TRIGGERS = 0x1000000,
|
||||||
|
|
|
@ -91,6 +91,14 @@ bool GamepadDevice::handleButtonInput(int port, DreamcastKey key, bool pressed)
|
||||||
if (pressed && settings.platform.isNaomi())
|
if (pressed && settings.platform.isNaomi())
|
||||||
card_reader::insertCard();
|
card_reader::insertCard();
|
||||||
break;
|
break;
|
||||||
|
case EMU_BTN_LOADSTATE:
|
||||||
|
if (pressed)
|
||||||
|
gui_loadState();
|
||||||
|
break;
|
||||||
|
case EMU_BTN_SAVESTATE:
|
||||||
|
if (pressed)
|
||||||
|
gui_saveState();
|
||||||
|
break;
|
||||||
case DC_AXIS_LT:
|
case DC_AXIS_LT:
|
||||||
if (port >= 0)
|
if (port >= 0)
|
||||||
lt[port] = pressed ? 255 : 0;
|
lt[port] = pressed ? 255 : 0;
|
||||||
|
|
|
@ -56,6 +56,8 @@ button_list[] =
|
||||||
{ DC_AXIS_RIGHT, "compat", "btn_analog_right" },
|
{ DC_AXIS_RIGHT, "compat", "btn_analog_right" },
|
||||||
{ DC_BTN_RELOAD, "dreamcast", "reload" },
|
{ DC_BTN_RELOAD, "dreamcast", "reload" },
|
||||||
{ EMU_BTN_INSERT_CARD, "emulator", "insert_card" },
|
{ EMU_BTN_INSERT_CARD, "emulator", "insert_card" },
|
||||||
|
{ EMU_BTN_LOADSTATE, "emulator", "btn_jump_state" },
|
||||||
|
{ EMU_BTN_SAVESTATE, "emulator", "btn_quick_save" },
|
||||||
};
|
};
|
||||||
|
|
||||||
static struct
|
static struct
|
||||||
|
|
|
@ -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()
|
static void gui_display_commands()
|
||||||
{
|
{
|
||||||
imguiDriver->displayVmus();
|
imguiDriver->displayVmus();
|
||||||
|
@ -527,10 +532,10 @@ static void gui_display_commands()
|
||||||
ImGui::Begin("##commands", NULL, ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoMove | ImGuiWindowFlags_AlwaysAutoResize);
|
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
|
// 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;
|
gui_state = GuiState::Closed;
|
||||||
dc_loadstate(config::SavestateSlot);
|
dc_loadstate(config::SavestateSlot);
|
||||||
|
@ -554,7 +559,7 @@ static void gui_display_commands()
|
||||||
ImGui::SameLine();
|
ImGui::SameLine();
|
||||||
|
|
||||||
// Save State
|
// 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;
|
gui_state = GuiState::Closed;
|
||||||
dc_savestate(config::SavestateSlot);
|
dc_savestate(config::SavestateSlot);
|
||||||
|
@ -727,6 +732,8 @@ const Mapping dcButtons[] = {
|
||||||
{ EMU_BTN_MENU, "Menu" },
|
{ EMU_BTN_MENU, "Menu" },
|
||||||
{ EMU_BTN_ESCAPE, "Exit" },
|
{ EMU_BTN_ESCAPE, "Exit" },
|
||||||
{ EMU_BTN_FFORWARD, "Fast-forward" },
|
{ EMU_BTN_FFORWARD, "Fast-forward" },
|
||||||
|
{ EMU_BTN_LOADSTATE, "Load State" },
|
||||||
|
{ EMU_BTN_SAVESTATE, "Save State" },
|
||||||
|
|
||||||
{ EMU_BTN_NONE, nullptr }
|
{ EMU_BTN_NONE, nullptr }
|
||||||
};
|
};
|
||||||
|
@ -774,6 +781,8 @@ const Mapping arcadeButtons[] = {
|
||||||
{ EMU_BTN_MENU, "Menu" },
|
{ EMU_BTN_MENU, "Menu" },
|
||||||
{ EMU_BTN_ESCAPE, "Exit" },
|
{ EMU_BTN_ESCAPE, "Exit" },
|
||||||
{ EMU_BTN_FFORWARD, "Fast-forward" },
|
{ EMU_BTN_FFORWARD, "Fast-forward" },
|
||||||
|
{ EMU_BTN_LOADSTATE, "Load State" },
|
||||||
|
{ EMU_BTN_SAVESTATE, "Save State" },
|
||||||
{ EMU_BTN_INSERT_CARD, "Insert Card" },
|
{ EMU_BTN_INSERT_CARD, "Insert Card" },
|
||||||
|
|
||||||
{ EMU_BTN_NONE, nullptr }
|
{ 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" };
|
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.
|
// Here our selection data is an index.
|
||||||
|
|
||||||
ImGui::SetNextItemWidth(comboWidth);
|
ImGui::SetNextItemWidth(comboWidth);
|
||||||
|
@ -2998,6 +3011,37 @@ void gui_save()
|
||||||
boxart.saveDatabase();
|
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
|
#ifdef TARGET_UWP
|
||||||
// Ugly but a good workaround for MS stupidity
|
// 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
|
// UWP doesn't allow the UI thread to wait on a thread/task. When an std::future is ready, it is possible
|
||||||
|
|
|
@ -48,6 +48,8 @@ void gui_start_game(const std::string& path);
|
||||||
void gui_error(const std::string& what);
|
void gui_error(const std::string& what);
|
||||||
void gui_setOnScreenKeyboardCallback(void (*callback)(bool show));
|
void gui_setOnScreenKeyboardCallback(void (*callback)(bool show));
|
||||||
void gui_save();
|
void gui_save();
|
||||||
|
void gui_loadState();
|
||||||
|
void gui_saveState();
|
||||||
|
|
||||||
enum class GuiState {
|
enum class GuiState {
|
||||||
Closed,
|
Closed,
|
||||||
|
|
Loading…
Reference in New Issue