From 458868a63476f2b9543726a7185fd216639668d9 Mon Sep 17 00:00:00 2001 From: Flyinghead Date: Wed, 8 Sep 2021 17:18:01 +0200 Subject: [PATCH] ggpo: always save delta ram. Disable ff,cheats,savestates when online ggpo: always save delta ram on save_game_state as frames may be rerun and resaved Global network online status (ggpo, naomi, modem, bba) Disable fast forward, cheats and savestates when online. --- core/cheats.cpp | 3 +-- core/emulator.cpp | 8 ++++++++ core/emulator.h | 1 + core/input/gamepad_device.cpp | 2 +- core/network/ggpo.cpp | 19 +++++++++--------- core/network/naomi_network.cpp | 6 +++++- core/network/picoppp.cpp | 13 ++++--------- core/network/picoppp.h | 1 - core/rend/gui.cpp | 35 +++++++++++++++++++++++++++++----- core/types.h | 1 + 10 files changed, 60 insertions(+), 29 deletions(-) diff --git a/core/cheats.cpp b/core/cheats.cpp index a09890e55..a18b8b90e 100644 --- a/core/cheats.cpp +++ b/core/cheats.cpp @@ -23,7 +23,6 @@ #include "cheats.h" #include "hw/sh4/sh4_mem.h" #include "reios/reios.h" -#include "network/picoppp.h" #include "cfg/cfg.h" const WidescreenCheat CheatManager::widescreen_cheats[] = @@ -464,7 +463,7 @@ void CheatManager::apply() for (size_t i = 0; i < ARRAY_SIZE(widescreen_cheat->addresses) && widescreen_cheat->addresses[i] != 0; i++) writeRam(widescreen_cheat->addresses[i], widescreen_cheat->values[i], 32); } - if (active && !networkStarted()) + if (active && !settings.online) { bool skipCheat = false; for (const Cheat& cheat : cheats) diff --git a/core/emulator.cpp b/core/emulator.cpp index 4489d6572..ea3fe4023 100644 --- a/core/emulator.cpp +++ b/core/emulator.cpp @@ -543,6 +543,7 @@ static void *dc_run_thread(void*) ERROR_LOG(COMMON, "%s", e.what()); sh4_cpu.Stop(); lastError = e.what(); + dc_set_network_state(false); } ggpo::stopSession(); @@ -745,6 +746,13 @@ std::string dc_get_last_error() return error; } +void dc_set_network_state(bool online) +{ + DEBUG_LOG(NETWORK, "Network state %d", online); + settings.online = online; + settings.input.fastForwardMode &= !online; +} + EventManager EventManager::Instance; void EventManager::registerEvent(Event event, Callback callback) diff --git a/core/emulator.h b/core/emulator.h index d338fd11d..56acf8e5b 100644 --- a/core/emulator.h +++ b/core/emulator.h @@ -52,6 +52,7 @@ void dc_get_load_status(); bool dc_is_running(); void dc_resize_renderer(); std::string dc_get_last_error(); +void dc_set_network_state(bool online); enum class Event { Start, diff --git a/core/input/gamepad_device.cpp b/core/input/gamepad_device.cpp index fb00dcce4..df1b7c4da 100644 --- a/core/input/gamepad_device.cpp +++ b/core/input/gamepad_device.cpp @@ -90,7 +90,7 @@ bool GamepadDevice::gamepad_btn_input(u32 code, bool pressed) break; case EMU_BTN_FFORWARD: if (pressed && !gui_is_open()) - settings.input.fastForwardMode = !settings.input.fastForwardMode; + settings.input.fastForwardMode = !settings.input.fastForwardMode && !settings.online; break; case EMU_BTN_TRIGGER_LEFT: lt[port] = pressed ? 255 : 0; diff --git a/core/network/ggpo.cpp b/core/network/ggpo.cpp index e08228e7a..1289c7632 100644 --- a/core/network/ggpo.cpp +++ b/core/network/ggpo.cpp @@ -219,15 +219,8 @@ static bool save_game_state(unsigned char **buffer, int *len, int *checksum, int #endif if (frame > 0) { - // Save the delta to frame-1 - if (deltaStates.count(frame - 1) == 0) - { - deltaStates[frame - 1].load(); - DEBUG_LOG(NETWORK, "Saved frame %d pages: %d ram, %d vram, %d aica ram", frame - 1, (u32)deltaStates[frame - 1].ram.size(), - (u32)deltaStates[frame - 1].vram.size(), (u32)deltaStates[frame - 1].aram.size()); - } #ifdef SYNC_TEST - else + if (deltaStates.count(frame - 1) != 0) { MemPages memPages; memPages.load(); @@ -270,6 +263,10 @@ static bool save_game_state(unsigned char **buffer, int *len, int *checksum, int } } #endif + // Save the delta to frame-1 + deltaStates[frame - 1].load(); + DEBUG_LOG(NETWORK, "Saved frame %d pages: %d ram, %d vram, %d aica ram", frame - 1, (u32)deltaStates[frame - 1].ram.size(), + (u32)deltaStates[frame - 1].vram.size(), (u32)deltaStates[frame - 1].aram.size()); } memwatch::protect(); @@ -409,6 +406,7 @@ void stopSession() return; ggpo_close_session(ggpoSession); ggpoSession = nullptr; + dc_set_network_state(false); } void getInput(u32 out_kcode[4], u8 out_lt[4], u8 out_rt[4]) @@ -421,8 +419,8 @@ void getInput(u32 out_kcode[4], u8 out_lt[4], u8 out_rt[4]) memcpy(out_rt, rt, sizeof(rt)); return; } - memset(out_lt, 0, sizeof(out_lt)); - memset(out_rt, 0, sizeof(out_rt)); + memset(out_lt, 0, sizeof(lt)); + memset(out_rt, 0, sizeof(rt)); // should not call any callback u32 inputs[4]; ggpo_synchronize_input(ggpoSession, (void *)&inputs[0], sizeof(inputs[0]) * 2, nullptr); // FIXME numPlayers @@ -531,6 +529,7 @@ std::future startNetwork() getInput(k); } #endif + dc_set_network_state(active()); return active(); }); } diff --git a/core/network/naomi_network.cpp b/core/network/naomi_network.cpp index 38393473e..ce5e7a59e 100644 --- a/core/network/naomi_network.cpp +++ b/core/network/naomi_network.cpp @@ -28,6 +28,7 @@ #include "hw/naomi/naomi_cart.h" #include "hw/naomi/naomi_flashrom.h" #include "cfg/option.h" +#include "emulator.h" #ifdef _MSC_VER #if defined(_WIN64) @@ -618,6 +619,7 @@ void NaomiNetwork::shutdown() } if (VALID(client_sock)) closeSocket(client_sock); + dc_set_network_state(false); } void NaomiNetwork::terminate() @@ -636,7 +638,9 @@ std::future NaomiNetwork::startNetworkAsync() network_stopping = false; start_now = false; return std::async(std::launch::async, [this] { - return startNetwork(); + bool res = startNetwork(); + dc_set_network_state(res); + return res; }); } diff --git a/core/network/picoppp.cpp b/core/network/picoppp.cpp index 729910bfa..608b85758 100644 --- a/core/network/picoppp.cpp +++ b/core/network/picoppp.cpp @@ -47,6 +47,7 @@ extern "C" { #include "reios/reios.h" #include "hw/naomi/naomi_cart.h" #include "cfg/option.h" +#include "emulator.h" #include #include @@ -1065,6 +1066,7 @@ static cThread pico_thread(pico_thread_func, NULL); bool start_pico() { + dc_set_network_state(true); if (pico_thread_running) return false; pico_thread_running = true; @@ -1075,15 +1077,11 @@ bool start_pico() void stop_pico() { + dc_set_network_state(false); pico_thread_running = false; pico_thread.WaitToEnd(); } -bool networkStarted() -{ - return pico_thread_running; -} - #else #include "types.h" @@ -1093,8 +1091,5 @@ void stop_pico() { } void write_pico(u8 b) { } int read_pico() { return -1; } void pico_receive_eth_frame(const u8* frame, u32 size) {} -bool networkStarted() -{ - return false; -} + #endif diff --git a/core/network/picoppp.h b/core/network/picoppp.h index 0444301a3..220f4358a 100644 --- a/core/network/picoppp.h +++ b/core/network/picoppp.h @@ -24,7 +24,6 @@ bool start_pico(); void stop_pico(); void write_pico(u8 b); int read_pico(); -bool networkStarted(); void pico_receive_eth_frame(const u8 *frame, u32 size); // implemented in bba diff --git a/core/rend/gui.cpp b/core/rend/gui.cpp index 5655355be..48257f3c6 100644 --- a/core/rend/gui.cpp +++ b/core/rend/gui.cpp @@ -465,17 +465,22 @@ static void gui_display_commands() ImGui::Begin("##commands", NULL, ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoMove | ImGuiWindowFlags_AlwaysAutoResize); - if (settings.imgread.ImagePath[0] == '\0') + bool loadSaveStateDisabled = settings.imgread.ImagePath[0] == '\0' || settings.online; + if (loadSaveStateDisabled) { ImGui::PushItemFlag(ImGuiItemFlags_Disabled, true); ImGui::PushStyleVar(ImGuiStyleVar_Alpha, ImGui::GetStyle().Alpha * 0.5f); } - if (ImGui::Button("Load State", ImVec2(110 * scaling, 50 * scaling))) + + // Load State + if (ImGui::Button("Load State", ImVec2(110 * scaling, 50 * scaling)) && !loadSaveStateDisabled) { gui_state = GuiState::Closed; dc_loadstate(config::SavestateSlot); } ImGui::SameLine(); + + // Slot # std::string slot = "Slot " + std::to_string((int)config::SavestateSlot + 1); if (ImGui::Button(slot.c_str(), ImVec2(80 * scaling - ImGui::GetStyle().FramePadding.x, 50 * scaling))) ImGui::OpenPopup("slot_select_popup"); @@ -490,18 +495,22 @@ static void gui_display_commands() ImGui::EndPopup(); } ImGui::SameLine(); - if (ImGui::Button("Save State", ImVec2(110 * scaling, 50 * scaling))) + + // Save State + if (ImGui::Button("Save State", ImVec2(110 * scaling, 50 * scaling)) && !loadSaveStateDisabled) { gui_state = GuiState::Closed; dc_savestate(config::SavestateSlot); } - if (settings.imgread.ImagePath[0] == '\0') + if (loadSaveStateDisabled) { ImGui::PopItemFlag(); ImGui::PopStyleVar(); } ImGui::Columns(2, "buttons", false); + + // Settings if (ImGui::Button("Settings", ImVec2(150 * scaling, 50 * scaling))) { gui_state = GuiState::Settings; @@ -514,6 +523,8 @@ static void gui_display_commands() } ImGui::NextColumn(); + + // Insert/Eject Disk const char *disk_label = libGDR_GetDiscType() == Open ? "Insert Disk" : "Eject Disk"; if (ImGui::Button(disk_label, ImVec2(150 * scaling, 50 * scaling))) { @@ -528,11 +539,25 @@ static void gui_display_commands() } } ImGui::NextColumn(); - if (ImGui::Button("Cheats", ImVec2(150 * scaling, 50 * scaling))) + + // Cheats + if (settings.online) + { + ImGui::PushItemFlag(ImGuiItemFlags_Disabled, true); + ImGui::PushStyleVar(ImGuiStyleVar_Alpha, ImGui::GetStyle().Alpha * 0.5f); + } + if (ImGui::Button("Cheats", ImVec2(150 * scaling, 50 * scaling)) && !settings.online) { gui_state = GuiState::Cheats; } + if (settings.online) + { + ImGui::PopItemFlag(); + ImGui::PopStyleVar(); + } ImGui::Columns(1, nullptr, false); + + // Exit if (ImGui::Button("Exit", ImVec2(300 * scaling + ImGui::GetStyle().ColumnsMinSpacing + ImGui::GetStyle().FramePadding.x * 2 - 1, 50 * scaling))) { diff --git a/core/types.h b/core/types.h index 447310d8c..cc0ab546a 100644 --- a/core/types.h +++ b/core/types.h @@ -356,6 +356,7 @@ struct settings_t bool gameStarted; bool endOfFrame; bool disableRenderer; + bool online; }; extern settings_t settings;