mirror of
https://github.com/hrydgard/ppsspp.git
synced 2025-02-03 20:22:45 +00:00
Replay: Attempt to ignore reads in PSP/GAME.
Unless there are writes in this directory, we should be able to safely ignore them. Currently detection isn't perfect (like PSP/./GAME/../GAME), but this should catch the vast majority of cases.
This commit is contained in:
parent
4144e71b7a
commit
33cfac549d
@ -98,7 +98,7 @@ static bool FixFilenameCase(const std::string &path, std::string &filename)
|
||||
return retValue;
|
||||
}
|
||||
|
||||
bool FixPathCase(std::string& basePath, std::string &path, FixPathCaseBehavior behavior)
|
||||
bool FixPathCase(const std::string &basePath, std::string &path, FixPathCaseBehavior behavior)
|
||||
{
|
||||
size_t len = path.size();
|
||||
|
||||
@ -158,25 +158,25 @@ DirectoryFileSystem::~DirectoryFileSystem() {
|
||||
CloseAll();
|
||||
}
|
||||
|
||||
std::string DirectoryFileHandle::GetLocalPath(std::string& basePath, std::string localpath)
|
||||
std::string DirectoryFileHandle::GetLocalPath(const std::string &basePath, std::string localpath)
|
||||
{
|
||||
if (localpath.empty())
|
||||
return basePath;
|
||||
|
||||
if (localpath[0] == '/')
|
||||
localpath.erase(0,1);
|
||||
//Convert slashes
|
||||
localpath.erase(0, 1);
|
||||
|
||||
std::string result = basePath + localpath;
|
||||
#ifdef _WIN32
|
||||
for (size_t i = 0; i < localpath.size(); i++) {
|
||||
if (localpath[i] == '/')
|
||||
localpath[i] = '\\';
|
||||
for (char &c : result) {
|
||||
if (c == '/')
|
||||
c = '\\';
|
||||
}
|
||||
#endif
|
||||
return basePath + localpath;
|
||||
return result;
|
||||
}
|
||||
|
||||
bool DirectoryFileHandle::Open(std::string &basePath, std::string &fileName, FileAccess access, u32 &error)
|
||||
{
|
||||
bool DirectoryFileHandle::Open(const std::string &basePath, std::string &fileName, FileAccess access, u32 &error) {
|
||||
error = 0;
|
||||
|
||||
#if HOST_IS_CASE_SENSITIVE
|
||||
@ -190,7 +190,7 @@ bool DirectoryFileHandle::Open(std::string &basePath, std::string &fileName, Fil
|
||||
// else we try fopen first (in case we're lucky) before simulating case insensitivity
|
||||
#endif
|
||||
|
||||
std::string fullName = GetLocalPath(basePath,fileName);
|
||||
std::string fullName = GetLocalPath(basePath, fileName);
|
||||
VERBOSE_LOG(FILESYS,"Actually opening %s", fullName.c_str());
|
||||
|
||||
// On the PSP, truncating doesn't lose data. If you seek later, you'll recover it.
|
||||
@ -322,6 +322,11 @@ bool DirectoryFileHandle::Open(std::string &basePath, std::string &fileName, Fil
|
||||
}
|
||||
#endif
|
||||
|
||||
// Try to detect reads/writes to PSP/GAME to avoid them in replays.
|
||||
if (fullName.find("/PSP/GAME/") != fullName.npos || fullName.find("\\PSP\\GAME\\") != fullName.npos) {
|
||||
inGameDir_ = true;
|
||||
}
|
||||
|
||||
return success;
|
||||
}
|
||||
|
||||
@ -333,7 +338,7 @@ size_t DirectoryFileHandle::Read(u8* pointer, s64 size)
|
||||
// On a PSP. it actually is truncated, but the data wasn't erased.
|
||||
off_t off = (off_t)Seek(0, FILEMOVE_CURRENT);
|
||||
if (needsTrunc_ <= off) {
|
||||
return replay_ ? ReplayApplyDiskRead(pointer, 0, (uint32_t)size, CoreTiming::GetGlobalTimeUs()) : 0;
|
||||
return replay_ ? ReplayApplyDiskRead(pointer, 0, (uint32_t)size, inGameDir_, CoreTiming::GetGlobalTimeUs()) : 0;
|
||||
}
|
||||
if (needsTrunc_ < off + size) {
|
||||
size = needsTrunc_ - off;
|
||||
@ -344,7 +349,7 @@ size_t DirectoryFileHandle::Read(u8* pointer, s64 size)
|
||||
#else
|
||||
bytesRead = read(hFile, pointer, size);
|
||||
#endif
|
||||
return replay_ ? ReplayApplyDiskRead(pointer, (uint32_t)bytesRead, (uint32_t)size, CoreTiming::GetGlobalTimeUs()) : bytesRead;
|
||||
return replay_ ? ReplayApplyDiskRead(pointer, (uint32_t)bytesRead, (uint32_t)size, inGameDir_, CoreTiming::GetGlobalTimeUs()) : bytesRead;
|
||||
}
|
||||
|
||||
size_t DirectoryFileHandle::Write(const u8* pointer, s64 size)
|
||||
@ -371,6 +376,10 @@ size_t DirectoryFileHandle::Write(const u8* pointer, s64 size)
|
||||
}
|
||||
}
|
||||
|
||||
if (replay_) {
|
||||
bytesWritten = ReplayApplyDiskWrite(pointer, (uint64_t)bytesWritten, (uint64_t)size, &diskFull, inGameDir_, CoreTiming::GetGlobalTimeUs());
|
||||
}
|
||||
|
||||
if (diskFull) {
|
||||
ERROR_LOG(FILESYS, "Disk full");
|
||||
I18NCategory *err = GetI18NCategory("Error");
|
||||
|
@ -54,7 +54,7 @@ enum FixPathCaseBehavior {
|
||||
FPC_PARTIAL_ALLOWED, // don't care how many exist (mkdir recursive)
|
||||
};
|
||||
|
||||
bool FixPathCase(std::string& basePath, std::string &path, FixPathCaseBehavior behavior);
|
||||
bool FixPathCase(const std::string &basePath, std::string &path, FixPathCaseBehavior behavior);
|
||||
#endif
|
||||
|
||||
struct DirectoryFileHandle {
|
||||
@ -70,12 +70,13 @@ struct DirectoryFileHandle {
|
||||
#endif
|
||||
s64 needsTrunc_ = -1;
|
||||
bool replay_ = true;
|
||||
bool inGameDir_ = false;
|
||||
|
||||
DirectoryFileHandle(Flags flags) : replay_(flags != SKIP_REPLAY) {
|
||||
}
|
||||
|
||||
std::string GetLocalPath(std::string& basePath, std::string localpath);
|
||||
bool Open(std::string& basePath, std::string& fileName, FileAccess access, u32 &err);
|
||||
std::string GetLocalPath(const std::string &basePath, std::string localpath);
|
||||
bool Open(const std::string &basePath, std::string &fileName, FileAccess access, u32 &err);
|
||||
size_t Read(u8* pointer, s64 size);
|
||||
size_t Write(const u8* pointer, s64 size);
|
||||
size_t Seek(s32 position, FileMove type);
|
||||
|
@ -118,6 +118,7 @@ static std::vector<ReplayItem> replayItems;
|
||||
static size_t replayExecPos = 0;
|
||||
static bool replaySaveWroteHeader = false;
|
||||
static ReplayState replayState = ReplayState::IDLE;
|
||||
static bool replaySawGameDirWrite = false;
|
||||
|
||||
static size_t replayCtrlPos = 0;
|
||||
static uint32_t lastButtons = 0;
|
||||
@ -299,6 +300,7 @@ void ReplayAbort() {
|
||||
replayExecPos = 0;
|
||||
replaySaveWroteHeader = false;
|
||||
replayState = ReplayState::IDLE;
|
||||
replaySawGameDirWrite = false;
|
||||
|
||||
replayCtrlPos = 0;
|
||||
lastButtons = 0;
|
||||
@ -439,7 +441,12 @@ uint64_t ReplayApplyDisk64(ReplayAction action, uint64_t result, uint64_t t) {
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t ReplayApplyDiskRead(void *data, uint32_t readSize, uint32_t dataSize, uint64_t t) {
|
||||
uint32_t ReplayApplyDiskRead(void *data, uint32_t readSize, uint32_t dataSize, bool inGameDir, uint64_t t) {
|
||||
// Ignore PSP/GAME reads if we haven't seen a write there.
|
||||
if (inGameDir && !replaySawGameDirWrite) {
|
||||
return readSize;
|
||||
}
|
||||
|
||||
switch (replayState) {
|
||||
case ReplayState::EXECUTE:
|
||||
{
|
||||
@ -466,6 +473,23 @@ uint32_t ReplayApplyDiskRead(void *data, uint32_t readSize, uint32_t dataSize, u
|
||||
}
|
||||
}
|
||||
|
||||
uint64_t ReplayApplyDiskWrite(const void *data, uint64_t writeSize, uint64_t dataSize, bool *diskFull, bool inGameDir, uint64_t t) {
|
||||
switch (replayState) {
|
||||
case ReplayState::EXECUTE:
|
||||
case ReplayState::SAVE:
|
||||
// Never let the disk return full during replay.
|
||||
if (diskFull)
|
||||
*diskFull = false;
|
||||
if (inGameDir)
|
||||
replaySawGameDirWrite = true;
|
||||
return writeSize;
|
||||
|
||||
case ReplayState::IDLE:
|
||||
default:
|
||||
return writeSize;
|
||||
}
|
||||
}
|
||||
|
||||
static int64_t ConvertFromTm(const struct tm *t) {
|
||||
// Remember, mktime modifies.
|
||||
struct tm copy = *t;
|
||||
|
@ -68,6 +68,7 @@ void ReplayAbort();
|
||||
void ReplayApplyCtrl(uint32_t &buttons, uint8_t analog[2][2], uint64_t t);
|
||||
uint32_t ReplayApplyDisk(ReplayAction action, uint32_t result, uint64_t t);
|
||||
uint64_t ReplayApplyDisk64(ReplayAction action, uint64_t result, uint64_t t);
|
||||
uint32_t ReplayApplyDiskRead(void *data, uint32_t readSize, uint32_t dataSize, uint64_t t);
|
||||
uint32_t ReplayApplyDiskRead(void *data, uint32_t readSize, uint32_t dataSize, bool inGameDir, uint64_t t);
|
||||
uint64_t ReplayApplyDiskWrite(const void *data, uint64_t writeSize, uint64_t dataSize, bool *diskFull, bool inGameDir, uint64_t t);
|
||||
PSPFileInfo ReplayApplyDiskFileInfo(const PSPFileInfo &data, uint64_t t);
|
||||
std::vector<PSPFileInfo> ReplayApplyDiskListing(const std::vector<PSPFileInfo> &data, uint64_t t);
|
||||
|
Loading…
x
Reference in New Issue
Block a user