From e0e300a91e9d6e72c5d5d1338a9989fe0b63cd2b Mon Sep 17 00:00:00 2001 From: NovaRain Date: Tue, 22 Dec 2020 16:31:17 +0800 Subject: [PATCH] Added sfall_func7 and sfall_func8 new opcodes Added 3 new attrType values to "get_window_attribute" function. Minor code edits. --- artifacts/scripting/compiler/sslc_readme.txt | 4 ++++ artifacts/scripting/headers/sfall.h | 3 +++ artifacts/scripting/sfall function notes.txt | 5 +++- artifacts/scripting/sfall opcode list.txt | 3 +++ sfall/FalloutEngine.cpp | 24 ++++++++------------ sfall/Graphics.cpp | 10 +++++--- sfall/ScriptExtender.cpp | 5 +++- sfall/ScriptOps/InterfaceOps.hpp | 21 +++++++++++++---- sfall/ScriptOps/MetaruleOps.hpp | 2 ++ 9 files changed, 54 insertions(+), 23 deletions(-) diff --git a/artifacts/scripting/compiler/sslc_readme.txt b/artifacts/scripting/compiler/sslc_readme.txt index f5de9bfc..db9cf304 100644 --- a/artifacts/scripting/compiler/sslc_readme.txt +++ b/artifacts/scripting/compiler/sslc_readme.txt @@ -340,6 +340,10 @@ There are several changes in this version of sslc which may result in problems f === Changelog === ================= +> sfall 4.2.9 +- added support for additional universal opcodes sfall_func7 and sfall_func8 +- fixed a compilation error when the script has a UTF-8 BOM + > sfall 4.2.7 - added ability to declare local variables anywhere in the procedure body diff --git a/artifacts/scripting/headers/sfall.h b/artifacts/scripting/headers/sfall.h index 92b13b71..3e1654cd 100644 --- a/artifacts/scripting/headers/sfall.h +++ b/artifacts/scripting/headers/sfall.h @@ -286,8 +286,11 @@ #define get_flags(obj) sfall_func1("get_flags", obj) #define get_ini_section(file, sect) sfall_func2("get_ini_section", file, sect) #define get_ini_sections(file) sfall_func1("get_ini_sections", file) +#define get_interface_rect(winType) sfall_func2("get_window_attribute", winType, -1) #define get_interface_x(winType) sfall_func2("get_window_attribute", winType, 1) #define get_interface_y(winType) sfall_func2("get_window_attribute", winType, 2) +#define get_interface_width(winType) sfall_func2("get_window_attribute", winType, 3) +#define get_interface_height(winType) sfall_func2("get_window_attribute", winType, 4) #define get_inven_ap_cost sfall_func0("get_inven_ap_cost") #define get_map_enter_position sfall_func0("get_map_enter_position") #define get_metarule_table sfall_func0("get_metarule_table") diff --git a/artifacts/scripting/sfall function notes.txt b/artifacts/scripting/sfall function notes.txt index 6cea5252..f177c321 100644 --- a/artifacts/scripting/sfall function notes.txt +++ b/artifacts/scripting/sfall function notes.txt @@ -381,7 +381,7 @@ Some utility/math functions are available: > any sfall_funcX(string funcName, ...) - these opcodes allows to use additional scripting functions, that do not require new opcode - first argument is always function name (string) -- there are 7 versions of this opcode for different number of additional arguments (for convenience) +- there are 9 versions of this opcode for different number of additional arguments (for convenience) - opcodes have return value, but it is not necessary to use it @@ -666,6 +666,9 @@ optional argument: - winType: the type number of the interface window (see WINTYPE_* constants in sfall.h) - attrType: 0 - checks and returns a value of 1 if the specified interface window is created by the game (same as without the argument) 1 - X position, 2 - Y position (relative to the top-left corner of the game screen) + 3 - interface width size, 4 - interface height size + -1 - returns an associative array of keys (left, top, right, bottom) and values that define the position of the window rectangle + (use standard syntax to access array values, e.g. winRect.top, winRect.bottom) - returns -1 if the specified attribute cannot be obtained > void sfall_func2("set_town_title", int areaID, string title) diff --git a/artifacts/scripting/sfall opcode list.txt b/artifacts/scripting/sfall opcode list.txt index 89700e7e..6f1350e5 100644 --- a/artifacts/scripting/sfall opcode list.txt +++ b/artifacts/scripting/sfall opcode list.txt @@ -362,6 +362,9 @@ 0x827f - div operator (unsigned integer division) +0x8280 - any sfall_func7(string funcName, arg1, arg2, arg3, arg4, arg5, arg6, arg7) +0x8281 - any sfall_func8(string funcName, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8) + * These functions require AllowUnsafeScripting to be enabled in ddraw.ini diff --git a/sfall/FalloutEngine.cpp b/sfall/FalloutEngine.cpp index 28563808..46da6fe2 100644 --- a/sfall/FalloutEngine.cpp +++ b/sfall/FalloutEngine.cpp @@ -1089,8 +1089,8 @@ void __cdecl BufToBuf(BYTE* src, long width, long height, long src_width, BYTE* size_t blockCount = width / 64; // 64 bytes size_t remainder = width % 64; - size_t remainderD = remainder / 4; - size_t remainderB = remainder % 4; + size_t sizeD = remainder >> 2; + size_t sizeB = remainder & 3; size_t s_pitch = src_width - width; size_t d_pitch = dst_width - width; @@ -1126,9 +1126,9 @@ void __cdecl BufToBuf(BYTE* src, long width, long height, long src_width, BYTE* dec ecx; // blockCount jnz copyBlock; // copies the remaining bytes - mov ecx, remainderD; + mov ecx, sizeD; rep movsd; - mov ecx, remainderB; + mov ecx, sizeB; rep movsb; add esi, ebx; // s_pitch add edi, edx; // d_pitch @@ -1137,9 +1137,9 @@ void __cdecl BufToBuf(BYTE* src, long width, long height, long src_width, BYTE* emms; jmp end; copySmall: // copies the small size data - mov ecx, remainderD; + mov ecx, sizeD; rep movsd; - mov ecx, remainderB; + mov ecx, sizeB; rep movsb; add esi, ebx; // s_pitch add edi, edx; // d_pitch @@ -1153,8 +1153,8 @@ end: void __cdecl TransBufToBuf(BYTE* src, long width, long height, long src_width, BYTE* dst, long dst_width) { if (height <= 0 || width <= 0) return; - size_t blockCount = width / 8; - size_t lastBytes = width % 8; + size_t blockCount = width >> 3; + size_t lastBytes = width & 7; size_t s_pitch = src_width - width; size_t d_pitch = dst_width - width; @@ -1589,13 +1589,9 @@ void WinFillRect(long winID, long x, long y, long width, long height, BYTE index // 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(surf, 0, win->width); - surf += win->width; - } + std::memset(win->surface, 0, win->width * win->height); if (refresh) { - GNWWinRefresh(win, &win->rect, 0); + GNWWinRefresh(win, &win->rect, nullptr); } } diff --git a/sfall/Graphics.cpp b/sfall/Graphics.cpp index 9f758a0e..0f420a01 100644 --- a/sfall/Graphics.cpp +++ b/sfall/Graphics.cpp @@ -1337,7 +1337,7 @@ static void __fastcall sf_GNW_win_refresh(WINinfo* win, RECT* updateRect, BYTE* mov edx, ds:[_screen_buffer]; call refresh_all_; } - int w = updateRect->right - updateRect->left + 1; + int w = (updateRect->right - updateRect->left) + 1; if (*ptr_mouse_is_hidden || !MouseIn(updateRect->left, updateRect->top, updateRect->right, updateRect->bottom)) { /*__asm { @@ -1346,7 +1346,9 @@ static void __fastcall sf_GNW_win_refresh(WINinfo* win, RECT* updateRect, BYTE* call GNW_button_refresh_; }*/ int h = (updateRect->bottom - updateRect->top) + 1; + UpdateDDSurface(GetBuffer(), w, h, w, updateRect); // update the entire rectangle area + } else { MouseShow(); // for updating background cursor area RECT mouseRect; @@ -1364,8 +1366,10 @@ static void __fastcall sf_GNW_win_refresh(WINinfo* win, RECT* updateRect, BYTE* mov edx, rects; call GNW_button_refresh_; }*/ + int wRect = (rects->wRect.right - rects->wRect.left) + 1; int hRect = (rects->wRect.bottom - rects->wRect.top) + 1; + UpdateDDSurface(&GetBuffer()[rects->wRect.left - updateRect->left] + (rects->wRect.top - updateRect->top) * w, wRect, hRect, w, &rects->wRect); RectList* next = rects->nextRect; @@ -1403,7 +1407,7 @@ static void __fastcall sf_GNW_win_refresh(WINinfo* win, RECT* updateRect, BYTE* } int widthFrom = win->width; - int toWidth = (toBuffer) ? updateRect->right - updateRect->left + 1 : Gfx_GetGameWidthRes(); + int toWidth = (toBuffer) ? (updateRect->right - updateRect->left) + 1 : Gfx_GetGameWidthRes(); WinClip(win, &rects, toBuffer); @@ -1414,7 +1418,7 @@ static void __fastcall sf_GNW_win_refresh(WINinfo* win, RECT* updateRect, BYTE* int height = (crect.bottom - crect.top) + 1;; // for current rectangle BYTE* surface; - if (win->wID) { + if (win->wID > 0) { __asm { mov eax, win; mov edx, currRect; diff --git a/sfall/ScriptExtender.cpp b/sfall/ScriptExtender.cpp index da31ffd7..899ce804 100644 --- a/sfall/ScriptExtender.cpp +++ b/sfall/ScriptExtender.cpp @@ -2080,12 +2080,15 @@ void ScriptExtender_Init() { opcodes[0x279] = op_sfall_metarule3; opcodes[0x27a] = op_sfall_metarule4; opcodes[0x27b] = op_sfall_metarule5; - opcodes[0x27c] = op_sfall_metarule6; // if you need more arguments - use arrays + opcodes[0x27c] = op_sfall_metarule6; opcodes[0x27d] = op_register_hook_proc_spec; opcodes[0x27e] = op_reg_anim_callback; opcodes[0x27f] = op_div; // div operator + opcodes[0x280] = op_sfall_metarule7; + opcodes[0x281] = op_sfall_metarule8; // if you need more arguments - use arrays + InitOpcodeMetaTable(); InitMetaruleTable(); } diff --git a/sfall/ScriptOps/InterfaceOps.hpp b/sfall/ScriptOps/InterfaceOps.hpp index 3e9215a5..ee2b9156 100644 --- a/sfall/ScriptOps/InterfaceOps.hpp +++ b/sfall/ScriptOps/InterfaceOps.hpp @@ -712,7 +712,7 @@ static void mf_interface_art_draw() { if (win && (int)win != -1) { result = InterfaceDrawImage(opHandler, win, "interface_art_draw"); } else { - opHandler.printOpcodeError("interface_art_draw() - the game interface window is not created or invalid value for the interface."); + opHandler.printOpcodeError("interface_art_draw() - the game interface window is not created or invalid window type number."); } opHandler.setReturn(result); } @@ -795,15 +795,28 @@ static void mf_get_window_attribute() { } long result = 0; switch (opHandler.arg(1).rawValue()) { + case -1: // rectangle map.left map.top map.right map.bottom + result = CreateTempArray(-1, 0); // associative + setArray(result, ScriptValue("left").rawValue(), VAR_TYPE_STR, win->rect.x, VAR_TYPE_INT, 0); + setArray(result, ScriptValue("top").rawValue(), VAR_TYPE_STR, win->rect.y, VAR_TYPE_INT, 0); + setArray(result, ScriptValue("right").rawValue(), VAR_TYPE_STR, win->rect.offx, VAR_TYPE_INT, 0); + setArray(result, ScriptValue("bottom").rawValue(), VAR_TYPE_STR, win->rect.offy, VAR_TYPE_INT, 0); + break; case 0: // check if window exists result = 1; break; - case 1: // x + case 1: result = win->rect.x; break; - case 2: // y + case 2: result = win->rect.y; break; + case 3: + result = win->width; + break; + case 4: + result = win->height; + break; } opHandler.setReturn(result); } @@ -811,7 +824,7 @@ static void mf_get_window_attribute() { static void mf_interface_print() { // same as vanilla PrintRect WINinfo* win = Interface_GetWindow(opHandler.arg(1).rawValue()); if (win == nullptr || (int)win == -1) { - opHandler.printOpcodeError("interface_print() - the game interface window is not created or invalid value for the interface."); + opHandler.printOpcodeError("interface_print() - the game interface window is not created or invalid window type number."); opHandler.setReturn(-1); return; } diff --git a/sfall/ScriptOps/MetaruleOps.hpp b/sfall/ScriptOps/MetaruleOps.hpp index bd93b95c..f11bb601 100644 --- a/sfall/ScriptOps/MetaruleOps.hpp +++ b/sfall/ScriptOps/MetaruleOps.hpp @@ -261,5 +261,7 @@ metaruleOpcode(3, 4) metaruleOpcode(4, 5) metaruleOpcode(5, 6) metaruleOpcode(6, 7) +metaruleOpcode(7, 8) +metaruleOpcode(8, 9) #undef metaruleOpcode