Added language path for premade files (#368)

Added AppIface.msg file support to Hero Appearance mod.
This commit is contained in:
NovaRain
2021-04-21 11:28:48 +08:00
parent 83eee2ba1e
commit 460bc045b9
9 changed files with 129 additions and 32 deletions
+1 -1
View File
@@ -408,7 +408,7 @@ BYTE* __fastcall loadPCX(const char* file, long* width, long* height) {
}
}
long __fastcall get_game_config_string(const char* outValue, const char* section, const char* param) {
long __fastcall get_game_config_string(const char** outValue, const char* section, const char* param) {
__asm {
mov ebx, param;
mov eax, FO_VAR_game_config;
+1 -1
View File
@@ -82,7 +82,7 @@ void __cdecl trans_buf_to_buf(BYTE* src, long width, long height, long src_width
BYTE* __fastcall loadPCX(const char* file, long* width, long* height);
long __fastcall get_game_config_string(const char* outValue, const char* section, const char* param);
long __fastcall get_game_config_string(const char** outValue, const char* section, const char* param);
// X-Macro for wrapper functions.
#define WRAP_WATCOM_FUNC0(retType, name) \
+3
View File
@@ -1205,6 +1205,9 @@ void Graphics::init() {
SafeWrite8(0x50FB6B, '2'); // Set call DirectDrawCreate2
HookCall(0x44260C, game_init_hook);
// Patch HRP to show the mouse cursor over the window title
if (Graphics::mode == 5 && hrpVersionValid) SafeWrite8(HRPAddress(0x10027142), CodeType::JumpShort);
textureFilter = IniReader::GetConfigInt("Graphics", "TextureFilter", 1);
dlogr(" Done", DL_INIT);
}
+38 -18
View File
@@ -700,21 +700,32 @@ void __stdcall HeroSelectWindow(int raceStyleFlag) {
int oldFont = GetFont();
SetFont(0x67);
char titleText[16];
// Get alternate text from ini if available
if (isStyle) {
IniReader::Translate("AppearanceMod", "StyleText", "Style", titleText, 16);
char *RaceStyleBtn, *DoneBtn;
fo::MessageList MsgList;
if (fo::func::message_load(&MsgList, "game\\AppIface.msg") == 1) {
RaceStyleBtn = GetMsg(&MsgList, (isStyle) ? 101 : 100, 2);
DoneBtn = GetMsg(&MsgList, 102, 2);
} else {
IniReader::Translate("AppearanceMod", "RaceText", "Race", titleText, 16);
// Get alternate text from ini if available (TODO: remove this in the future)
char titleText[16];
char doneText[16];
if (isStyle) {
IniReader::Translate("AppearanceMod", "StyleText", "Style", titleText, 16);
} else {
IniReader::Translate("AppearanceMod", "RaceText", "Race", titleText, 16);
}
IniReader::Translate("AppearanceMod", "DoneBtn", "Done", doneText, 16);
RaceStyleBtn = titleText;
DoneBtn = doneText;
}
BYTE textColour = fo::var::PeanutButter; // PeanutButter colour - palette offset stored in mem
DWORD titleTextWidth = fo::GetTextWidth(titleText);
fo::PrintText(titleText, textColour, 92 - titleTextWidth / 2, 10, titleTextWidth, 484, mainSurface);
DWORD titleTextWidth = fo::GetTextWidth(RaceStyleBtn);
fo::PrintText(RaceStyleBtn, textColour, 92 - titleTextWidth / 2, 10, titleTextWidth, 484, mainSurface);
IniReader::Translate("AppearanceMod", "DoneBtn", "Done", titleText, 16);
titleTextWidth = fo::GetTextWidth(titleText);
fo::PrintText(titleText, textColour, 80 - titleTextWidth / 2, 185, titleTextWidth, 484, mainSurface);
titleTextWidth = fo::GetTextWidth(DoneBtn);
fo::PrintText(DoneBtn, textColour, 80 - titleTextWidth / 2, 185, titleTextWidth, 484, mainSurface);
surface_draw(484, 230, 484, 0, 0, mainSurface, 484, 0, 0, winSurface);
fo::func::win_show(winRef);
@@ -1215,18 +1226,27 @@ static void __declspec(naked) FixCharScrnBack() {
int oldFont = GetFont();
SetFont(0x67);
char RaceText[8], StyleText[8];
// Get alternate text from ini if available
IniReader::Translate("AppearanceMod", "RaceText", "Race", RaceText, 8);
IniReader::Translate("AppearanceMod", "StyleText", "Style", StyleText, 8);
char *RaceBtn, *StyleBtn;
fo::MessageList MsgList;
DWORD raceTextWidth = fo::GetTextWidth(RaceText);
DWORD styleTextWidth = fo::GetTextWidth(StyleText);
if (fo::func::message_load(&MsgList, "game\\AppIface.msg") == 1) {
RaceBtn = GetMsg(&MsgList, 100, 2);
StyleBtn = GetMsg(&MsgList, 101, 2);
} else {
// Get alternate text from ini if available (TODO: remove this in the future)
char RaceText[8], StyleText[8];
IniReader::Translate("AppearanceMod", "RaceText", "Race", RaceText, 8);
IniReader::Translate("AppearanceMod", "StyleText", "Style", StyleText, 8);
RaceBtn = RaceText;
StyleBtn = StyleText;
}
DWORD raceTextWidth = fo::GetTextWidth(RaceBtn);
DWORD styleTextWidth = fo::GetTextWidth(StyleBtn);
BYTE PeanutButter = fo::var::PeanutButter; // palette offset stored in mem
fo::PrintText(RaceText, PeanutButter, 372 - raceTextWidth / 2, 6, raceTextWidth, 640, charScrnBackSurface);
fo::PrintText(StyleText, PeanutButter, 372 - styleTextWidth / 2, 231, styleTextWidth, 640, charScrnBackSurface);
fo::PrintText(RaceBtn, PeanutButter, 372 - raceTextWidth / 2, 6, raceTextWidth, 640, charScrnBackSurface);
fo::PrintText(StyleBtn, PeanutButter, 372 - styleTextWidth / 2, 231, styleTextWidth, 640, charScrnBackSurface);
SetFont(oldFont);
}
+10 -3
View File
@@ -53,6 +53,12 @@ const fo::MessageList* gameMsgFiles[] = {
};
#undef CASTMSG
static char gameLanguage[128];
const char* Message::GameLanguage() {
return &gameLanguage[0];
}
ExtraGameMessageListsMap gExtraGameMsgLists;
static std::vector<std::string> msgFileList;
@@ -244,9 +250,10 @@ static void ClearScriptAddedExtraGameMsg() { // C++11
}
static void FallbackEnglishLoadMsgFiles() {
char value[128];
if (fo::func::get_game_config_string(value, "system", "language") && _stricmp(value, "english") != 0) {
HookCall(0x484B18, message_load_hook);
const char* lang;
if (fo::func::get_game_config_string(&lang, "system", "language")) {
strncpy_s(gameLanguage, lang, _TRUNCATE);
if (_stricmp(lang, "english") != 0) HookCall(0x484B18, message_load_hook);
}
}
+2
View File
@@ -59,6 +59,8 @@ public:
void init();
void exit() override;
static const char* GameLanguage();
static long AddExtraMsgFile(const char* msgName, long msgNumber);
};
+2
View File
@@ -815,6 +815,8 @@ void MiscPatches::init() {
BlockCall(0x4425E6); // Patch out ereg call
SafeWrite8(0x4810AB, CodeType::JumpShort); // Disable selfrun
SimplePatch<DWORD>(0x440C2A, "Misc", "SpecialDeathGVAR", fo::GVAR_MODOC_SHITTY_DEATH);
// Remove hardcoding for maps with IDs 19 and 37
+71 -8
View File
@@ -17,14 +17,73 @@
*/
#include "..\main.h"
#include "..\FalloutEngine\Structs.h"
#include "..\FalloutEngine\Fallout2.h"
#include "Message.h"
#include "Premade.h"
namespace sfall
{
fo::PremadeChar* premade;
static fo::PremadeChar* premade;
static const char* __fastcall GetLangPremadePath(const char* premadePath) {
static char premadeLangPath[64]; // premade\<language>\combat.bio
static bool isDefault = false;
static long len = 0;
if (isDefault) return nullptr;
if (len == 0) {
len = std::strlen(Message::GameLanguage());
if (len == 0 || len > 40) {
isDefault = true;
return nullptr;
}
isDefault = (_stricmp(Message::GameLanguage(), "english") == 0);
if (isDefault) return nullptr;
std::strncpy(premadeLangPath, premadePath, 8);
std::strcpy(&premadeLangPath[8], Message::GameLanguage());
}
std::strcpy(&premadeLangPath[8 + len], &premadePath[7]);
return premadeLangPath;
}
static const char* __fastcall PremadeGCD(const char* premadePath) {
const char* path = GetLangPremadePath(premadePath);
return (path && fo::func::db_access(path)) ? path : premadePath;
}
static fo::DbFile* __fastcall PremadeBIO(const char* premadePath, const char* mode) {
premadePath = GetLangPremadePath(premadePath);
return (premadePath) ? fo::func::db_fopen(premadePath, mode) : nullptr;
}
static void __declspec(naked) select_display_bio_hook() {
__asm {
push eax;
push edx;
mov ecx, eax; // premade path
call PremadeBIO;
test eax, eax;
jz default;
add esp, 8;
retn;
default:
pop edx;
pop eax;
jmp fo::funcoffs::db_fopen_;
}
}
static void __declspec(naked) select_update_display_hook() {
__asm {
mov ecx, eax; // premade path
call PremadeGCD;
jmp fo::funcoffs::proto_dude_init_;
}
}
void Premade::init() {
auto premadePaths = IniReader::GetConfigList("misc", "PremadePaths", "", 512);
@@ -39,17 +98,21 @@ void Premade::init() {
dlog_f(" Failed: %s exceeds 11 characters\n", DL_INIT, premadePaths[i].c_str());
return;
}
strcpy(premade[i].path, path.c_str());
std::strcpy(premade[i].path, path.c_str());
premade[i].fid = atoi(premadeFids[i].c_str());
}
SafeWrite32(0x51C8D4, count);
SafeWrite32(0x4A7D76, (DWORD)premade);
SafeWrite32(0x4A8B1E, (DWORD)premade);
SafeWrite32(0x4A7E2C, (DWORD)&premade[0].fid);
strcpy((char*)0x50AF68, premade[0].path);
SafeWrite32(0x51C8D4, count); // _premade_total
SafeWrite32(0x4A7D76, (DWORD)premade); // select_update_display_
SafeWrite32(0x4A8B1E, (DWORD)premade); // select_display_bio_
SafeWrite32(0x4A7E2C, (DWORD)&premade[0].fid); // select_display_portrait_
std::strcpy((char*)0x50AF68, premade[0].path); // for selfrun
dlogr(" Done", DL_INIT);
}
// Add language path for premade GCD/BIO files
HookCall(0x4A8B44, select_display_bio_hook);
HookCall(0x4A7D91, select_update_display_hook);
}
}
+1 -1
View File
@@ -208,7 +208,7 @@ static int __stdcall ArtInitHook() {
if (listpos != tiles->total) {
tiles->names = (char*)fo::func::mem_realloc(tiles->names, listpos * 13);
for (long i = tiles->total; i < listpos; i++) {
sprintf_s(&tiles->names[i * 13], 12, "zzz%04d.frm", i - tiles->total);
sprintf(&tiles->names[i * 13], "zzz%04d.frm", i - tiles->total);
}
tiles->total = listpos;
}