Skip to content

Commit

Permalink
Merge pull request #12153 from unknownbrackets/replay
Browse files Browse the repository at this point in the history
Replay: Add file header handling and ignore PSP/GAME reads
  • Loading branch information
hrydgard committed Jul 8, 2019
2 parents 510daa6 + 33cfac5 commit 179cafc
Show file tree
Hide file tree
Showing 8 changed files with 165 additions and 54 deletions.
35 changes: 22 additions & 13 deletions Core/FileSystems/DirectoryFileSystem.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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();

Expand Down Expand Up @@ -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
Expand All @@ -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.
Expand Down Expand Up @@ -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;
}

Expand All @@ -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;
Expand All @@ -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)
Expand All @@ -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");
Expand Down
7 changes: 4 additions & 3 deletions Core/FileSystems/DirectoryFileSystem.h
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand All @@ -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);
Expand Down
4 changes: 4 additions & 0 deletions Core/HLE/sceKernelTime.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -188,3 +188,7 @@ std::string KernelTimeNowFormatted() {
std::string timestamp = StringFromFormat("%04d-%02d-%02d_%02d-%02d-%02d", years, months, days, hours, minutes, seconds);
return timestamp;
}

void KernelTimeSetBase(int64_t seconds) {
start_time = (time_t)seconds;
}
1 change: 1 addition & 0 deletions Core/HLE/sceKernelTime.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ int sceKernelSysClock2USecWide(u32 lowClock, u32 highClock, u32 lowPtr, u32 high
u64 sceKernelUSec2SysClockWide(u32 usec);
u32 sceKernelLibcClock();
std::string KernelTimeNowFormatted();
void KernelTimeSetBase(int64_t seconds);

void __KernelTimeInit();
void __KernelTimeDoState(PointerWrap &p);
21 changes: 19 additions & 2 deletions Core/HLE/sceRtc.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,10 @@ static time_t rtc_timegm(struct tm *tm)

#endif

static void RtcUpdateBaseTicks() {
rtcBaseTicks = 1000000ULL * rtcBaseTime.tv_sec + rtcBaseTime.tv_usec + rtcMagicOffset;
}

void __RtcInit()
{
// This is the base time, the only case we use gettimeofday() for.
Expand All @@ -147,7 +151,7 @@ void __RtcInit()
rtcBaseTime.tv_sec = tv.tv_sec;
rtcBaseTime.tv_usec = 0;
// Precalculate the current time in microseconds (rtcMagicOffset is offset to 1970.)
rtcBaseTicks = 1000000ULL * rtcBaseTime.tv_sec + rtcBaseTime.tv_usec + rtcMagicOffset;
RtcUpdateBaseTicks();
}

void __RtcDoState(PointerWrap &p)
Expand All @@ -158,7 +162,7 @@ void __RtcDoState(PointerWrap &p)

p.Do(rtcBaseTime);
// Update the precalc, pointless to savestate this as it's just based on the other value.
rtcBaseTicks = 1000000ULL * rtcBaseTime.tv_sec + rtcBaseTime.tv_usec + rtcMagicOffset;
RtcUpdateBaseTicks();
}

void __RtcTimeOfDay(PSPTimeval *tv)
Expand All @@ -171,6 +175,19 @@ void __RtcTimeOfDay(PSPTimeval *tv)
tv->tv_usec = adjustedUs % 1000000UL;
}

int32_t RtcBaseTime(int32_t *micro) {
if (micro) {
*micro = rtcBaseTime.tv_usec;
}
return rtcBaseTime.tv_sec;
}

void RtcSetBaseTime(int32_t seconds, int32_t micro) {
rtcBaseTime.tv_sec = seconds;
rtcBaseTime.tv_usec = micro;
RtcUpdateBaseTicks();
}

static void __RtcTmToPspTime(ScePspDateTime &t, const tm *val)
{
t.year = val->tm_year + 1900;
Expand Down
2 changes: 2 additions & 0 deletions Core/HLE/sceRtc.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@ struct PSPTimeval {
};

void __RtcTimeOfDay(PSPTimeval *tv);
int32_t RtcBaseTime(int32_t *micro = nullptr);
void RtcSetBaseTime(int32_t seconds, int32_t micro = 0);

void Register_sceRtc();
void __RtcInit();
Expand Down
Loading

0 comments on commit 179cafc

Please sign in to comment.