diff --git a/data/zone_source/ara_h2_mod_font_default_bold.csv b/data/zone_source/ara_h2_mod_font_default_bold.csv new file mode 100644 index 00000000..797f23b4 --- /dev/null +++ b/data/zone_source/ara_h2_mod_font_default_bold.csv @@ -0,0 +1 @@ +ttf,fonts/defaultBold.otf diff --git a/data/zone_source/build.txt b/data/zone_source/build.txt index e43a24fd..693e3b70 100644 --- a/data/zone_source/build.txt +++ b/data/zone_source/build.txt @@ -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 diff --git a/data/zone_source/h2_mod_font_default.csv b/data/zone_source/h2_mod_font_default.csv new file mode 100644 index 00000000..bf5a6574 --- /dev/null +++ b/data/zone_source/h2_mod_font_default.csv @@ -0,0 +1 @@ +ttf,fonts/default.otf diff --git a/data/zone_source/h2_mod_font_default_bold.csv b/data/zone_source/h2_mod_font_default_bold.csv new file mode 100644 index 00000000..797f23b4 --- /dev/null +++ b/data/zone_source/h2_mod_font_default_bold.csv @@ -0,0 +1 @@ +ttf,fonts/defaultBold.otf diff --git a/data/zone_source/h2_mod_font_mix.csv b/data/zone_source/h2_mod_font_mix.csv new file mode 100644 index 00000000..01a85ad6 --- /dev/null +++ b/data/zone_source/h2_mod_font_mix.csv @@ -0,0 +1 @@ +ttf,fonts/mix.ttf \ No newline at end of file diff --git a/data/zone_source/h2_mod_pre_gfx.csv b/data/zone_source/h2_mod_pre_gfx.csv index 38745790..9f24c14b 100644 --- a/data/zone_source/h2_mod_pre_gfx.csv +++ b/data/zone_source/h2_mod_pre_gfx.csv @@ -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 diff --git a/data/zonetool/h2_mod_pre_gfx/fonts/ibmplexsansarabic-semibold_custom.ttf b/data/zonetool/ara_h2_mod_font_default_bold/defaultBold.ttf similarity index 100% rename from data/zonetool/h2_mod_pre_gfx/fonts/ibmplexsansarabic-semibold_custom.ttf rename to data/zonetool/ara_h2_mod_font_default_bold/defaultBold.ttf diff --git a/data/zonetool/h2_mod_pre_gfx/fonts/mix_gothic.ttf b/data/zonetool/fonts/bank.ttf similarity index 100% rename from data/zonetool/h2_mod_pre_gfx/fonts/mix_gothic.ttf rename to data/zonetool/fonts/bank.ttf diff --git a/data/zonetool/h2_mod_pre_gfx/fonts/mix.ttf b/data/zonetool/fonts/default.otf similarity index 100% rename from data/zonetool/h2_mod_pre_gfx/fonts/mix.ttf rename to data/zonetool/fonts/default.otf diff --git a/data/zonetool/h2_mod_pre_gfx/fonts/mix_open.ttf b/data/zonetool/fonts/defaultBold.otf similarity index 100% rename from data/zonetool/h2_mod_pre_gfx/fonts/mix_open.ttf rename to data/zonetool/fonts/defaultBold.otf diff --git a/data/zonetool/fonts/mix.ttf b/data/zonetool/fonts/mix.ttf new file mode 100644 index 00000000..6bdf48ec Binary files /dev/null and b/data/zonetool/fonts/mix.ttf differ diff --git a/data/zonetool/h2_mod_pre_gfx/font_replacements.csv b/data/zonetool/h2_mod_pre_gfx/font_replacements.csv deleted file mode 100644 index 518f3e67..00000000 --- a/data/zonetool/h2_mod_pre_gfx/font_replacements.csv +++ /dev/null @@ -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, \ No newline at end of file diff --git a/data/zonetool/h2_mod_pre_gfx/font_zones.csv b/data/zonetool/h2_mod_pre_gfx/font_zones.csv new file mode 100644 index 00000000..04b2ad25 --- /dev/null +++ b/data/zonetool/h2_mod_pre_gfx/font_zones.csv @@ -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 diff --git a/src/client/component/fastfiles.cpp b/src/client/component/fastfiles.cpp index e5c44e9c..0bb8c80c 100644 --- a/src/client/component/fastfiles.cpp +++ b/src/client/component/fastfiles.cpp @@ -6,6 +6,7 @@ #include "command.hpp" #include "console.hpp" #include "mods.hpp" +#include "fonts.hpp" #include #include @@ -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& zones, - utils::memory::allocator& allocator, const std::string& name, + bool try_add_zone(std::vector& 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& 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(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); } diff --git a/src/client/component/fastfiles.hpp b/src/client/component/fastfiles.hpp index be2a072c..227056d7 100644 --- a/src/client/component/fastfiles.hpp +++ b/src/client/component/fastfiles.hpp @@ -1,6 +1,7 @@ #pragma once #include "game/game.hpp" +#include 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); } diff --git a/src/client/component/fonts.cpp b/src/client/component/fonts.cpp index 097241e8..bb1509b4 100644 --- a/src/client/component/fonts.cpp +++ b/src/client/component/fonts.cpp @@ -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& get_font_replacements() - { - static std::vector 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("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; 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(name_, size); - } - - utils::hook::detour cl_init_renderer_hook; - void* cl_init_renderer_stub() - { - load_font_replacements(); - return cl_init_renderer_hook.invoke(); - } - 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("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); diff --git a/src/client/component/fonts.hpp b/src/client/component/fonts.hpp index c2d22869..a57b886b 100644 --- a/src/client/component/fonts.hpp +++ b/src/client/component/fonts.hpp @@ -1,7 +1,11 @@ #pragma once +#include "game/game.hpp" +#include + namespace fonts { void add(const std::string& name, const std::string& data); void clear(); + void load_font_zones(); }