Skip to content

Commit

Permalink
Merge pull request #531 from sfall-team/feature/inventory-slot-extens…
Browse files Browse the repository at this point in the history
…ions

Added inventory/barter slot extensions
  • Loading branch information
NovaRain authored May 10, 2024
2 parents e435e1d + fa8a42e commit b25a622
Show file tree
Hide file tree
Showing 32 changed files with 615 additions and 313 deletions.
9 changes: 9 additions & 0 deletions artifacts/ddraw.ini
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,15 @@ WorldMapTravelMarkers=0
;Set to 1 to display terrain types when hovering the cursor over the player's marker on the world map
WorldMapTerrainInfo=0

;Set to 1 to enable tall trade/barter window with 4 item slots per table instead of 3
;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 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
[Sound]
;Sets the number of allowed simultaneous sound effects
Expand Down
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
102 changes: 1 addition & 101 deletions sfall/FalloutEngine/EngineUtils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -409,7 +409,7 @@ fo::GameObject* __fastcall MultiHexMoveIsBlocking(fo::GameObject* source, long d

// Returns the terrain type of the sub-tile at the specified coordinates on the world map
long wmGetTerrainType(long xPos, long yPos) {
long* terrainId;
long* terrainId{};
__asm {
lea ebx, terrainId;
mov edx, yPos;
Expand Down Expand Up @@ -667,105 +667,5 @@ void RefreshGNW(bool skipOwner) {
fo::var::setInt(FO_VAR_doing_refresh_all) = 0;
}

//////////////////////////// UNLISTED FRM FUNCTIONS ////////////////////////////

static bool LoadFrmHeader(fo::UnlistedFrm *frmHeader, fo::DbFile* frmStream) {
if (fo::func::db_freadInt(frmStream, &frmHeader->version) == -1)
return false;
else if (fo::func::db_freadShort(frmStream, &frmHeader->FPS) == -1)
return false;
else if (fo::func::db_freadShort(frmStream, &frmHeader->actionFrame) == -1)
return false;
else if (fo::func::db_freadShort(frmStream, &frmHeader->numFrames) == -1)
return false;
else if (fo::func::db_freadShortCount(frmStream, frmHeader->xCentreShift, 6) == -1)
return false;
else if (fo::func::db_freadShortCount(frmStream, frmHeader->yCentreShift, 6) == -1)
return false;
else if (fo::func::db_freadIntCount(frmStream, frmHeader->oriOffset, 6) == -1)
return false;
else if (fo::func::db_freadInt(frmStream, &frmHeader->frameAreaSize) == -1)
return false;

return true;
}

static bool LoadFrmFrame(fo::UnlistedFrm::Frame *frame, fo::DbFile* frmStream) {
//FRMframe *frameHeader = (FRMframe*)frameMEM;
//BYTE* frameBuff = frame + sizeof(FRMframe);

if (fo::func::db_freadShort(frmStream, &frame->width) == -1)
return false;
else if (fo::func::db_freadShort(frmStream, &frame->height) == -1)
return false;
else if (fo::func::db_freadInt(frmStream, &frame->size) == -1)
return false;
else if (fo::func::db_freadShort(frmStream, &frame->x) == -1)
return false;
else if (fo::func::db_freadShort(frmStream, &frame->y) == -1)
return false;

frame->indexBuff = new BYTE[frame->size];
if (fo::func::db_fread(frame->indexBuff, 1, frame->size, frmStream) != frame->size)
return false;

return true;
}

fo::UnlistedFrm *LoadUnlistedFrm(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);
}

fo::UnlistedFrm *frm = new fo::UnlistedFrm;

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)) {
fo::func::db_fclose(frmStream);
delete frm;
return nullptr;
}

DWORD oriOffset_1st = frm->oriOffset[0];
DWORD oriOffset_new = 0;
frm->frames = new fo::UnlistedFrm::Frame[6 * frm->numFrames];
for (int ori = 0; ori < 6; ori++) {
if (ori == 0 || frm->oriOffset[ori] != oriOffset_1st) {
frm->oriOffset[ori] = oriOffset_new;
for (int fNum = 0; fNum < frm->numFrames; fNum++) {
if (!LoadFrmFrame(&frm->frames[oriOffset_new + fNum], frmStream)) {
fo::func::db_fclose(frmStream);
delete frm;
return nullptr;
}
}
oriOffset_new += frm->numFrames;
} else {
frm->oriOffset[ori] = 0;
}
}

fo::func::db_fclose(frmStream);
} else {
delete frm;
return nullptr;
}
return frm;
}

}
}
16 changes: 14 additions & 2 deletions sfall/FalloutEngine/EngineUtils.h
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,20 @@ namespace fo
namespace util
{

// To safely unlock cache entries after using art_ptr_lock and similar functions
struct ArtCacheLock {
DWORD entryPtr = 0;

ArtCacheLock() { }
ArtCacheLock(DWORD _lock) : entryPtr(_lock) { }
~ArtCacheLock() {
if (entryPtr != 0) {
fo::func::art_ptr_unlock(entryPtr);
entryPtr = 0;
}
}
};

__inline void DisplayPrint(const std::string& str) {
fo::func::display_print(str.c_str());
}
Expand Down Expand Up @@ -191,7 +205,5 @@ void RedrawObject(fo::GameObject* obj);
// Redraws all windows
void RefreshGNW(bool skipOwner = false);

fo::UnlistedFrm *LoadUnlistedFrm(char *frmName, unsigned int folderRef);

}
}
27 changes: 27 additions & 0 deletions sfall/FalloutEngine/Enums.h
Original file line number Diff line number Diff line change
Expand Up @@ -927,4 +927,31 @@ enum DialogOutFlags : long
DIALOGOUT_CLEAN = 0x20 // no buttons
};

enum InventoryWindowType : unsigned long
{
// Normal inventory window with quick character sheet.
INVENTORY_WINDOW_TYPE_NORMAL,

// Narrow inventory window with just an item scroller that's shown when
// a "Use item on" is selected from context menu.
INVENTORY_WINDOW_TYPE_USE_ITEM_ON,

// Looting/strealing interface.
INVENTORY_WINDOW_TYPE_LOOT,

// Barter interface.
INVENTORY_WINDOW_TYPE_TRADE,

// Supplementary "Move items" window. Used to set quantity of items when
// moving items between inventories.
INVENTORY_WINDOW_TYPE_MOVE_ITEMS,

// Supplementary "Set timer" window. Internally it's implemented as "Move
// items" window but with timer overlay and slightly different adjustment
// mechanics.
INVENTORY_WINDOW_TYPE_SET_TIMER,

INVENTORY_WINDOW_TYPE_COUNT,
};

}
82 changes: 15 additions & 67 deletions sfall/FalloutEngine/Structs.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,8 @@ namespace sfall
struct Rectangle {
long x, y, width, height;

long right() { return x + (width - 1); }
long bottom() { return y + (height - 1); }
long right() const { return x + (width - 1); }
long bottom() const { return y + (height - 1); }
};

}
Expand Down Expand Up @@ -208,25 +208,25 @@ struct GameObject {
long rads;
long poison;

inline bool IsDead() {
inline bool IsDead() const {
return ((damageFlags & DamageFlag::DAM_DEAD) != 0);
}
inline bool IsNotDead() {
inline bool IsNotDead() const {
return ((damageFlags & DamageFlag::DAM_DEAD) == 0);
}
inline bool IsActive() {
inline bool IsActive() const {
return ((damageFlags & (DamageFlag::DAM_KNOCKED_OUT | DamageFlag::DAM_LOSE_TURN)) == 0);
}
inline bool IsNotActive() {
inline bool IsNotActive() const {
return ((damageFlags & (DamageFlag::DAM_KNOCKED_OUT | DamageFlag::DAM_LOSE_TURN)) != 0);
}
inline bool IsActiveNotDead() {
inline bool IsActiveNotDead() const {
return ((damageFlags & (DamageFlag::DAM_DEAD | DamageFlag::DAM_KNOCKED_OUT | DamageFlag::DAM_LOSE_TURN)) == 0);
}
inline bool IsNotActiveOrDead() {
inline bool IsNotActiveOrDead() const {
return ((damageFlags & (DamageFlag::DAM_DEAD | DamageFlag::DAM_KNOCKED_OUT | DamageFlag::DAM_LOSE_TURN)) != 0);
}
inline bool IsFleeing() {
inline bool IsFleeing() const {
return ((combatState & CombatStateFlag::InFlee) != 0);
}

Expand Down Expand Up @@ -255,23 +255,23 @@ struct GameObject {
GameObject* owner; // not saved
long scriptIndex;

inline char Type() {
inline char Type() const {
return (protoId >> 24);
}
inline char TypeFid() {
inline char TypeFid() const {
return ((artFid >> 24) & 0x0F);
}

inline bool IsCritter() {
inline bool IsCritter() const {
return (Type() == fo::ObjType::OBJ_TYPE_CRITTER);
}
inline bool IsNotCritter() {
inline bool IsNotCritter() const {
return (Type() != fo::ObjType::OBJ_TYPE_CRITTER);
}
inline bool IsItem() {
inline bool IsItem() const {
return (Type() == fo::ObjType::OBJ_TYPE_ITEM);
}
inline bool IsNotItem() {
inline bool IsNotItem() const {
return (Type() != fo::ObjType::OBJ_TYPE_ITEM);
}
};
Expand Down Expand Up @@ -498,58 +498,6 @@ struct TileFrmFile : public FrmHeaderData {

static_assert(sizeof(TileFrmFile) == 2954, "Incorrect TileFrmFile definition.");

// structures for loading unlisted frms
struct UnlistedFrm {
DWORD version;
WORD FPS;
WORD actionFrame;
WORD numFrames;
WORD xCentreShift[6];
WORD yCentreShift[6];
DWORD oriOffset[6];
DWORD frameAreaSize;

struct Frame {
WORD width;
WORD height;
DWORD size;
WORD x;
WORD y;
BYTE *indexBuff;

Frame() {
width = 0;
height = 0;
size = 0;
x = 0;
y = 0;
indexBuff = nullptr;
}
~Frame() {
if (indexBuff != nullptr)
delete[] indexBuff;
}
} *frames;

UnlistedFrm() {
version = 0;
FPS = 0;
actionFrame = 0;
numFrames = 0;
for (int i = 0; i < 6; i++) {
xCentreShift[i] = 0;
yCentreShift[i] = 0;
oriOffset[i] = 0;
}
frameAreaSize = 0;
frames = nullptr;
}

~UnlistedFrm() {
if (frames != nullptr) delete[] frames;
}
};

//for holding a message
struct MessageNode {
long number;
Expand Down
1 change: 1 addition & 0 deletions sfall/FalloutEngine/VariableOffsets.h
Original file line number Diff line number Diff line change
Expand Up @@ -169,6 +169,7 @@
#define FO_VAR_intface_full_width 0x56FB4C
#define FO_VAR_intfaceEnabled 0x518F10
#define FO_VAR_intotal 0x43E95C
#define FO_VAR_inven_cur_disp 0x519054
#define FO_VAR_inven_dude 0x519058
#define FO_VAR_inven_pid 0x51905C
#define FO_VAR_inven_scroll_dn_bid 0x5190E8
Expand Down
1 change: 1 addition & 0 deletions sfall/FalloutEngine/Variables_def.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ VAR_(BlueColor, BYTE)
VAR_(bottom_line, DWORD)
VAR_(btable, DWORD)
VAR_(btncnt, DWORD)
VAR_(buf_length_2, long)
VARD(cap, fo::AIcap) // dynamic array
VAR_(carCurrentArea, DWORD)
VAR_(carGasAmount, long) // from 0 to 80000
Expand Down
15 changes: 6 additions & 9 deletions sfall/HRP/Dialog.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@

#include "..\main.h"
#include "..\FalloutEngine\Fallout2.h"
#include "..\Modules\ExtraArt.h"
#include "..\Modules\LoadGameHook.h"

#include "Init.h"
Expand All @@ -22,7 +23,7 @@ namespace sf = sfall;
static const long width = 640; // art
static long scr_width = 639;

static fo::UnlistedFrm* altDialogArt;
static fo::FrmFile* altDialogArt;

bool Dialog::DIALOG_SCRN_ART_FIX = true;
bool Dialog::DIALOG_SCRN_BACKGROUND = false;
Expand Down Expand Up @@ -172,20 +173,16 @@ static bool loadAltDialogArt = false;
static void __cdecl talk_to_refresh_background_window_hook_buf_to_buf(BYTE* src, long w, long h, long srcWidth, BYTE* dst, long dstWidth) {
if (!loadAltDialogArt) {
loadAltDialogArt = true;
altDialogArt = fo::util::LoadUnlistedFrm("HR_ALLTLK.frm", fo::ArtType::OBJ_TYPE_INTRFACE);
altDialogArt = sf::LoadUnlistedFrmCached("HR_ALLTLK.frm", fo::ArtType::OBJ_TYPE_INTRFACE);
}
if (altDialogArt) {
src = altDialogArt->frames->indexBuff;
srcWidth = altDialogArt->frames->width;
src = altDialogArt->frameData[0].data;
srcWidth = altDialogArt->frameData[0].width;
}
fo::func::buf_to_buf(src, w, h, srcWidth, dst, dstWidth);
}

static void UnloadDialogArt() {
if (altDialogArt) {
delete altDialogArt;
altDialogArt = nullptr;
}
loadAltDialogArt = false;
}

Expand Down Expand Up @@ -273,7 +270,7 @@ void Dialog::init() {
fo::var::backgrndRects[i].offy += 5;
}

sf::LoadGameHook::OnGameExit() += UnloadDialogArt;
sf::LoadGameHook::OnGameReset() += UnloadDialogArt;
}
}

Expand Down
Loading

0 comments on commit b25a622

Please sign in to comment.