2023-06-18 01:16:24 +02:00
|
|
|
//=============================================================================//
|
|
|
|
//
|
|
|
|
// Purpose:
|
|
|
|
//
|
|
|
|
//=============================================================================//
|
|
|
|
#include "memstd.h"
|
|
|
|
|
2023-06-25 11:37:52 +02:00
|
|
|
static bool s_bAllocatorInitialized = false;
|
|
|
|
static void InitAllocator()
|
|
|
|
{
|
|
|
|
if (!s_bAllocatorInitialized)
|
|
|
|
{
|
|
|
|
s_bAllocatorInitialized = true;
|
|
|
|
|
|
|
|
// https://en.wikipedia.org/wiki/Win32_Thread_Information_Block
|
|
|
|
const PEB64* processEnvBlock = reinterpret_cast<PEB64*>(__readgsqword(0x60));
|
|
|
|
const QWORD imageBase = processEnvBlock->ImageBaseAddress;
|
|
|
|
|
|
|
|
CreateGlobalMemAlloc = CModule::GetExportedSymbol(imageBase,
|
|
|
|
"CreateGlobalMemAlloc").RCast<CStdMemAlloc* (*)(void)>();
|
|
|
|
|
|
|
|
g_pMemAllocSingleton = CModule::GetExportedSymbol(imageBase,
|
|
|
|
"g_pMemAllocSingleton").DerefSelf().RCast<CStdMemAlloc*>();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-06-18 01:16:24 +02:00
|
|
|
//=============================================================================//
|
2023-06-25 11:37:52 +02:00
|
|
|
// Reimplementation of standard C functions for memalloc callbacks
|
|
|
|
// ---------------------------------------------------------------------------
|
|
|
|
// The replacement functions use the game's internal memalloc system instead
|
2023-06-18 01:16:24 +02:00
|
|
|
//=============================================================================//
|
|
|
|
extern "C" void* R_malloc(size_t nSize)
|
|
|
|
{
|
|
|
|
Assert(nSize);
|
2023-06-25 11:37:52 +02:00
|
|
|
InitAllocator();
|
2023-06-26 22:34:24 +02:00
|
|
|
return MemAllocSingleton()->Alloc(nSize);
|
2023-06-18 01:16:24 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
extern "C" void R_free(void* pBlock)
|
|
|
|
{
|
2023-06-18 12:06:28 +02:00
|
|
|
//Assert(pBlock);
|
2023-06-25 11:37:52 +02:00
|
|
|
InitAllocator();
|
2023-06-18 01:16:24 +02:00
|
|
|
MemAllocSingleton()->Free(pBlock);
|
|
|
|
}
|
|
|
|
|
|
|
|
extern "C" void* R_realloc(void* pBlock, size_t nSize)
|
|
|
|
{
|
2023-06-25 11:37:52 +02:00
|
|
|
//Assert(pBlock && nSize);
|
|
|
|
|
|
|
|
InitAllocator();
|
2023-06-18 01:16:24 +02:00
|
|
|
|
|
|
|
if (nSize)
|
2023-06-26 22:34:24 +02:00
|
|
|
return MemAllocSingleton()->Realloc(pBlock, nSize);
|
2023-06-18 01:16:24 +02:00
|
|
|
else
|
|
|
|
{
|
2023-06-26 22:34:24 +02:00
|
|
|
MemAllocSingleton()->InternalFree(pBlock, "tier0_static128", 0);
|
2023-06-18 01:16:24 +02:00
|
|
|
return nullptr;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
extern "C" char* R_strdup(const char* pString)
|
|
|
|
{
|
|
|
|
Assert(pString);
|
|
|
|
|
2023-06-25 11:37:52 +02:00
|
|
|
InitAllocator();
|
|
|
|
|
2023-06-18 01:16:24 +02:00
|
|
|
const size_t nLen = strlen(pString) + 1;
|
2023-06-26 22:34:24 +02:00
|
|
|
void* pNew = MemAllocSingleton()->Alloc(nLen);
|
2023-06-18 01:16:24 +02:00
|
|
|
|
|
|
|
if (!pNew)
|
|
|
|
return nullptr;
|
|
|
|
|
|
|
|
return reinterpret_cast<char*>(memcpy(pNew, pString, nLen));
|
|
|
|
}
|
|
|
|
|
|
|
|
extern "C" void* R_calloc(size_t nCount, size_t nSize)
|
|
|
|
{
|
|
|
|
Assert(nCount && nSize);
|
|
|
|
|
2023-06-25 11:37:52 +02:00
|
|
|
InitAllocator();
|
|
|
|
|
2023-06-18 01:16:24 +02:00
|
|
|
const size_t nTotal = nCount * nSize;
|
2023-06-26 22:34:24 +02:00
|
|
|
void* pNew = MemAllocSingleton()->Alloc(nTotal);
|
2023-06-18 01:16:24 +02:00
|
|
|
|
|
|
|
memset(pNew, NULL, nTotal);
|
|
|
|
return pNew;
|
|
|
|
}
|
2023-06-25 11:37:52 +02:00
|
|
|
|
2023-06-27 21:37:15 +02:00
|
|
|
extern "C" void* R_recalloc(void* pBlock, size_t nSize)
|
|
|
|
{
|
|
|
|
InitAllocator();
|
|
|
|
|
|
|
|
void* pMemOut = MemAllocSingleton()->Realloc(pBlock, nSize);
|
|
|
|
|
|
|
|
if (!pBlock)
|
|
|
|
memset(pMemOut, NULL, nSize);
|
|
|
|
|
|
|
|
return pMemOut;
|
|
|
|
}
|
2023-06-26 22:34:24 +02:00
|
|
|
|
|
|
|
extern "C" size_t R_mallocsize(void* pBlock)
|
|
|
|
{
|
|
|
|
InitAllocator();
|
|
|
|
size_t nSize = MemAllocSingleton()->GetSize(pBlock);
|
|
|
|
return nSize;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2023-06-25 11:37:52 +02:00
|
|
|
// !TODO: other 'new' operators introduced in C++17.
|
|
|
|
void* operator new(std::size_t n) noexcept(false)
|
|
|
|
{
|
|
|
|
return malloc(n);
|
|
|
|
}
|
|
|
|
void operator delete(void* p) throw()
|
|
|
|
{
|
|
|
|
return free(p);
|
|
|
|
}
|