153 lines
4.8 KiB
C++
153 lines
4.8 KiB
C++
#include <std_include.hpp>
|
|
#include "loader/component_loader.hpp"
|
|
#include "game/dvars.hpp"
|
|
|
|
#include "branding.hpp"
|
|
#include "scheduler.hpp"
|
|
|
|
#include <utils/hook.hpp>
|
|
#include <utils/string.hpp>
|
|
|
|
#include <version.hpp>
|
|
|
|
namespace branding {
|
|
namespace {
|
|
#ifdef _DEBUG
|
|
constexpr auto* BUILD_TYPE = "IW4x_DEV SP";
|
|
#else
|
|
constexpr auto* BUILD_TYPE = "IW4x SP";
|
|
#endif
|
|
|
|
const char* get_version_string() {
|
|
const auto* result = utils::string::va(
|
|
"{0} {1} build {2} {3}", BUILD_TYPE, "(Alpha)", get_build_number(),
|
|
reinterpret_cast<const char*>(0x6A1574));
|
|
|
|
return result;
|
|
}
|
|
|
|
void dvar_set_version_string(const game::dvar_t* dvar, const char* /*value*/) {
|
|
const auto* result = get_version_string();
|
|
utils::hook::invoke<void>(0x480E70, dvar, result);
|
|
}
|
|
|
|
void cg_draw_version() {
|
|
assert(game::ScrPlace_IsFullScreenActive());
|
|
|
|
// Default values
|
|
constexpr auto font_scale = 0.25f;
|
|
constexpr auto max_chars = std::numeric_limits<int>::max();
|
|
// Default colours
|
|
constexpr float shadow_color[] = {0.0f, 0.0f, 0.0f, 0.69f};
|
|
constexpr float color[] = {0.4f, 0.69f, 1.0f, 0.69f};
|
|
|
|
auto* const placement = game::ScrPlace_GetUnsafeFullPlacement();
|
|
auto* const font = game::UI_GetFontHandle(placement, 0, 0.583f);
|
|
|
|
const auto width = game::UI_TextWidth((*dvars::version)->current.string, 0,
|
|
font, font_scale);
|
|
const auto height = game::UI_TextHeight(font, font_scale);
|
|
|
|
game::UI_DrawText(
|
|
placement, (*dvars::version)->current.string, max_chars, font,
|
|
1.0f -
|
|
(dvars::cg_drawVersionX->current.value + static_cast<float>(width)),
|
|
1.0f -
|
|
(dvars::cg_drawVersionY->current.value + static_cast<float>(height)),
|
|
3, 3, font_scale, shadow_color, 0);
|
|
game::UI_DrawText(placement, (*dvars::version)->current.string, max_chars,
|
|
font,
|
|
(0.0f - static_cast<float>(width)) -
|
|
dvars::cg_drawVersionX->current.value,
|
|
(0.0f - static_cast<float>(height)) -
|
|
dvars::cg_drawVersionY->current.value,
|
|
3, 3, font_scale, color, 0);
|
|
}
|
|
|
|
void cg_draw_full_screen_debug_overlays_stub(int local_client_num) {
|
|
assert(game::ScrPlace_IsFullScreenActive());
|
|
|
|
if (dvars::cg_drawVersion->current.enabled) {
|
|
cg_draw_version();
|
|
}
|
|
|
|
utils::hook::invoke<void>(0x44BD00, local_client_num);
|
|
}
|
|
|
|
volatile bool left_side = true;
|
|
game::Font_s** small_font;
|
|
void branding_loop() {
|
|
float color[4] = {1.0f, 1.0f, 1.0f, 0.25f};
|
|
const auto* text = "AlterWare IW4x-SP";
|
|
|
|
if (!*small_font) {
|
|
return;
|
|
}
|
|
|
|
auto* const scr_place =
|
|
game::ScrPlace_GetActivePlacement(game::LOCAL_CLIENT_0);
|
|
const auto x =
|
|
left_side
|
|
? 10.0f
|
|
: scr_place->realViewportSize[0] -
|
|
static_cast<float>(game::R_TextWidth(text, 0, *small_font)) -
|
|
10.0f;
|
|
|
|
game::R_AddCmdDrawText(text, std::numeric_limits<int>::max(), *small_font, x,
|
|
30.0f, 1.0f, 1.0f, 0.0f, color, 3);
|
|
}
|
|
} // namespace
|
|
|
|
const char* get_build_number() {
|
|
return SHORTVERSION " latest " __DATE__ " " __TIME__;
|
|
}
|
|
|
|
class component final : public component_interface {
|
|
public:
|
|
void post_load() override {
|
|
utils::hook(0x46F570, get_build_number, HOOK_JUMP).install()->quick();
|
|
utils::hook(0x60429A, dvar_set_version_string, HOOK_CALL)
|
|
.install() // hook*
|
|
->quick();
|
|
|
|
utils::hook::set<const char*>(0x446A48, "iw4x-sp: Console");
|
|
utils::hook::set<const char*>(0x50C110, "iw4x-sp: Game");
|
|
|
|
utils::hook::set<const char*>(0x579364, "iw4x-sp: " SHORTVERSION "> ");
|
|
|
|
// Com_Init_Try_Block_Function
|
|
utils::hook::set<const char*>(0x604004, BUILD_TYPE);
|
|
utils::hook::set<const char*>(0x603FFF, SHORTVERSION);
|
|
utils::hook::set<const char*>(0x603FF5, __DATE__);
|
|
|
|
register_branding_dvars();
|
|
utils::hook(0x57DAFF, cg_draw_full_screen_debug_overlays_stub, HOOK_CALL)
|
|
.install() // hook*
|
|
->quick();
|
|
|
|
small_font = reinterpret_cast<game::Font_s**>(0x192A0DC);
|
|
scheduler::loop(branding_loop, scheduler::pipeline::renderer);
|
|
scheduler::loop([] { left_side = !left_side; },
|
|
scheduler::pipeline::renderer, 60s);
|
|
}
|
|
|
|
static void register_branding_dvars() {
|
|
#ifdef _DEBUG
|
|
constexpr auto value = true;
|
|
#else
|
|
constexpr auto value = false;
|
|
#endif
|
|
dvars::cg_drawVersion = game::Dvar_RegisterBool(
|
|
"cg_drawVersion", value, game::DVAR_NONE, "Draw the game version");
|
|
dvars::cg_drawVersionX = game::Dvar_RegisterFloat(
|
|
"cg_drawVersionX", 50.0f, 0.0f, 512.0f, game::DVAR_NONE,
|
|
"X offset for the version string");
|
|
dvars::cg_drawVersionY = game::Dvar_RegisterFloat(
|
|
"cg_drawVersionY", 18.0f, 0.0f, 512.0f, game::DVAR_NONE,
|
|
"Y offset for the version string");
|
|
}
|
|
};
|
|
} // namespace branding
|
|
|
|
REGISTER_COMPONENT(branding::component)
|