[Menus]: Add two new directives (#747)
This commit is contained in:
parent
43906f4fc0
commit
a468cdfae9
@ -53,6 +53,8 @@
|
|||||||
#include "Modules/Vote.hpp"
|
#include "Modules/Vote.hpp"
|
||||||
#include "Modules/Weapon.hpp"
|
#include "Modules/Weapon.hpp"
|
||||||
|
|
||||||
|
#include "Modules/BotLib/lPrecomp.hpp"
|
||||||
|
|
||||||
namespace Components
|
namespace Components
|
||||||
{
|
{
|
||||||
bool Loader::Pregame = true;
|
bool Loader::Pregame = true;
|
||||||
@ -168,6 +170,8 @@ namespace Components
|
|||||||
|
|
||||||
Register(new GSC());
|
Register(new GSC());
|
||||||
|
|
||||||
|
Register(new lPrecomp());
|
||||||
|
|
||||||
Pregame = false;
|
Pregame = false;
|
||||||
|
|
||||||
// Make sure preDestroy is called when the game shuts down
|
// Make sure preDestroy is called when the game shuts down
|
||||||
|
@ -264,9 +264,9 @@ namespace Assets
|
|||||||
AssertSize(Game::Font_s, 24);
|
AssertSize(Game::Font_s, 24);
|
||||||
AssertSize(Game::Glyph, 24);
|
AssertSize(Game::Glyph, 24);
|
||||||
|
|
||||||
Utils::Stream* buffer = builder->getBuffer();
|
auto* buffer = builder->getBuffer();
|
||||||
Game::Font_s* asset = header.font;
|
auto* asset = header.font;
|
||||||
Game::Font_s* dest = buffer->dest<Game::Font_s>();
|
auto* dest = buffer->dest<Game::Font_s>();
|
||||||
|
|
||||||
buffer->save(asset);
|
buffer->save(asset);
|
||||||
|
|
||||||
|
155
src/Components/Modules/BotLib/lPrecomp.cpp
Normal file
155
src/Components/Modules/BotLib/lPrecomp.cpp
Normal file
@ -0,0 +1,155 @@
|
|||||||
|
#include <STDInclude.hpp>
|
||||||
|
#include "lPrecomp.hpp"
|
||||||
|
|
||||||
|
namespace Components
|
||||||
|
{
|
||||||
|
// Two new directives! Refer to (https://en.cppreference.com/w/cpp/preprocessor/conditional)
|
||||||
|
Game::directive_s lPrecomp::directives[] =
|
||||||
|
{
|
||||||
|
{"if", Game::PC_Directive_if},
|
||||||
|
{"ifdef", Game::PC_Directive_ifdef},
|
||||||
|
{"ifndef", Game::PC_Directive_ifndef},
|
||||||
|
{"elifdef", lPrecomp::PC_Directive_elifdef},
|
||||||
|
{"elifndef", lPrecomp::PC_Directive_elifndef},
|
||||||
|
{"elif", Game::PC_Directive_elif},
|
||||||
|
{"else", Game::PC_Directive_else},
|
||||||
|
{"endif", Game::PC_Directive_endif},
|
||||||
|
{"include", Game::PC_Directive_include},
|
||||||
|
{"define", Game::PC_Directive_define},
|
||||||
|
{"undef", Game::PC_Directive_undef},
|
||||||
|
{"line", Game::PC_Directive_line},
|
||||||
|
{"error", Game::PC_Directive_error},
|
||||||
|
{"pragma", Game::PC_Directive_pragma},
|
||||||
|
{"eval", Game::PC_Directive_eval},
|
||||||
|
{"evalfloat", Game::PC_Directive_evalfloat},
|
||||||
|
{nullptr, nullptr}
|
||||||
|
};
|
||||||
|
|
||||||
|
int lPrecomp::PC_Directive_elif_def(Game::source_s* source, int* value, int type)
|
||||||
|
{
|
||||||
|
Game::token_s token;
|
||||||
|
int skip;
|
||||||
|
|
||||||
|
if (!Game::PC_ReadLine(source, &token, false))
|
||||||
|
{
|
||||||
|
Game::SourceError(source, "#elifdef without name");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (token.type != TT_NAME)
|
||||||
|
{
|
||||||
|
Game::PC_UnreadSourceToken(source, &token);
|
||||||
|
Game::SourceError(source, "expected name after #elifdef, found %s", token.string);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto* d = Game::PC_FindHashedDefine(source->definehash, token.string);
|
||||||
|
*value = skip = (type == INDENT_IFDEF) == (d == nullptr);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// #elifdef identifier is essentially equivalent to #elif defined identifier
|
||||||
|
int lPrecomp::PC_Directive_elifdef(Game::source_s* source)
|
||||||
|
{
|
||||||
|
int type;
|
||||||
|
int skip;
|
||||||
|
|
||||||
|
Game::PC_PopIndent(source, &type, &skip);
|
||||||
|
if (!type || type == INDENT_ELSE)
|
||||||
|
{
|
||||||
|
Game::SourceError(source, "misplaced #elifdef");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
int value;
|
||||||
|
if (PC_Directive_elif_def(source, &value, INDENT_IFDEF))
|
||||||
|
{
|
||||||
|
if (skip == Game::SKIP_YES)
|
||||||
|
{
|
||||||
|
skip = value;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
skip = Game::SKIP_ALL_ELIFS;
|
||||||
|
}
|
||||||
|
|
||||||
|
Game::PC_PushIndent(source, INDENT_ELIF, skip);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// #elifndef identifier is essentially equivalent to #elif !defined identifier
|
||||||
|
int lPrecomp::PC_Directive_elifndef(Game::source_s* source)
|
||||||
|
{
|
||||||
|
int type;
|
||||||
|
int skip;
|
||||||
|
|
||||||
|
Game::PC_PopIndent(source, &type, &skip);
|
||||||
|
if (!type || type == INDENT_ELSE)
|
||||||
|
{
|
||||||
|
Game::SourceError(source, "misplaced #elifndef");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
int value;
|
||||||
|
if (PC_Directive_elif_def(source, &value, INDENT_IFNDEF))
|
||||||
|
{
|
||||||
|
if (skip == Game::SKIP_YES)
|
||||||
|
{
|
||||||
|
skip = value;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
skip = Game::SKIP_ALL_ELIFS;
|
||||||
|
}
|
||||||
|
|
||||||
|
Game::PC_PushIndent(source, INDENT_ELIF, skip);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
int lPrecomp::PC_ReadDirective(Game::source_s* source)
|
||||||
|
{
|
||||||
|
Game::token_s token;
|
||||||
|
|
||||||
|
// Read the directive name
|
||||||
|
if (!Game::PC_ReadSourceToken(source, &token))
|
||||||
|
{
|
||||||
|
Game::SourceError(source, "found # without name");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Directive name must be on the same line
|
||||||
|
if (token.linescrossed > 0)
|
||||||
|
{
|
||||||
|
Game::PC_UnreadSourceToken(source, &token);
|
||||||
|
Game::SourceError(source, "found # at end of line");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// If it is a name
|
||||||
|
if (token.type == TT_NAME)
|
||||||
|
{
|
||||||
|
// Find the precompiler directive
|
||||||
|
for (auto i = 0; directives[i].name; ++i)
|
||||||
|
{
|
||||||
|
if (!std::strcmp(directives[i].name, token.string))
|
||||||
|
{
|
||||||
|
return directives[i].func(source);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Game::SourceError(source, "unknown precompiler directive %s", token.string);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
lPrecomp::lPrecomp()
|
||||||
|
{
|
||||||
|
Utils::Hook(0x4ACD19, PC_ReadDirective, HOOK_CALL).install()->quick();
|
||||||
|
}
|
||||||
|
}
|
46
src/Components/Modules/BotLib/lPrecomp.hpp
Normal file
46
src/Components/Modules/BotLib/lPrecomp.hpp
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
namespace Components
|
||||||
|
{
|
||||||
|
class lPrecomp : public Component
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
lPrecomp();
|
||||||
|
|
||||||
|
private:
|
||||||
|
enum
|
||||||
|
{
|
||||||
|
INDENT_IF = 1,
|
||||||
|
INDENT_ELSE = 2,
|
||||||
|
INDENT_ELIF = 4,
|
||||||
|
INDENT_IFDEF = 8,
|
||||||
|
INDENT_IFNDEF = 10,
|
||||||
|
};
|
||||||
|
|
||||||
|
enum
|
||||||
|
{
|
||||||
|
TT_STRING = 1,
|
||||||
|
TT_LITERAL = 2,
|
||||||
|
TT_NUMBER = 3,
|
||||||
|
TT_NAME = 4,
|
||||||
|
TT_PUNCTUATION = 5,
|
||||||
|
TT_DECIMAL = 8,
|
||||||
|
TT_HEX = 0x100,
|
||||||
|
TT_OCTAL = 0x200,
|
||||||
|
TT_BINARY = 0x400,
|
||||||
|
TT_FLOAT = 0x800,
|
||||||
|
TT_INTEGER = 0x1000,
|
||||||
|
TT_LONG = 0x2000,
|
||||||
|
TT_UNSIGNED = 0x4000,
|
||||||
|
};
|
||||||
|
|
||||||
|
static Game::directive_s directives[];
|
||||||
|
|
||||||
|
static int PC_Directive_elif_def(Game::source_s* source, int* value, int type);
|
||||||
|
|
||||||
|
static int PC_Directive_elifdef(Game::source_s* source);
|
||||||
|
static int PC_Directive_elifndef(Game::source_s* source);
|
||||||
|
|
||||||
|
static int PC_ReadDirective(Game::source_s* source);
|
||||||
|
};
|
||||||
|
}
|
@ -55,14 +55,14 @@ namespace Components
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Reserve it, if yes
|
// Reserve it, if yes
|
||||||
Game::sourceFiles[i] = reinterpret_cast<Game::source_t*>(1);
|
Game::sourceFiles[i] = reinterpret_cast<Game::source_s*>(1);
|
||||||
|
|
||||||
return i;
|
return i;
|
||||||
}
|
}
|
||||||
|
|
||||||
Game::script_t* Menus::LoadMenuScript(const std::string& name, const std::string& buffer)
|
Game::script_s* Menus::LoadMenuScript(const std::string& name, const std::string& buffer)
|
||||||
{
|
{
|
||||||
auto* script = static_cast<Game::script_t*>(Game::GetClearedMemory(sizeof(Game::script_t) + 1 + buffer.length()));
|
auto* script = static_cast<Game::script_s*>(Game::GetClearedMemory(sizeof(Game::script_s) + 1 + buffer.length()));
|
||||||
if (!script) return nullptr;
|
if (!script) return nullptr;
|
||||||
|
|
||||||
strcpy_s(script->filename, sizeof(script->filename), name.data());
|
strcpy_s(script->filename, sizeof(script->filename), name.data());
|
||||||
@ -136,7 +136,7 @@ namespace Components
|
|||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
Game::pc_token_t token;
|
Game::pc_token_s token;
|
||||||
if (!Game::PC_ReadTokenHandle(handle, &token) || token.string[0] != '{')
|
if (!Game::PC_ReadTokenHandle(handle, &token) || token.string[0] != '{')
|
||||||
{
|
{
|
||||||
allocator->free(menu->items);
|
allocator->free(menu->items);
|
||||||
@ -195,8 +195,8 @@ namespace Components
|
|||||||
|
|
||||||
if (!menuFile.exists()) return nullptr;
|
if (!menuFile.exists()) return nullptr;
|
||||||
|
|
||||||
Game::pc_token_t token;
|
Game::pc_token_s token;
|
||||||
int handle = LoadMenuSource(menu, menuFile.getBuffer());
|
const auto handle = LoadMenuSource(menu, menuFile.getBuffer());
|
||||||
|
|
||||||
if (IsValidSourceHandle(handle))
|
if (IsValidSourceHandle(handle))
|
||||||
{
|
{
|
||||||
@ -259,7 +259,7 @@ namespace Components
|
|||||||
|
|
||||||
if (menuFile.exists())
|
if (menuFile.exists())
|
||||||
{
|
{
|
||||||
Game::pc_token_t token;
|
Game::pc_token_s token;
|
||||||
const auto handle = LoadMenuSource(menu, menuFile.getBuffer());
|
const auto handle = LoadMenuSource(menu, menuFile.getBuffer());
|
||||||
|
|
||||||
if (IsValidSourceHandle(handle))
|
if (IsValidSourceHandle(handle))
|
||||||
@ -744,11 +744,11 @@ namespace Components
|
|||||||
{
|
{
|
||||||
if (menu->window.name == "connect"s) // Check if we're supposed to draw the loadscreen
|
if (menu->window.name == "connect"s) // Check if we're supposed to draw the loadscreen
|
||||||
{
|
{
|
||||||
Game::menuDef_t* originalConnect = AssetHandler::FindOriginalAsset(Game::XAssetType::ASSET_TYPE_MENU, "connect").menu;
|
const auto* originalConnect = AssetHandler::FindOriginalAsset(Game::XAssetType::ASSET_TYPE_MENU, "connect").menu;
|
||||||
|
|
||||||
if (originalConnect == menu) // Check if we draw the original loadscreen
|
if (originalConnect == menu) // Check if we draw the original loadscreen
|
||||||
{
|
{
|
||||||
if (MenuList.find("connect") != Menus::MenuList.end()) // Check if we have a custom loadscreen, to prevent drawing the original one on top
|
if (MenuList.contains("connect")) // Check if we have a custom load screen, to prevent drawing the original one on top
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -801,8 +801,8 @@ namespace Components
|
|||||||
if (Dedicated::IsEnabled()) return;
|
if (Dedicated::IsEnabled()) return;
|
||||||
|
|
||||||
// Intercept asset finding
|
// Intercept asset finding
|
||||||
AssetHandler::OnFind(Game::XAssetType::ASSET_TYPE_MENU, MenuFindHook);
|
AssetHandler::OnFind(Game::ASSET_TYPE_MENU, MenuFindHook);
|
||||||
AssetHandler::OnFind(Game::XAssetType::ASSET_TYPE_MENULIST, MenuListFindHook);
|
AssetHandler::OnFind(Game::ASSET_TYPE_MENULIST, MenuListFindHook);
|
||||||
|
|
||||||
// Don't open connect menu
|
// Don't open connect menu
|
||||||
// Utils::Hook::Nop(0x428E48, 5);
|
// Utils::Hook::Nop(0x428E48, 5);
|
||||||
|
@ -31,7 +31,7 @@ namespace Components
|
|||||||
|
|
||||||
static void SafeMergeMenus(std::vector<std::pair<bool, Game::menuDef_t*>>* menus, std::vector<std::pair<bool, Game::menuDef_t*>> newMenus);
|
static void SafeMergeMenus(std::vector<std::pair<bool, Game::menuDef_t*>>* menus, std::vector<std::pair<bool, Game::menuDef_t*>> newMenus);
|
||||||
|
|
||||||
static Game::script_t* LoadMenuScript(const std::string& name, const std::string& buffer);
|
static Game::script_s* LoadMenuScript(const std::string& name, const std::string& buffer);
|
||||||
static int LoadMenuSource(const std::string& name, const std::string& buffer);
|
static int LoadMenuSource(const std::string& name, const std::string& buffer);
|
||||||
|
|
||||||
static int ReserveSourceHandle();
|
static int ReserveSourceHandle();
|
||||||
|
@ -669,7 +669,7 @@ namespace Components
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG_MAT_LOG
|
||||||
AssetHandler::OnLoad([](Game::XAssetType type, Game::XAssetHeader asset, const std::string& /*name*/, bool* /*restrict*/)
|
AssetHandler::OnLoad([](Game::XAssetType type, Game::XAssetHeader asset, const std::string& /*name*/, bool* /*restrict*/)
|
||||||
{
|
{
|
||||||
if (type == Game::XAssetType::ASSET_TYPE_GFXWORLD)
|
if (type == Game::XAssetType::ASSET_TYPE_GFXWORLD)
|
||||||
|
@ -130,11 +130,6 @@ namespace Game
|
|||||||
|
|
||||||
Scr_AddSourceBuffer_t Scr_AddSourceBuffer = Scr_AddSourceBuffer_t(0x61ABC0);
|
Scr_AddSourceBuffer_t Scr_AddSourceBuffer = Scr_AddSourceBuffer_t(0x61ABC0);
|
||||||
|
|
||||||
PC_FreeDefine_t PC_FreeDefine = PC_FreeDefine_t(0x4E0D60);
|
|
||||||
PC_ReadToken_t PC_ReadToken = PC_ReadToken_t(0x4ACCD0);
|
|
||||||
PC_ReadTokenHandle_t PC_ReadTokenHandle = PC_ReadTokenHandle_t(0x4D2060);
|
|
||||||
PC_SourceError_t PC_SourceError = PC_SourceError_t(0x467A00);
|
|
||||||
|
|
||||||
Party_GetMaxPlayers_t Party_GetMaxPlayers = Party_GetMaxPlayers_t(0x4F5D60);
|
Party_GetMaxPlayers_t Party_GetMaxPlayers = Party_GetMaxPlayers_t(0x4F5D60);
|
||||||
PartyHost_CountMembers_t PartyHost_CountMembers = PartyHost_CountMembers_t(0x497330);
|
PartyHost_CountMembers_t PartyHost_CountMembers = PartyHost_CountMembers_t(0x497330);
|
||||||
PartyHost_GetMemberAddressBySlot_t PartyHost_GetMemberAddressBySlot = PartyHost_GetMemberAddressBySlot_t(0x44E100);
|
PartyHost_GetMemberAddressBySlot_t PartyHost_GetMemberAddressBySlot = PartyHost_GetMemberAddressBySlot_t(0x44E100);
|
||||||
@ -267,7 +262,7 @@ namespace Game
|
|||||||
|
|
||||||
cmd_function_s** cmd_functions = reinterpret_cast<cmd_function_s**>(0x1AAC658);
|
cmd_function_s** cmd_functions = reinterpret_cast<cmd_function_s**>(0x1AAC658);
|
||||||
|
|
||||||
source_t** sourceFiles = reinterpret_cast<source_t**>(0x7C4A98);
|
source_s** sourceFiles = reinterpret_cast<source_s**>(0x7C4A98);
|
||||||
|
|
||||||
float* cgameFOVSensitivityScale = reinterpret_cast<float*>(0xB2F884);
|
float* cgameFOVSensitivityScale = reinterpret_cast<float*>(0xB2F884);
|
||||||
|
|
||||||
|
@ -320,18 +320,6 @@ namespace Game
|
|||||||
typedef char*(*Scr_AddSourceBuffer_t)(const char* filename, const char* extFilename, const char* codePos, bool archive);
|
typedef char*(*Scr_AddSourceBuffer_t)(const char* filename, const char* extFilename, const char* codePos, bool archive);
|
||||||
extern Scr_AddSourceBuffer_t Scr_AddSourceBuffer;
|
extern Scr_AddSourceBuffer_t Scr_AddSourceBuffer;
|
||||||
|
|
||||||
typedef void(*PC_FreeDefine_t)(define_s* define);
|
|
||||||
extern PC_FreeDefine_t PC_FreeDefine;
|
|
||||||
|
|
||||||
typedef int(*PC_ReadToken_t)(source_t*, token_t*);
|
|
||||||
extern PC_ReadToken_t PC_ReadToken;
|
|
||||||
|
|
||||||
typedef int(*PC_ReadTokenHandle_t)(int handle, pc_token_s *pc_token);
|
|
||||||
extern PC_ReadTokenHandle_t PC_ReadTokenHandle;
|
|
||||||
|
|
||||||
typedef void(*PC_SourceError_t)(int, const char*, ...);
|
|
||||||
extern PC_SourceError_t PC_SourceError;
|
|
||||||
|
|
||||||
typedef int(*Party_GetMaxPlayers_t)(PartyData* party);
|
typedef int(*Party_GetMaxPlayers_t)(PartyData* party);
|
||||||
extern Party_GetMaxPlayers_t Party_GetMaxPlayers;
|
extern Party_GetMaxPlayers_t Party_GetMaxPlayers;
|
||||||
|
|
||||||
@ -611,7 +599,7 @@ namespace Game
|
|||||||
|
|
||||||
extern float* cgameFOVSensitivityScale;
|
extern float* cgameFOVSensitivityScale;
|
||||||
|
|
||||||
extern source_t** sourceFiles;
|
extern source_s** sourceFiles;
|
||||||
|
|
||||||
extern UiContext* uiContext;
|
extern UiContext* uiContext;
|
||||||
|
|
||||||
|
@ -7,6 +7,7 @@
|
|||||||
#include "FileSystem.hpp"
|
#include "FileSystem.hpp"
|
||||||
#include "Functions.hpp"
|
#include "Functions.hpp"
|
||||||
#include "Dvars.hpp"
|
#include "Dvars.hpp"
|
||||||
|
#include "PreProcessor.hpp"
|
||||||
#include "Script.hpp"
|
#include "Script.hpp"
|
||||||
#include "Server.hpp"
|
#include "Server.hpp"
|
||||||
#include "System.hpp"
|
#include "System.hpp"
|
||||||
|
86
src/Game/PreProcessor.cpp
Normal file
86
src/Game/PreProcessor.cpp
Normal file
@ -0,0 +1,86 @@
|
|||||||
|
#include <STDInclude.hpp>
|
||||||
|
|
||||||
|
namespace Game
|
||||||
|
{
|
||||||
|
PC_FreeDefine_t PC_FreeDefine = PC_FreeDefine_t(0x4E0D60);
|
||||||
|
PC_FindHashedDefine_t PC_FindHashedDefine = PC_FindHashedDefine_t(0x421E00);
|
||||||
|
PC_ReadToken_t PC_ReadToken = PC_ReadToken_t(0x4ACCD0);
|
||||||
|
PC_ReadTokenHandle_t PC_ReadTokenHandle = PC_ReadTokenHandle_t(0x4D2060);
|
||||||
|
PC_ReadSourceToken_t PC_ReadSourceToken = PC_ReadSourceToken_t(0x4B16F0);
|
||||||
|
PC_UnreadSourceToken_t PC_UnreadSourceToken = PC_UnreadSourceToken_t(0x47CD00);
|
||||||
|
PC_SourceError_t PC_SourceError = PC_SourceError_t(0x467A00);
|
||||||
|
|
||||||
|
SourceError_t SourceError = SourceError_t(0x44C6C0);
|
||||||
|
|
||||||
|
PC_Directive_if_def_t PC_Directive_if_def = PC_Directive_if_def_t(0x490A70);
|
||||||
|
|
||||||
|
PC_Directive_if_t PC_Directive_if = PC_Directive_if_t(0x486220);
|
||||||
|
PC_Directive_ifdef_t PC_Directive_ifdef = PC_Directive_ifdef_t(0x4F4ED0);
|
||||||
|
PC_Directive_ifndef_t PC_Directive_ifndef = PC_Directive_ifndef_t(0x42EF10);
|
||||||
|
PC_Directive_elif_t PC_Directive_elif = PC_Directive_elif_t(0x41AAB0);
|
||||||
|
PC_Directive_else_t PC_Directive_else = PC_Directive_else_t(0x4B55B0);
|
||||||
|
PC_Directive_endif_t PC_Directive_endif = PC_Directive_endif_t(0x491920);
|
||||||
|
PC_Directive_include_t PC_Directive_include = PC_Directive_include_t(0x495310);
|
||||||
|
PC_Directive_define_t PC_Directive_define = PC_Directive_define_t(0x42E460);
|
||||||
|
PC_Directive_undef_t PC_Directive_undef = PC_Directive_undef_t(0x4E1820);
|
||||||
|
PC_Directive_line_t PC_Directive_line = PC_Directive_line_t(0x4FD8A0);
|
||||||
|
PC_Directive_error_t PC_Directive_error = PC_Directive_error_t(0x494AA0);
|
||||||
|
PC_Directive_pragma_t PC_Directive_pragma = PC_Directive_pragma_t(0x42C160);
|
||||||
|
PC_Directive_eval_t PC_Directive_eval = PC_Directive_eval_t(0x57DB20);
|
||||||
|
PC_Directive_evalfloat_t PC_Directive_evalfloat = PC_Directive_evalfloat_t(0x4BC2A0);
|
||||||
|
|
||||||
|
__declspec(naked) int PC_ReadLine([[maybe_unused]] source_s* source, [[maybe_unused]] token_s* token, [[maybe_unused]] bool expandDefines)
|
||||||
|
{
|
||||||
|
static const DWORD PC_ReadLine_t = 0x57D830;
|
||||||
|
|
||||||
|
__asm
|
||||||
|
{
|
||||||
|
push eax
|
||||||
|
pushad
|
||||||
|
|
||||||
|
mov ebx, [esp + 0x24 + 0x4] // source
|
||||||
|
|
||||||
|
push [esp + 0x24 + 0xC] // expandDefines
|
||||||
|
push [esp + 0x24 + 0xC] // token
|
||||||
|
call PC_ReadLine_t
|
||||||
|
add esp, 0x8
|
||||||
|
|
||||||
|
mov [esp + 0x20], eax
|
||||||
|
popad
|
||||||
|
pop eax
|
||||||
|
|
||||||
|
ret
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void PC_PushIndent(source_s* source, int type_, int skip)
|
||||||
|
{
|
||||||
|
static const DWORD PC_PushIndent_t = 0x57D740;
|
||||||
|
|
||||||
|
__asm
|
||||||
|
{
|
||||||
|
pushad
|
||||||
|
mov edi, skip
|
||||||
|
mov esi, source
|
||||||
|
push type_
|
||||||
|
call PC_PushIndent_t
|
||||||
|
add esp, 0x4
|
||||||
|
popad
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void PC_PopIndent(source_s* source, int* type_, int* skip)
|
||||||
|
{
|
||||||
|
static const DWORD PC_PopIndent_t = 0x57D780;
|
||||||
|
|
||||||
|
__asm
|
||||||
|
{
|
||||||
|
pushad
|
||||||
|
mov edx, skip
|
||||||
|
mov eax, type_
|
||||||
|
mov ecx, source
|
||||||
|
call PC_PopIndent_t
|
||||||
|
popad
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
77
src/Game/PreProcessor.hpp
Normal file
77
src/Game/PreProcessor.hpp
Normal file
@ -0,0 +1,77 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
namespace Game
|
||||||
|
{
|
||||||
|
typedef void(*PC_FreeDefine_t)(define_s* define);
|
||||||
|
extern PC_FreeDefine_t PC_FreeDefine;
|
||||||
|
|
||||||
|
typedef define_s*(*PC_FindHashedDefine_t)(define_s** definehash, const char* name);
|
||||||
|
extern PC_FindHashedDefine_t PC_FindHashedDefine;
|
||||||
|
|
||||||
|
typedef int(*PC_ReadToken_t)(source_s*, token_s*);
|
||||||
|
extern PC_ReadToken_t PC_ReadToken;
|
||||||
|
|
||||||
|
typedef int(*PC_ReadTokenHandle_t)(int handle, pc_token_s* pc_token);
|
||||||
|
extern PC_ReadTokenHandle_t PC_ReadTokenHandle;
|
||||||
|
|
||||||
|
typedef int(*PC_ReadSourceToken_t)(source_s* source, token_s* token);
|
||||||
|
extern PC_ReadSourceToken_t PC_ReadSourceToken;
|
||||||
|
|
||||||
|
typedef int(*PC_UnreadSourceToken_t)(source_s* source, token_s* token);
|
||||||
|
extern PC_UnreadSourceToken_t PC_UnreadSourceToken;
|
||||||
|
|
||||||
|
typedef void(*PC_SourceError_t)(int, const char*, ...);
|
||||||
|
extern PC_SourceError_t PC_SourceError;
|
||||||
|
|
||||||
|
typedef void(*SourceError_t)(source_s* source, const char* str, ...);
|
||||||
|
extern SourceError_t SourceError;
|
||||||
|
|
||||||
|
typedef int(*PC_Directive_if_def_t)(source_s* source, int type);
|
||||||
|
extern PC_Directive_if_def_t PC_Directive_if_def;
|
||||||
|
|
||||||
|
typedef int(*PC_Directive_if_t)(source_s* source);
|
||||||
|
extern PC_Directive_if_t PC_Directive_if;
|
||||||
|
|
||||||
|
typedef int(*PC_Directive_ifdef_t)(source_s* source);
|
||||||
|
extern PC_Directive_ifdef_t PC_Directive_ifdef;
|
||||||
|
|
||||||
|
typedef int(*PC_Directive_ifndef_t)(source_s* source);
|
||||||
|
extern PC_Directive_ifndef_t PC_Directive_ifndef;
|
||||||
|
|
||||||
|
typedef int(*PC_Directive_elif_t)(source_s* source);
|
||||||
|
extern PC_Directive_elif_t PC_Directive_elif;
|
||||||
|
|
||||||
|
typedef int(*PC_Directive_else_t)(source_s* source);
|
||||||
|
extern PC_Directive_else_t PC_Directive_else;
|
||||||
|
|
||||||
|
typedef int(*PC_Directive_endif_t)(source_s* source);
|
||||||
|
extern PC_Directive_endif_t PC_Directive_endif;
|
||||||
|
|
||||||
|
typedef int(*PC_Directive_include_t)(source_s* source);
|
||||||
|
extern PC_Directive_include_t PC_Directive_include;
|
||||||
|
|
||||||
|
typedef int(*PC_Directive_define_t)(source_s* source);
|
||||||
|
extern PC_Directive_define_t PC_Directive_define;
|
||||||
|
|
||||||
|
typedef int(*PC_Directive_undef_t)(source_s* source);
|
||||||
|
extern PC_Directive_undef_t PC_Directive_undef;
|
||||||
|
|
||||||
|
typedef int(*PC_Directive_line_t)(source_s* source);
|
||||||
|
extern PC_Directive_line_t PC_Directive_line;
|
||||||
|
|
||||||
|
typedef int(*PC_Directive_error_t)(source_s* source);
|
||||||
|
extern PC_Directive_error_t PC_Directive_error;
|
||||||
|
|
||||||
|
typedef int(*PC_Directive_pragma_t)(source_s* source);
|
||||||
|
extern PC_Directive_pragma_t PC_Directive_pragma;
|
||||||
|
|
||||||
|
typedef int(*PC_Directive_eval_t)(source_s* source);
|
||||||
|
extern PC_Directive_eval_t PC_Directive_eval;
|
||||||
|
|
||||||
|
typedef int(*PC_Directive_evalfloat_t)(source_s* source);
|
||||||
|
extern PC_Directive_evalfloat_t PC_Directive_evalfloat;
|
||||||
|
|
||||||
|
extern int PC_ReadLine(source_s* source, token_s* token, bool expandDefines);
|
||||||
|
extern void PC_PushIndent(source_s* source, int type, int skip);
|
||||||
|
extern void PC_PopIndent(source_s* source, int* type, int* skip);
|
||||||
|
}
|
@ -7367,31 +7367,38 @@ namespace Game
|
|||||||
CModelSectionHeader sectionHeader[4];
|
CModelSectionHeader sectionHeader[4];
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef struct punctuation_s
|
struct punctuation_s
|
||||||
{
|
{
|
||||||
char* p; //punctuation character(s)
|
char* p; //punctuation character(s)
|
||||||
int n; //punctuation indication
|
int n; //punctuation indication
|
||||||
punctuation_s* next; //next punctuation
|
punctuation_s* next; //next punctuation
|
||||||
} punctuation_t;
|
};
|
||||||
|
|
||||||
#define MAX_TOKEN 1024
|
#define MAX_TOKEN 1024
|
||||||
#define MAX_TOKENLENGTH 1024
|
#define MAX_TOKENLENGTH 1024
|
||||||
|
|
||||||
typedef struct token_s
|
enum parseSkip_t
|
||||||
{
|
{
|
||||||
char string[MAX_TOKEN]; //available token
|
SKIP_NO = 0x0,
|
||||||
int type; //last read token type
|
SKIP_YES = 0x1,
|
||||||
int subtype; //last read token sub type
|
SKIP_ALL_ELIFS = 0x2,
|
||||||
unsigned long int intvalue; //integer value
|
};
|
||||||
long double floatvalue; //floating point value
|
|
||||||
char* whitespace_p; //start of white space before token
|
|
||||||
char* endwhitespace_p; //start of white space before token
|
|
||||||
int line; //line the token was on
|
|
||||||
int linescrossed; //lines crossed in white space
|
|
||||||
token_s* next; //next token in chain
|
|
||||||
} token_t;
|
|
||||||
|
|
||||||
typedef struct script_s
|
struct token_s
|
||||||
|
{
|
||||||
|
char string[MAX_TOKEN]; // available token
|
||||||
|
int type; // last read token type
|
||||||
|
int subtype; // last read token sub type
|
||||||
|
unsigned long int intvalue; // integer value
|
||||||
|
long double floatvalue; // floating point value
|
||||||
|
char* whitespace_p; // start of white space before token
|
||||||
|
char* endwhitespace_p; // start of white space before token
|
||||||
|
int line; // line the token was on
|
||||||
|
int linescrossed; // lines crossed in white space
|
||||||
|
token_s* next; // next token in chain
|
||||||
|
};
|
||||||
|
|
||||||
|
struct script_s
|
||||||
{
|
{
|
||||||
char filename[64]; //file name of the script
|
char filename[64]; //file name of the script
|
||||||
char* buffer; //buffer containing the script
|
char* buffer; //buffer containing the script
|
||||||
@ -7405,54 +7412,60 @@ namespace Game
|
|||||||
int lastline; //line before reading token
|
int lastline; //line before reading token
|
||||||
int tokenavailable; //set by UnreadLastToken
|
int tokenavailable; //set by UnreadLastToken
|
||||||
int flags; //several script flags
|
int flags; //several script flags
|
||||||
punctuation_t* punctuations; //the punctuations used in the script
|
punctuation_s* punctuations; //the punctuations used in the script
|
||||||
punctuation_t** punctuationtable;
|
punctuation_s** punctuationtable;
|
||||||
token_t token; //available token
|
token_s token; //available token
|
||||||
script_s* next; //next script in a chain
|
script_s* next; //next script in a chain
|
||||||
} script_t;
|
};
|
||||||
|
|
||||||
typedef struct define_s
|
struct define_s
|
||||||
{
|
{
|
||||||
char* name; //define name
|
char* name; //define name
|
||||||
int flags; //define flags
|
int flags; //define flags
|
||||||
int builtin; // > 0 if builtin define
|
int builtin; // > 0 if builtin define
|
||||||
int numparms; //number of define parameters
|
int numparms; //number of define parameters
|
||||||
token_t* parms; //define parameters
|
token_s* parms; //define parameters
|
||||||
token_t* tokens; //macro tokens (possibly containing parm tokens)
|
token_s* tokens; //macro tokens (possibly containing parm tokens)
|
||||||
define_s* next; //next defined macro in a list
|
define_s* next; //next defined macro in a list
|
||||||
define_s* hashnext; //next define in the hash chain
|
define_s* hashnext; //next define in the hash chain
|
||||||
} define_t;
|
};
|
||||||
|
|
||||||
typedef struct indent_s
|
struct indent_s
|
||||||
{
|
{
|
||||||
int type; //indent type
|
int type; //indent type
|
||||||
int skip; //true if skipping current indent
|
int skip; //true if skipping current indent
|
||||||
script_t* script; //script the indent was in
|
script_s* script; //script the indent was in
|
||||||
indent_s* next; //next indent on the indent stack
|
indent_s* next; //next indent on the indent stack
|
||||||
} indent_t;
|
};
|
||||||
|
|
||||||
typedef struct source_s
|
struct source_s
|
||||||
{
|
{
|
||||||
char filename[MAX_QPATH]; //file name of the script
|
char filename[MAX_QPATH]; //file name of the script
|
||||||
char includepath[MAX_QPATH]; //path to include files
|
char includepath[MAX_QPATH]; //path to include files
|
||||||
punctuation_t* punctuations; //punctuations to use
|
punctuation_s* punctuations; //punctuations to use
|
||||||
script_t* scriptstack; //stack with scripts of the source
|
script_s* scriptstack; //stack with scripts of the source
|
||||||
token_t* tokens; //tokens to read first
|
token_s* tokens; //tokens to read first
|
||||||
define_t* defines; //list with macro definitions
|
define_s* defines; //list with macro definitions
|
||||||
define_t** definehash; //hash chain with defines
|
define_s** definehash; //hash chain with defines
|
||||||
indent_t* indentstack; //stack with indents
|
indent_s* indentstack; //stack with indents
|
||||||
int skip; // > 0 if skipping conditional code
|
int skip; // > 0 if skipping conditional code
|
||||||
token_t token; //last read token
|
token_s token; //last read token
|
||||||
} source_t;
|
};
|
||||||
|
|
||||||
typedef struct pc_token_s
|
struct directive_s
|
||||||
|
{
|
||||||
|
const char* name;
|
||||||
|
int (*func)(source_s* source);
|
||||||
|
};
|
||||||
|
|
||||||
|
struct pc_token_s
|
||||||
{
|
{
|
||||||
int type;
|
int type;
|
||||||
int subtype;
|
int subtype;
|
||||||
int intvalue;
|
int intvalue;
|
||||||
float floatvalue;
|
float floatvalue;
|
||||||
char string[MAX_TOKENLENGTH];
|
char string[MAX_TOKENLENGTH];
|
||||||
} pc_token_t;
|
};
|
||||||
|
|
||||||
template <typename T, int N, int M>
|
template <typename T, int N, int M>
|
||||||
struct KeywordHashEntry
|
struct KeywordHashEntry
|
||||||
|
Loading…
Reference in New Issue
Block a user