diff --git a/sfall/Modules/Credits.cpp b/sfall/Modules/Credits.cpp index b3f24fe6..05572417 100644 --- a/sfall/Modules/Credits.cpp +++ b/sfall/Modules/Credits.cpp @@ -177,7 +177,7 @@ static __declspec(naked) void ShowCreditsHook() { } } -// Loads the credits from the 'english' folder if it does not exist in the current language directory +// Loads the credits from the 'english' folder if not found in the current language directory static __declspec(naked) void CreditsFileHook() { __asm { mov ebx, edx; // keep mode @@ -201,8 +201,7 @@ noFile: } void FallbackEnglishCredits() { - const char* lang; - if (fo::func::get_game_config_string(&lang, "system", "language") && _stricmp(lang, "english") != 0) { + if (nonEngLang) { HookCall(0x42C900, CreditsFileHook); } } diff --git a/sfall/Modules/LoadOrder.cpp b/sfall/Modules/LoadOrder.cpp index f438a93d..99cfcae2 100644 --- a/sfall/Modules/LoadOrder.cpp +++ b/sfall/Modules/LoadOrder.cpp @@ -577,10 +577,44 @@ artNotExist: } } +static __declspec(naked) void game_splash_screen_hack() { + __asm { + mov nonEngLang, 1; + // overwritten engine code + mov ecx, [esp + 0xA4 - 0x24 + 4]; + retn; + } +} + +static __declspec(naked) void game_splash_screen_hook() { + __asm { + call fo::funcoffs::db_fopen_; + cmp nonEngLang, 0; + jne checkFile; + retn; +checkFile: + test eax, eax; + jz noFile; + retn; +noFile: + mov eax, dword ptr [esp + 0xA4 - 0x20 + 4]; // splash value + push eax; + push 0x5023E8; // "art\splash\" + push 0x502404; // "%ssplash%d.rix" + lea ebx, [esp + 0xA4 - 0x64 + 16]; // fullname + push ebx; + call fo::funcoffs::sprintf_; + add esp, 16; + mov edx, edi; // mode + mov eax, ebx; // fullname + jmp fo::funcoffs::db_fopen_; + } +} + static fo::DbFile* __fastcall LoadFont(const char* font, const char* mode) { char file[128]; const char* lang; - if (fo::func::get_game_config_string(&lang, "system", "language") && _stricmp(lang, "english") != 0) { + if (fo::func::get_game_config_string(&lang, "system", "language") && nonEngLang) { std::sprintf(file, "fonts\\%s\\%s", lang, font); return fo::func::db_fopen(file, mode); } @@ -674,6 +708,11 @@ void LoadOrder::init() { MakeCall(0x47FB80, SlotMap2Game_hack); // load game MakeCall(0x47FBBF, SlotMap2Game_hack_attr, 1); + // Set sfall global boolean if the game language is not English + MakeCall(0x4443F2, game_splash_screen_hack, 2); + // Load splash screens from the default path if not found in the art\\splash\ directory + HookCall(0x44444E, game_splash_screen_hook); + // Load fonts based on the game language const DWORD loadFontAddr[] = { 0x4D5621, // load_font_ diff --git a/sfall/Modules/Message.cpp b/sfall/Modules/Message.cpp index 3d8d4e9c..c8be6dfd 100644 --- a/sfall/Modules/Message.cpp +++ b/sfall/Modules/Message.cpp @@ -303,7 +303,7 @@ void FallbackEnglishLoadMsgFiles() { const char* lang; if (fo::func::get_game_config_string(&lang, "system", "language")) { strncpy_s(gameLanguage, lang, _TRUNCATE); - if (_stricmp(lang, "english") != 0) { + if (nonEngLang) { HookCall(0x484B18, message_load_hook_db_fopen); HookCall(0x484C4B, message_search_hook_message_find); HookCall(0x4849B9, message_exit_hook_mem_free); diff --git a/sfall/Modules/Premade.cpp b/sfall/Modules/Premade.cpp index f123d507..991b50be 100644 --- a/sfall/Modules/Premade.cpp +++ b/sfall/Modules/Premade.cpp @@ -39,7 +39,7 @@ static const char* __fastcall GetLangPremadePath(const char* premadePath) { isDefault = true; return nullptr; } - isDefault = (_stricmp(Message::GameLanguage(), "english") == 0); + isDefault = !nonEngLang; if (isDefault) return nullptr; std::strncpy(premadeLangPath, premadePath, 8); diff --git a/sfall/main.cpp b/sfall/main.cpp index a1c52c23..2ebfdbfd 100644 --- a/sfall/main.cpp +++ b/sfall/main.cpp @@ -100,6 +100,8 @@ bool hrpVersionValid = false; // HRP 4.1.8 version validation bool extWrapper = false; +bool nonEngLang = false; + static DWORD hrpDLLBaseAddr = 0; // 0x10000000 DWORD HRPAddress(DWORD addr) { diff --git a/sfall/main.h b/sfall/main.h index 81de097d..7bb06a23 100644 --- a/sfall/main.h +++ b/sfall/main.h @@ -83,6 +83,8 @@ extern bool hrpVersionValid; extern bool extWrapper; +extern bool nonEngLang; + DWORD HRPAddress(DWORD addr); __inline long GetIntHRPValue(DWORD addr) {