diff --git a/src/core/memory_card.cpp b/src/core/memory_card.cpp index 5cfc1c569..76e5dda94 100644 --- a/src/core/memory_card.cpp +++ b/src/core/memory_card.cpp @@ -1,4 +1,4 @@ -// SPDX-FileCopyrightText: 2019-2023 Connor McLaughlin +// SPDX-FileCopyrightText: 2019-2024 Connor McLaughlin // SPDX-License-Identifier: (GPL-3.0 OR CC-BY-NC-ND-4.0) #include "memory_card.h" @@ -65,6 +65,19 @@ bool MemoryCard::DoState(StateWrapper& sw) return !sw.HasError(); } +void MemoryCard::CopyState(const MemoryCard* src) +{ + DebugAssert(m_data == src->m_data); + + m_state = src->m_state; + m_FLAG.bits = src->m_FLAG.bits; + m_address = src->m_address; + m_sector_offset = src->m_sector_offset; + m_checksum = src->m_checksum; + m_last_byte = src->m_last_byte; + m_changed = src->m_changed; +} + void MemoryCard::ResetTransferState() { m_state = State::Idle; diff --git a/src/core/memory_card.h b/src/core/memory_card.h index daee8973d..aef10d6d0 100644 --- a/src/core/memory_card.h +++ b/src/core/memory_card.h @@ -30,6 +30,7 @@ public: void Reset(); bool DoState(StateWrapper& sw); + void CopyState(const MemoryCard* src); void ResetTransferState(); bool Transfer(const u8 data_in, u8* data_out); diff --git a/src/core/pad.cpp b/src/core/pad.cpp index 068f73ee6..007c304e2 100644 --- a/src/core/pad.cpp +++ b/src/core/pad.cpp @@ -1,4 +1,4 @@ -// SPDX-FileCopyrightText: 2019-2023 Connor McLaughlin and contributors. +// SPDX-FileCopyrightText: 2019-2024 Connor McLaughlin and contributors. // SPDX-License-Identifier: (GPL-3.0 OR CC-BY-NC-ND-4.0) #include "pad.h" @@ -19,6 +19,8 @@ #include "common/fifo_queue.h" #include "common/log.h" +#include "IconsFontAwesome5.h" + #include #include @@ -257,16 +259,16 @@ bool Pad::DoStateMemcard(StateWrapper& sw, u32 i, bool is_memory_state) if (card_present_in_state && !s_memory_cards[i] && g_settings.load_devices_from_save_states) { - Host::AddFormattedOSDMessage( - 20.0f, - TRANSLATE("OSDMessage", "Memory card %u present in save state but not in system. Creating temporary card."), - i + 1u); + Host::AddIconOSDMessage( + fmt::format("card_load_warning_{}", i), ICON_FA_SD_CARD, + fmt::format( + TRANSLATE_FS("OSDMessage", "Memory card {} present in save state but not in system. Creating temporary card."), + i + 1u), + Host::OSD_ERROR_DURATION); s_memory_cards[i] = MemoryCard::Create(); } MemoryCard* card_ptr = s_memory_cards[i].get(); - std::unique_ptr card_from_state; - if (card_present_in_state) { if (sw.IsReading() && !g_settings.load_devices_from_save_states) @@ -284,22 +286,24 @@ bool Pad::DoStateMemcard(StateWrapper& sw, u32 i, bool is_memory_state) if (sw.IsWriting()) return true; // all done as far as writes concerned. - if (card_from_state) + if (card_ptr != s_memory_cards[i].get()) { if (s_memory_cards[i]) { - if (s_memory_cards[i]->GetData() == card_from_state->GetData()) + if (s_memory_cards[i]->GetData() == card_ptr->GetData()) { - card_from_state->SetFilename(s_memory_cards[i]->GetFilename()); - s_memory_cards[i] = std::move(card_from_state); + Log_DevFmt("Card {} data matches, copying state", i + 1u); + s_memory_cards[i]->CopyState(card_ptr); } else { - Host::AddFormattedOSDMessage( - 20.0f, - TRANSLATE("OSDMessage", - "Memory card %u from save state does match current card data. Simulating replugging."), - i + 1u); + Host::AddIconOSDMessage( + fmt::format("card_load_warning_{}", i), ICON_FA_SD_CARD, + fmt::format( + TRANSLATE_FS("OSDMessage", + "Memory card {} from save state does match current card data. Simulating replugging."), + i + 1u), + Host::OSD_WARNING_DURATION); // this is a potentially serious issue - some games cache info from memcards and jumping around // with savestates can lead to card corruption on the next save attempts (and may not be obvious @@ -307,15 +311,17 @@ bool Pad::DoStateMemcard(StateWrapper& sw, u32 i, bool is_memory_state) // for the game to decide it was removed and purge its cache. Once implemented, this could be // described as deferred re-plugging in the log. - Log_WarningPrintf("Memory card %u data mismatch. Using current data via instant-replugging.", i + 1u); + Log_WarningFmt("Memory card {} data mismatch. Using current data via instant-replugging.", i + 1u); s_memory_cards[i]->Reset(); } } else { - Host::AddFormattedOSDMessage( - 20.0f, TRANSLATE("OSDMessage", "Memory card %u present in save state but not in system. Ignoring card."), - i + 1u); + Host::AddIconOSDMessage( + fmt::format("card_load_warning_{}", i), ICON_FA_SD_CARD, + fmt::format( + TRANSLATE_FS("OSDMessage", "Memory card {} present in save state but not in system. Ignoring card."), i + 1u), + Host::OSD_ERROR_DURATION); } return true; @@ -325,16 +331,21 @@ bool Pad::DoStateMemcard(StateWrapper& sw, u32 i, bool is_memory_state) { if (g_settings.load_devices_from_save_states) { - Host::AddFormattedOSDMessage( - 20.0f, TRANSLATE("OSDMessage", "Memory card %u present in system but not in save state. Removing card."), - i + 1u); + Host::AddIconOSDMessage( + fmt::format("card_load_warning_{}", i), ICON_FA_SD_CARD, + fmt::format( + TRANSLATE_FS("OSDMessage", "Memory card {} present in system but not in save state. Removing card."), i + 1u), + Host::OSD_ERROR_DURATION); s_memory_cards[i].reset(); } else { - Host::AddFormattedOSDMessage( - 20.0f, TRANSLATE("OSDMessage", "Memory card %u present in system but not in save state. Replugging card."), - i + 1u); + Host::AddIconOSDMessage( + fmt::format("card_load_warning_{}", i), ICON_FA_SD_CARD, + fmt::format( + TRANSLATE_FS("OSDMessage", "Memory card {} present in system but not in save state. Replugging card."), + i + 1u), + Host::OSD_WARNING_DURATION); s_memory_cards[i]->Reset(); } }