finished read through of SlippiSavestate.cpp

This commit is contained in:
Nikhil Narayana 2023-08-20 17:19:50 -07:00
commit 7f8ec1fff0
No known key found for this signature in database
GPG key ID: 1B34839FA8D6245E
3 changed files with 61 additions and 57 deletions

View file

@ -163,7 +163,7 @@ CEXISlippi::CEXISlippi(Core::System& system, const std::string current_file_name
local_selections.Reset(); local_selections.Reset();
// Forces savestate to re-init regions when a new ISO is loaded // Forces savestate to re-init regions when a new ISO is loaded
SlippiSavestate::shouldForceInit = true; SlippiSavestate::should_force_init = true;
// Update user file and then listen for User // Update user file and then listen for User
#ifndef IS_PLAYBACK #ifndef IS_PLAYBACK

View file

@ -16,15 +16,15 @@
#include "Core/PowerPC/PowerPC.h" #include "Core/PowerPC/PowerPC.h"
#include "Core/System.h" #include "Core/System.h"
bool SlippiSavestate::shouldForceInit; bool SlippiSavestate::should_force_init;
SlippiSavestate::SlippiSavestate() SlippiSavestate::SlippiSavestate()
{ {
initBackupLocs(); initBackupLocs();
for (auto it = backupLocs.begin(); it != backupLocs.end(); ++it) for (auto it = backup_locs.begin(); it != backup_locs.end(); ++it)
{ {
auto size = it->endAddress - it->startAddress; auto size = it->end_address - it->start_address;
it->data = static_cast<u8*>(Common::AllocateAlignedMemory(size, 64)); it->data = static_cast<u8*>(Common::AllocateAlignedMemory(size, 64));
} }
@ -33,12 +33,12 @@ SlippiSavestate::SlippiSavestate()
// getDolphinState(p); // getDolphinState(p);
// const size_t buffer_size = reinterpret_cast<size_t>(ptr); // const size_t buffer_size = reinterpret_cast<size_t>(ptr);
// dolphinSsBackup.resize(buffer_size); // dolphin_ss_backup.resize(buffer_size);
} }
SlippiSavestate::~SlippiSavestate() SlippiSavestate::~SlippiSavestate()
{ {
for (auto it = backupLocs.begin(); it != backupLocs.end(); ++it) for (auto it = backup_locs.begin(); it != backup_locs.end(); ++it)
{ {
Common::FreeAlignedMemory(it->data); Common::FreeAlignedMemory(it->data);
} }
@ -51,7 +51,7 @@ bool cmpFn(SlippiSavestate::PreserveBlock pb1, SlippiSavestate::PreserveBlock pb
void SlippiSavestate::initBackupLocs() void SlippiSavestate::initBackupLocs()
{ {
static std::vector<ssBackupLoc> fullBackupRegions = { static std::vector<ssBackupLoc> full_backup_regions = {
{0x80005520, 0x80005940, nullptr}, // Data Sections 0 and 1 {0x80005520, 0x80005940, nullptr}, // Data Sections 0 and 1
{0x803b7240, 0x804DEC00, nullptr}, // Data Sections 2-7 and in between sections including BSS {0x803b7240, 0x804DEC00, nullptr}, // Data Sections 2-7 and in between sections including BSS
@ -62,7 +62,7 @@ void SlippiSavestate::initBackupLocs()
{0x0, 0x0, nullptr}, // Unknown Region Pt2, Heap [80bd5c40 - 811AD5A0). {0x0, 0x0, nullptr}, // Unknown Region Pt2, Heap [80bd5c40 - 811AD5A0).
}; };
static std::vector<PreserveBlock> excludeSections = { static std::vector<PreserveBlock> exclude_sections = {
// Sound stuff // Sound stuff
{0x804031A0, 0x24}, // [804031A0 - 804031C4) {0x804031A0, 0x24}, // [804031A0 - 804031C4)
{0x80407FB4, 0x34C}, // [80407FB4 - 80408300) {0x80407FB4, 0x34C}, // [80407FB4 - 80408300)
@ -101,85 +101,89 @@ void SlippiSavestate::initBackupLocs()
//{0x806e516c, 0xA8}, // Cam Block 2, including gaps //{0x806e516c, 0xA8}, // Cam Block 2, including gaps
}; };
static std::vector<ssBackupLoc> processedLocs = {}; static std::vector<ssBackupLoc> processed_locs = {};
// If the processed locations are already computed, just copy them directly // If the processed locations are already computed, just copy them directly
if (processedLocs.size()) if (processed_locs.size())
{ {
backupLocs.insert(backupLocs.end(), processedLocs.begin(), processedLocs.end()); backup_locs.insert(backup_locs.end(), processed_locs.begin(), processed_locs.end());
return; return;
} }
ASSERT(Core::IsCPUThread()); ASSERT(Core::IsCPUThread());
Core::CPUThreadGuard guard(Core::System::GetInstance()); Core::CPUThreadGuard guard(Core::System::GetInstance());
// Get Main Heap Boundaries // Get Main Heap Boundaries
fullBackupRegions[3].startAddress = PowerPC::HostRead_U32(guard, 0x804d76b8); full_backup_regions[3].start_address = PowerPC::HostRead_U32(guard, 0x804d76b8);
fullBackupRegions[3].endAddress = PowerPC::HostRead_U32(guard, 0x804d76bc); full_backup_regions[3].end_address = PowerPC::HostRead_U32(guard, 0x804d76bc);
WARN_LOG_FMT(SLIPPI_ONLINE, "Heap start is: {:#x}", fullBackupRegions[3].startAddress); WARN_LOG_FMT(SLIPPI_ONLINE, "Heap start is: {:#x}", full_backup_regions[3].start_address);
WARN_LOG_FMT(SLIPPI_ONLINE, "Heap end is: {:#x}", fullBackupRegions[3].endAddress); WARN_LOG_FMT(SLIPPI_ONLINE, "Heap end is: {:#x}", full_backup_regions[3].end_address);
// Sort exclude sections // Sort exclude sections
std::sort(excludeSections.begin(), excludeSections.end(), cmpFn); std::sort(exclude_sections.begin(), exclude_sections.end(), cmpFn);
// Initialize backupLocs to full regions // Initialize backup_locs to full regions
backupLocs.insert(backupLocs.end(), fullBackupRegions.begin(), fullBackupRegions.end()); backup_locs.insert(backup_locs.end(), full_backup_regions.begin(), full_backup_regions.end());
// Remove exclude sections from backupLocs // Remove exclude sections from backup_locs
int idx = 0; int idx = 0;
for (auto it = excludeSections.begin(); it != excludeSections.end(); ++it) for (auto it = exclude_sections.begin(); it != exclude_sections.end(); ++it)
{ {
PreserveBlock ipb = *it; PreserveBlock ipb = *it;
while (ipb.length > 0) while (ipb.length > 0)
{ {
// Move up the backupLocs index until we reach a section relevant to us // Move up the backup_locs index until we reach a section relevant to us
while (idx < backupLocs.size() && ipb.address >= backupLocs[idx].endAddress) while (idx < backup_locs.size() && ipb.address >= backup_locs[idx].end_address)
{ {
idx += 1; idx += 1;
} }
// Once idx is beyond backup locs, we are already not backup up this exclusion section // Once idx is beyond backup locs, we are already not backup up this exclusion section
if (idx >= backupLocs.size()) if (idx >= backup_locs.size())
{ {
break; break;
} }
// Handle case where our exclusion starts before the actual backup section // Handle case where our exclusion starts before the actual backup section
if (ipb.address < backupLocs[idx].startAddress) if (ipb.address < backup_locs[idx].start_address)
{ {
int newSize = (s32)ipb.length - ((s32)backupLocs[idx].startAddress - (s32)ipb.address); int new_size =
static_cast<s32>(ipb.length) -
(static_cast<s32>(backup_locs[idx].start_address) - static_cast<s32>(ipb.address));
ipb.length = newSize > 0 ? newSize : 0; ipb.length = new_size > 0 ? new_size : 0;
ipb.address = backupLocs[idx].startAddress; ipb.address = backup_locs[idx].start_address;
continue; continue;
} }
// Determine new size (how much we removed from backup) // Determine new size (how much we removed from backup)
int newSize = (s32)ipb.length - ((s32)backupLocs[idx].endAddress - (s32)ipb.address); int new_size =
static_cast<s32>(ipb.length) -
(static_cast<s32>(backup_locs[idx].end_address) - static_cast<s32>(ipb.address));
// Add split section after exclusion // Add split section after exclusion
if (backupLocs[idx].endAddress > ipb.address + ipb.length) if (backup_locs[idx].end_address > ipb.address + ipb.length)
{ {
ssBackupLoc newLoc = {ipb.address + ipb.length, backupLocs[idx].endAddress, nullptr}; ssBackupLoc newLoc = {ipb.address + ipb.length, backup_locs[idx].end_address, nullptr};
backupLocs.insert(backupLocs.begin() + idx + 1, newLoc); backup_locs.insert(backup_locs.begin() + idx + 1, newLoc);
} }
// Modify section to end at the exclusion start // Modify section to end at the exclusion start
backupLocs[idx].endAddress = ipb.address; backup_locs[idx].end_address = ipb.address;
if (backupLocs[idx].endAddress <= backupLocs[idx].startAddress) if (backup_locs[idx].end_address <= backup_locs[idx].start_address)
{ {
backupLocs.erase(backupLocs.begin() + idx); backup_locs.erase(backup_locs.begin() + idx);
} }
// Set new size to see if there's still more to process // Set new size to see if there's still more to process
newSize = newSize > 0 ? newSize : 0; new_size = new_size > 0 ? new_size : 0;
ipb.address = ipb.address + (ipb.length - newSize); ipb.address = ipb.address + (ipb.length - new_size);
ipb.length = (u32)newSize; ipb.length = static_cast<u32>(new_size);
} }
} }
processedLocs.clear(); processed_locs.clear();
processedLocs.insert(processedLocs.end(), backupLocs.begin(), backupLocs.end()); processed_locs.insert(processed_locs.end(), backup_locs.begin(), backup_locs.end());
} }
void SlippiSavestate::getDolphinState(PointerWrap& p) void SlippiSavestate::getDolphinState(PointerWrap& p)
@ -207,14 +211,14 @@ void SlippiSavestate::getDolphinState(PointerWrap& p)
void SlippiSavestate::Capture() void SlippiSavestate::Capture()
{ {
// First copy memory // First copy memory
for (auto it = backupLocs.begin(); it != backupLocs.end(); ++it) for (auto it = backup_locs.begin(); it != backup_locs.end(); ++it)
{ {
auto size = it->endAddress - it->startAddress; auto size = it->end_address - it->start_address;
Core::System::GetInstance().GetMemory().CopyFromEmu(it->data, it->startAddress, size); Core::System::GetInstance().GetMemory().CopyFromEmu(it->data, it->start_address, size);
} }
//// Second copy dolphin states //// Second copy dolphin states
// u8 *ptr = &dolphinSsBackup[0]; // u8 *ptr = &dolphin_ss_backup[0];
// PointerWrap p(&ptr, PointerWrap::MODE_WRITE); // PointerWrap p(&ptr, PointerWrap::MODE_WRITE);
// getDolphinState(p); // getDolphinState(p);
} }
@ -237,30 +241,30 @@ void SlippiSavestate::Load(std::vector<PreserveBlock> blocks)
// Back up // Back up
for (auto it = blocks.begin(); it != blocks.end(); ++it) for (auto it = blocks.begin(); it != blocks.end(); ++it)
{ {
if (!preservationMap.count(*it)) if (!preservation_map.count(*it))
{ {
// TODO: Clear preservation map when game ends // TODO: Clear preservation map when game ends
preservationMap[*it] = std::vector<u8>(it->length); preservation_map[*it] = std::vector<u8>(it->length);
} }
memory.CopyFromEmu(&preservationMap[*it][0], it->address, it->length); memory.CopyFromEmu(&preservation_map[*it][0], it->address, it->length);
} }
// Restore memory blocks // Restore memory blocks
for (auto it = backupLocs.begin(); it != backupLocs.end(); ++it) for (auto it = backup_locs.begin(); it != backup_locs.end(); ++it)
{ {
auto size = it->endAddress - it->startAddress; auto size = it->end_address - it->start_address;
memory.CopyToEmu(it->startAddress, it->data, size); memory.CopyToEmu(it->start_address, it->data, size);
} }
//// Restore audio //// Restore audio
// u8 *ptr = &dolphinSsBackup[0]; // u8 *ptr = &dolphin_ss_backup[0];
// PointerWrap p(&ptr, PointerWrap::MODE_READ); // PointerWrap p(&ptr, PointerWrap::MODE_READ);
// getDolphinState(p); // getDolphinState(p);
// Restore // Restore
for (auto it = blocks.begin(); it != blocks.end(); ++it) for (auto it = blocks.begin(); it != blocks.end(); ++it)
{ {
memory.CopyToEmu(it->address, &preservationMap[*it][0], it->length); memory.CopyToEmu(it->address, &preservation_map[*it][0], it->length);
} }
} }

View file

@ -26,18 +26,18 @@ public:
void Capture(); void Capture();
void Load(std::vector<PreserveBlock> blocks); void Load(std::vector<PreserveBlock> blocks);
static bool shouldForceInit; static bool should_force_init;
private: private:
typedef struct typedef struct
{ {
u32 startAddress; u32 start_address;
u32 endAddress; u32 end_address;
u8* data; u8* data;
} ssBackupLoc; } ssBackupLoc;
// These are the game locations to back up and restore // These are the game locations to back up and restore
std::vector<ssBackupLoc> backupLocs = {}; std::vector<ssBackupLoc> backup_locs = {};
void initBackupLocs(); void initBackupLocs();
@ -55,9 +55,9 @@ private:
} }
}; };
std::unordered_map<PreserveBlock, std::vector<u8>, preserve_hash_fn> preservationMap; std::unordered_map<PreserveBlock, std::vector<u8>, preserve_hash_fn> preservation_map;
std::vector<u8> dolphinSsBackup; // std::vector<u8> dolphin_ss_backup;
void getDolphinState(PointerWrap& p); void getDolphinState(PointerWrap& p);
}; };