mirror of
https://github.com/sfall-team/sfall.git
synced 2026-07-27 16:52:34 -07:00
Added language path for loading fonts (#368)
Some code fixes to support the language path.
This commit is contained in:
+1
-1
@@ -6,7 +6,7 @@
|
||||
UseCommandLine=0
|
||||
|
||||
;Uncomment and point to a file to get alternate translations for some sfall messages
|
||||
;This file can be placed in data\text\<language>\ for sfall to get the translations depending on the game language
|
||||
;This file can be placed in text\<language>\ for sfall to get the translations depending on the game language
|
||||
;TranslationsINI=sfall\Translations.ini
|
||||
|
||||
;XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
|
||||
|
||||
@@ -30,18 +30,52 @@ namespace fo
|
||||
|
||||
static fo::MessageNode messageBuf;
|
||||
|
||||
const char* GetMessageStr(const fo::MessageList* fileAddr, long messageId) {
|
||||
return fo::func::getmsg(fileAddr, &messageBuf, messageId);
|
||||
const char* GetMessageStr(const fo::MessageList* file, long messageId) {
|
||||
return fo::func::getmsg(file, &messageBuf, messageId);
|
||||
}
|
||||
|
||||
const char* MessageSearch(const fo::MessageList* fileAddr, long messageId) {
|
||||
const char* MessageSearch(const fo::MessageList* file, long messageId) {
|
||||
messageBuf.number = messageId;
|
||||
if (fo::func::message_search(fileAddr, &messageBuf) == 1) {
|
||||
if (fo::func::message_search(file, &messageBuf) == 1) {
|
||||
return messageBuf.message;
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
fo::MessageNode* GetMsgNode(fo::MessageList* msgList, int msgNum) {
|
||||
if (msgList != nullptr && msgList->numMsgs > 0) {
|
||||
fo::MessageNode *msgNode = msgList->nodes;
|
||||
long last = msgList->numMsgs - 1;
|
||||
long first = 0;
|
||||
long mid;
|
||||
|
||||
// Use Binary Search to find msg
|
||||
while (first <= last) {
|
||||
mid = (first + last) / 2;
|
||||
if (msgNum > msgNode[mid].number)
|
||||
first = mid + 1;
|
||||
else if (msgNum < msgNode[mid].number)
|
||||
last = mid - 1;
|
||||
else
|
||||
return &msgNode[mid];
|
||||
}
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// Alternative version of getmsg_ function
|
||||
char* GetMsg(fo::MessageList* msgList, int msgNum, int msgType) {
|
||||
fo::MessageNode *msgNode = GetMsgNode(msgList, msgNum);
|
||||
if (msgNode) {
|
||||
if (msgType == 2) {
|
||||
return msgNode->message;
|
||||
} else if (msgType == 1) {
|
||||
return msgNode->audio;
|
||||
}
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
fo::Queue* QueueFind(fo::GameObject* object, long type) {
|
||||
if (fo::var::queue) {
|
||||
fo::Queue* queue = fo::var::queue;
|
||||
@@ -582,14 +616,23 @@ static bool LoadFrmFrame(fo::UnlistedFrm::Frame *frame, fo::DbFile* frmStream) {
|
||||
fo::UnlistedFrm *LoadUnlistedFrm(char *frmName, unsigned int folderRef) {
|
||||
if (folderRef > fo::OBJ_TYPE_SKILLDEX) return nullptr;
|
||||
|
||||
char *artfolder = fo::var::art[folderRef].path; // address of art type name
|
||||
const char *artfolder = fo::var::art[folderRef].path; // address of art type name
|
||||
char frmPath[MAX_PATH];
|
||||
|
||||
sprintf_s(frmPath, MAX_PATH, "art\\%s\\%s", artfolder, frmName);
|
||||
if (fo::var::use_language) {
|
||||
sprintf_s(frmPath, MAX_PATH, "art\\%s\\%s\\%s", (const char*)&fo::var::language, artfolder, frmName);
|
||||
} else {
|
||||
sprintf_s(frmPath, MAX_PATH, "art\\%s\\%s", artfolder, frmName);
|
||||
}
|
||||
|
||||
fo::UnlistedFrm *frm = new fo::UnlistedFrm;
|
||||
|
||||
auto frmStream = fo::func::xfopen(frmPath, "rb");
|
||||
auto frmStream = fo::func::db_fopen(frmPath, "rb");
|
||||
|
||||
if (!frmStream && fo::var::use_language) {
|
||||
sprintf_s(frmPath, MAX_PATH, "art\\%s\\%s", artfolder, frmName);
|
||||
frmStream = fo::func::db_fopen(frmPath, "rb");
|
||||
}
|
||||
|
||||
if (frmStream != nullptr) {
|
||||
if (!LoadFrmHeader(frm, frmStream)) {
|
||||
|
||||
@@ -43,10 +43,14 @@ __forceinline void sf_rect_free(fo::RectList* rect) {
|
||||
}
|
||||
|
||||
// returns message string from given file or "Error" when not found
|
||||
const char* GetMessageStr(const fo::MessageList* fileAddr, long messageId);
|
||||
const char* GetMessageStr(const fo::MessageList* file, long messageId);
|
||||
|
||||
// similar to GetMessageStr, but returns nullptr when no message is found
|
||||
const char* MessageSearch(const fo::MessageList* fileAddr, long messageId);
|
||||
const char* MessageSearch(const fo::MessageList* file, long messageId);
|
||||
|
||||
fo::MessageNode* GetMsgNode(fo::MessageList* msgList, int msgNum);
|
||||
|
||||
char* GetMsg(fo::MessageList* msgList, int msgNum, int msgType);
|
||||
|
||||
fo::Queue* QueueFind(fo::GameObject* object, long type);
|
||||
|
||||
|
||||
@@ -136,6 +136,7 @@
|
||||
#define FO_VAR_itemButtonItems 0x5970F8
|
||||
#define FO_VAR_itemCurrentItem 0x518F78
|
||||
#define FO_VAR_kb_lock_flags 0x51E2EA
|
||||
#define FO_VAR_language 0x56C970 // aka _darn_foreign_sub_path
|
||||
#define FO_VAR_last_buttons 0x51E2AC
|
||||
#define FO_VAR_last_button_winID 0x51E404
|
||||
#define FO_VAR_last_level 0x5707B4
|
||||
@@ -280,6 +281,7 @@
|
||||
#define FO_VAR_title_color 0x56D750
|
||||
#define FO_VAR_title_font 0x56D748
|
||||
#define FO_VAR_trait_data 0x51DB84
|
||||
#define FO_VAR_use_language 0x510898 // aka _darn_foreigners
|
||||
#define FO_VAR_view_page 0x664520
|
||||
#define FO_VAR_wd_obj 0x59E98C
|
||||
#define FO_VAR_window 0x6ADE58
|
||||
|
||||
@@ -98,6 +98,7 @@ VAR_(inventry_message_file, fo::MessageList)
|
||||
VARA(itemButtonItems, fo::ItemButtonItem, 2) // 0 - left, 1 - right
|
||||
VAR_(itemCurrentItem, long) // 0 - left, 1 - right
|
||||
VAR_(kb_lock_flags, DWORD)
|
||||
VARA(language, char, 32)
|
||||
VAR_(last_buttons, DWORD)
|
||||
VAR_(last_button_winID, DWORD)
|
||||
VAR_(last_level, DWORD)
|
||||
@@ -223,6 +224,7 @@ VAR_(tile, DWORD)
|
||||
VAR_(title_color, DWORD)
|
||||
VAR_(title_font, DWORD)
|
||||
VARA(trait_data, fo::TraitInfo, fo::TRAIT_count)
|
||||
VAR_(use_language, DWORD)
|
||||
VAR_(view_page, DWORD)
|
||||
VAR_(wd_obj, DWORD)
|
||||
VARA(window, fo::Window*, 50)
|
||||
|
||||
@@ -18,13 +18,11 @@
|
||||
|
||||
#include "..\main.h"
|
||||
#include "..\FalloutEngine\Fallout2.h"
|
||||
#include "..\FalloutEngine\EngineUtils.h"
|
||||
#include "..\Translate.h"
|
||||
|
||||
#include "Inventory.h"
|
||||
#include "LoadGameHook.h"
|
||||
#include "LoadOrder.h"
|
||||
#include "Message.h"
|
||||
#include "PartyControl.h"
|
||||
#include "ScriptExtender.h"
|
||||
|
||||
@@ -578,8 +576,8 @@ static void DrawCharNote(bool style, int winRef, DWORD xPosWin, DWORD yPosWin, B
|
||||
char *MsgFileName = (style) ? "game\\AppStyle.msg" : "game\\AppRace.msg";
|
||||
|
||||
if (fo::func::message_load(&MsgList, MsgFileName) == 1) {
|
||||
TitleMsg = GetMsg(&MsgList, 100, 2);
|
||||
InfoMsg = GetMsg(&MsgList, 101, 2);
|
||||
TitleMsg = fo::GetMsg(&MsgList, 100, 2);
|
||||
InfoMsg = fo::GetMsg(&MsgList, 101, 2);
|
||||
}
|
||||
|
||||
fo::Window *winInfo = fo::func::GNW_find(winRef);
|
||||
@@ -704,8 +702,8 @@ void __stdcall HeroSelectWindow(int raceStyleFlag) {
|
||||
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);
|
||||
RaceStyleBtn = fo::GetMsg(&MsgList, (isStyle) ? 101 : 100, 2);
|
||||
DoneBtn = fo::GetMsg(&MsgList, 102, 2);
|
||||
} else {
|
||||
// Get alternate text from ini if available (TODO: remove this in the future)
|
||||
char titleText[16];
|
||||
@@ -1230,8 +1228,8 @@ static void __declspec(naked) FixCharScrnBack() {
|
||||
fo::MessageList MsgList;
|
||||
|
||||
if (fo::func::message_load(&MsgList, "game\\AppIface.msg") == 1) {
|
||||
RaceBtn = GetMsg(&MsgList, 100, 2);
|
||||
StyleBtn = GetMsg(&MsgList, 101, 2);
|
||||
RaceBtn = fo::GetMsg(&MsgList, 100, 2);
|
||||
StyleBtn = fo::GetMsg(&MsgList, 101, 2);
|
||||
} else {
|
||||
// Get alternate text from ini if available (TODO: remove this in the future)
|
||||
char RaceText[8], StyleText[8];
|
||||
|
||||
@@ -435,6 +435,32 @@ artNotExist:
|
||||
}
|
||||
}
|
||||
|
||||
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) {
|
||||
std::sprintf(file, "%s\\%s", lang, font);
|
||||
return fo::func::db_fopen(file, mode);
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void __declspec(naked) load_font_hook() {
|
||||
__asm {
|
||||
mov ebp, edx;
|
||||
mov ebx, eax;
|
||||
mov ecx, eax;
|
||||
call LoadFont;
|
||||
test eax, eax;
|
||||
jz default;
|
||||
retn;
|
||||
default:
|
||||
mov edx, ebp;
|
||||
mov eax, ebx;
|
||||
jmp fo::funcoffs::db_fopen_;
|
||||
}
|
||||
}
|
||||
|
||||
static void SfallResourceFile() {
|
||||
const char* sfallRes = "sfall.dat";
|
||||
|
||||
@@ -501,6 +527,12 @@ void LoadOrder::init() {
|
||||
MakeCall(0x47FBBF, SlotMap2Game_hack_attr, 1);
|
||||
dlogr(" Done", DL_INIT);
|
||||
|
||||
// Load fonts depending on the game language
|
||||
HookCalls(load_font_hook, {
|
||||
0x4D5621, // load_font_
|
||||
0x441D58 // FMLoadFont_
|
||||
});
|
||||
|
||||
LoadGameHook::OnAfterGameInit() += RemoveSavFiles;
|
||||
LoadGameHook::OnGameReset() += []() {
|
||||
savPrototypes.clear();
|
||||
|
||||
+16
-46
@@ -30,7 +30,7 @@ namespace sfall
|
||||
|
||||
#define CASTMSG(adr) reinterpret_cast<fo::MessageList*>(adr)
|
||||
|
||||
const fo::MessageList* gameMsgFiles[] = {
|
||||
const fo::MessageList* Message::gameMsgFiles[] = {
|
||||
CASTMSG(MSG_FILE_COMBAT),
|
||||
CASTMSG(MSG_FILE_AI),
|
||||
CASTMSG(MSG_FILE_SCRNAME),
|
||||
@@ -54,13 +54,13 @@ const fo::MessageList* gameMsgFiles[] = {
|
||||
};
|
||||
#undef CASTMSG
|
||||
|
||||
static char gameLanguage[41]; // max length of language string is 40
|
||||
static char gameLanguage[32]; // (max length of language string is 40)
|
||||
|
||||
const char* Message::GameLanguage() {
|
||||
return &gameLanguage[0];
|
||||
}
|
||||
|
||||
ExtraGameMessageListsMap gExtraGameMsgLists;
|
||||
ExtraGameMessageListsMap Message::gExtraGameMsgLists;
|
||||
static std::vector<std::string> msgFileList;
|
||||
|
||||
static long msgNumCounter = 0x3000;
|
||||
@@ -70,15 +70,17 @@ static long heroIsFemale = -1;
|
||||
// Searches the special character in the text and removes the text depending on the player's gender
|
||||
// example: <MaleText^FemaleText>
|
||||
static long __fastcall ReplaceGenderWord(fo::MessageNode* msgData, DWORD* msgFile) {
|
||||
|
||||
if (!InDialog() || msgData->flags & MSG_GENDER_CHECK_FLG) return 1;
|
||||
if (heroIsFemale < 0) heroIsFemale = fo::HeroIsFemale();
|
||||
|
||||
unsigned char* _pos = (u_char*)msgData->message;
|
||||
unsigned char* _pos = (unsigned char*)msgData->message;
|
||||
unsigned char* pos;
|
||||
while ((pos = (u_char*)std::strchr((char*)_pos, '^')) != 0) { // pos - pointer to the character position
|
||||
|
||||
while ((pos = (unsigned char*)std::strchr((char*)_pos, '^')) != 0) { // pos - pointer to the character position
|
||||
_pos = pos; // next find position
|
||||
for (u_char* n = pos - 1; ; n--) {
|
||||
if (n < (u_char*)msgData->message) {
|
||||
for (unsigned char* n = pos - 1; ; n--) {
|
||||
if (n < (unsigned char*)msgData->message) {
|
||||
_pos++; // error, open char not found
|
||||
break;
|
||||
} else if (*n == '<') {
|
||||
@@ -111,6 +113,7 @@ static long __fastcall ReplaceGenderWord(fo::MessageNode* msgData, DWORD* msgFil
|
||||
}
|
||||
if (_pos > pos) break;
|
||||
}
|
||||
|
||||
// set flag
|
||||
unsigned long outValue;
|
||||
fo::func::message_find(msgFile, msgData->number, &outValue);
|
||||
@@ -157,39 +160,6 @@ noFile:
|
||||
}
|
||||
}
|
||||
|
||||
fo::MessageNode* GetMsgNode(fo::MessageList* msgList, int msgRef) {
|
||||
if (msgList != nullptr && msgList->numMsgs > 0) {
|
||||
fo::MessageNode *msgNode = msgList->nodes;
|
||||
long last = msgList->numMsgs - 1;
|
||||
long first = 0;
|
||||
long mid;
|
||||
|
||||
// Use Binary Search to find msg
|
||||
while (first <= last) {
|
||||
mid = (first + last) / 2;
|
||||
if (msgRef > msgNode[mid].number)
|
||||
first = mid + 1;
|
||||
else if (msgRef < msgNode[mid].number)
|
||||
last = mid - 1;
|
||||
else
|
||||
return &msgNode[mid];
|
||||
}
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
char* GetMsg(fo::MessageList* msgList, int msgRef, int msgNum) {
|
||||
fo::MessageNode *msgNode = GetMsgNode(msgList, msgRef);
|
||||
if (msgNode) {
|
||||
if (msgNum == 2) {
|
||||
return msgNode->message;
|
||||
} else if (msgNum == 1) {
|
||||
return msgNode->audio;
|
||||
}
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
static void ReadExtraGameMsgFiles() {
|
||||
if (!msgFileList.empty()) {
|
||||
int number = 0;
|
||||
@@ -205,7 +175,7 @@ static void ReadExtraGameMsgFiles() {
|
||||
path += ".msg";
|
||||
fo::MessageList* list = new fo::MessageList();
|
||||
if (fo::func::message_load(list, path.c_str()) == 1) {
|
||||
gExtraGameMsgLists.insert(std::make_pair(0x2000 + number, list));
|
||||
Message::gExtraGameMsgLists.insert(std::make_pair(0x2000 + number, list));
|
||||
} else {
|
||||
delete list;
|
||||
}
|
||||
@@ -218,7 +188,7 @@ static void ReadExtraGameMsgFiles() {
|
||||
long Message::AddExtraMsgFile(const char* msgName, long msgNumber) {
|
||||
if (msgNumber) {
|
||||
if (msgNumber < 0x2000 || msgNumber > 0x2FFF) return -1;
|
||||
if (gExtraGameMsgLists.count(msgNumber)) return 0; // file has already been added
|
||||
if (Message::gExtraGameMsgLists.count(msgNumber)) return 0; // file has already been added
|
||||
} else if (msgNumCounter > 0x3FFF) return -3;
|
||||
|
||||
std::string path("game\\");
|
||||
@@ -233,15 +203,15 @@ long Message::AddExtraMsgFile(const char* msgName, long msgNumber) {
|
||||
//}
|
||||
}
|
||||
if (msgNumber == 0) msgNumber = msgNumCounter++;
|
||||
gExtraGameMsgLists.emplace(msgNumber, list);
|
||||
Message::gExtraGameMsgLists.emplace(msgNumber, list);
|
||||
return msgNumber;
|
||||
}
|
||||
|
||||
static void ClearScriptAddedExtraGameMsg() { // C++11
|
||||
for (auto it = gExtraGameMsgLists.begin(); it != gExtraGameMsgLists.end();) {
|
||||
for (auto it = Message::gExtraGameMsgLists.begin(); it != Message::gExtraGameMsgLists.end();) {
|
||||
if (it->first >= 0x3000 && it->first <= 0x3FFF) {
|
||||
fo::func::message_exit(it->second.get());
|
||||
it = gExtraGameMsgLists.erase(it);
|
||||
it = Message::gExtraGameMsgLists.erase(it);
|
||||
} else {
|
||||
++it;
|
||||
}
|
||||
@@ -259,7 +229,7 @@ static void FallbackEnglishLoadMsgFiles() {
|
||||
}
|
||||
|
||||
static void ClearReadExtraGameMsgFiles() {
|
||||
for (auto it = gExtraGameMsgLists.begin(); it != gExtraGameMsgLists.end(); ++it) {
|
||||
for (auto it = Message::gExtraGameMsgLists.begin(); it != Message::gExtraGameMsgLists.end(); ++it) {
|
||||
fo::func::message_exit(it->second.get());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,10 +18,11 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <memory>
|
||||
#include <unordered_map>
|
||||
|
||||
#include "..\main.h"
|
||||
#include "..\FalloutEngine\Fallout2.h"
|
||||
//#include "..\FalloutEngine\Fallout2.h"
|
||||
|
||||
#include "Module.h"
|
||||
|
||||
@@ -50,8 +51,6 @@ namespace sfall
|
||||
#define MSG_FILE_WORLDMAP (0x672FB0)
|
||||
|
||||
typedef std::unordered_map<int, std::unique_ptr<fo::MessageList>> ExtraGameMessageListsMap;
|
||||
extern ExtraGameMessageListsMap gExtraGameMsgLists;
|
||||
extern const fo::MessageList* gameMsgFiles[];
|
||||
|
||||
class Message : public Module {
|
||||
public:
|
||||
@@ -61,10 +60,10 @@ public:
|
||||
|
||||
static const char* GameLanguage();
|
||||
|
||||
static ExtraGameMessageListsMap gExtraGameMsgLists;
|
||||
static const fo::MessageList* gameMsgFiles[];
|
||||
|
||||
static long AddExtraMsgFile(const char* msgName, long msgNumber);
|
||||
};
|
||||
|
||||
fo::MessageNode* GetMsgNode(fo::MessageList* msgList, int msgRef);
|
||||
char* GetMsg(fo::MessageList* msgList, int msgRef, int msgNum);
|
||||
|
||||
}
|
||||
|
||||
@@ -29,7 +29,7 @@
|
||||
namespace sfall
|
||||
{
|
||||
|
||||
static char mapName[17] = {};
|
||||
static char mapName[16] = {};
|
||||
static char patchName[65] = {};
|
||||
static char versionString[65] = {};
|
||||
|
||||
@@ -761,7 +761,7 @@ static void EngineOptimizationPatches() {
|
||||
void MiscPatches::init() {
|
||||
EngineOptimizationPatches();
|
||||
|
||||
if (IniReader::GetConfigString("Misc", "StartingMap", "", mapName, 17)) {
|
||||
if (IniReader::GetConfigString("Misc", "StartingMap", "", mapName, 16)) {
|
||||
dlog("Applying starting map patch.", DL_INIT);
|
||||
SafeWrite32(0x480AAA, (DWORD)&mapName);
|
||||
dlogr(" Done", DL_INIT);
|
||||
|
||||
@@ -26,19 +26,19 @@
|
||||
namespace sfall
|
||||
{
|
||||
|
||||
static char startMaleModelName[65] = {};
|
||||
static char startMaleModelName[33] = {};
|
||||
char defaultMaleModelName[65] = {};
|
||||
static char startFemaleModelName[65] = {};
|
||||
static char startFemaleModelName[33] = {};
|
||||
char defaultFemaleModelName[65] = {};
|
||||
|
||||
void PlayerModel::init() {
|
||||
if (IniReader::GetConfigString("Misc", "MaleStartModel", "", startMaleModelName, 65)) {
|
||||
if (IniReader::GetConfigString("Misc", "MaleStartModel", "", startMaleModelName, 33)) {
|
||||
dlog("Applying male start model patch.", DL_INIT);
|
||||
SafeWrite32(0x418B88, (DWORD)&startMaleModelName);
|
||||
dlogr(" Done", DL_INIT);
|
||||
}
|
||||
|
||||
if (IniReader::GetConfigString("Misc", "FemaleStartModel", "", startFemaleModelName, 65)) {
|
||||
if (IniReader::GetConfigString("Misc", "FemaleStartModel", "", startFemaleModelName, 33)) {
|
||||
dlog("Applying female start model patch.", DL_INIT);
|
||||
SafeWrite32(0x418BAB, (DWORD)&startFemaleModelName);
|
||||
dlogr(" Done", DL_INIT);
|
||||
|
||||
@@ -28,14 +28,14 @@ namespace sfall
|
||||
static fo::PremadeChar* premade;
|
||||
|
||||
static const char* __fastcall GetLangPremadePath(const char* premadePath) {
|
||||
static char premadeLangPath[65]; // premade\<language>\combat.bio
|
||||
static char premadeLangPath[56]; // 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) {
|
||||
if (len == 0 || len >= 32) {
|
||||
isDefault = true;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
@@ -506,16 +506,27 @@ static fo::FrmFile* LoadArtFile(const char* file, long frame, long direction, fo
|
||||
return frmPtr;
|
||||
}
|
||||
|
||||
static long GetArtFIDFile(long fid, const char* &file) {
|
||||
static long GetArtFIDFile(long fid, char* outFilePath) {
|
||||
long direction = 0;
|
||||
long _fid = fid & 0xFFFFFFF;
|
||||
file = fo::func::art_get_name(_fid); // .frm
|
||||
|
||||
const char* artPathName = fo::func::art_get_name(_fid); // <cd>\art\type\file.frm
|
||||
|
||||
if (_fid >> 24 == fo::OBJ_TYPE_CRITTER) {
|
||||
direction = (fid >> 28);
|
||||
if (direction > 0 && !fo::func::db_access(file)) {
|
||||
file = fo::func::art_get_name(fid); // .fr#
|
||||
if (direction > 0 && !fo::func::db_access(artPathName)) {
|
||||
artPathName = fo::func::art_get_name(fid); // .fr#
|
||||
}
|
||||
} else {
|
||||
if (fo::var::use_language) {
|
||||
const char* _artPathName = std::strchr(artPathName, '\\');
|
||||
if (_artPathName && *(++_artPathName)) {
|
||||
sprintf_s(outFilePath, MAX_PATH, "art\\%s\\%s", (const char*)fo::var::language, _artPathName);
|
||||
if (fo::func::db_access(outFilePath)) return direction;
|
||||
}
|
||||
}
|
||||
}
|
||||
std::strcpy(outFilePath, artPathName);
|
||||
return direction;
|
||||
}
|
||||
|
||||
@@ -532,7 +543,9 @@ static long DrawImage(OpcodeContext& ctx, bool isScaled) {
|
||||
long fid = ctx.arg(0).rawValue();
|
||||
if (fid == -1) return -1;
|
||||
|
||||
direction = GetArtFIDFile(fid, file);
|
||||
char fileBuf[MAX_PATH];
|
||||
direction = GetArtFIDFile(fid, fileBuf);
|
||||
file = fileBuf;
|
||||
} else {
|
||||
file = ctx.arg(0).strValue(); // path to frm/pcx file
|
||||
}
|
||||
@@ -602,7 +615,10 @@ static long InterfaceDrawImage(OpcodeContext& ctx, fo::Window* ifaceWin) {
|
||||
if (fid == -1) return -1;
|
||||
|
||||
useShift = (((fid & 0xF000000) >> 24) == fo::OBJ_TYPE_CRITTER);
|
||||
direction = GetArtFIDFile(fid, file);
|
||||
|
||||
char fileBuf[MAX_PATH];
|
||||
direction = GetArtFIDFile(fid, fileBuf);
|
||||
file = fileBuf;
|
||||
} else {
|
||||
file = ctx.arg(1).strValue(); // path to frm/pcx file
|
||||
}
|
||||
|
||||
@@ -17,7 +17,6 @@
|
||||
*/
|
||||
|
||||
#include "..\..\..\FalloutEngine\Fallout2.h"
|
||||
#include "..\..\..\FalloutEngine\EngineUtils.h"
|
||||
#include "..\..\ScriptExtender.h"
|
||||
#include "..\..\Message.h"
|
||||
#include "..\Arrays.h"
|
||||
@@ -350,13 +349,13 @@ void op_message_str_game(OpcodeContext& ctx) {
|
||||
if (fileId >= 0) {
|
||||
int msgId = ctx.arg(1).rawValue();
|
||||
if (fileId < 20) { // main msg files
|
||||
msg = fo::GetMessageStr(gameMsgFiles[fileId], msgId);
|
||||
msg = fo::GetMessageStr(Message::gameMsgFiles[fileId], msgId);
|
||||
} else if (fileId >= 0x1000 && fileId <= 0x1005) { // proto msg files
|
||||
msg = fo::GetMessageStr(&fo::var::proto_msg_files[fileId - 0x1000], msgId);
|
||||
} else if (fileId >= 0x2000) { // Extra game message files.
|
||||
ExtraGameMessageListsMap::iterator it = gExtraGameMsgLists.find(fileId);
|
||||
if (it != gExtraGameMsgLists.end()) {
|
||||
msg = GetMsg(it->second.get(), msgId, 2);
|
||||
ExtraGameMessageListsMap::iterator it = Message::gExtraGameMsgLists.find(fileId);
|
||||
if (it != Message::gExtraGameMsgLists.end()) {
|
||||
msg = fo::GetMsg(it->second.get(), msgId, 2);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user