mirror of
https://github.com/dolphin-emu/dolphin.git
synced 2025-08-25 11:46:27 +00:00
finished read through of SlippiSavestate.cpp
This commit is contained in:
parent
1b26177cc4
commit
7f8ec1fff0
3 changed files with 61 additions and 57 deletions
|
@ -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
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
||||||
};
|
};
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue