Added "win_fill_color" script function

This commit is contained in:
NovaRain
2020-10-24 13:54:43 +08:00
parent 0a44f7118a
commit a8919367ea
10 changed files with 132 additions and 55 deletions
+2
View File
@@ -265,6 +265,7 @@
#define art_cache_clear sfall_func0("art_cache_clear")
#define attack_is_aimed sfall_func0("attack_is_aimed")
#define car_gas_amount sfall_func0("car_gas_amount")
#define clear_window sfall_func0("win_fill_color")
#define combat_data sfall_func0("combat_data")
#define create_win(winName, x, y, w, h) sfall_func5("create_win", winName, x, y, w, h)
#define create_win_flag(winName, x, y, w, h, flag) sfall_func6("create_win", winName, x, y, w, h, flag)
@@ -341,5 +342,6 @@
#define unjam_lock(obj) sfall_func1("unjam_lock", obj)
#define unset_unique_id(obj) sfall_func2("set_unique_id", obj, -1)
#define unwield_slot(critter, slot) sfall_func2("unwield_slot", critter, slot)
#define win_fill_color(x, y, width, height, color) sfall_func5("win_fill_color", x, y, width, height, color)
#endif
+7 -2
View File
@@ -647,7 +647,7 @@ optional arguments:
- message: the text in the dialog box. Use the '\n' control character to move text to a new line (example: "Hello\nWorld!")
optional arguments:
- flags: mode flags (see MSGBOX_* constants in define_extra.h). Pass -1 to skip setting the flags (default flags are NORMAL and YESNO)
- color1/color2: the color index in Fallout palette. color1 sets the text color for the first line, and color2 for all subsequent lines of text (default color is 145)
- color1/color2: the color index in the game palette. color1 sets the text color for the first line, and color2 for all subsequent lines of text (default color is 145)
> int sfall_func1("get_stat_min", int stat)
> int sfall_func1("get_stat_max", int stat)
@@ -677,7 +677,7 @@ optional arguments:
- text: the text to be printed. Use the '\n' control character to move text to a new line (example: "Hello\nWorld!")
- winType: the type number of the interface window (see WINTYPE_* constants in sfall.h)
- x/y: offset relative to the top-left corner of the window
- color: the color index in Fallout palette. Pass 0 if the text color was previously set by vanilla SetTextColor function
- color: the color index in the game palette. Pass 0 if the text color was previously set by vanilla SetTextColor function
it can also take additional flags (via bwor) for displaying text:
0x0010000 - adds a shadow to the text, the 'textshadow' compiler constant
0x1000000 - prevents immediate redrawing of the interface window, the 'textdirect' compiler constant (works the other way around)
@@ -689,6 +689,11 @@ optional arguments:
- can be used in conjunction with the get_object_data and set_object_data functions
example: sfall_func3("set_object_data", sfall_func0("combat_data"), C_ATTACK_UNUSED, 255);
> int sfall_func0("win_fill_color")
> int sfall_func5("win_fill_color", int x, int y, int width, int height, int color)
- fills the rectangle area of the currently selected script window with the specified color, or clears the entire window with transparent color (called without arguments)
- color: the color index in the game palette (from 0 to 255)
------------------------
------ MORE INFO -------
------------------------
+18 -3
View File
@@ -210,7 +210,7 @@ DWORD* ptr_stack_offset = reinterpret_cast<DWORD*>(_stack_offset
DWORD* ptr_stat_data = reinterpret_cast<DWORD*>(_stat_data);
DWORD* ptr_stat_flag = reinterpret_cast<DWORD*>(_stat_flag);
SubTitleList** ptr_subtitleList = reinterpret_cast<SubTitleList**>(_subtitleList);
DWORD* ptr_sWindows = reinterpret_cast<DWORD*>(_sWindows); // total 16 sWindow struct
sWindow* ptr_sWindows = reinterpret_cast<sWindow*>(_sWindows); // array of 16 sWindow
DWORD* ptr_Tag_ = reinterpret_cast<DWORD*>(_Tag_);
DWORD* ptr_tag_skill = reinterpret_cast<DWORD*>(_tag_skill);
DWORD* ptr_target_curr_stack = reinterpret_cast<DWORD*>(_target_curr_stack);
@@ -721,6 +721,7 @@ const DWORD scr_set_ext_param_ = 0x4A3B34;
const DWORD scr_set_local_var_ = 0x4A6E58;
const DWORD scr_set_objs_ = 0x4A3B0C;
const DWORD scr_write_ScriptNode_ = 0x4A5704;
const DWORD selectWindowID_ = 0x4B81C4;
const DWORD set_focus_func_ = 0x4C9438;
const DWORD set_game_time_ = 0x4A347C;
const DWORD setup_move_timer_win_ = 0x476AB8;
@@ -1572,11 +1573,25 @@ void DrawToSurface(long width, long height, long fromX, long fromY, long fromWid
}
}
// Fills the specified non-scripted interface window with index color 0 (black color)
// Fills the specified interface window with index color
void WinFillRect(long winID, long x, long y, long width, long height, BYTE indexColor) {
WINinfo* win = GNWFind(winID);
BYTE* surf = win->surface + (win->width * y) + x;
long pitch = win->width - width;
while (height--) {
long w = width;
while (w--) *surf++ = indexColor;
surf += pitch;
};
}
// Fills the specified interface window with index color 0 (black color)
void ClearWindow(long winID, bool refresh) {
WINinfo* win = GNWFind(winID);
BYTE* surf = win->surface;
for (long i = 0; i < win->height; i++) {
std::memset(win->surface, 0, win->width);
std::memset(surf, 0, win->width);
surf += win->width;
}
if (refresh) {
GNWWinRefresh(win, &win->rect, 0);
+6 -2
View File
@@ -515,7 +515,7 @@ extern DWORD* ptr_stack_offset;
extern DWORD* ptr_stat_data;
extern DWORD* ptr_stat_flag;
extern SubTitleList** ptr_subtitleList;
extern DWORD* ptr_sWindows; // total 16 sWindow struct
extern sWindow* ptr_sWindows; // array of 16 sWindow
extern DWORD* ptr_Tag_;
extern DWORD* ptr_tag_skill;
extern DWORD* ptr_target_curr_stack;
@@ -1018,6 +1018,7 @@ extern const DWORD scr_set_ext_param_;
extern const DWORD scr_set_local_var_;
extern const DWORD scr_set_objs_;
extern const DWORD scr_write_ScriptNode_;
extern const DWORD selectWindowID_;
extern const DWORD set_focus_func_;
extern const DWORD set_game_time_;
extern const DWORD setup_move_timer_win_;
@@ -1341,7 +1342,10 @@ void DrawToSurface(long width, long height, long fromX, long fromY, long fromWid
void DrawToSurface(long width, long height, long fromX, long fromY, long fromWidth, BYTE* fromSurf, long toX, long toY, long toWidth, long toHeight, BYTE* toSurf);
// Fills the specified non-scripted interface window with index color 0 (black color)
// Fills the specified interface window with index color
void WinFillRect(long winID, long x, long y, long width, long height, BYTE indexColor);
// Fills the specified interface window with index color 0 (black color)
void ClearWindow(long winID, bool refresh = true);
// Print text to surface
+1
View File
@@ -187,6 +187,7 @@ WRAP_WATCOM_FUNC3(long, RegisterObjectTakeOut, register_object_take_out_, TGameO
WRAP_WATCOM_FUNC3(long, RegisterObjectTurnTowards, register_object_turn_towards_, TGameObj*, object, long, tileNum, long, nothing)
WRAP_WATCOM_FUNC2(long, RollRandom, roll_random_, long, minValue, long, maxValue)
WRAP_WATCOM_FUNC1(long*, RunProgram, runProgram_, TProgram*, progPtr)
WRAP_WATCOM_FUNC1(long, SelectWindowID, selectWindowID_, long, sWinID)
WRAP_WATCOM_FUNC1(TScript*, ScrFindFirstAt, scr_find_first_at_, long, elevation)
WRAP_WATCOM_FUNC0(TScript*, ScrFindNextAt, scr_find_next_at_)
WRAP_WATCOM_FUNC1(TGameObj*, ScrFindObjFromProgram, scr_find_obj_from_program_, TProgram*, program)
+42 -24
View File
@@ -158,8 +158,7 @@ struct CombatGcsd {
struct TScript {
long id;
long next;
// first 3 bits - elevation, rest - tile number
long elevationAndTile;
long elevationAndTile; // first 3 bits - elevation, rest - tile number
long spatialRadius;
long flags;
long scriptIdx;
@@ -175,31 +174,50 @@ struct TScript {
TGameObj *targetObject;
long actionNum;
long scriptOverrides;
char gap_48[4];
long field_48;
long howMuch;
char gap_50[4];
long field_50;
long procedureTable[28];
};
// Script run-time data
struct TProgram {
const char* fileName;
const char* fileName; // path and file name of the script "scripts\*.int"
long *codeStackPtr;
long gap_8;
long gap_9;
long field_8;
long field_C;
long *codePtr;
long field_14;
long gap_18;
long field_18;
long *dStackPtr;
long *aStackPtr;
long *dStackOffs;
long *aStackOffs;
long gap_2C;
long field_2C;
long *stringRefPtr;
long gap_34;
long *procTablePtr;
long field_34; // procTablePtr
long *procTablePtr; // field_38
long regs[12];
long field_6C;
long field_70;
long field_74;
long field_78;
long field_7C;
union {
long flags;
struct {
char flags1;
char flags2;
char flags3;
char flags4;
};
};
long currentScriptWin; // current window for executing script
long field_88;
};
static_assert(sizeof(TProgram) == 140, "Incorrect TProgram definition.");
struct ItemButtonItem {
TGameObj* item;
union {
@@ -478,14 +496,14 @@ struct WINinfo {
long width;
long height;
long clearColour;
long rand1;
long rand2;
long randX;
long randY;
BYTE *surface; // bytes frame data ref to palette
long *buttonsList;
long unknown5; // buttonptr?
long unknown6;
long buttonT1; // buttonptr?
long buttonT2;
long *menuBar;
long *drawFunc;
long *drawFunc; // trans_buf_to_buf_
};
struct sWindow {
@@ -493,18 +511,18 @@ struct sWindow {
long wID;
long width;
long height;
long unknown1;
long unknown2;
long unknown3;
long unknown4;
long region1;
long region2;
long region3;
long region4;
long *buttons;
long numButtons;
long unknown5;
long unknown6;
long setPositionX;
long setPositionY;
long clearColour;
long flags;
long unknown7;
long unknown8;
float randX;
float randY;
};
struct LSData {
+1
View File
@@ -880,6 +880,7 @@ static const SfallOpcodeMetadata opcodeMetaArray[] = {
{mf_tile_by_position, "tile_by_position", {DATATYPE_MASK_INT, DATATYPE_MASK_INT}},
{mf_unjam_lock, "unjam_lock", {DATATYPE_MASK_VALID_OBJ}},
{mf_unwield_slot, "unwield_slot", {DATATYPE_MASK_VALID_OBJ, DATATYPE_MASK_INT}},
{mf_win_fill_color, "win_fill_color", {DATATYPE_MASK_INT, DATATYPE_MASK_INT, DATATYPE_MASK_INT, DATATYPE_MASK_INT, DATATYPE_MASK_INT}},
#ifndef NDEBUG
{mf_test, "validate_test", {DATATYPE_MASK_INT, DATATYPE_MASK_INT | DATATYPE_MASK_FLOAT, DATATYPE_MASK_STR, DATATYPE_NONE}},
#endif
+42 -17
View File
@@ -457,11 +457,9 @@ static void mf_create_win() {
static void mf_show_window() {
if (opHandler.numArgs() > 0) {
const char* name = opHandler.arg(0).strValue();
sWindow sWin;
for (size_t i = 0; i < 16; i++) {
sWin = *(sWindow*)&ptr_sWindows[i * 23]; // sWindow struct = 92 bytes
if (_stricmp(name, sWin.name) == 0) {
WinShow(sWin.wID);
if (_stricmp(name, ptr_sWindows[i].name) == 0) {
WinShow(ptr_sWindows[i].wID);
return;
}
}
@@ -474,11 +472,9 @@ static void mf_show_window() {
static void mf_hide_window() {
if (opHandler.numArgs() > 0) {
const char* name = opHandler.arg(0).strValue();
sWindow sWin;
for (size_t i = 0; i < 16; i++) {
sWin = *(sWindow*)&ptr_sWindows[i * 23]; // sWindow struct = 92 bytes
if (_stricmp(name, sWin.name) == 0) {
WinHide(sWin.wID);
if (_stricmp(name, ptr_sWindows[i].name) == 0) {
WinHide(ptr_sWindows[i].wID);
return;
}
}
@@ -503,16 +499,14 @@ static void mf_set_window_flag() {
bool mode = opHandler.arg(2).asBool();
if (opHandler.arg(0).isString()) {
const char* name = opHandler.arg(0).strValue();
sWindow sWin;
for (size_t i = 0; i < 16; i++) {
sWin = *(sWindow*)&ptr_sWindows[i * 23]; // sWindow struct = 92 bytes
if (_stricmp(name, sWin.name) == 0) {
WINinfo* win = GNWFind(sWin.wID);
if (_stricmp(name, ptr_sWindows[i].name) == 0) {
WINinfo* win = GNWFind(ptr_sWindows[i].wID);
if (mode) {
sWin.flags |= bitFlag;
ptr_sWindows[i].flags |= bitFlag;
win->flags |= bitFlag;
} else {
sWin.flags &= ~bitFlag;
ptr_sWindows[i].flags &= ~bitFlag;
win->flags &= ~bitFlag;
}
return;
@@ -547,7 +541,7 @@ static FrmFile* LoadArtFile(const char* file, long frame, long direction, FrmFra
FrmFile* frmPtr = nullptr;
if (checkPCX) {
const char* pos = strrchr(file, '.');
if (pos && _stricmp(pos, ".PCX") == 0) {
if (pos && _stricmp(++pos, "PCX") == 0) {
long w, h;
BYTE* data = LoadPCXData(file, &w, &h);
if (!data) return nullptr;
@@ -584,6 +578,7 @@ static long GetArtFIDFile(long fid, const char* &file) {
}
static void mf_draw_image() {
SelectWindowID(opHandler.program()->currentScriptWin);
if (*(DWORD*)_currentWindow == -1) {
opHandler.printOpcodeError("draw_image() - no created/selected window for the image.");
opHandler.setReturn(0);
@@ -604,7 +599,7 @@ static void mf_draw_image() {
file = opHandler.arg(0).strValue(); // path to frm/pcx file
}
// initialize other args
int frameno = 0, x = 0, y = 0, noTrans = 0;
long frameno = 0, x = 0, y = 0, noTrans = 0;
switch (opHandler.numArgs()) {
case 5:
noTrans = opHandler.arg(4).rawValue();
@@ -633,6 +628,7 @@ static void mf_draw_image() {
}
static void mf_draw_image_scaled() {
SelectWindowID(opHandler.program()->currentScriptWin);
if (*(DWORD*)_currentWindow == -1) {
opHandler.printOpcodeError("draw_image_scaled() - no created/selected window for the image.");
opHandler.setReturn(0);
@@ -653,7 +649,7 @@ static void mf_draw_image_scaled() {
file = opHandler.arg(0).strValue(); // path to frm/pcx file
}
// initialize other args
int frameno = 0, x = 0, y = 0, wsize = 0;
long frameno = 0, x = 0, y = 0, wsize = 0;
switch (opHandler.numArgs()) {
case 6:
case 5:
@@ -907,3 +903,32 @@ static void mf_interface_print() { // same as vanilla PrintRect
// no redraw (textdirect)
if (!(color & 0x1000000)) GNWWinRefresh(win, &win->rect, 0);
}
static void mf_win_fill_color() {
SelectWindowID(opHandler.program()->currentScriptWin);
long iWin = *(DWORD*)_currentWindow;
if (iWin == -1) {
opHandler.printOpcodeError("win_fill_color() - no created or selected window.");
opHandler.setReturn(-1);
return;
}
// initialize args
long x = 0, y = 0, width = 0, height = 0, color = 0;
switch (opHandler.numArgs()) {
case 5:
color = opHandler.arg(4).rawValue();
case 4:
height = opHandler.arg(3).rawValue();
case 3:
width = opHandler.arg(2).rawValue();
case 2:
y = opHandler.arg(1).rawValue();
case 1:
x = opHandler.arg(0).rawValue();
}
if (opHandler.numArgs() > 0) {
WinFillRect(ptr_sWindows[iWin].wID, x, y, width, height, (BYTE)color);
} else {
ClearWindow(ptr_sWindows[iWin].wID, false); // full clear
}
}
+1
View File
@@ -184,6 +184,7 @@ static const SfallMetarule metaruleArray[] = {
{"tile_refresh_display", mf_tile_refresh_display, 0, 0},
{"unjam_lock", mf_unjam_lock, 1, 1},
{"unwield_slot", mf_unwield_slot, 2, 2},
{"win_fill_color", mf_win_fill_color, 0, 5},
#ifndef NDEBUG
{"validate_test", mf_test, 2, 5},
#endif
+12 -7
View File
@@ -164,23 +164,28 @@ static bool LoadFrm(Frm* frm) {
return true;
}
static long dialogWinX = 0, dialogWinY = 0;
static struct DialogWinPos {
long x;
long y;
DialogWinPos() : x(-1) {}
} dialogWinPos;
static void __fastcall DrawHeadFrame(Frm* frm, int frameno) {
if (frm && !frm->broken) {
if (!frm->loaded && !LoadFrm(frm)) goto loadFail;
FrmFrameData* frame = FramePtr((FrmHeaderData*)frm, frameno, 0);
if (dialogWinX == -1) {
if (dialogWinPos.x == -1) {
WINinfo* dialogWin = GNWFind(*ptr_dialogueBackWindow);
dialogWinX = dialogWin->rect.x;
dialogWinY = dialogWin->rect.y;
dialogWinPos.x = dialogWin->rect.x;
dialogWinPos.y = dialogWin->rect.y;
}
Gfx_SetHeadTex(frm->textures[frameno],
frame->width,
frame->height,
frame->x + frm->xshift + dialogWinX,
frame->y + frm->yshift + dialogWinY
frame->x + frm->xshift + dialogWinPos.x,
frame->y + frm->yshift + dialogWinPos.y
);
showHighlights = frm->showHighlights;
return;
@@ -209,7 +214,7 @@ void __declspec(naked) gdDestroyHeadWindow_hack() {
__asm {
call Gfx_SetDefaultTechnique;
mov showHighlights, 0;
//mov dialogWinX, -1; // uncomment if the dialog window position is supposed to change
//mov dword ptr ds:[dialogWinPos], -1; // uncomment if the dialog window position is supposed to change
pop ebp;
pop edi;
pop edx;