Skip to content

Commit e8487ec

Browse files
committed
Added "win_fill_color" script function.
1 parent a4fda2b commit e8487ec

10 files changed

Lines changed: 102 additions & 38 deletions

File tree

artifacts/scripting/headers/sfall.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -294,6 +294,7 @@
294294
#define art_cache_clear sfall_func0("art_cache_clear")
295295
#define attack_is_aimed sfall_func0("attack_is_aimed")
296296
#define car_gas_amount sfall_func0("car_gas_amount")
297+
#define clear_window sfall_func0("win_fill_color")
297298
#define combat_data sfall_func0("combat_data")
298299
#define create_win(winName, x, y, w, h) sfall_func5("create_win", winName, x, y, w, h)
299300
#define create_win_flag(winName, x, y, w, h, flag) sfall_func6("create_win", winName, x, y, w, h, flag)
@@ -384,6 +385,7 @@
384385
#define unjam_lock(obj) sfall_func1("unjam_lock", obj)
385386
#define unset_unique_id(obj) sfall_func2("set_unique_id", obj, -1)
386387
#define unwield_slot(critter, slot) sfall_func2("unwield_slot", critter, slot)
388+
#define win_fill_color(x, y, width, height, color) sfall_func5("win_fill_color", x, y, width, height, color)
387389

388390
#define set_fake_perk_npc(npc, perk, level, image, desc) sfall_func5("set_fake_perk_npc", npc, perk, level, image, desc)
389391
#define set_fake_trait_npc(npc, trait, active, image, desc) sfall_func5("set_fake_trait_npc", npc, trait, active, image, desc)

artifacts/scripting/sfall function notes.txt

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -776,6 +776,11 @@ optional arguments:
776776
- this can be used in conjunction with the get_object_data and set_object_data functions
777777
example: sfall_func3("set_object_data", sfall_func0("combat_data"), C_ATTACK_UNUSED, 255);
778778

779+
> int sfall_func0("win_fill_color")
780+
> int sfall_func5("win_fill_color", int x, int y, int width, int height, int color)
781+
- fills the rectangle area of the script window with the specified color, or clears the transparent window (function without arguments)
782+
- color: the color index of the game palette (from 0 to 255)
783+
779784
------------------------
780785
------ MORE INFO -------
781786
------------------------

sfall/FalloutEngine/EngineUtils.cpp

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -398,11 +398,25 @@ void DrawToSurface(long width, long height, long fromX, long fromY, long fromWid
398398
}
399399
}
400400

401-
// Fills the specified non-scripted interface window with index color 0 (black color)
401+
// Fills the specified interface window with index color
402+
void WinFillRect(long winID, long x, long y, long width, long height, BYTE indexColor) {
403+
fo::Window* win = fo::func::GNW_find(winID);
404+
BYTE* surf = win->surface + (win->width * y) + x;
405+
long pitch = win->width - width;
406+
while (height--) {
407+
long w = width;
408+
while (w--) *surf++ = indexColor;
409+
surf += pitch;
410+
};
411+
}
412+
413+
// Fills the specified interface window with index color 0 (black color)
402414
void ClearWindow(long winID, bool refresh) {
403415
fo::Window* win = fo::func::GNW_find(winID);
416+
BYTE* surf = win->surface;
404417
for (long i = 0; i < win->height; i++) {
405-
std::memset(win->surface, 0, win->width);
418+
std::memset(surf, 0, win->width);
419+
surf += win->width;
406420
}
407421
if (refresh) {
408422
fo::func::GNW_win_refresh(win, &win->rect, 0);

sfall/FalloutEngine/EngineUtils.h

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -120,7 +120,10 @@ void DrawToSurface(long width, long height, long fromX, long fromY, long fromWid
120120

121121
void DrawToSurface(long width, long height, long fromX, long fromY, long fromWidth, BYTE* fromSurf, long toX, long toY, long toWidth, long toHeight, BYTE* toSurf);
122122

123-
// Fills the specified non-scripted interface window with index color 0 (black color)
123+
// Fills the specified interface window with index color
124+
void WinFillRect(long winID, long x, long y, long width, long height, BYTE indexColor);
125+
126+
// Fills the specified interface window with index color 0 (black color)
124127
void ClearWindow(long winID, bool refresh = true);
125128

126129
// Print text to surface

sfall/FalloutEngine/Functions_def.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -259,6 +259,7 @@ WRAP_WATCOM_FUNC3(long, register_object_take_out, GameObject*, object, long, hol
259259
WRAP_WATCOM_FUNC3(long, register_object_turn_towards, GameObject*, object, long, tileNum, long, nothing)
260260
WRAP_WATCOM_FUNC2(long, roll_random, long, minValue, long, maxValue)
261261
WRAP_WATCOM_FUNC1(long*, runProgram, Program*, progPtr)
262+
WRAP_WATCOM_FUNC1(long, selectWindowID, long, sWinID)
262263
WRAP_WATCOM_FUNC1(ScriptInstance*, scr_find_first_at, long, elevation)
263264
WRAP_WATCOM_FUNC0(ScriptInstance*, scr_find_next_at)
264265
WRAP_WATCOM_FUNC1(GameObject*, scr_find_obj_from_program, Program*, program)

sfall/FalloutEngine/Structs.h

Lines changed: 44 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -188,8 +188,7 @@ struct CombatGcsd {
188188
struct ScriptInstance {
189189
long id;
190190
long next;
191-
// first 3 bits - elevation, rest - tile number
192-
long elevationAndTile;
191+
long elevationAndTile; // first 3 bits - elevation, rest - tile number
193192
long spatialRadius;
194193
long flags;
195194
long scriptIdx;
@@ -205,31 +204,50 @@ struct ScriptInstance {
205204
GameObject *targetObject;
206205
long actionNum;
207206
long scriptOverrides;
208-
char gap_48[4];
207+
long field_48;
209208
long howMuch;
210-
char gap_50[4];
209+
long field_50;
211210
long procedureTable[28];
212211
};
213212

214213
// Script run-time data
215214
struct Program {
216-
const char* fileName;
215+
const char* fileName; // path and file name of the script "scripts\*.int"
217216
long *codeStackPtr;
218-
long gap_8;
219-
long gap_9;
217+
long field_8;
218+
long field_C;
220219
long *codePtr;
221220
long field_14;
222-
long gap_18;
221+
long field_18;
223222
long *dStackPtr;
224223
long *aStackPtr;
225224
long *dStackOffs;
226225
long *aStackOffs;
227-
long gap_2C;
226+
long field_2C;
228227
long *stringRefPtr;
229-
long gap_34;
230-
long *procTablePtr;
228+
long field_34; // procTablePtr
229+
long *procTablePtr; // field_38
230+
long regs[12];
231+
long field_6C;
232+
long field_70;
233+
long field_74;
234+
long field_78;
235+
long field_7C;
236+
union {
237+
long flags;
238+
struct {
239+
char flags1;
240+
char flags2;
241+
char flags3;
242+
char flags4;
243+
};
244+
};
245+
long currentScriptWin; // current window for executing script
246+
long field_88;
231247
};
232248

249+
static_assert(sizeof(Program) == 140, "Incorrect Program definition.");
250+
233251
struct ItemButtonItem {
234252
GameObject* item;
235253
union {
@@ -354,7 +372,7 @@ struct FrmFile { // sizeof 2954
354372
}
355373
};
356374

357-
static_assert(sizeof(FrmFile) == 2954, "struct FrmFile size is not correct");
375+
static_assert(sizeof(FrmFile) == 2954, "Incorrect FrmFile definition.");
358376

359377
// structures for loading unlisted frms
360378
struct UnlistedFrm {
@@ -584,8 +602,7 @@ struct Proto {
584602

585603
long flags;
586604
long flagsExt;
587-
// 0x0Y00XXXX: Y - script type (0=s_system, 1=s_spatial, 2=s_time, 3=s_item, 4=s_critter); XXXX - number in scripts.lst. -1 means no script.
588-
long scriptId;
605+
long scriptId; // 0x0Y00XXXX: Y - script type (0=s_system, 1=s_spatial, 2=s_time, 3=s_item, 4=s_critter); XXXX - number in scripts.lst. -1 means no script.
589606
ItemType type;
590607

591608
union {
@@ -730,33 +747,33 @@ struct Window {
730747
long width;
731748
long height;
732749
long clearColour;
733-
long rand1;
734-
long rand2;
750+
long randX;
751+
long randY;
735752
BYTE *surface; // bytes frame data ref to palette
736753
long *buttonsList;
737-
long unknown5; // buttonptr?
738-
long unknown6;
754+
long buttonT1; // buttonptr?
755+
long buttonT2;
739756
long *menuBar;
740-
long *drawFunc;
757+
long *drawFunc; // trans_buf_to_buf_
741758
};
742759

743760
struct sWindow {
744761
char name[32];
745762
long wID;
746763
long width;
747764
long height;
748-
long unknown1;
749-
long unknown2;
750-
long unknown3;
751-
long unknown4;
765+
long region1;
766+
long region2;
767+
long region3;
768+
long region4;
752769
long *buttons;
753770
long numButtons;
754-
long unknown5;
755-
long unknown6;
771+
long setPositionX;
772+
long setPositionY;
756773
long clearColour;
757774
long flags;
758-
long unknown7;
759-
long unknown8;
775+
float randX;
776+
float randY;
760777
};
761778

762779
struct LSData {

sfall/Modules/Scripting/Handlers/Interface.cpp

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -475,7 +475,7 @@ static fo::FrmFile* LoadArtFile(const char* file, long frame, long direction, fo
475475
fo::FrmFile* frmPtr = nullptr;
476476
if (checkPCX) {
477477
const char* pos = strrchr(file, '.');
478-
if (pos && _stricmp(pos, ".PCX") == 0) {
478+
if (pos && _stricmp(++pos, "PCX") == 0) {
479479
long w, h;
480480
BYTE* data = fo::func::loadPCX(file, &w, &h);
481481
if (!data) return nullptr;
@@ -512,6 +512,7 @@ static long GetArtFIDFile(long fid, const char* &file) {
512512
}
513513

514514
static long DrawImage(OpcodeContext& ctx, bool isScaled) {
515+
fo::func::selectWindowID(ctx.program()->currentScriptWin);
515516
if (*(DWORD*)FO_VAR_currentWindow == -1) {
516517
ctx.printOpcodeError("%s() - no created/selected window for the image.", ctx.getMetaruleName());
517518
return 0;
@@ -783,5 +784,20 @@ void mf_interface_print(OpcodeContext& ctx) { // same as vanilla PrintRect
783784
if (!(color & 0x1000000)) fo::func::GNW_win_refresh(win, &win->rect, 0);
784785
}
785786

787+
void mf_win_fill_color(OpcodeContext& ctx) {
788+
fo::func::selectWindowID(ctx.program()->currentScriptWin);
789+
long iWin = *(DWORD*)FO_VAR_currentWindow;
790+
if (iWin == -1) {
791+
ctx.printOpcodeError("%s() - no created or selected window.", ctx.getMetaruleName());
792+
ctx.setReturn(-1);
793+
return;
794+
}
795+
if (ctx.numArgs() > 0) {
796+
fo::WinFillRect(fo::var::sWindows[iWin].wID, ctx.arg(0).rawValue(), ctx.arg(1).rawValue(), ctx.arg(2).rawValue(), ctx.arg(3).rawValue(), ctx.arg(4).rawValue());
797+
} else {
798+
fo::ClearWindow(fo::var::sWindows[iWin].wID, false); // full clear
799+
}
800+
}
801+
786802
}
787803
}

sfall/Modules/Scripting/Handlers/Interface.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -119,5 +119,7 @@ void mf_get_window_attribute(OpcodeContext&);
119119

120120
void mf_interface_print(OpcodeContext&);
121121

122+
void mf_win_fill_color(OpcodeContext&);
123+
122124
}
123125
}

sfall/Modules/Scripting/Handlers/Metarule.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -150,6 +150,7 @@ static const SfallMetarule metarules[] = {
150150
{"tile_refresh_display", mf_tile_refresh_display, 0, 0},
151151
{"unjam_lock", mf_unjam_lock, 1, 1, -1, {ARG_OBJECT}},
152152
{"unwield_slot", mf_unwield_slot, 2, 2, -1, {ARG_OBJECT, ARG_INT}},
153+
{"win_fill_color", mf_win_fill_color, 0, 5, -1, {ARG_INT, ARG_INT, ARG_INT, ARG_INT, ARG_INT}},
153154
#ifndef NDEBUG
154155
{"validate_test", mf_test, 2, 5, -1, {ARG_INT, ARG_NUMBER, ARG_STRING, ARG_OBJECT, ARG_ANY}},
155156
#endif

sfall/Modules/TalkingHeads.cpp

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -172,24 +172,27 @@ static bool LoadFrm(Frm* frm) {
172172
return true;
173173
}
174174

175-
static long dialogWinX = 0, dialogWinY = 0;
175+
static struct DialogWinPos {
176+
long x = -1;
177+
long y;
178+
} dialogWinPos;
176179

177180
static void __fastcall DrawHeadFrame(Frm* frm, int frameno) {
178181
if (frm && !frm->broken) {
179182
if (!frm->loaded && !LoadFrm(frm)) goto loadFail;
180183
fo::FrmFrameData* frame = fo::func::frame_ptr((fo::FrmHeaderData*)frm, frameno, 0);
181184

182-
if (dialogWinX == -1) {
185+
if (dialogWinPos.x == -1) {
183186
fo::Window* dialogWin = fo::func::GNW_find(fo::var::dialogueBackWindow);
184187
if (texHighlight) Graphics::SetHighlightTexture(texHighlight, dialogWin->rect.x, dialogWin->rect.y);
185-
dialogWinX = dialogWin->rect.x;
186-
dialogWinY = dialogWin->rect.y;
188+
dialogWinPos.x = dialogWin->rect.x;
189+
dialogWinPos.y = dialogWin->rect.y;
187190
}
188191
Graphics::SetHeadTex(frm->textures[frameno],
189192
frame->width,
190193
frame->height,
191-
frame->x + frm->xshift + dialogWinX,
192-
frame->y + frm->yshift + dialogWinY,
194+
frame->x + frm->xshift + dialogWinPos.x,
195+
frame->y + frm->yshift + dialogWinPos.y,
193196
(frm->showHighlights == 2)
194197
);
195198
showHighlights = frm->showHighlights;
@@ -219,7 +222,7 @@ void __declspec(naked) gdDestroyHeadWindow_hack() {
219222
__asm {
220223
call Graphics::SetDefaultTechnique;
221224
mov showHighlights, 0;
222-
//mov dialogWinX, -1; // uncomment if the dialog window position is supposed to change
225+
//mov dword ptr ds:[dialogWinPos], -1; // uncomment if the dialog window position is supposed to change
223226
pop ebp;
224227
pop edi;
225228
pop edx;

0 commit comments

Comments
 (0)