More font fixes
This commit is contained in:
parent
0ea88fa8e7
commit
3dee271fb2
@ -47,14 +47,9 @@ namespace fonts
|
|||||||
std::unordered_map<std::string, std::string> raw_fonts;
|
std::unordered_map<std::string, std::string> raw_fonts;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct font_replacement
|
utils::memory::allocator font_allocator;
|
||||||
{
|
|
||||||
game::language_t language;
|
|
||||||
std::string font;
|
|
||||||
std::string replacement;
|
|
||||||
};
|
|
||||||
|
|
||||||
game::StringTable* get_font_replacements()
|
game::StringTable* get_font_replacements_table()
|
||||||
{
|
{
|
||||||
if (!game::DB_XAssetExists(game::ASSET_TYPE_STRINGTABLE, "font_replacements.csv"))
|
if (!game::DB_XAssetExists(game::ASSET_TYPE_STRINGTABLE, "font_replacements.csv"))
|
||||||
{
|
{
|
||||||
@ -64,16 +59,36 @@ namespace fonts
|
|||||||
return game::DB_FindXAssetHeader(game::ASSET_TYPE_STRINGTABLE, "font_replacements.csv", false).stringTable;
|
return game::DB_FindXAssetHeader(game::ASSET_TYPE_STRINGTABLE, "font_replacements.csv", false).stringTable;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string get_font_replacement(const std::string& name)
|
struct font_replacement
|
||||||
{
|
{
|
||||||
const auto table = get_font_replacements();
|
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 table = get_font_replacements_table();
|
||||||
if (table == nullptr)
|
if (table == nullptr)
|
||||||
{
|
{
|
||||||
return name;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const auto current_language = language::current();
|
const auto current_language = language::current();
|
||||||
const std::string language_str = game::languages[current_language].name;
|
|
||||||
|
|
||||||
for (auto row = 0; row < table->rowCount; row++)
|
for (auto row = 0; row < table->rowCount; row++)
|
||||||
{
|
{
|
||||||
@ -81,20 +96,30 @@ namespace fonts
|
|||||||
{
|
{
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
const auto row_values = &table->values[(row * table->columnCount)];
|
const auto row_values = &table->values[(row * table->columnCount)];
|
||||||
const auto lang = row_values[0].string;
|
const auto lang = row_values[0].string;
|
||||||
if (lang != language_str)
|
if (std::strcmp(lang, game::languages[current_language].name))
|
||||||
{
|
{
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
const auto font = row_values[1].string;
|
const auto font = utils::memory::get_allocator()->duplicate_string(row_values[1].string);
|
||||||
const auto replacement = row_values[2].string;
|
const auto replacement = utils::memory::get_allocator()->duplicate_string(row_values[2].string);
|
||||||
|
replacements.emplace_back(font, replacement);
|
||||||
|
}
|
||||||
|
|
||||||
if (font == name)
|
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;
|
return replacement.new_font;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -115,12 +140,12 @@ namespace fonts
|
|||||||
|
|
||||||
void free_font(game::TTF* font)
|
void free_font(game::TTF* font)
|
||||||
{
|
{
|
||||||
utils::memory::get_allocator()->free(font->buffer);
|
font_allocator.free(font->buffer);
|
||||||
utils::memory::get_allocator()->free(font->name);
|
font_allocator.free(font->name);
|
||||||
utils::memory::get_allocator()->free(font);
|
font_allocator.free(font);
|
||||||
}
|
}
|
||||||
|
|
||||||
game::TTF* load_font(const std::string& name, const std::string& original_name)
|
game::TTF* load_font(const std::string& name)
|
||||||
{
|
{
|
||||||
return font_data.access<game::TTF*>([&](font_data_t& data_) -> game::TTF*
|
return font_data.access<game::TTF*>([&](font_data_t& data_) -> game::TTF*
|
||||||
{
|
{
|
||||||
@ -140,18 +165,18 @@ namespace fonts
|
|||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
const auto material = create_font(original_name, data);
|
const auto material = create_font(name, data);
|
||||||
data_.fonts[name] = material;
|
data_.fonts[name] = material;
|
||||||
|
|
||||||
return material;
|
return material;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
game::TTF* try_load_font(const std::string& name, const std::string& original_name)
|
game::TTF* try_load_font(const std::string& name)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
return load_font(name, original_name);
|
return load_font(name);
|
||||||
}
|
}
|
||||||
catch (const std::exception& e)
|
catch (const std::exception& e)
|
||||||
{
|
{
|
||||||
@ -163,19 +188,7 @@ namespace fonts
|
|||||||
|
|
||||||
game::TTF* db_find_xasset_header_stub(game::XAssetType type, const char* name, int create_default)
|
game::TTF* db_find_xasset_header_stub(game::XAssetType type, const char* name, int create_default)
|
||||||
{
|
{
|
||||||
const auto name_ = get_font_replacement(name);
|
auto result = try_load_font(name);
|
||||||
auto result = try_load_font(name_, name);
|
|
||||||
|
|
||||||
if (result == nullptr)
|
|
||||||
{
|
|
||||||
result = game::DB_FindXAssetHeader(type, name_.data(), 0).ttf;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (result == nullptr && (name != name_))
|
|
||||||
{
|
|
||||||
console::error("Couldn't find replacement font \"%s\" for \"%s\"\n", name_.data(), name);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (result == nullptr)
|
if (result == nullptr)
|
||||||
{
|
{
|
||||||
result = game::DB_FindXAssetHeader(type, name, create_default).ttf;
|
result = game::DB_FindXAssetHeader(type, name, create_default).ttf;
|
||||||
@ -184,6 +197,20 @@ namespace fonts
|
|||||||
return result;
|
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;
|
game::Font_s* bank_font = nullptr;
|
||||||
|
|
||||||
utils::hook::detour ui_get_font_handle_hook;
|
utils::hook::detour ui_get_font_handle_hook;
|
||||||
@ -320,6 +347,7 @@ namespace fonts
|
|||||||
free_font(font.second);
|
free_font(font.second);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
font_allocator.clear();
|
||||||
data_.fonts.clear();
|
data_.fonts.clear();
|
||||||
*reinterpret_cast<int*>(0x14EE3ACB8) = 0; // reset registered font count
|
*reinterpret_cast<int*>(0x14EE3ACB8) = 0; // reset registered font count
|
||||||
});
|
});
|
||||||
@ -331,6 +359,8 @@ namespace fonts
|
|||||||
void post_unpack() override
|
void post_unpack() override
|
||||||
{
|
{
|
||||||
utils::hook::call(0x140747096, db_find_xasset_header_stub);
|
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
|
// add custom fonts to hud elem fonts
|
||||||
ui_asset_cache_hook.create(0x140606090, ui_asset_cache_stub);
|
ui_asset_cache_hook.create(0x140606090, ui_asset_cache_stub);
|
||||||
|
Loading…
Reference in New Issue
Block a user