[ScriptErrors]: Add useful errors to scripts (#721)
This commit is contained in:
parent
f34377b456
commit
33f554effd
@ -3,6 +3,7 @@
|
||||
#include "Int64.hpp"
|
||||
#include "IO.hpp"
|
||||
#include "Script.hpp"
|
||||
#include "ScriptError.hpp"
|
||||
#include "ScriptExtension.hpp"
|
||||
#include "ScriptPatches.hpp"
|
||||
#include "ScriptStorage.hpp"
|
||||
@ -14,6 +15,7 @@ namespace Components
|
||||
Loader::Register(new Int64());
|
||||
Loader::Register(new IO());
|
||||
Loader::Register(new Script());
|
||||
Loader::Register(new ScriptError());
|
||||
Loader::Register(new ScriptExtension());
|
||||
Loader::Register(new ScriptPatches());
|
||||
Loader::Register(new ScriptStorage());
|
||||
|
@ -6,10 +6,6 @@ namespace Components
|
||||
std::vector<Script::ScriptFunction> Script::CustomScrFunctions;
|
||||
std::vector<Script::ScriptMethod> Script::CustomScrMethods;
|
||||
|
||||
std::string Script::ScriptName;
|
||||
std::vector<std::string> Script::ScriptNameStack;
|
||||
unsigned short Script::FunctionName;
|
||||
std::unordered_map<int, std::string> Script::ScriptBaseProgramNum;
|
||||
int Script::LastFrameTime = -1;
|
||||
|
||||
std::unordered_map<const char*, const char*> Script::ReplacedFunctions;
|
||||
@ -18,191 +14,6 @@ namespace Components
|
||||
std::unordered_map<std::string, int> Script::ScriptMainHandles;
|
||||
std::unordered_map<std::string, int> Script::ScriptInitHandles;
|
||||
|
||||
void Script::FunctionError()
|
||||
{
|
||||
const auto* funcName = Game::SL_ConvertToString(FunctionName);
|
||||
|
||||
Game::Scr_ShutdownAllocNode();
|
||||
|
||||
Logger::Print(Game::CON_CHANNEL_PARSERSCRIPT, "\n");
|
||||
Logger::Print(Game::CON_CHANNEL_PARSERSCRIPT, "******* script compile error *******\n");
|
||||
Logger::Print(Game::CON_CHANNEL_PARSERSCRIPT, "Error: unknown function {} in {}\n", funcName, ScriptName);
|
||||
Logger::Print(Game::CON_CHANNEL_PARSERSCRIPT, "************************************\n");
|
||||
|
||||
Logger::Error(Game::ERR_SCRIPT_DROP, "script compile error\nunknown function {}\n{}\n\n", funcName, ScriptName);
|
||||
}
|
||||
|
||||
__declspec(naked) void Script::StoreFunctionNameStub()
|
||||
{
|
||||
__asm
|
||||
{
|
||||
mov eax, [esp - 8h]
|
||||
mov FunctionName, ax
|
||||
|
||||
sub esp, 0Ch
|
||||
push 0
|
||||
push edi
|
||||
|
||||
mov eax, 612DB6h
|
||||
jmp eax
|
||||
}
|
||||
}
|
||||
|
||||
void Script::RuntimeError(const char* codePos, unsigned int index, const char* msg, const char* dialogMessage)
|
||||
{
|
||||
// Allow error messages to be printed if developer mode is on
|
||||
// Should check scrVarPub.developer but it's absent
|
||||
// in this version of the game so let's check the dvar
|
||||
if (!Game::scrVmPub->terminal_error && !(*Game::com_developer)->current.integer)
|
||||
return;
|
||||
|
||||
// If were are developing let's call RuntimeErrorInternal
|
||||
// scrVmPub.debugCode seems to be always false
|
||||
if (Game::scrVmPub->debugCode || Game::scrVarPub->developer_script)
|
||||
{
|
||||
Game::RuntimeErrorInternal(Game::CON_CHANNEL_PARSERSCRIPT, codePos, index, msg);
|
||||
}
|
||||
else
|
||||
{
|
||||
Logger::Print(Game::CON_CHANNEL_PARSERSCRIPT, "{}\n", msg);
|
||||
}
|
||||
|
||||
// Let's not throw error unless we have to
|
||||
if (Game::scrVmPub->terminal_error)
|
||||
{
|
||||
if (dialogMessage == nullptr)
|
||||
dialogMessage = "";
|
||||
|
||||
Logger::Error(Game::ERR_SCRIPT_DROP, "\x15script runtime error\n(see console for details)\n{}\n{}", msg, dialogMessage);
|
||||
}
|
||||
}
|
||||
|
||||
void Script::StoreScriptName(const char* name)
|
||||
{
|
||||
ScriptNameStack.push_back(ScriptName);
|
||||
ScriptName = name;
|
||||
|
||||
if (!Utils::String::EndsWith(ScriptName, ".gsc"))
|
||||
{
|
||||
ScriptName.append(".gsc");
|
||||
}
|
||||
}
|
||||
|
||||
__declspec(naked) void Script::StoreScriptNameStub()
|
||||
{
|
||||
__asm
|
||||
{
|
||||
pushad
|
||||
|
||||
lea ecx, [esp + 30h]
|
||||
push ecx
|
||||
|
||||
call StoreScriptName
|
||||
add esp, 4h
|
||||
|
||||
popad
|
||||
|
||||
push ebp
|
||||
mov ebp, ds:1CDEAA8h
|
||||
|
||||
push 427DC3h
|
||||
retn
|
||||
}
|
||||
}
|
||||
|
||||
void Script::RestoreScriptName()
|
||||
{
|
||||
ScriptName = ScriptNameStack.back();
|
||||
ScriptNameStack.pop_back();
|
||||
}
|
||||
|
||||
__declspec(naked) void Script::RestoreScriptNameStub()
|
||||
{
|
||||
__asm
|
||||
{
|
||||
pushad
|
||||
call RestoreScriptName
|
||||
popad
|
||||
|
||||
mov ds:1CDEAA8h, ebp
|
||||
|
||||
push 427E77h
|
||||
retn
|
||||
}
|
||||
}
|
||||
|
||||
void Script::PrintSourcePos(const char* filename, unsigned int offset)
|
||||
{
|
||||
FileSystem::File script(filename);
|
||||
|
||||
if (script.exists())
|
||||
{
|
||||
std::string buffer = script.getBuffer();
|
||||
Utils::String::Replace(buffer, "\t", " ");
|
||||
|
||||
auto line = 1, lineOffset = 0, inlineOffset = 0;
|
||||
|
||||
for (size_t i = 0; i < buffer.size(); ++i)
|
||||
{
|
||||
// Terminate line
|
||||
if (i == offset)
|
||||
{
|
||||
while (buffer[i] != '\r' && buffer[i] != '\n' && buffer[i] != '\0')
|
||||
{
|
||||
++i;
|
||||
}
|
||||
|
||||
buffer[i] = '\0';
|
||||
break;
|
||||
}
|
||||
|
||||
if (buffer[i] == '\n')
|
||||
{
|
||||
++line;
|
||||
lineOffset = static_cast<int>(i); // Includes the line break!
|
||||
inlineOffset = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
++inlineOffset;
|
||||
}
|
||||
}
|
||||
|
||||
Logger::Print(Game::CON_CHANNEL_PARSERSCRIPT, "in file {}, line {}:", filename, line);
|
||||
Logger::Print(Game::CON_CHANNEL_PARSERSCRIPT, "{}\n", buffer.substr(lineOffset));
|
||||
|
||||
for (auto i = 0; i < (inlineOffset - 1); ++i)
|
||||
{
|
||||
Logger::Print(Game::CON_CHANNEL_PARSERSCRIPT, " ");
|
||||
}
|
||||
|
||||
Logger::Print(Game::CON_CHANNEL_PARSERSCRIPT, "*\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
Logger::Print(Game::CON_CHANNEL_PARSERSCRIPT, "in file {}, offset {}\n", filename, offset);
|
||||
}
|
||||
}
|
||||
|
||||
void Script::CompileError(unsigned int offset, const char* message, ...)
|
||||
{
|
||||
char msgbuf[1024] = {0};
|
||||
va_list va;
|
||||
va_start(va, message);
|
||||
_vsnprintf_s(msgbuf, _TRUNCATE, message, va);
|
||||
va_end(va);
|
||||
|
||||
Game::Scr_ShutdownAllocNode();
|
||||
|
||||
Logger::Print(Game::CON_CHANNEL_PARSERSCRIPT, "\n");
|
||||
Logger::Print(Game::CON_CHANNEL_PARSERSCRIPT, "******* script compile error *******\n");
|
||||
Logger::Print(Game::CON_CHANNEL_PARSERSCRIPT, "Error: {} ", msgbuf);
|
||||
PrintSourcePos(ScriptName.data(), offset);
|
||||
Logger::Print(Game::CON_CHANNEL_PARSERSCRIPT, "************************************\n\n");
|
||||
|
||||
Logger::Error(Game::ERR_SCRIPT_DROP, "script compile error\n{}\n{}\n(see console for actual details)\n", msgbuf, ScriptName);
|
||||
}
|
||||
|
||||
void Script::Scr_LoadGameType_Stub()
|
||||
{
|
||||
for (const auto& handle : ScriptMainHandles)
|
||||
@ -376,77 +187,6 @@ namespace Components
|
||||
return Utils::Hook::Call<Game::BuiltinMethod(const char**, int*)>(0x5FA360)(pName, type); // Player_GetMethod
|
||||
}
|
||||
|
||||
void Script::StoreScriptBaseProgramNum()
|
||||
{
|
||||
ScriptBaseProgramNum.insert_or_assign(Utils::Hook::Get<int>(0x1CFEEF8), ScriptName);
|
||||
}
|
||||
|
||||
void Script::Scr_PrintPrevCodePos(int scriptPos)
|
||||
{
|
||||
auto bestCodePos = -1, nextCodePos = -1, offset = -1;
|
||||
std::string file;
|
||||
|
||||
for (const auto& [key, value] : ScriptBaseProgramNum)
|
||||
{
|
||||
const auto codePos = key;
|
||||
|
||||
if (codePos > scriptPos)
|
||||
{
|
||||
if (nextCodePos == -1 || codePos < nextCodePos)
|
||||
nextCodePos = codePos;
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
if (codePos < bestCodePos)
|
||||
continue;
|
||||
|
||||
bestCodePos = codePos;
|
||||
|
||||
file = value;
|
||||
offset = scriptPos - bestCodePos;
|
||||
}
|
||||
|
||||
if (bestCodePos == -1)
|
||||
return;
|
||||
|
||||
Logger::Print(Game::CON_CHANNEL_PARSERSCRIPT, "\n@ {} ({} - {})\n", scriptPos, bestCodePos, nextCodePos);
|
||||
Logger::Print(Game::CON_CHANNEL_PARSERSCRIPT, "in {} ({} through the source)\n\n", file, ((offset * 100.0f) / (nextCodePos - bestCodePos)));
|
||||
}
|
||||
|
||||
__declspec(naked) void Script::Scr_PrintPrevCodePosStub()
|
||||
{
|
||||
__asm
|
||||
{
|
||||
push esi
|
||||
call Scr_PrintPrevCodePos
|
||||
add esp, 4h
|
||||
|
||||
pop esi
|
||||
retn
|
||||
}
|
||||
}
|
||||
|
||||
__declspec(naked) void Script::StoreScriptBaseProgramNumStub()
|
||||
{
|
||||
__asm
|
||||
{
|
||||
// execute our hook
|
||||
pushad
|
||||
call StoreScriptBaseProgramNum
|
||||
popad
|
||||
|
||||
// execute overwritten code caused by the jump hook
|
||||
sub eax, ds:201A460h // gScrVarPub_programBuffer
|
||||
add esp, 0Ch
|
||||
mov ds:1CFEEF8h, eax // gScrCompilePub_programLen
|
||||
|
||||
// jump back to the original code
|
||||
push 426C3Bh
|
||||
retn
|
||||
}
|
||||
}
|
||||
|
||||
unsigned int Script::SetExpFogStub()
|
||||
{
|
||||
if (Game::Scr_GetNumParam() == 6)
|
||||
@ -636,23 +376,10 @@ namespace Components
|
||||
|
||||
Script::Script()
|
||||
{
|
||||
Utils::Hook(0x612DB0, StoreFunctionNameStub, HOOK_JUMP).install()->quick();
|
||||
Utils::Hook(0x427E71, RestoreScriptNameStub, HOOK_JUMP).install()->quick();
|
||||
Utils::Hook(0x427DBC, StoreScriptNameStub, HOOK_JUMP).install()->quick();
|
||||
Utils::Hook(0x426C2D, StoreScriptBaseProgramNumStub, HOOK_JUMP).install()->quick();
|
||||
Utils::Hook(0x42281B, Scr_PrintPrevCodePosStub, HOOK_JUMP).install()->quick();
|
||||
|
||||
Utils::Hook(0x61E3AD, RuntimeError, HOOK_CALL).install()->quick();
|
||||
Utils::Hook(0x621976, RuntimeError, HOOK_CALL).install()->quick();
|
||||
Utils::Hook(0x62246E, RuntimeError, HOOK_CALL).install()->quick();
|
||||
// Skip check in GScr_CheckAllowedToSetPersistentData to prevent log spam in RuntimeError.
|
||||
// On IW5 the function is entirely nullsubbed
|
||||
Utils::Hook::Set<std::uint8_t>(0x5F8DBF, 0xEB);
|
||||
|
||||
Utils::Hook(0x612E8D, FunctionError, HOOK_CALL).install()->quick();
|
||||
Utils::Hook(0x612EA2, FunctionError, HOOK_CALL).install()->quick();
|
||||
Utils::Hook(0x434260, CompileError, HOOK_JUMP).install()->quick();
|
||||
|
||||
Utils::Hook(0x48EFFE, Scr_LoadGameType_Stub, HOOK_CALL).install()->quick();
|
||||
Utils::Hook(0x48F008, Scr_StartupGameType_Stub, HOOK_CALL).install()->quick();
|
||||
Utils::Hook(0x45D44A, GScr_LoadGameTypeScript_Stub, HOOK_CALL).install()->quick();
|
||||
|
@ -57,10 +57,6 @@ namespace Components
|
||||
static std::vector<ScriptFunction> CustomScrFunctions;
|
||||
static std::vector<ScriptMethod> CustomScrMethods;
|
||||
|
||||
static std::string ScriptName;
|
||||
static std::vector<std::string> ScriptNameStack;
|
||||
static unsigned short FunctionName;
|
||||
static std::unordered_map<int, std::string> ScriptBaseProgramNum;
|
||||
static int LastFrameTime;
|
||||
|
||||
static std::unordered_map<std::string, int> ScriptMainHandles;
|
||||
@ -69,19 +65,6 @@ namespace Components
|
||||
static std::unordered_map<const char*, const char*> ReplacedFunctions;
|
||||
static const char* ReplacedPos;
|
||||
|
||||
static void CompileError(unsigned int offset, const char* message, ...);
|
||||
static void PrintSourcePos(const char* filename, unsigned int offset);
|
||||
|
||||
static void FunctionError();
|
||||
static void StoreFunctionNameStub();
|
||||
static void RuntimeError(const char* codePos, unsigned int index, const char* msg, const char* dialogMessage);
|
||||
|
||||
static void StoreScriptName(const char* name);
|
||||
static void StoreScriptNameStub();
|
||||
|
||||
static void RestoreScriptName();
|
||||
static void RestoreScriptNameStub();
|
||||
|
||||
static void Scr_LoadGameType_Stub();
|
||||
static void Scr_StartupGameType_Stub();
|
||||
static void GScr_LoadGameTypeScript_Stub();
|
||||
@ -89,11 +72,6 @@ namespace Components
|
||||
static Game::BuiltinFunction BuiltIn_GetFunctionStub(const char** pName, int* type);
|
||||
static Game::BuiltinMethod BuiltIn_GetMethodStub(const char** pName, int* type);
|
||||
|
||||
static void StoreScriptBaseProgramNumStub();
|
||||
static void StoreScriptBaseProgramNum();
|
||||
static void Scr_PrintPrevCodePosStub();
|
||||
static void Scr_PrintPrevCodePos(int);
|
||||
|
||||
static unsigned int SetExpFogStub();
|
||||
|
||||
static void GetReplacedPos(const char* pos);
|
||||
|
1149
src/Components/Modules/GSC/ScriptError.cpp
Normal file
1149
src/Components/Modules/GSC/ScriptError.cpp
Normal file
File diff suppressed because it is too large
Load Diff
67
src/Components/Modules/GSC/ScriptError.hpp
Normal file
67
src/Components/Modules/GSC/ScriptError.hpp
Normal file
@ -0,0 +1,67 @@
|
||||
#pragma once
|
||||
|
||||
namespace Components
|
||||
{
|
||||
class ScriptError : public Component
|
||||
{
|
||||
public:
|
||||
ScriptError();
|
||||
|
||||
static int Scr_IsInOpcodeMemory(const char* pos);
|
||||
static int Scr_GetLineNum(unsigned int bufferIndex, unsigned int sourcePos);
|
||||
|
||||
static void RuntimeError(const char* codePos, unsigned int index, const char* msg, const char* dialogMessage);
|
||||
|
||||
private:
|
||||
// Replacement for variables not present in currently available structs
|
||||
static int developer_;
|
||||
|
||||
static Game::scrParserGlob_t scrParserGlob;
|
||||
static Game::scrParserPub_t scrParserPub;
|
||||
|
||||
static Game::HunkUser* g_debugUser;
|
||||
|
||||
static void AddOpcodePos(unsigned int sourcePos, int type);
|
||||
static void RemoveOpcodePos();
|
||||
static void AddThreadStartOpcodePos(unsigned int sourcePos);
|
||||
|
||||
static unsigned int Scr_GetPrevSourcePos(const char* codePos, unsigned int index);
|
||||
static Game::OpcodeLookup* Scr_GetPrevSourcePosOpcodeLookup(const char* codePos);
|
||||
static void Scr_CopyFormattedLine(char* line, const char* rawLine);
|
||||
static int Scr_GetLineNumInternal(const char* buf, unsigned int sourcePos, const char** startLine, int* col, Game::SourceBufferInfo* binfo);
|
||||
static unsigned int Scr_GetSourceBuffer(const char* codePos);
|
||||
static void Scr_PrintPrevCodePos(int channel, const char* codePos, unsigned int index);
|
||||
static int Scr_GetLineInfo(const char* buf, unsigned int sourcePos, int* col, char* line, Game::SourceBufferInfo* binfo);
|
||||
static void Scr_PrintSourcePos(int channel, const char* filename, const char* buf, unsigned int sourcePos);
|
||||
|
||||
static void RuntimeErrorInternal(int channel, const char* codePos, unsigned int index, const char* msg);
|
||||
|
||||
static void CompileError(unsigned int sourcePos, const char* msg, ...);
|
||||
static void CompileError2(const char* codePos, const char* msg, ...);
|
||||
|
||||
static void Scr_GetTextSourcePos(const char* buf, const char* codePos, char* line);
|
||||
|
||||
static void Scr_InitOpcodeLookup();
|
||||
static void Scr_ShutdownOpcodeLookup();
|
||||
|
||||
static void EmitThreadInternal_Stub();
|
||||
|
||||
static Game::SourceBufferInfo* Scr_GetNewSourceBuffer();
|
||||
static void Scr_AddSourceBufferInternal(const char* extFilename, const char* codePos, char* sourceBuf, int len, bool doEolFixup, bool archive);
|
||||
static char* Scr_ReadFile_FastFile(const char* filename, const char* extFilename, const char* codePos, bool archive);
|
||||
static char* Scr_ReadFile_LoadObj(const char* filename, const char* extFilename, const char* codePos, bool archive);
|
||||
static char* Scr_ReadFile(const char* filename, const char* extFilename, const char* codePos, bool archive);
|
||||
static char* Scr_AddSourceBuffer(const char* filename, const char* extFilename, const char* codePos, bool archive);
|
||||
static unsigned int Scr_LoadScriptInternal_Hk(const char* filename, Game::PrecacheEntry* entries, int entriesCount);
|
||||
|
||||
static void Scr_Settings_Hk(int developer, int developer_script, int abort_on_error);
|
||||
|
||||
static void MT_Reset_Stub();
|
||||
static void SL_ShutdownSystem_Stub(unsigned int user);
|
||||
|
||||
static void Hunk_InitDebugMemory();
|
||||
static void Hunk_ShutdownDebugMemory();
|
||||
static void* Hunk_AllocDebugMem(int size);
|
||||
static void Hunk_FreeDebugMem(void* ptr);
|
||||
};
|
||||
}
|
@ -8,7 +8,7 @@ namespace Components
|
||||
auto fileHandle = 0;
|
||||
auto fileSize = Game::FS_FOpenFileRead(filename, &fileHandle);
|
||||
|
||||
if (fileHandle != 0)
|
||||
if (fileHandle)
|
||||
{
|
||||
if ((fileSize + 1) <= size)
|
||||
{
|
||||
@ -37,7 +37,7 @@ namespace Components
|
||||
auto fileHandle = 0;
|
||||
auto fileSize = Game::FS_FOpenFileRead(filename, &fileHandle);
|
||||
|
||||
if (fileHandle != 0)
|
||||
if (fileHandle)
|
||||
{
|
||||
if (fileSize < 0x8000)
|
||||
{
|
||||
@ -99,9 +99,8 @@ namespace Components
|
||||
|
||||
const char* RawFiles::Com_LoadInfoString_Hk(const char* fileName, const char* fileDesc, const char* ident, char* loadBuffer)
|
||||
{
|
||||
const char* buffer;
|
||||
|
||||
buffer = Com_LoadInfoString_LoadObj(fileName, fileDesc, ident, loadBuffer);
|
||||
const auto* buffer = Com_LoadInfoString_LoadObj(fileName, fileDesc, ident, loadBuffer);
|
||||
if (!buffer)
|
||||
{
|
||||
buffer = Game::Com_LoadInfoString_FastFile(fileName, fileDesc, ident, loadBuffer);
|
||||
|
@ -56,7 +56,7 @@ BOOL APIENTRY DllMain(HINSTANCE /*hinstDLL*/, DWORD fdwReason, LPVOID /*lpvReser
|
||||
|
||||
#ifndef DEBUG_BINARY_CHECK
|
||||
const auto* binary = reinterpret_cast<const char*>(0x6F9358);
|
||||
if (binary == nullptr || std::strcmp(binary, BASEGAME_NAME) != 0)
|
||||
if (binary == nullptr || std::memcmp(binary, BASEGAME_NAME, 14) != 0)
|
||||
#endif
|
||||
{
|
||||
MessageBoxA(nullptr,
|
||||
|
@ -247,9 +247,6 @@ namespace Game
|
||||
Vec2Normalize_t Vec2Normalize = Vec2Normalize_t(0x416F70);
|
||||
Vec2NormalizeFast_t Vec2NormalizeFast = Vec2NormalizeFast_t(0x5FC830);
|
||||
|
||||
Z_VirtualAlloc_t Z_VirtualAlloc = Z_VirtualAlloc_t(0x4CFBA0);
|
||||
Z_Malloc_t Z_Malloc = Z_Malloc_t(0x4F3680);
|
||||
|
||||
I_strncpyz_t I_strncpyz = I_strncpyz_t(0x4D6F80);
|
||||
I_CleanStr_t I_CleanStr = I_CleanStr_t(0x4AD470);
|
||||
|
||||
|
@ -569,12 +569,6 @@ namespace Game
|
||||
typedef void(*Vec2NormalizeFast_t)(float* v);
|
||||
extern Vec2NormalizeFast_t Vec2NormalizeFast;
|
||||
|
||||
typedef void*(*Z_VirtualAlloc_t)(int size);
|
||||
extern Z_VirtualAlloc_t Z_VirtualAlloc;
|
||||
|
||||
typedef void*(*Z_Malloc_t)(int size);
|
||||
extern Z_Malloc_t Z_Malloc;
|
||||
|
||||
typedef void(*I_strncpyz_t)(char* dest, const char* src, int destsize);
|
||||
extern I_strncpyz_t I_strncpyz;
|
||||
|
||||
|
@ -10,6 +10,7 @@
|
||||
#include "Script.hpp"
|
||||
#include "Server.hpp"
|
||||
#include "System.hpp"
|
||||
#include "Zone.hpp"
|
||||
|
||||
namespace Game
|
||||
{
|
||||
|
@ -6,6 +6,12 @@ namespace Game
|
||||
RemoveRefToObject_t RemoveRefToObject = RemoveRefToObject_t(0x437190);
|
||||
AllocObject_t AllocObject = AllocObject_t(0x434320);
|
||||
AddRefToValue_t AddRefToValue = AddRefToValue_t(0x482740);
|
||||
FindVariable_t FindVariable = FindVariable_t(0x4AB650);
|
||||
GetVariable_t GetVariable = GetVariable_t(0x419970);
|
||||
RemoveVariable_t RemoveVariable = RemoveVariable_t(0x480B40);
|
||||
FindObject_t FindObject = FindObject_t(0x4CF2F0);
|
||||
GetObject_t GetObject = GetObject_t(0x48B9D0);
|
||||
GetNewVariable_t GetNewVariable = GetNewVariable_t(0x4CC520);
|
||||
AllocThread_t AllocThread = AllocThread_t(0x4F78C0);
|
||||
|
||||
VM_Execute_0_t VM_Execute_0 = VM_Execute_0_t(0x6222A0);
|
||||
@ -16,7 +22,9 @@ namespace Game
|
||||
Scr_StartupGameType_t Scr_StartupGameType = Scr_StartupGameType_t(0x438720);
|
||||
|
||||
Scr_LoadScript_t Scr_LoadScript = Scr_LoadScript_t(0x45D940);
|
||||
Scr_ReadFile_FastFile_t Scr_ReadFile_FastFile = Scr_ReadFile_FastFile_t(0x61AAB0);
|
||||
Scr_GetFunctionHandle_t Scr_GetFunctionHandle = Scr_GetFunctionHandle_t(0x4234F0);
|
||||
Scr_CreateCanonicalFilename_t Scr_CreateCanonicalFilename = Scr_CreateCanonicalFilename_t(0x4A0220);
|
||||
|
||||
Scr_GetString_t Scr_GetString = Scr_GetString_t(0x425900);
|
||||
Scr_GetConstString_t Scr_GetConstString = Scr_GetConstString_t(0x494830);
|
||||
@ -75,10 +83,18 @@ namespace Game
|
||||
SL_AddRefToString_t SL_AddRefToString = SL_AddRefToString_t(0x4D9B00);
|
||||
SL_RemoveRefToString_t SL_RemoveRefToString = SL_RemoveRefToString_t(0x47CD70);
|
||||
|
||||
ScriptParse_t ScriptParse = ScriptParse_t(0x48A4F0);
|
||||
ScriptCompile_t ScriptCompile = ScriptCompile_t(0x426B80);
|
||||
|
||||
scr_const_t* scr_const = reinterpret_cast<scr_const_t*>(0x1AA2E00);
|
||||
|
||||
scrVmPub_t* scrVmPub = reinterpret_cast<scrVmPub_t*>(0x2040CF0);
|
||||
scrVarPub_t* scrVarPub = reinterpret_cast<scrVarPub_t*>(0x201A408);
|
||||
scrCompilePub_t* scrCompilePub = reinterpret_cast<scrCompilePub_t*>(0x1CDEEC0);
|
||||
scrAnimPub_t* scrAnimPub = reinterpret_cast<scrAnimPub_t*>(0x1CDEAA0);
|
||||
|
||||
char* g_EndPos = reinterpret_cast<char*>(0x2045498);
|
||||
bool* g_loadedImpureScript = reinterpret_cast<bool*>(0x1DC2208);
|
||||
|
||||
game_hudelem_s* g_hudelems = reinterpret_cast<game_hudelem_s*>(0x18565A8);
|
||||
|
||||
|
@ -14,6 +14,24 @@ namespace Game
|
||||
typedef void(*AddRefToValue_t)(int type, VariableUnion u);
|
||||
extern AddRefToValue_t AddRefToValue;
|
||||
|
||||
typedef unsigned int(*FindVariable_t)(unsigned int parentId, unsigned int unsignedValue);
|
||||
extern FindVariable_t FindVariable;
|
||||
|
||||
typedef unsigned int(*GetVariable_t)(unsigned int parentId, unsigned int unsignedValue);
|
||||
extern GetVariable_t GetVariable;
|
||||
|
||||
typedef void(*RemoveVariable_t)(unsigned int parentId, unsigned int unsignedValue);
|
||||
extern RemoveVariable_t RemoveVariable;
|
||||
|
||||
typedef unsigned int(*FindObject_t)(unsigned int parentId, unsigned int id);
|
||||
extern FindObject_t FindObject;
|
||||
|
||||
typedef unsigned int(*GetObject_t)(unsigned int parentId, unsigned int id);
|
||||
extern GetObject_t GetObject;
|
||||
|
||||
typedef unsigned int(*GetNewVariable_t)(unsigned int parentId, unsigned int unsignedValue);
|
||||
extern GetNewVariable_t GetNewVariable;
|
||||
|
||||
typedef unsigned int(*AllocThread_t)(unsigned int self);
|
||||
extern AllocThread_t AllocThread;
|
||||
|
||||
@ -44,7 +62,7 @@ namespace Game
|
||||
typedef void(*Scr_ShutdownAllocNode_t)();
|
||||
extern Scr_ShutdownAllocNode_t Scr_ShutdownAllocNode;
|
||||
|
||||
typedef char* (*Scr_GetGameTypeNameForScript_t)(const char* pszGameTypeScript);
|
||||
typedef char*(*Scr_GetGameTypeNameForScript_t)(const char* pszGameTypeScript);
|
||||
extern Scr_GetGameTypeNameForScript_t Scr_GetGameTypeNameForScript;
|
||||
|
||||
typedef int(*Scr_IsValidGameType_t)(const char* pszGameType);
|
||||
@ -59,6 +77,15 @@ namespace Game
|
||||
typedef int(*Scr_LoadScript_t)(const char*);
|
||||
extern Scr_LoadScript_t Scr_LoadScript;
|
||||
|
||||
typedef char*(*Scr_ReadFile_FastFile_t)(const char* filename, const char* extFilename, const char* codePos, const char* archive);
|
||||
extern Scr_ReadFile_FastFile_t Scr_ReadFile_FastFile;
|
||||
|
||||
typedef int(*Scr_GetFunctionHandle_t)(const char* filename, const char* name);
|
||||
extern Scr_GetFunctionHandle_t Scr_GetFunctionHandle;
|
||||
|
||||
typedef unsigned int(*Scr_CreateCanonicalFilename_t)(const char* filename);
|
||||
extern Scr_CreateCanonicalFilename_t Scr_CreateCanonicalFilename;
|
||||
|
||||
typedef const char*(*Scr_GetString_t)(unsigned int index);
|
||||
extern Scr_GetString_t Scr_GetString;
|
||||
|
||||
@ -86,9 +113,6 @@ namespace Game
|
||||
typedef unsigned int(*Scr_GetEntityId_t)(int entnum, unsigned int classnum);
|
||||
extern Scr_GetEntityId_t Scr_GetEntityId;
|
||||
|
||||
typedef int(*Scr_GetFunctionHandle_t)(const char* filename, const char* name);
|
||||
extern Scr_GetFunctionHandle_t Scr_GetFunctionHandle;
|
||||
|
||||
typedef int(*Scr_ExecThread_t)(int handle, unsigned int paramcount);
|
||||
extern Scr_ExecThread_t Scr_ExecThread;
|
||||
|
||||
@ -176,6 +200,18 @@ namespace Game
|
||||
typedef void(*SL_RemoveRefToString_t)(unsigned int stringValue);
|
||||
extern SL_RemoveRefToString_t SL_RemoveRefToString;
|
||||
|
||||
typedef void(*ScriptParse_t)(sval_u* parseData, unsigned char user);
|
||||
extern ScriptParse_t ScriptParse;
|
||||
|
||||
typedef void(*ScriptCompile_t)(sval_u* val, unsigned int filePosId, unsigned int fileCountId, unsigned int scriptId, PrecacheEntry* entries, int entriesCount);
|
||||
extern ScriptCompile_t ScriptCompile;
|
||||
|
||||
constexpr auto MAX_OPCODE_LOOKUP_SIZE = 0x1000000;
|
||||
constexpr auto MAX_SOURCEPOS_LOOKUP_SIZE = 0x800000;
|
||||
constexpr auto MAX_SOURCEBUF_LOOKUP_SIZE = 0x40000;
|
||||
|
||||
constexpr auto LOCAL_VAR_STACK_SIZE = 64;
|
||||
|
||||
extern void IncInParam();
|
||||
|
||||
extern void Scr_AddBool(int value);
|
||||
@ -188,6 +224,11 @@ namespace Game
|
||||
|
||||
extern scrVmPub_t* scrVmPub;
|
||||
extern scrVarPub_t* scrVarPub;
|
||||
extern scrCompilePub_t* scrCompilePub;
|
||||
extern scrAnimPub_t* scrAnimPub;
|
||||
|
||||
extern char* g_EndPos;
|
||||
extern bool* g_loadedImpureScript;
|
||||
|
||||
extern game_hudelem_s* g_hudelems;
|
||||
}
|
||||
|
@ -5949,6 +5949,38 @@ namespace Game
|
||||
int dataCount;
|
||||
};
|
||||
|
||||
struct PrecacheEntry
|
||||
{
|
||||
unsigned __int16 filename;
|
||||
bool include;
|
||||
unsigned int sourcePos;
|
||||
};
|
||||
|
||||
struct XAnimParent
|
||||
{
|
||||
unsigned short flags;
|
||||
unsigned short children;
|
||||
};
|
||||
|
||||
struct XAnimEntry
|
||||
{
|
||||
unsigned short numAnims;
|
||||
unsigned short parent;
|
||||
union
|
||||
{
|
||||
XAnimParts* parts;
|
||||
XAnimParent animParent;
|
||||
} ___u2;
|
||||
};
|
||||
|
||||
struct XAnim_s
|
||||
{
|
||||
unsigned int size;
|
||||
const char* debugName;
|
||||
const char** debugAnimNames;
|
||||
XAnimEntry entries[1];
|
||||
};
|
||||
|
||||
struct HunkUser
|
||||
{
|
||||
HunkUser* current;
|
||||
@ -6102,6 +6134,154 @@ namespace Game
|
||||
|
||||
static_assert(sizeof(scrVarPub_t) == 0x24060);
|
||||
|
||||
struct scrCompilePub_t
|
||||
{
|
||||
int value_count;
|
||||
int far_function_count;
|
||||
unsigned int loadedscripts;
|
||||
unsigned int scriptsPos;
|
||||
unsigned int scriptsCount;
|
||||
unsigned int scriptsDefine;
|
||||
unsigned int builtinFunc;
|
||||
unsigned int builtinMeth;
|
||||
unsigned __int16 canonicalStrings[65536];
|
||||
const char* in_ptr;
|
||||
bool in_ptr_valid;
|
||||
const char* parseBuf;
|
||||
bool script_loading;
|
||||
bool allowedBreakpoint;
|
||||
int developer_statement;
|
||||
char* opcodePos;
|
||||
unsigned int programLen;
|
||||
int func_table_size;
|
||||
int func_table[1024];
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
SOURCE_TYPE_BREAKPOINT = 0x1,
|
||||
SOURCE_TYPE_CALL = 0x2,
|
||||
SOURCE_TYPE_CALL_POINTER = 0x4,
|
||||
SOURCE_TYPE_THREAD_START = 0x8,
|
||||
SOURCE_TYPE_BUILTIN_CALL = 0x10,
|
||||
SOURCE_TYPE_NOTIFY = 0x20,
|
||||
SOURCE_TYPE_GETFUNCTION = 0x40,
|
||||
SOURCE_TYPE_WAIT = 0x80,
|
||||
};
|
||||
|
||||
struct OpcodeLookup
|
||||
{
|
||||
const char* codePos;
|
||||
unsigned int sourcePosIndex;
|
||||
unsigned __int16 sourcePosCount;
|
||||
int profileTime;
|
||||
int profileBuiltInTime;
|
||||
int profileUsage;
|
||||
};
|
||||
|
||||
static_assert(sizeof(OpcodeLookup) == 24);
|
||||
|
||||
struct SourceLookup
|
||||
{
|
||||
unsigned int sourcePos;
|
||||
int type;
|
||||
};
|
||||
|
||||
struct SaveSourceBufferInfo
|
||||
{
|
||||
char* buf;
|
||||
char* sourceBuf;
|
||||
int len;
|
||||
};
|
||||
|
||||
struct scrParserGlob_t
|
||||
{
|
||||
OpcodeLookup* opcodeLookup;
|
||||
unsigned int opcodeLookupMaxSize;
|
||||
unsigned int opcodeLookupLen;
|
||||
SourceLookup* sourcePosLookup;
|
||||
unsigned int sourcePosLookupMaxSize;
|
||||
unsigned int sourcePosLookupLen;
|
||||
unsigned int sourceBufferLookupMaxSize;
|
||||
const char* currentCodePos;
|
||||
unsigned int currentSourcePosCount;
|
||||
SaveSourceBufferInfo* saveSourceBufferLookup;
|
||||
unsigned int saveSourceBufferLookupLen;
|
||||
int delayedSourceIndex;
|
||||
int threadStartSourceIndex;
|
||||
};
|
||||
|
||||
struct SourceBufferInfo
|
||||
{
|
||||
const char* codePos;
|
||||
char* buf;
|
||||
const char* sourceBuf;
|
||||
int len;
|
||||
int sortedIndex;
|
||||
bool archive;
|
||||
int time;
|
||||
int avgTime;
|
||||
int maxTime;
|
||||
float totalTime;
|
||||
float totalBuiltIn;
|
||||
};
|
||||
|
||||
struct scrParserPub_t
|
||||
{
|
||||
SourceBufferInfo* sourceBufferLookup;
|
||||
unsigned int sourceBufferLookupLen;
|
||||
const char* scriptfilename;
|
||||
const char* sourceBuf;
|
||||
};
|
||||
|
||||
struct scr_animtree_t
|
||||
{
|
||||
XAnim_s* anims;
|
||||
};
|
||||
|
||||
struct scrAnimPub_t
|
||||
{
|
||||
unsigned int animtrees;
|
||||
unsigned int animtree_node;
|
||||
unsigned int animTreeNames;
|
||||
scr_animtree_t xanim_lookup[2][128];
|
||||
unsigned int xanim_num[2];
|
||||
unsigned int animTreeIndex;
|
||||
bool animtree_loading;
|
||||
};
|
||||
|
||||
struct scr_localVar_t
|
||||
{
|
||||
unsigned int name;
|
||||
unsigned int sourcePos;
|
||||
};
|
||||
|
||||
struct scr_block_t
|
||||
{
|
||||
int abortLevel;
|
||||
int localVarsCreateCount;
|
||||
int localVarsPublicCount;
|
||||
int localVarsCount;
|
||||
char localVarsInitBits[8];
|
||||
scr_localVar_t localVars[64];
|
||||
};
|
||||
|
||||
union sval_u
|
||||
{
|
||||
int type;
|
||||
unsigned int stringValue;
|
||||
unsigned int idValue;
|
||||
float floatValue;
|
||||
int intValue;
|
||||
sval_u* node;
|
||||
unsigned int sourcePosValue;
|
||||
const char* codePosValue;
|
||||
const char* debugString;
|
||||
scr_block_t* block;
|
||||
};
|
||||
|
||||
static_assert(sizeof(sval_u) == 0x4);
|
||||
|
||||
struct scr_const_t
|
||||
{
|
||||
scr_string_t _;
|
||||
@ -8452,33 +8632,7 @@ namespace Game
|
||||
float scale;
|
||||
};
|
||||
|
||||
struct XAnimParent
|
||||
{
|
||||
unsigned short flags;
|
||||
unsigned short children;
|
||||
};
|
||||
|
||||
struct XAnimEntry
|
||||
{
|
||||
unsigned short numAnims;
|
||||
unsigned short parent;
|
||||
|
||||
union
|
||||
{
|
||||
XAnimParts* parts;
|
||||
XAnimParent animParent;
|
||||
};
|
||||
};
|
||||
|
||||
struct XAnim_s
|
||||
{
|
||||
unsigned int size;
|
||||
const char* debugName;
|
||||
const char** debugAnimNames;
|
||||
XAnimEntry entries[1];
|
||||
};
|
||||
|
||||
struct __declspec(align(4)) XAnimTree_s
|
||||
struct XAnimTree_s
|
||||
{
|
||||
XAnim_s* anims;
|
||||
int info_usage;
|
||||
|
@ -24,6 +24,7 @@ namespace Game
|
||||
Sys_SuspendOtherThreads_t Sys_SuspendOtherThreads = Sys_SuspendOtherThreads_t(0x45A190);
|
||||
Sys_SetValue_t Sys_SetValue = Sys_SetValue_t(0x4B2F50);
|
||||
Sys_CreateFile_t Sys_CreateFile = Sys_CreateFile_t(0x4B2EF0);
|
||||
Sys_OutOfMemErrorInternal_t Sys_OutOfMemErrorInternal = Sys_OutOfMemErrorInternal_t(0x4B2E60);
|
||||
|
||||
char(*sys_exitCmdLine)[1024] = reinterpret_cast<char(*)[1024]>(0x649FB68);
|
||||
|
||||
|
@ -68,6 +68,9 @@ namespace Game
|
||||
typedef Sys_File(*Sys_CreateFile_t)(const char* dir, const char* filename);
|
||||
extern Sys_CreateFile_t Sys_CreateFile;
|
||||
|
||||
typedef void(*Sys_OutOfMemErrorInternal_t)(const char* filename, int line);
|
||||
extern Sys_OutOfMemErrorInternal_t Sys_OutOfMemErrorInternal;
|
||||
|
||||
extern char(*sys_exitCmdLine)[1024];
|
||||
|
||||
extern RTL_CRITICAL_SECTION* s_criticalSection;
|
||||
@ -99,3 +102,5 @@ namespace Game
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
#define Sys_OutOfMemError() Game::Sys_OutOfMemErrorInternal(__FILE__, __LINE__);
|
||||
|
75
src/Game/Zone.cpp
Normal file
75
src/Game/Zone.cpp
Normal file
@ -0,0 +1,75 @@
|
||||
#include <STDInclude.hpp>
|
||||
|
||||
namespace Game
|
||||
{
|
||||
Z_VirtualAlloc_t Z_VirtualAlloc = Z_VirtualAlloc_t(0x4CFBA0);
|
||||
Z_Malloc_t Z_Malloc = Z_Malloc_t(0x4F3680);
|
||||
|
||||
Hunk_UserCreate_t Hunk_UserCreate = Hunk_UserCreate_t(0x430E90);
|
||||
Hunk_UserDestroy_t Hunk_UserDestroy = Hunk_UserDestroy_t(0x435910);
|
||||
Hunk_AllocateTempMemoryHigh_t Hunk_AllocateTempMemoryHigh = Hunk_AllocateTempMemoryHigh_t(0x475B30);
|
||||
Hunk_UserAlloc_t Hunk_UserAlloc = Hunk_UserAlloc_t(0x45D1C0);
|
||||
|
||||
TempMalloc_t TempMalloc = TempMalloc_t(0x4613A0);
|
||||
|
||||
int Z_TryVirtualCommitInternal(void* ptr, int size)
|
||||
{
|
||||
assert((size >= 0));
|
||||
|
||||
return VirtualAlloc(ptr, size, (size > 0x20000 ? 0 : MEM_TOP_DOWN) | MEM_COMMIT, PAGE_READWRITE) != nullptr;
|
||||
}
|
||||
|
||||
void Z_VirtualDecommitInternal(void* ptr, int size)
|
||||
{
|
||||
assert((size >= 0));
|
||||
#pragma warning(push)
|
||||
#pragma warning(disable: 6250)
|
||||
[[maybe_unused]] const auto result = VirtualFree(ptr, size, MEM_DECOMMIT);
|
||||
#pragma warning(pop)
|
||||
}
|
||||
|
||||
void Z_VirtualCommitInternal(void* ptr, int size)
|
||||
{
|
||||
if (Z_TryVirtualCommitInternal(ptr, size))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
Sys_OutOfMemError();
|
||||
}
|
||||
|
||||
void Z_VirtualFreeInternal(void* ptr)
|
||||
{
|
||||
VirtualFree(ptr, 0, MEM_RELEASE);
|
||||
}
|
||||
|
||||
void Z_VirtualCommit(void* ptr, int size)
|
||||
{
|
||||
assert(ptr);
|
||||
assert(size);
|
||||
|
||||
Z_VirtualCommitInternal(ptr, size);
|
||||
}
|
||||
|
||||
void* Z_VirtualReserve(int size)
|
||||
{
|
||||
assert((size >= 0));
|
||||
|
||||
void* buf = VirtualAlloc(nullptr, size, (size > 0x20000 ? 0 : MEM_TOP_DOWN) | MEM_RESERVE, PAGE_READWRITE);
|
||||
assert(buf);
|
||||
return buf;
|
||||
}
|
||||
|
||||
void Z_VirtualDecommit(void* ptr, int size)
|
||||
{
|
||||
assert(ptr);
|
||||
assert(size);
|
||||
|
||||
Z_VirtualDecommitInternal(ptr, size);
|
||||
}
|
||||
|
||||
void Z_VirtualFree(void* ptr)
|
||||
{
|
||||
Z_VirtualFreeInternal(ptr);
|
||||
}
|
||||
}
|
32
src/Game/Zone.hpp
Normal file
32
src/Game/Zone.hpp
Normal file
@ -0,0 +1,32 @@
|
||||
#pragma once
|
||||
|
||||
namespace Game
|
||||
{
|
||||
typedef void*(*Z_VirtualAlloc_t)(int size);
|
||||
extern Z_VirtualAlloc_t Z_VirtualAlloc;
|
||||
|
||||
typedef void*(*Z_Malloc_t)(int size);
|
||||
extern Z_Malloc_t Z_Malloc;
|
||||
|
||||
typedef HunkUser*(*Hunk_UserCreate_t)(int maxSize, const char* name, bool fixed, int type);
|
||||
extern Hunk_UserCreate_t Hunk_UserCreate;
|
||||
|
||||
typedef void(*Hunk_UserDestroy_t)(HunkUser* user);
|
||||
extern Hunk_UserDestroy_t Hunk_UserDestroy;
|
||||
|
||||
typedef void*(*Hunk_AllocateTempMemoryHigh_t)(int size);
|
||||
extern Hunk_AllocateTempMemoryHigh_t Hunk_AllocateTempMemoryHigh;
|
||||
|
||||
typedef void*(*Hunk_UserAlloc_t)(HunkUser* user, int size, int alignment);
|
||||
extern Hunk_UserAlloc_t Hunk_UserAlloc;
|
||||
|
||||
typedef char*(*TempMalloc_t)(int len);
|
||||
extern TempMalloc_t TempMalloc;
|
||||
|
||||
constexpr auto PAGE_SIZE = 4096;
|
||||
|
||||
extern void* Z_VirtualReserve(int size);
|
||||
extern void Z_VirtualCommit(void* ptr, int size);
|
||||
extern void Z_VirtualDecommit(void* ptr, int size);
|
||||
extern void Z_VirtualFree(void* ptr);
|
||||
}
|
@ -95,6 +95,10 @@ using namespace std::literals;
|
||||
#undef min
|
||||
#endif
|
||||
|
||||
#ifdef GetObject
|
||||
#undef GetObject
|
||||
#endif
|
||||
|
||||
#define AssertSize(x, size) \
|
||||
static_assert(sizeof(x) == (size), \
|
||||
"Structure has an invalid size. " #x " must be " #size " bytes")
|
||||
|
Loading…
Reference in New Issue
Block a user