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();
// 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
#ifndef IS_PLAYBACK

View file

@ -16,15 +16,15 @@
#include "Core/PowerPC/PowerPC.h"
#include "Core/System.h"
bool SlippiSavestate::shouldForceInit;
bool SlippiSavestate::should_force_init;
SlippiSavestate::SlippiSavestate()
{
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));
}
@ -33,12 +33,12 @@ SlippiSavestate::SlippiSavestate()
// getDolphinState(p);
// const size_t buffer_size = reinterpret_cast<size_t>(ptr);
// dolphinSsBackup.resize(buffer_size);
// dolphin_ss_backup.resize(buffer_size);
}
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);
}
@ -51,7 +51,7 @@ bool cmpFn(SlippiSavestate::PreserveBlock pb1, SlippiSavestate::PreserveBlock pb
void SlippiSavestate::initBackupLocs()
{
static std::vector<ssBackupLoc> fullBackupRegions = {
static std::vector<ssBackupLoc> full_backup_regions = {
{0x80005520, 0x80005940, nullptr}, // Data Sections 0 and 1
{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).
};
static std::vector<PreserveBlock> excludeSections = {
static std::vector<PreserveBlock> exclude_sections = {
// Sound stuff
{0x804031A0, 0x24}, // [804031A0 - 804031C4)
{0x80407FB4, 0x34C}, // [80407FB4 - 80408300)
@ -101,85 +101,89 @@ void SlippiSavestate::initBackupLocs()
//{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 (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;
}
ASSERT(Core::IsCPUThread());
Core::CPUThreadGuard guard(Core::System::GetInstance());
// Get Main Heap Boundaries
fullBackupRegions[3].startAddress = PowerPC::HostRead_U32(guard, 0x804d76b8);
fullBackupRegions[3].endAddress = PowerPC::HostRead_U32(guard, 0x804d76bc);
WARN_LOG_FMT(SLIPPI_ONLINE, "Heap start is: {:#x}", fullBackupRegions[3].startAddress);
WARN_LOG_FMT(SLIPPI_ONLINE, "Heap end is: {:#x}", fullBackupRegions[3].endAddress);
full_backup_regions[3].start_address = PowerPC::HostRead_U32(guard, 0x804d76b8);
full_backup_regions[3].end_address = PowerPC::HostRead_U32(guard, 0x804d76bc);
WARN_LOG_FMT(SLIPPI_ONLINE, "Heap start is: {:#x}", full_backup_regions[3].start_address);
WARN_LOG_FMT(SLIPPI_ONLINE, "Heap end is: {:#x}", full_backup_regions[3].end_address);
// Sort exclude sections
std::sort(excludeSections.begin(), excludeSections.end(), cmpFn);
std::sort(exclude_sections.begin(), exclude_sections.end(), cmpFn);
// Initialize backupLocs to full regions
backupLocs.insert(backupLocs.end(), fullBackupRegions.begin(), fullBackupRegions.end());
// Initialize backup_locs to full regions
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;
for (auto it = excludeSections.begin(); it != excludeSections.end(); ++it)
for (auto it = exclude_sections.begin(); it != exclude_sections.end(); ++it)
{
PreserveBlock ipb = *it;
while (ipb.length > 0)
{
// Move up the backupLocs index until we reach a section relevant to us
while (idx < backupLocs.size() && ipb.address >= backupLocs[idx].endAddress)
// Move up the backup_locs index until we reach a section relevant to us
while (idx < backup_locs.size() && ipb.address >= backup_locs[idx].end_address)
{
idx += 1;
}
// 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;
}
// 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.address = backupLocs[idx].startAddress;
ipb.length = new_size > 0 ? new_size : 0;
ipb.address = backup_locs[idx].start_address;
continue;
}
// 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
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};
backupLocs.insert(backupLocs.begin() + idx + 1, newLoc);
ssBackupLoc newLoc = {ipb.address + ipb.length, backup_locs[idx].end_address, nullptr};
backup_locs.insert(backup_locs.begin() + idx + 1, newLoc);
}
// Modify section to end at the exclusion start
backupLocs[idx].endAddress = ipb.address;
if (backupLocs[idx].endAddress <= backupLocs[idx].startAddress)
backup_locs[idx].end_address = ipb.address;
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
newSize = newSize > 0 ? newSize : 0;
ipb.address = ipb.address + (ipb.length - newSize);
ipb.length = (u32)newSize;
new_size = new_size > 0 ? new_size : 0;
ipb.address = ipb.address + (ipb.length - new_size);
ipb.length = static_cast<u32>(new_size);
}
}
processedLocs.clear();
processedLocs.insert(processedLocs.end(), backupLocs.begin(), backupLocs.end());
processed_locs.clear();
processed_locs.insert(processed_locs.end(), backup_locs.begin(), backup_locs.end());
}
void SlippiSavestate::getDolphinState(PointerWrap& p)
@ -207,14 +211,14 @@ void SlippiSavestate::getDolphinState(PointerWrap& p)
void SlippiSavestate::Capture()
{
// 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;
Core::System::GetInstance().GetMemory().CopyFromEmu(it->data, it->startAddress, size);
auto size = it->end_address - it->start_address;
Core::System::GetInstance().GetMemory().CopyFromEmu(it->data, it->start_address, size);
}
//// Second copy dolphin states
// u8 *ptr = &dolphinSsBackup[0];
// u8 *ptr = &dolphin_ss_backup[0];
// PointerWrap p(&ptr, PointerWrap::MODE_WRITE);
// getDolphinState(p);
}
@ -237,30 +241,30 @@ void SlippiSavestate::Load(std::vector<PreserveBlock> blocks)
// Back up
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
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
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;
memory.CopyToEmu(it->startAddress, it->data, size);
auto size = it->end_address - it->start_address;
memory.CopyToEmu(it->start_address, it->data, size);
}
//// Restore audio
// u8 *ptr = &dolphinSsBackup[0];
// u8 *ptr = &dolphin_ss_backup[0];
// PointerWrap p(&ptr, PointerWrap::MODE_READ);
// getDolphinState(p);
// Restore
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 Load(std::vector<PreserveBlock> blocks);
static bool shouldForceInit;
static bool should_force_init;
private:
typedef struct
{
u32 startAddress;
u32 endAddress;
u32 start_address;
u32 end_address;
u8* data;
} ssBackupLoc;
// These are the game locations to back up and restore
std::vector<ssBackupLoc> backupLocs = {};
std::vector<ssBackupLoc> backup_locs = {};
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);
};