mirror of
https://github.com/sfall-team/sfall.git
synced 2026-07-27 16:52:34 -07:00
Added language path for premade files (#368)
Added AppIface.msg file support to Hero Appearance mod.
This commit is contained in:
@@ -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;
|
||||
|
||||
@@ -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) \
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -700,21 +700,32 @@ void __stdcall HeroSelectWindow(int raceStyleFlag) {
|
||||
int oldFont = GetFont();
|
||||
SetFont(0x67);
|
||||
|
||||
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 {
|
||||
// Get alternate text from ini if available (TODO: remove this in the future)
|
||||
char titleText[16];
|
||||
// Get alternate text from ini if available
|
||||
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 *RaceBtn, *StyleBtn;
|
||||
fo::MessageList MsgList;
|
||||
|
||||
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];
|
||||
// Get alternate text from ini if available
|
||||
IniReader::Translate("AppearanceMod", "RaceText", "Race", RaceText, 8);
|
||||
IniReader::Translate("AppearanceMod", "StyleText", "Style", StyleText, 8);
|
||||
|
||||
DWORD raceTextWidth = fo::GetTextWidth(RaceText);
|
||||
DWORD styleTextWidth = fo::GetTextWidth(StyleText);
|
||||
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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -59,6 +59,8 @@ public:
|
||||
void init();
|
||||
void exit() override;
|
||||
|
||||
static const char* GameLanguage();
|
||||
|
||||
static long AddExtraMsgFile(const char* msgName, long msgNumber);
|
||||
};
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user