mirror of
https://github.com/Mauler125/r5sdk.git
synced 2025-02-09 19:15:03 +01:00
81 lines
2.8 KiB
C++
81 lines
2.8 KiB
C++
|
//=============================================================================//
|
||
|
//
|
||
|
// Purpose: async file loading, unloading and the management thereof
|
||
|
//
|
||
|
//=============================================================================//
|
||
|
#include "rtech/ipakfile.h"
|
||
|
#include "rtech/pak/paktools.h"
|
||
|
#include "asyncio.h"
|
||
|
|
||
|
//----------------------------------------------------------------------------------
|
||
|
// open a file and add it to the async file handle array
|
||
|
//----------------------------------------------------------------------------------
|
||
|
int FS_OpenAsyncFile(const char* const filePath, const int logLevel, size_t* const fileSizeOut)
|
||
|
{
|
||
|
const CHAR* fileToLoad = filePath;
|
||
|
char overridePath[1024];
|
||
|
|
||
|
// is this a pak file and do we have an override
|
||
|
if (strstr(fileToLoad, PLATFORM_PAK_PATH) &&
|
||
|
Pak_GetOverride(fileToLoad, overridePath, sizeof(overridePath)))
|
||
|
{
|
||
|
fileToLoad = overridePath;
|
||
|
}
|
||
|
|
||
|
const HANDLE hFile = CreateFileA(fileToLoad, GENERIC_READ,
|
||
|
FILE_SHARE_READ | FILE_SHARE_DELETE, 0, OPEN_EXISTING, FILE_SUPPORTS_GHOSTING, 0);
|
||
|
|
||
|
if (hFile == INVALID_HANDLE_VALUE)
|
||
|
return FS_ASYNC_FILE_INVALID;
|
||
|
|
||
|
if (fileSizeOut)
|
||
|
{
|
||
|
// get the size of the file we just opened
|
||
|
LARGE_INTEGER fileSize;
|
||
|
|
||
|
if (GetFileSizeEx(hFile, &fileSize))
|
||
|
*fileSizeOut = fileSize.QuadPart;
|
||
|
}
|
||
|
|
||
|
const int fileIdx = g_pAsyncFileSlotMgr->FindSlot();
|
||
|
const int slotNum = (fileIdx & ASYNC_MAX_FILE_HANDLES_MASK);
|
||
|
|
||
|
AsyncHandleTracker_t& tracker = g_pAsyncFileSlots[slotNum];
|
||
|
|
||
|
tracker.m_nFileNumber = fileIdx;
|
||
|
tracker.m_hFileHandle = hFile;
|
||
|
tracker.m_nCurOfs = 1;
|
||
|
|
||
|
if (async_debug_level->GetInt() >= logLevel)
|
||
|
Msg(eDLL_T::RTECH, "%s: Opened file: '%s' to slot #%d\n", __FUNCTION__, fileToLoad, slotNum);
|
||
|
|
||
|
return fileIdx;
|
||
|
}
|
||
|
|
||
|
//----------------------------------------------------------------------------------
|
||
|
// close a file and remove it from the async file handle array
|
||
|
//----------------------------------------------------------------------------------
|
||
|
void FS_CloseAsyncFile(const short fileHandle)
|
||
|
{
|
||
|
const int slotNum = fileHandle & ASYNC_MAX_FILE_HANDLES_MASK;
|
||
|
AsyncHandleTracker_t& tracker = g_pAsyncFileSlots[slotNum];
|
||
|
|
||
|
if (ThreadInterlockedExchangeAdd(&tracker.m_nCurOfs, 0xFFFFFFFF) <= 1)
|
||
|
{
|
||
|
CloseHandle(tracker.m_hFileHandle);
|
||
|
tracker.m_hFileHandle = INVALID_HANDLE_VALUE;
|
||
|
|
||
|
g_pAsyncFileSlotMgr->FreeSlot(slotNum);
|
||
|
|
||
|
if (async_debug_close->GetBool())
|
||
|
Msg(eDLL_T::RTECH, "%s: Closed file from slot #%d\n", __FUNCTION__, slotNum);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
///////////////////////////////////////////////////////////////////////////////
|
||
|
void V_AsyncIO::Detour(const bool bAttach) const
|
||
|
{
|
||
|
DetourSetup(&v_FS_OpenAsyncFile, &FS_OpenAsyncFile, bAttach);
|
||
|
DetourSetup(&v_FS_CloseAsyncFile, &FS_CloseAsyncFile, bAttach);
|
||
|
}
|