mirror of
https://github.com/sfall-team/sfall.git
synced 2026-07-27 16:52:34 -07:00
Final preparations for extended UI patches
- Reduced inventory UI height by 8 pixels and moved all Done buttons down - Renamed all extra FRM files - Added checks that all required FRMs exist before applying patch - Add final FRM files (EN versions) - Minor refactoring
This commit is contained in:
+3
-3
@@ -134,12 +134,12 @@ WorldMapTravelMarkers=0
|
||||
WorldMapTerrainInfo=0
|
||||
|
||||
;Set to 1 to enable tall trade/barter window with 4 item slots per table instead of 3
|
||||
;Requires the high-res patch mode and new barter_239.frm and trade_238.frm files in art\intrface\ (included in sfall.dat)
|
||||
;The resolution of the hi-res patch must be set to at least 640x528
|
||||
;Requires the high-res mode with resolution of at least 640x528
|
||||
;Requires new frm files in art\intrface\: barter_e.frm (640x239), trade_e.frm (640x238) (included in sfall.dat)
|
||||
ExpandedBarter=0
|
||||
|
||||
;Set to 1 to enable tall inventory/loot/item select windows with 8 vertical slots instead of 6
|
||||
;Requires new frms: invbox_473.frm, loot_472.frm and use_472.frm files in art\intrface\ (included in sfall.dat) to display correctly
|
||||
;Requires new frm files in art\intrface\: invbox_e.frm (499x467), loot_e.frm (537x464) and use_e.frm (292x464) files (included in sfall.dat)
|
||||
ExpandedInventory=0
|
||||
|
||||
;XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
|
||||
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -63,22 +63,40 @@ PcxFile LoadPcxFileCached(const char* file) {
|
||||
return pcxFileCache.emplace(file, LoadPcxFile(file)).first->second;
|
||||
}
|
||||
|
||||
static void GetUnlistedFrmPath(const char* frmName, unsigned int folderRef, bool useLanguage, char* buf, size_t bufSize) {
|
||||
|
||||
const char* artfolder = fo::var::art[folderRef].path; // address of art type name
|
||||
if (useLanguage) {
|
||||
sprintf_s(buf, MAX_PATH, "art\\%s\\%s\\%s", (const char*)fo::var::language, artfolder, frmName);
|
||||
} else {
|
||||
sprintf_s(buf, MAX_PATH, "art\\%s\\%s", artfolder, frmName);
|
||||
}
|
||||
}
|
||||
|
||||
bool UnlistedFrmExists(const char* frmName, unsigned int folderRef) {
|
||||
if (folderRef > fo::OBJ_TYPE_SKILLDEX) return nullptr;
|
||||
|
||||
char frmPath[MAX_PATH];
|
||||
GetUnlistedFrmPath(frmName, folderRef, fo::var::use_language != 0, frmPath, MAX_PATH);
|
||||
|
||||
bool exists = fo::func::db_access(frmPath);
|
||||
if (!exists && fo::var::use_language) {
|
||||
GetUnlistedFrmPath(frmName, folderRef, false, frmPath, MAX_PATH);
|
||||
exists = fo::func::db_access(frmPath);
|
||||
}
|
||||
return exists;
|
||||
}
|
||||
|
||||
fo::FrmFile* LoadUnlistedFrmCached(const char* frmName, unsigned int folderRef) {
|
||||
if (folderRef > fo::OBJ_TYPE_SKILLDEX) return nullptr;
|
||||
|
||||
const char* artfolder = fo::var::art[folderRef].path; // address of art type name
|
||||
char frmPath[MAX_PATH];
|
||||
|
||||
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);
|
||||
}
|
||||
GetUnlistedFrmPath(frmName, folderRef, fo::var::use_language != 0, frmPath, MAX_PATH);
|
||||
|
||||
fo::FrmFile* frm = LoadFrmFileCached(frmPath);
|
||||
if (frm == nullptr && fo::var::use_language) {
|
||||
sprintf_s(frmPath, MAX_PATH, "art\\%s\\%s", artfolder, frmName);
|
||||
GetUnlistedFrmPath(frmName, folderRef, false, frmPath, MAX_PATH);
|
||||
frm = LoadFrmFileCached(frmPath);
|
||||
}
|
||||
return frm;
|
||||
|
||||
@@ -45,6 +45,7 @@ public:
|
||||
fo::FrmFile* LoadFrmFileCached(const char* file);
|
||||
PcxFile LoadPcxFileCached(const char* file);
|
||||
|
||||
bool UnlistedFrmExists(const char* frmName, unsigned int folderRef);
|
||||
fo::FrmFile* LoadUnlistedFrmCached(const char* file, unsigned int folderRef);
|
||||
|
||||
}
|
||||
|
||||
+65
-35
@@ -97,21 +97,34 @@ fo::Window* Interface::GetWindow(long winType) {
|
||||
return (winID > 0) ? fo::func::GNW_find(winID) : nullptr;
|
||||
}
|
||||
|
||||
static BYTE* LoadInterfaceFrmData(fo::FrmFile** frm, const char* frmName) {
|
||||
if (*frm == nullptr) {
|
||||
*frm = LoadUnlistedFrmCached(frmName, fo::ArtType::OBJ_TYPE_INTRFACE);
|
||||
if (*frm == nullptr) {
|
||||
return nullptr;
|
||||
}
|
||||
struct InterfaceCustomFrm {
|
||||
fo::FrmFile* frm;
|
||||
const char* frmName;
|
||||
bool isLoaded;
|
||||
|
||||
InterfaceCustomFrm(const char* _frmName) : frm(nullptr), frmName(_frmName), isLoaded(false) {}
|
||||
InterfaceCustomFrm(InterfaceCustomFrm &other) = delete;
|
||||
|
||||
bool ArtExists() const {
|
||||
return UnlistedFrmExists(frmName, fo::ArtType::OBJ_TYPE_INTRFACE);
|
||||
}
|
||||
return (*frm)->frameData[0].data;
|
||||
}
|
||||
|
||||
BYTE* LoadFrmData() {
|
||||
if (!isLoaded) {
|
||||
frm = LoadUnlistedFrmCached(frmName, fo::ArtType::OBJ_TYPE_INTRFACE);
|
||||
isLoaded = true;
|
||||
}
|
||||
return frm != nullptr
|
||||
? frm->frameData[0].data
|
||||
: nullptr;
|
||||
}
|
||||
};
|
||||
|
||||
static BYTE movePointBackground[16 * 9 * 5];
|
||||
static fo::FrmFile* ifaceFrm = nullptr;
|
||||
static InterfaceCustomFrm ifaceFrm{ "IFACE_E.frm" };
|
||||
|
||||
static void* LoadIfaceFrm() {
|
||||
return LoadInterfaceFrmData(&ifaceFrm, "IFACE_E.frm");
|
||||
return ifaceFrm.LoadFrmData();
|
||||
}
|
||||
|
||||
static void __declspec(naked) intface_init_hook_lock() {
|
||||
@@ -1113,15 +1126,14 @@ static void UIAnimationSpeedPatch() {
|
||||
SimplePatch<BYTE>(&addrs[4], 2, "Misc", "PipboyTimeAnimDelay", 50, 0, 127);
|
||||
}
|
||||
|
||||
static fo::FrmFile* barterTallFrm = nullptr;
|
||||
static fo::FrmFile* tradeTallFrm = nullptr;
|
||||
constexpr long numTallFrms = fo::INVENTORY_WINDOW_TYPE_TRADE;
|
||||
static fo::FrmFile* inventoryTallFrms[numTallFrms] = { nullptr, nullptr, nullptr };
|
||||
static const char* inventoryTallFrmNames[numTallFrms] = { "invbox_473.frm", "use_472.frm", "loot_472.frm"};
|
||||
static InterfaceCustomFrm barterTallFrm { "barter_e.frm" };
|
||||
static InterfaceCustomFrm tradeTallFrm { "trade_e.frm" };
|
||||
|
||||
static std::array<InterfaceCustomFrm, fo::INVENTORY_WINDOW_TYPE_TRADE> inventoryTallFrms { "invbox_e.frm", "use_e.frm", "loot_e.frm"};
|
||||
|
||||
static DWORD findInventoryWindowTypeByFid(DWORD fid) {
|
||||
fid &= 0xFFF;
|
||||
for (int i = 0; i < numTallFrms; ++i) {
|
||||
for (int i = 0; i < fo::INVENTORY_WINDOW_TYPE_TRADE; ++i) {
|
||||
if (fid == fo::var::iscr_data[i].artIndex)
|
||||
return i;
|
||||
}
|
||||
@@ -1132,25 +1144,21 @@ static BYTE* __fastcall inventory_get_art_data(DWORD fid) {
|
||||
DWORD windowType = findInventoryWindowTypeByFid(fid);
|
||||
if (windowType > fo::INVENTORY_WINDOW_TYPE_LOOT) return nullptr;
|
||||
|
||||
return LoadInterfaceFrmData(&inventoryTallFrms[windowType], inventoryTallFrmNames[windowType]);
|
||||
return inventoryTallFrms[windowType].LoadFrmData();
|
||||
}
|
||||
|
||||
static BYTE* __fastcall gdialog_barter_get_art_data() {
|
||||
if (fo::var::dialog_target_is_party) {
|
||||
return LoadInterfaceFrmData(&tradeTallFrm, "trade_238.frm");
|
||||
}
|
||||
return LoadInterfaceFrmData(&barterTallFrm, "barter_239.frm");
|
||||
return (fo::var::dialog_target_is_party ? tradeTallFrm : barterTallFrm).LoadFrmData();
|
||||
}
|
||||
|
||||
static DWORD __fastcall gdialog_barter_get_art_height() {
|
||||
fo::FrmFile** frm = fo::var::dialog_target_is_party
|
||||
? &tradeTallFrm
|
||||
: &barterTallFrm;
|
||||
fo::FrmFile* frm = fo::var::dialog_target_is_party
|
||||
? tradeTallFrm.frm
|
||||
: barterTallFrm.frm;
|
||||
|
||||
if (*frm == nullptr) {
|
||||
return 0;
|
||||
}
|
||||
return (*frm)->frameData[0].height;
|
||||
return frm != nullptr
|
||||
? frm->frameData[0].height
|
||||
: 0;
|
||||
}
|
||||
|
||||
// replace art data for dialog barter window
|
||||
@@ -1257,7 +1265,16 @@ static void ExpandedBarterPatch() {
|
||||
if (IniReader::GetConfigInt("Interface", "ExpandedBarter", 0) == 0) return;
|
||||
|
||||
const int dialogWindowHeight = 480 + extraBarterHeight;
|
||||
if (Graphics::GetGameHeightRes() < dialogWindowHeight) return;
|
||||
if (Graphics::GetGameHeightRes() < dialogWindowHeight) {
|
||||
dlog_f("Skipping expanded barter screen patch. Screen height = %d < %d\n", DL_INIT, Graphics::GetGameHeightRes(), dialogWindowHeight);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!barterTallFrm.ArtExists() || !tradeTallFrm.ArtExists()) {
|
||||
dlog_f("Skipping expanded barter screen patch. Missing required FRM files: %s, %s.\n", DL_INIT,
|
||||
barterTallFrm.frmName, tradeTallFrm.frmName);
|
||||
return;
|
||||
}
|
||||
|
||||
dlogr("Applying expanded barter screen patch.", DL_INIT);
|
||||
SafeWrite32(0x46EDA4, 3 + numExtraBarterSlots); // Trade window slot count 3 -> 4
|
||||
@@ -1285,13 +1302,26 @@ static void ExpandedBarterPatch() {
|
||||
static void ExpandedInventoryPatch() {
|
||||
if (IniReader::GetConfigInt("Interface", "ExpandedInventory", 0) == 0) return;
|
||||
|
||||
dlogr("Applying expanded inventory patch.", DL_INIT);
|
||||
for (size_t i = 0; i < inventoryTallFrms.size(); i++) {
|
||||
if (!inventoryTallFrms[i].ArtExists()) {
|
||||
dlog_f("Skipping expanded inventory screen patch. Missing required FRM file: %s.\n", DL_INIT, inventoryTallFrms[i].frmName);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
dlogr("Applying expanded inventory screen patch.", DL_INIT);
|
||||
const int numExtraSlots = 2;
|
||||
const int slotHeight = 48;
|
||||
const int extraHeight = slotHeight * numExtraSlots - 8; // shorten by a few pixels to reduce empty space below the last item slot
|
||||
SafeWrite32(0x46EC9E, 6 + numExtraSlots); // All other inventory windows slot count 6 -> 8
|
||||
fo::var::iscr_data[fo::INVENTORY_WINDOW_TYPE_NORMAL].height = 377 + slotHeight * numExtraSlots; // 377 + 96 (two slots) = 473
|
||||
fo::var::iscr_data[fo::INVENTORY_WINDOW_TYPE_USE_ITEM_ON].height = 376 + slotHeight * numExtraSlots; // 377 + 96 (two slots) = 473
|
||||
fo::var::iscr_data[fo::INVENTORY_WINDOW_TYPE_LOOT].height = 376 + slotHeight * numExtraSlots; // 377 + 96 (two slots) = 473
|
||||
fo::var::iscr_data[fo::INVENTORY_WINDOW_TYPE_NORMAL].height = 377 + extraHeight;
|
||||
fo::var::iscr_data[fo::INVENTORY_WINDOW_TYPE_USE_ITEM_ON].height = 376 + extraHeight;
|
||||
fo::var::iscr_data[fo::INVENTORY_WINDOW_TYPE_LOOT].height = 376 + extraHeight;
|
||||
|
||||
// Shift Done buttons down:
|
||||
SafeWrite32(0x46F26C, 329 + extraHeight); // Normal
|
||||
SafeWrite32(0x46F29C, 328 + extraHeight); // Use Item On
|
||||
SafeWrite32(0x46F2CC, 331 + extraHeight); // Loot
|
||||
|
||||
// Transparent inventory windows create issues:
|
||||
// - Subtle flickering when dragging items
|
||||
@@ -1364,10 +1394,10 @@ void Interface::init() {
|
||||
}
|
||||
}
|
||||
LoadGameHook::OnGameInit() += []() {
|
||||
// Needs to be invoked in OnGameInit when screen height is already known.
|
||||
// Needs to be invoked in OnGameInit when screen height is already known and db is initialized.
|
||||
ExpandedBarterPatch();
|
||||
ExpandedInventoryPatch();
|
||||
};
|
||||
ExpandedInventoryPatch();
|
||||
}
|
||||
|
||||
void Interface::exit() {
|
||||
|
||||
@@ -401,6 +401,7 @@
|
||||
<ClInclude Include="Modules\CritterPoison.h" />
|
||||
<ClInclude Include="Modules\CritterStats.h" />
|
||||
<ClInclude Include="Modules\EngineTweaks.h" />
|
||||
<ClInclude Include="Modules\ExtraArt.h" />
|
||||
<ClInclude Include="Modules\Interface.h" />
|
||||
<ClInclude Include="Modules\Drugs.h" />
|
||||
<ClInclude Include="Modules\HookScripts\CombatHs.h" />
|
||||
@@ -542,6 +543,7 @@
|
||||
<ClCompile Include="Modules\CritterPoison.cpp" />
|
||||
<ClCompile Include="Modules\CritterStats.cpp" />
|
||||
<ClCompile Include="Modules\EngineTweaks.cpp" />
|
||||
<ClCompile Include="Modules\ExtraArt.cpp" />
|
||||
<ClCompile Include="Modules\Interface.cpp" />
|
||||
<ClCompile Include="Modules\Drugs.cpp" />
|
||||
<ClCompile Include="Modules\HookScripts\CombatHs.cpp" />
|
||||
|
||||
@@ -457,6 +457,7 @@
|
||||
<ClInclude Include="Modules\Scripting\Handlers\IniFiles.h">
|
||||
<Filter>Modules\Scripting\Handlers</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="Modules\ExtraArt.h" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="main.cpp" />
|
||||
@@ -834,6 +835,7 @@
|
||||
<ClCompile Include="Modules\Scripting\Handlers\IniFiles.cpp">
|
||||
<Filter>Modules\Scripting\Handlers</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="Modules\ExtraArt.cpp" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ResourceCompile Include="version.rc" />
|
||||
|
||||
Reference in New Issue
Block a user