Added sfall_func7 and sfall_func8 new opcodes

Added 3 new attrType values to "get_window_attribute" function.
Minor code edits.
This commit is contained in:
NovaRain
2020-12-22 16:55:17 +08:00
parent d82db3f572
commit 2bc94e8036
9 changed files with 53 additions and 23 deletions
@@ -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
+3
View File
@@ -312,8 +312,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")
+4 -1
View File
@@ -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
@@ -720,6 +720,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)
@@ -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
+2 -6
View File
@@ -381,13 +381,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) {
fo::Window* win = fo::func::GNW_find(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) {
fo::func::GNW_win_refresh(win, &win->rect, 0);
fo::func::GNW_win_refresh(win, &win->rect, nullptr);
}
}
+8 -8
View File
@@ -287,8 +287,8 @@ void __cdecl buf_to_buf(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;
@@ -324,9 +324,9 @@ void __cdecl buf_to_buf(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
@@ -335,9 +335,9 @@ void __cdecl buf_to_buf(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
@@ -351,8 +351,8 @@ end:
void __cdecl trans_buf_to_buf(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;
+17 -4
View File
@@ -646,7 +646,7 @@ void mf_interface_art_draw(OpcodeContext& ctx) {
if (win && (int)win != -1) {
result = InterfaceDrawImage(ctx, win);
} else {
ctx.printOpcodeError("%s() - the game interface window is not created or invalid value for the interface.", ctx.getMetaruleName());
ctx.printOpcodeError("%s() - the game interface window is not created or invalid window type number.", ctx.getMetaruleName());
}
ctx.setReturn(result);
}
@@ -729,15 +729,28 @@ void mf_get_window_attribute(OpcodeContext& ctx) {
}
long result = 0;
switch (ctx.arg(1).rawValue()) {
case -1: // rectangle map.left map.top map.right map.bottom
result = CreateTempArray(-1, 0); // associative
setArray(result, ScriptValue("left"), ScriptValue(win->rect.x), false);
setArray(result, ScriptValue("top"), ScriptValue(win->rect.y), false);
setArray(result, ScriptValue("right"), ScriptValue(win->rect.offx), false);
setArray(result, ScriptValue("bottom"), ScriptValue(win->rect.offy), false);
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;
}
ctx.setReturn(result);
}
@@ -745,7 +758,7 @@ void mf_get_window_attribute(OpcodeContext& ctx) {
void mf_interface_print(OpcodeContext& ctx) { // same as vanilla PrintRect
fo::Window* win = Interface::GetWindow(ctx.arg(1).rawValue());
if (win == nullptr || (int)win == -1) {
ctx.printOpcodeError("%s() - the game interface window is not created or invalid value for the interface.", ctx.getMetaruleName());
ctx.printOpcodeError("%s() - the game interface window is not created or invalid window type number.", ctx.getMetaruleName());
ctx.setReturn(-1);
return;
}
+4 -1
View File
@@ -228,11 +228,14 @@ static SfallOpcodeInfo opcodeInfoArray[] = {
{0x279, "sfall_func3", HandleMetarule, 4, true},
{0x27a, "sfall_func4", HandleMetarule, 5, true},
{0x27b, "sfall_func5", HandleMetarule, 6, true},
{0x27c, "sfall_func6", HandleMetarule, 7, true}, // if you need more arguments - use arrays
{0x27c, "sfall_func6", HandleMetarule, 7, true},
{0x27d, "register_hook_proc_spec", op_register_hook, 2, false, 0, {ARG_INT, ARG_INT}},
{0x27e, "reg_anim_callback", op_reg_anim_callback, 1, false, 0, {ARG_INT}},
{0x27f, "div", op_div, 2, true, 0, {ARG_NUMBER, ARG_NUMBER}}, // div operator
{0x280, "sfall_func7", HandleMetarule, 8, true},
{0x281, "sfall_func8", HandleMetarule, 9, true}, // if you need more arguments - use arrays
};
// An array for opcode info, indexed by opcode.
+8 -3
View File
@@ -39,7 +39,7 @@ static void __fastcall sf_GNW_win_refresh(fo::Window* win, RECT* updateRect, BYT
mov edx, ds:[FO_VAR_screen_buffer];
call fo::funcoffs::refresh_all_;
}
int w = updateRect->right - updateRect->left + 1;
int w = (updateRect->right - updateRect->left) + 1;
if (fo::var::mouse_is_hidden || !fo::func::mouse_in(updateRect->left, updateRect->top, updateRect->right, updateRect->bottom)) {
/*__asm {
@@ -48,7 +48,9 @@ static void __fastcall sf_GNW_win_refresh(fo::Window* win, RECT* updateRect, BYT
call fo::funcoffs::GNW_button_refresh_;
}*/
int h = (updateRect->bottom - updateRect->top) + 1;
Graphics::UpdateDDSurface(GetBuffer(), w, h, w, updateRect); // update the entire rectangle area
} else {
fo::func::mouse_show(); // for updating background cursor area
RECT mouseRect;
@@ -66,8 +68,10 @@ static void __fastcall sf_GNW_win_refresh(fo::Window* win, RECT* updateRect, BYT
mov edx, rects;
call fo::funcoffs::GNW_button_refresh_;
}*/
int wRect = (rects->wRect.right - rects->wRect.left) + 1;
int hRect = (rects->wRect.bottom - rects->wRect.top) + 1;
Graphics::UpdateDDSurface(&GetBuffer()[rects->wRect.left - updateRect->left] + (rects->wRect.top - updateRect->top) * w, wRect, hRect, w, &rects->wRect);
fo::RectList* next = rects->nextRect;
@@ -102,7 +106,7 @@ static void __fastcall sf_GNW_win_refresh(fo::Window* win, RECT* updateRect, BYT
}
int widthFrom = win->width;
int toWidth = (toBuffer) ? updateRect->right - updateRect->left + 1 : Graphics::GetGameWidthRes();
int toWidth = (toBuffer) ? (updateRect->right - updateRect->left) + 1 : Graphics::GetGameWidthRes();
fo::func::win_clip(win, &rects, toBuffer);
@@ -113,7 +117,7 @@ static void __fastcall sf_GNW_win_refresh(fo::Window* win, RECT* updateRect, BYT
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;
@@ -144,6 +148,7 @@ static void __fastcall sf_GNW_win_refresh(fo::Window* win, RECT* updateRect, BYT
int width = (rects->rect.offx - rects->rect.x) + 1;
int height = (rects->rect.offy - rects->rect.y) + 1;
int widthFrom = toWidth;
Graphics::UpdateDDSurface(&GetBuffer()[rects->rect.x] + (rects->rect.y * widthFrom), width, height, widthFrom, &rects->wRect);
}
fo::RectList* next = rects->nextRect;