mirror of
https://github.com/Mauler125/r5sdk.git
synced 2025-02-09 19:15:03 +01:00
Fix EOF read errors and PAKFILE_LUMP not loading correctly when discrete
This commit adds support for loading cubemap lumps from the disk, several patches and hooks had to be implemented to make this work. Since the game was trying to read the pakfile lump from the BSP file (even when absent), it would read EOF (heavily reduces down map loading performance).
This commit is contained in:
parent
ceb438b7ca
commit
1fbc3291c7
@ -3,6 +3,9 @@
|
||||
#include "filesystem/basefilesystem.h"
|
||||
#include "filesystem/filesystem.h"
|
||||
|
||||
#include "bspfile.h"
|
||||
#include "engine/modelloader.h"
|
||||
|
||||
//---------------------------------------------------------------------------------
|
||||
// Purpose: prints the output of the filesystem based on the warning level
|
||||
// Input : *this -
|
||||
@ -13,7 +16,7 @@ void CBaseFileSystem::Warning(CBaseFileSystem* pFileSystem, FileWarningLevel_t l
|
||||
{
|
||||
if (level >= FileWarningLevel_t::FILESYSTEM_WARNING_REPORTALLACCESSES)
|
||||
{
|
||||
// Logging reads is very verbose! Explicitly toggle..
|
||||
// Logging reads are very verbose! Explicitly toggle..
|
||||
if (!fs_showAllReads->GetBool())
|
||||
{
|
||||
return;
|
||||
@ -101,6 +104,43 @@ bool CBaseFileSystem::VReadFromCache(CBaseFileSystem* pFileSystem, char* pszFile
|
||||
return result;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------
|
||||
// Purpose: mounts a BSP packfile lump as search path
|
||||
// Input : *this -
|
||||
// *pPath -
|
||||
// *pPathID -
|
||||
// *addType -
|
||||
//---------------------------------------------------------------------------------
|
||||
void CBaseFileSystem::VAddMapPackFile(CBaseFileSystem* pFileSystem, const char* pPath, const char* pPathID, SearchPathAdd_t addType)
|
||||
{
|
||||
// Since the mounting of the packfile lump is performed before the BSP header
|
||||
// is loaded and parsed, we have to do it here. The internal 'AddMapPackFile'
|
||||
// function has been patched to load the fields in the global 's_MapHeader'
|
||||
// field, instead of the one that is getting initialized (see r5apex.patch).
|
||||
if (s_MapHeader->ident != IDBSPHEADER || s_MapHeader->version != BSPVERSION)
|
||||
{
|
||||
FileHandle_t hBspFile = FileSystem()->Open(pPath, "rb", pPathID);
|
||||
if (hBspFile != FILESYSTEM_INVALID_HANDLE)
|
||||
{
|
||||
memset(s_MapHeader, '\0', sizeof(BSPHeader_t));
|
||||
FileSystem()->Read(s_MapHeader, sizeof(BSPHeader_t), hBspFile);
|
||||
}
|
||||
}
|
||||
|
||||
// If a lump exists, replace the path pointer with that of the lump so that
|
||||
// the internal function loads this instead.
|
||||
char lumpPathBuf[MAX_PATH];
|
||||
V_snprintf(lumpPathBuf, sizeof(lumpPathBuf), "%s.%.4X.bsp_lump", pPath, LUMP_PAKFILE);
|
||||
|
||||
// TODO[ AMOS ]: Attempt to read from cache first???
|
||||
if (FileSystem()->FileExists(lumpPathBuf, pPathID))
|
||||
{
|
||||
pPath = lumpPathBuf;
|
||||
}
|
||||
|
||||
v_CBaseFileSystem_AddMapPackFile(pFileSystem, pPath, pPathID, addType);
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------
|
||||
// Purpose: attempts to mount VPK file for filesystem usage
|
||||
// Input : *this -
|
||||
@ -173,6 +213,7 @@ void VBaseFileSystem::Attach() const
|
||||
DetourAttach((LPVOID*)&v_CBaseFileSystem_Warning, &CBaseFileSystem::Warning);
|
||||
DetourAttach((LPVOID*)&v_CBaseFileSystem_LoadFromVPK, &CBaseFileSystem::VReadFromVPK);
|
||||
DetourAttach((LPVOID*)&v_CBaseFileSystem_LoadFromCache, &CBaseFileSystem::VReadFromCache);
|
||||
DetourAttach((LPVOID*)&v_CBaseFileSystem_AddMapPackFile, &CBaseFileSystem::VAddMapPackFile);
|
||||
DetourAttach((LPVOID*)&v_CBaseFileSystem_MountVPKFile, &CBaseFileSystem::VMountVPKFile);
|
||||
DetourAttach((LPVOID*)&v_CBaseFileSystem_UnmountVPKFile, &CBaseFileSystem::VUnmountVPKFile);
|
||||
}
|
||||
@ -182,6 +223,7 @@ void VBaseFileSystem::Detach() const
|
||||
DetourDetach((LPVOID*)&v_CBaseFileSystem_Warning, &CBaseFileSystem::Warning);
|
||||
DetourDetach((LPVOID*)&v_CBaseFileSystem_LoadFromVPK, &CBaseFileSystem::VReadFromVPK);
|
||||
DetourDetach((LPVOID*)&v_CBaseFileSystem_LoadFromCache, &CBaseFileSystem::VReadFromCache);
|
||||
DetourDetach((LPVOID*)&v_CBaseFileSystem_AddMapPackFile, &CBaseFileSystem::VAddMapPackFile);
|
||||
DetourDetach((LPVOID*)&v_CBaseFileSystem_MountVPKFile, &CBaseFileSystem::VMountVPKFile);
|
||||
DetourDetach((LPVOID*)&v_CBaseFileSystem_UnmountVPKFile, &CBaseFileSystem::VUnmountVPKFile);
|
||||
}
|
||||
|
@ -11,6 +11,7 @@ public:
|
||||
static bool VCheckDisk(const char* pszFilePath);
|
||||
static FileHandle_t VReadFromVPK(CBaseFileSystem* pFileSystem, FileHandle_t pResults, char* pszFilePath);
|
||||
static bool VReadFromCache(CBaseFileSystem* pFileSystem, char* pszFilePath, FileSystemCache* pCache);
|
||||
static void VAddMapPackFile(CBaseFileSystem* pFileSystem, const char* pPath, const char* pPathID, SearchPathAdd_t addType);
|
||||
static VPKData_t* VMountVPKFile(CBaseFileSystem* pFileSystem, const char* pszVpkPath);
|
||||
static const char* VUnmountVPKFile(CBaseFileSystem* pFileSystem, const char* pszVpkPath);
|
||||
|
||||
@ -51,6 +52,9 @@ inline auto v_CBaseFileSystem_LoadFromVPK = p_CBaseFileSystem_LoadFromVPK.RCast<
|
||||
inline CMemory p_CBaseFileSystem_LoadFromCache;
|
||||
inline auto v_CBaseFileSystem_LoadFromCache = p_CBaseFileSystem_LoadFromCache.RCast<bool(*)(CBaseFileSystem* pFileSystem, const char* pszAssetName, FileSystemCache* pCache)>();
|
||||
|
||||
inline CMemory p_CBaseFileSystem_AddMapPackFile;
|
||||
inline auto v_CBaseFileSystem_AddMapPackFile = p_CBaseFileSystem_AddMapPackFile.RCast<void (*)(CBaseFileSystem* pFileSystem, const char* pPath, const char* pPathID, SearchPathAdd_t addType)>();
|
||||
|
||||
inline CMemory p_CBaseFileSystem_MountVPKFile;
|
||||
inline auto v_CBaseFileSystem_MountVPKFile = p_CBaseFileSystem_MountVPKFile.RCast<VPKData_t* (*)(CBaseFileSystem* pFileSystem, const char* pszVpkPath)>();
|
||||
|
||||
@ -70,6 +74,7 @@ class VBaseFileSystem : public IDetour
|
||||
LogFunAdr("CBaseFileSystem::Warning", p_CBaseFileSystem_Warning.GetPtr());
|
||||
LogFunAdr("CBaseFileSystem::LoadFromVPK", p_CBaseFileSystem_LoadFromVPK.GetPtr());
|
||||
LogFunAdr("CBaseFileSystem::LoadFromCache", p_CBaseFileSystem_LoadFromCache.GetPtr());
|
||||
LogFunAdr("CBaseFileSystem::AddMapPackFile", p_CBaseFileSystem_AddMapPackFile.GetPtr());
|
||||
LogFunAdr("CBaseFileSystem::MountVPKFile", p_CBaseFileSystem_MountVPKFile.GetPtr());
|
||||
LogFunAdr("CBaseFileSystem::UnmountVPKFile", p_CBaseFileSystem_UnmountVPKFile.GetPtr());
|
||||
LogFunAdr("CBaseFileSystem::GetMountedVPKHandle", p_CBaseFileSystem_GetMountedVPKHandle.GetPtr());
|
||||
@ -80,6 +85,7 @@ class VBaseFileSystem : public IDetour
|
||||
p_CBaseFileSystem_Warning = g_GameDll.FindPatternSIMD("4C 89 4C 24 20 C3 CC CC CC CC CC CC CC CC CC CC 48");
|
||||
p_CBaseFileSystem_LoadFromVPK = g_GameDll.FindPatternSIMD("48 89 5C 24 ?? 57 48 81 EC ?? ?? ?? ?? 49 8B C0 4C 8D 8C 24 ?? ?? ?? ??");
|
||||
p_CBaseFileSystem_LoadFromCache = g_GameDll.FindPatternSIMD("40 53 48 81 EC ?? ?? ?? ?? 80 3D ?? ?? ?? ?? ?? 49 8B D8");
|
||||
p_CBaseFileSystem_AddMapPackFile = g_GameDll.FindPatternSIMD("4C 89 44 24 ?? 48 89 54 24 ?? 55 ?? 41 54 41 55 48 8D AC 24 ?? ?? ?? ??");
|
||||
p_CBaseFileSystem_MountVPKFile = g_GameDll.FindPatternSIMD("48 89 5C 24 ?? 48 89 6C 24 ?? 57 48 81 EC ?? ?? ?? ?? 48 8B F9 4C 8D 05 ?? ?? ?? ??");
|
||||
p_CBaseFileSystem_UnmountVPKFile = g_GameDll.FindPatternSIMD("48 89 5C 24 ?? 57 48 83 EC 20 48 8B DA 48 8B F9 48 8B CB 48 8D 15 ?? ?? ?? ?? E8 ?? ?? ?? ?? 48 85 C0");
|
||||
p_CBaseFileSystem_GetMountedVPKHandle = g_GameDll.FindPatternSIMD("48 89 74 24 ?? 57 48 81 EC ?? ?? ?? ?? 48 8B F9 4C 8D 05 ?? ?? ?? ??");
|
||||
@ -87,6 +93,7 @@ class VBaseFileSystem : public IDetour
|
||||
v_CBaseFileSystem_Warning = p_CBaseFileSystem_Warning.RCast<void(*)(CBaseFileSystem*, FileWarningLevel_t, const char*, ...)>(); /*4C 89 4C 24 20 C3 ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? 48*/
|
||||
v_CBaseFileSystem_LoadFromVPK = p_CBaseFileSystem_LoadFromVPK.RCast<FileHandle_t(*)(CBaseFileSystem*, FileHandle_t, const char*)>(); /*48 89 5C 24 ?? 57 48 81 EC ?? ?? ?? ?? 49 8B C0 4C 8D 8C 24 ?? ?? ?? ??*/
|
||||
v_CBaseFileSystem_LoadFromCache = p_CBaseFileSystem_LoadFromCache.RCast<bool(*)(CBaseFileSystem*, const char*, FileSystemCache*)>(); /*40 53 48 81 EC ?? ?? ?? ?? 80 3D ?? ?? ?? ?? ?? 49 8B D8*/
|
||||
v_CBaseFileSystem_AddMapPackFile = p_CBaseFileSystem_AddMapPackFile.RCast<void (*)(CBaseFileSystem*, const char*, const char*, SearchPathAdd_t)>();
|
||||
v_CBaseFileSystem_MountVPKFile = p_CBaseFileSystem_MountVPKFile.RCast<VPKData_t*(*)(CBaseFileSystem*, const char*)>(); /*48 89 5C 24 ?? 48 89 6C 24 ?? 57 48 81 EC ?? ?? ?? ?? 48 8B F9 4C 8D 05 ?? ?? ?? ??*/
|
||||
v_CBaseFileSystem_UnmountVPKFile = p_CBaseFileSystem_UnmountVPKFile.RCast<const char*(*)(CBaseFileSystem*, const char*)>(); /*48 89 5C 24 ?? 57 48 83 EC 20 48 8B DA 48 8B F9 48 8B CB 48 8D 15 ?? ?? ?? ?? E8 ?? ?? ?? ?? 48 85 C0*/
|
||||
v_CBaseFileSystem_GetMountedVPKHandle = p_CBaseFileSystem_GetMountedVPKHandle.RCast<int (*)(CBaseFileSystem*, const char*)>(); /*48 89 74 24 ?? 57 48 81 EC ?? ?? ?? ?? 48 8B F9 4C 8D 05 ?? ?? ?? ??*/
|
||||
|
@ -2,6 +2,43 @@
|
||||
// Base game executable patch file; this executable
|
||||
// contains all patches applied directly to the image.
|
||||
|
||||
/////////////////////////////
|
||||
/////////////////////////////
|
||||
//// Code adjustments ////
|
||||
/////////////////////////////
|
||||
/////////////////////////////
|
||||
// This patch adds support for loading the 'LUMP_PAKFILE' lump as a discrete file.
|
||||
// The function originally loaded the BSP, and stored the header in a local variable.
|
||||
// This means that we need to store the BSP header in the lump too, if we want to load
|
||||
// the packfile lump separately. To avoid this, we hook this function in SDK code,
|
||||
// and load the BSP header into the static 's_MapHeader' memory. The patch below makes
|
||||
// the function read the static fields instead, and uses the descritprs in the header to
|
||||
// read out the lump path passed in. A separate tool sets the 'fileofs' field to 0, so the
|
||||
// packfile lump can be loaded without any additional patching.
|
||||
0x382152: "cmp dword ptr ds:[0x00000001666EC6C0], 0x50534272" // s_MapHeader.ident
|
||||
0x382162: "mov eax, dword ptr ds:[0x00000001666EC6C4]" // s_MapHeader.version
|
||||
|
||||
0x382174: "cmp dword ptr ds:[0x00000001666EC954], 0x10" // s_MapHeader.lumps[LUMP_PAKFILE].filelen
|
||||
0x382181: "movsxd rcx, dword ptr ds:[0x00000001666EC950]" // s_MapHeader.lumps[LUMP_PAKFILE].fileofs
|
||||
|
||||
0x382188: "mov rdx, rcx" // Move the operation done at 0x382181 (stored into RCX) into RDX; no need to index into it again.
|
||||
|
||||
// Due to the simplification of the operation above, 2 bytes had to be nopped.
|
||||
0x38218B: "nop"
|
||||
0x38218C: "nop"
|
||||
|
||||
0x38226E: "movsxd r8, dword ptr ds:[0x00000001666EC950]" // s_MapHeader.lumps[LUMP_PAKFILE].fileofs
|
||||
0x382275: "movsxd rdx, dword ptr ds:[0x00000001666EC954]" // s_MapHeader.lumps[LUMP_PAKFILE].filelen
|
||||
|
||||
0x38247B: "cmp dword ptr ds:[0x00000001666EC6C0], 0x50534272" // s_MapHeader.ident
|
||||
0x38248B: "mov eax, dword ptr ds:[0x00000001666EC6C4]" // s_MapHeader.version
|
||||
|
||||
0x38249D: "cmp dword ptr ds:[0x00000001666EC954], 0x10" // s_MapHeader.lumps[LUMP_PAKFILE].filelen
|
||||
0x3824B6: "movsxd r8, dword ptr ds:[0x00000001666EC950]" // s_MapHeader.lumps[LUMP_PAKFILE].fileofs
|
||||
|
||||
0x38257E: movsxd r8, dword ptr ds:[0x00000001666EC950] // s_MapHeader.lumps[LUMP_PAKFILE].fileofs
|
||||
0x382585: movsxd rdx, dword ptr ds:[0x00000001666EC954] // s_MapHeader.lumps[LUMP_PAKFILE].filelen
|
||||
|
||||
/////////////////////////////
|
||||
/////////////////////////////
|
||||
//// Code defects ////
|
||||
|
Loading…
x
Reference in New Issue
Block a user