aboutsummaryrefslogtreecommitdiff
path: root/primedev/core/tier0.cpp
blob: 639b3bf8ce1949358ecb8ff24796821f1b686122 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
#include "tier0.h"

IMemAlloc* g_pMemAllocSingleton = nullptr;

CommandLineType CommandLine;
Plat_FloatTimeType Plat_FloatTime;
ThreadInServerFrameThreadType ThreadInServerFrameThread;

typedef IMemAlloc* (*CreateGlobalMemAllocType)();
CreateGlobalMemAllocType CreateGlobalMemAlloc;

// needs to be a seperate function, since memalloc.cpp calls it
void TryCreateGlobalMemAlloc()
{
	// init memalloc stuff
	CreateGlobalMemAlloc =
		reinterpret_cast<CreateGlobalMemAllocType>(GetProcAddress(GetModuleHandleA("tier0.dll"), "CreateGlobalMemAlloc"));
	g_pMemAllocSingleton = CreateGlobalMemAlloc(); // if it already exists, this returns the preexisting IMemAlloc instance
}

HRESULT WINAPI _SetThreadDescription(HANDLE hThread, PCWSTR lpThreadDescription)
{
	// need to grab it dynamically as this function was only introduced at some point in Windows 10
	static decltype(&SetThreadDescription) _SetThreadDescription =
		CModule("KernelBase.dll").GetExportedFunction("SetThreadDescription").RCast<decltype(&SetThreadDescription)>();

	if (_SetThreadDescription)
		return _SetThreadDescription(hThread, lpThreadDescription);

	return ERROR_OLD_WIN_VERSION;
}

static void(__fastcall* o_pThreadSetDebugName)(HANDLE threadHandle, const char* name) = nullptr;
static void __fastcall h_ThreadSetDebugName(HANDLE threadHandle, const char* name)
{
	if (threadHandle == 0)
		threadHandle = GetCurrentThread();

	// TODO: This "method" of "charset conversion" from string to wstring is abhorrent. Change it to a proper one
	// as soon as Northstar has some helper function to do proper charset conversions.
	auto tmp = std::string(name);
	_SetThreadDescription(threadHandle, std::wstring(tmp.begin(), tmp.end()).c_str());

	o_pThreadSetDebugName(threadHandle, name);
}

ON_DLL_LOAD("tier0.dll", Tier0GameFuncs, (CModule module))
{
	// shouldn't be necessary, but do this just in case
	TryCreateGlobalMemAlloc();

	o_pThreadSetDebugName = module.GetExportedFunction("ThreadSetDebugName").RCast<decltype(o_pThreadSetDebugName)>();
	HookAttach(&(PVOID&)o_pThreadSetDebugName, (PVOID)h_ThreadSetDebugName);

	// setup tier0 funcs
	CommandLine = module.GetExportedFunction("CommandLine").RCast<CommandLineType>();
	Plat_FloatTime = module.GetExportedFunction("Plat_FloatTime").RCast<Plat_FloatTimeType>();
	ThreadInServerFrameThread = module.GetExportedFunction("ThreadInServerFrameThread").RCast<ThreadInServerFrameThreadType>();
}