Better font replacement system
This commit is contained in:
parent
74db7b53c6
commit
209184007c
1
data/zone_source/ara_h2_mod_font_default_bold.csv
Normal file
1
data/zone_source/ara_h2_mod_font_default_bold.csv
Normal file
@ -0,0 +1 @@
|
||||
ttf,fonts/defaultBold.otf
|
|
@ -1,4 +1,5 @@
|
||||
ara_h2_mod_common
|
||||
ara_h2_mod_font_default_bold
|
||||
deu_h2_mod_common
|
||||
eng_h2_mod_common
|
||||
eng_h2_mod_patch_af_caves
|
||||
@ -7,6 +8,9 @@ ens_h2_mod_patch_af_caves
|
||||
cze_h2_mod_common
|
||||
fra_h2_mod_common
|
||||
h2_mod_common
|
||||
h2_mod_font_default
|
||||
h2_mod_font_default_bold
|
||||
h2_mod_font_bank
|
||||
h2_mod_patch_af_caves
|
||||
h2_mod_patch_dc_whitehouse
|
||||
h2_mod_patch_ending
|
||||
|
1
data/zone_source/h2_mod_font_default.csv
Normal file
1
data/zone_source/h2_mod_font_default.csv
Normal file
@ -0,0 +1 @@
|
||||
ttf,fonts/default.otf
|
|
1
data/zone_source/h2_mod_font_default_bold.csv
Normal file
1
data/zone_source/h2_mod_font_default_bold.csv
Normal file
@ -0,0 +1 @@
|
||||
ttf,fonts/defaultBold.otf
|
|
1
data/zone_source/h2_mod_font_mix.csv
Normal file
1
data/zone_source/h2_mod_font_mix.csv
Normal file
@ -0,0 +1 @@
|
||||
ttf,fonts/mix.ttf
|
|
@ -1,6 +1,2 @@
|
||||
stringtable,font_replacements.csv
|
||||
ttf,fonts/ibmplexsansarabic-semibold_custom.ttf
|
||||
ttf,fonts/mix.ttf
|
||||
ttf,fonts/mix_gothic.ttf
|
||||
ttf,fonts/mix_open.ttf
|
||||
stringtable,font_zones.csv
|
||||
localize,branding
|
||||
|
|
BIN
data/zonetool/fonts/mix.ttf
Normal file
BIN
data/zonetool/fonts/mix.ttf
Normal file
Binary file not shown.
@ -1,25 +0,0 @@
|
||||
arabic,fonts/bank.ttf,fonts/mix_gothic.ttf,
|
||||
arabic,fonts/default.otf,fonts/mix.ttf,
|
||||
arabic,fonts/defaultBold.otf,fonts/ibmplexsansarabic-semibold_custom.ttf,
|
||||
czech,fonts/bank.ttf,fonts/mix_gothic.ttf,
|
||||
czech,fonts/default.otf,fonts/mix.ttf,
|
||||
czech,fonts/defaultBold.otf,fonts/mix_open.ttf,
|
||||
japanese_full,fonts/default.otf,fonts/mix.ttf,
|
||||
japanese_full,fonts/defaultBold.otf,fonts/mix_open.ttf,
|
||||
japanese_partial,fonts/default.otf,fonts/mix.ttf,
|
||||
japanese_partial,fonts/defaultBold.otf,fonts/mix_open.ttf,
|
||||
korean,fonts/default.otf,fonts/mix.ttf,
|
||||
korean,fonts/defaultBold.otf,fonts/mix_open.ttf,
|
||||
polish,fonts/bank.ttf,fonts/mix_gothic.ttf,
|
||||
polish,fonts/default.otf,fonts/mix.ttf,
|
||||
polish,fonts/defaultBold.otf,fonts/mix_open.ttf,
|
||||
russian,fonts/bank.ttf,fonts/mix_gothic.ttf,
|
||||
russian,fonts/default.otf,fonts/mix.ttf,
|
||||
russian,fonts/defaultBold.otf,fonts/mix_open.ttf,
|
||||
russian_partial,fonts/bank.ttf,fonts/mix_gothic.ttf,
|
||||
russian_partial,fonts/default.otf,fonts/mix.ttf,
|
||||
russian_partial,fonts/defaultBold.otf,fonts/mix_open.ttf,
|
||||
simplified_chinese,fonts/default.otf,fonts/mix.ttf,
|
||||
simplified_chinese,fonts/defaultBold.otf,fonts/mix_open.ttf,
|
||||
traditional_chinese,fonts/default.otf,fonts/mix.ttf,
|
||||
traditional_chinese,fonts/defaultBold.otf,fonts/mix_open.ttf,
|
|
11
data/zonetool/h2_mod_pre_gfx/font_zones.csv
Normal file
11
data/zonetool/h2_mod_pre_gfx/font_zones.csv
Normal file
@ -0,0 +1,11 @@
|
||||
*,h2_mod_font_mix
|
||||
arabic,h2_mod_font_bank,h2_mod_font_default,h2_mod_font_default_bold
|
||||
czech,h2_mod_font_bank,h2_mod_font_default,h2_mod_font_default_bold
|
||||
japanese_full,h2_mod_font_default,h2_mod_font_default_bold
|
||||
japanese_partial,h2_mod_font_default,h2_mod_font_default_bold
|
||||
korean,h2_mod_font_default,h2_mod_font_default_bold
|
||||
polish,h2_mod_font_bank,h2_mod_font_default,h2_mod_font_default_bold
|
||||
russian,h2_mod_font_bank,h2_mod_font_default,h2_mod_font_default_bold
|
||||
russian_partial,h2_mod_font_bank,h2_mod_font_default,h2_mod_font_default_bold
|
||||
simplified_chinese,h2_mod_font_default,h2_mod_font_default_bold
|
||||
traditional_chinese,h2_mod_font_default,h2_mod_font_default_bold
|
|
@ -6,6 +6,7 @@
|
||||
#include "command.hpp"
|
||||
#include "console.hpp"
|
||||
#include "mods.hpp"
|
||||
#include "fonts.hpp"
|
||||
|
||||
#include <utils/hook.hpp>
|
||||
#include <utils/concurrency.hpp>
|
||||
@ -104,29 +105,8 @@ namespace fastfiles
|
||||
a.jmp(0x140415E29);
|
||||
}
|
||||
|
||||
bool try_load_zone(const std::string& name, bool localized, bool game = false)
|
||||
{
|
||||
if (localized)
|
||||
{
|
||||
const auto language = game::SEH_GetCurrentLanguageCode();
|
||||
try_load_zone(language + "_"s + name, false);
|
||||
}
|
||||
|
||||
if (!fastfiles::exists(name))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
game::XZoneInfo info{};
|
||||
info.name = name.data();
|
||||
info.allocFlags = (game ? game::DB_ZONE_GAME : game::DB_ZONE_COMMON) | game::DB_ZONE_CUSTOM;
|
||||
info.freeFlags = 0;
|
||||
game::DB_LoadXAssets(&info, 1u, game::DBSyncMode::DB_LOAD_ASYNC);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool try_add_zone(std::vector<game::XZoneInfo>& zones,
|
||||
utils::memory::allocator& allocator, const std::string& name,
|
||||
bool try_add_zone(std::vector<game::XZoneInfo>& zones,
|
||||
utils::memory::allocator& allocator, const std::string& name,
|
||||
bool localized, bool game = false)
|
||||
{
|
||||
if (localized)
|
||||
@ -148,19 +128,6 @@ namespace fastfiles
|
||||
return true;
|
||||
}
|
||||
|
||||
void load_mod_zones()
|
||||
{
|
||||
try_load_zone("mod", true);
|
||||
const auto mod_zones = mods::get_mod_zones();
|
||||
for (const auto& zone : mod_zones)
|
||||
{
|
||||
if (zone.alloc_flags & game::DB_ZONE_COMMON)
|
||||
{
|
||||
try_load_zone(zone.name, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void add_mod_zones(std::vector<game::XZoneInfo>& zones, utils::memory::allocator& allocator)
|
||||
{
|
||||
try_add_zone(zones, allocator, "mod", true);
|
||||
@ -194,6 +161,7 @@ namespace fastfiles
|
||||
push_zones(zones, zone_info, zone_count);
|
||||
|
||||
game::DB_LoadXAssets(zones.data(), static_cast<int>(zones.size()), sync_mode);
|
||||
fonts::load_font_zones();
|
||||
}
|
||||
|
||||
void load_post_gfx_and_ui_and_common_zones(game::XZoneInfo* zone_info,
|
||||
@ -632,6 +600,27 @@ namespace fastfiles
|
||||
});
|
||||
}
|
||||
|
||||
bool try_load_zone(const std::string& name, bool localized, bool game)
|
||||
{
|
||||
if (localized)
|
||||
{
|
||||
const auto language = game::SEH_GetCurrentLanguageCode();
|
||||
try_load_zone(language + "_"s + name, false);
|
||||
}
|
||||
|
||||
if (!fastfiles::exists(name))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
game::XZoneInfo info{};
|
||||
info.name = name.data();
|
||||
info.allocFlags = (game ? game::DB_ZONE_GAME : game::DB_ZONE_COMMON) | game::DB_ZONE_CUSTOM;
|
||||
info.freeFlags = 0;
|
||||
game::DB_LoadXAssets(&info, 1u, game::DBSyncMode::DB_LOAD_ASYNC);
|
||||
return true;
|
||||
}
|
||||
|
||||
class component final : public component_interface
|
||||
{
|
||||
public:
|
||||
@ -691,7 +680,7 @@ namespace fastfiles
|
||||
}
|
||||
|
||||
const auto name = params.get(1);
|
||||
if (!try_load_zone(name, false))
|
||||
if (!fastfiles::try_load_zone(name, false))
|
||||
{
|
||||
console::warn("loadzone: zone \"%s\" could not be found!\n", name);
|
||||
}
|
||||
|
@ -1,6 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
#include "game/game.hpp"
|
||||
#include <utils/memory.hpp>
|
||||
|
||||
namespace fastfiles
|
||||
{
|
||||
@ -8,4 +9,5 @@ namespace fastfiles
|
||||
std::string get_current_fastfile();
|
||||
|
||||
bool exists(const std::string& zone);
|
||||
bool try_load_zone(const std::string& name, bool localized, bool game = false);
|
||||
}
|
||||
|
@ -7,6 +7,7 @@
|
||||
#include "command.hpp"
|
||||
#include "language.hpp"
|
||||
#include "config.hpp"
|
||||
#include "fastfiles.hpp"
|
||||
|
||||
#include "game/game.hpp"
|
||||
#include "game/dvars.hpp"
|
||||
@ -49,89 +50,6 @@ namespace fonts
|
||||
|
||||
utils::memory::allocator font_allocator;
|
||||
|
||||
game::StringTable* get_font_replacements_table()
|
||||
{
|
||||
if (!game::DB_XAssetExists(game::ASSET_TYPE_STRINGTABLE, "font_replacements.csv"))
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return game::DB_FindXAssetHeader(game::ASSET_TYPE_STRINGTABLE, "font_replacements.csv", false).stringTable;
|
||||
}
|
||||
|
||||
struct font_replacement
|
||||
{
|
||||
const char* target_font;
|
||||
const char* new_font;
|
||||
};
|
||||
|
||||
std::vector<font_replacement>& get_font_replacements()
|
||||
{
|
||||
static std::vector<font_replacement> replacements = {};
|
||||
return replacements;
|
||||
}
|
||||
|
||||
void load_font_replacements()
|
||||
{
|
||||
static auto loaded = false;
|
||||
if (loaded)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
loaded = true;
|
||||
auto& replacements = get_font_replacements();
|
||||
|
||||
const auto disabled = config::get<bool>("disable_custom_fonts");
|
||||
if (disabled.has_value() && disabled.value() && language::current() != game::LANGUAGE_CZECH)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
const auto table = get_font_replacements_table();
|
||||
if (table == nullptr)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
const auto current_language = language::current();
|
||||
|
||||
for (auto row = 0; row < table->rowCount; row++)
|
||||
{
|
||||
if (table->columnCount < 3)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
const auto row_values = &table->values[(row * table->columnCount)];
|
||||
const auto lang = row_values[0].string;
|
||||
if (std::strcmp(lang, game::languages[current_language].name))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
const auto font = utils::memory::get_allocator()->duplicate_string(row_values[1].string);
|
||||
const auto replacement = utils::memory::get_allocator()->duplicate_string(row_values[2].string);
|
||||
replacements.emplace_back(font, replacement);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
const char* get_font_replacement(const char* name)
|
||||
{
|
||||
const auto& replacements = get_font_replacements();
|
||||
for (const auto& replacement : replacements)
|
||||
{
|
||||
if (!std::strcmp(name, replacement.target_font))
|
||||
{
|
||||
return replacement.new_font;
|
||||
}
|
||||
}
|
||||
|
||||
return name;
|
||||
}
|
||||
|
||||
utils::concurrency::container<font_data_t> font_data;
|
||||
|
||||
game::TTF* create_font(const std::string& name, const std::string& data)
|
||||
@ -203,20 +121,6 @@ namespace fonts
|
||||
return result;
|
||||
}
|
||||
|
||||
utils::hook::detour r_register_font_hook;
|
||||
void* r_register_font_stub(const char* name, int size)
|
||||
{
|
||||
const auto name_ = get_font_replacement(name);
|
||||
return r_register_font_hook.invoke<void*>(name_, size);
|
||||
}
|
||||
|
||||
utils::hook::detour cl_init_renderer_hook;
|
||||
void* cl_init_renderer_stub()
|
||||
{
|
||||
load_font_replacements();
|
||||
return cl_init_renderer_hook.invoke<void*>();
|
||||
}
|
||||
|
||||
game::Font_s* bank_font = nullptr;
|
||||
|
||||
utils::hook::detour ui_get_font_handle_hook;
|
||||
@ -359,14 +263,53 @@ namespace fonts
|
||||
});
|
||||
}
|
||||
|
||||
void load_font_zones()
|
||||
{
|
||||
const auto disabled = config::get<bool>("disable_custom_fonts");
|
||||
if (disabled.has_value() && disabled.value() && language::current() != game::LANGUAGE_CZECH)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
const auto table = game::DB_FindXAssetHeader(game::ASSET_TYPE_STRINGTABLE, "font_zones.csv", 0).stringTable;
|
||||
if (table == nullptr)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
const auto lang = language::current();
|
||||
const auto lang_name = game::languages[lang].name;
|
||||
for (auto row = 0; row < table->rowCount; row++)
|
||||
{
|
||||
if (table->columnCount < 3)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
const auto row_values = &table->values[(row * table->columnCount)];
|
||||
const auto lang_value = row_values[0].string;
|
||||
if (std::strcmp(lang_value, lang_name) && lang_value != "*"s)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
for (auto col = 1; col < table->columnCount; col++)
|
||||
{
|
||||
const auto zone = row_values[col].string;
|
||||
if (zone != nullptr)
|
||||
{
|
||||
fastfiles::try_load_zone(zone, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class component final : public component_interface
|
||||
{
|
||||
public:
|
||||
void post_unpack() override
|
||||
{
|
||||
utils::hook::call(0x140747096, db_find_xasset_header_stub);
|
||||
r_register_font_hook.create(0x140746FE0, r_register_font_stub);
|
||||
cl_init_renderer_hook.create(0x1403D5AA0, cl_init_renderer_stub);
|
||||
|
||||
// add custom fonts to hud elem fonts
|
||||
ui_asset_cache_hook.create(0x140606090, ui_asset_cache_stub);
|
||||
|
@ -1,7 +1,11 @@
|
||||
#pragma once
|
||||
|
||||
#include "game/game.hpp"
|
||||
#include <utils/memory.hpp>
|
||||
|
||||
namespace fonts
|
||||
{
|
||||
void add(const std::string& name, const std::string& data);
|
||||
void clear();
|
||||
void load_font_zones();
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user