Added aspect ratio scaling to draw_image_scaled.

Rewrote create_message_window script function in C++.
This commit is contained in:
NovaRain
2019-05-11 08:49:30 +08:00
parent 4b221b5367
commit a63ea24572
6 changed files with 35 additions and 50 deletions
@@ -10,6 +10,12 @@
#define OBJ_TYPE_MISC (5)
#define OBJ_TYPE_SPATIAL (6)
#define ART_TYPE_INTERFACE (6)
#define ART_TYPE_INVENT (7)
#define ART_TYPE_HEADS (8)
#define ART_TYPE_BACKGRND (9)
#define ART_TYPE_SKILLDEX (10)
#define WEAPON_TYPE_NONE (0)
#define WEAPON_TYPE_UNARMED (1)
#define WEAPON_TYPE_MELEE (2)
+2 -2
View File
@@ -594,9 +594,9 @@ Some utility/math functions are available:
Optional arguments:
- frame: frame number, the first frame starts from zero
- x/y: offset relative to the top-left corner of the window
- width/height: image size, used to scale the image when displaying it
- width/height: image size, used to scale the image when displaying it. Pass -1 to either width or height to keep aspect ratio when scaling
- noTransparent: pass true to display an image without transparent background
- NOTE: to omit optional arguments, call the functions with different sfall_funcX (e.g. sfall_func4("draw_image", pathFile, frame, x, y))
- NOTE: to omit optional arguments starting from the right, call the functions with different sfall_funcX (e.g. sfall_func4("draw_image", pathFile, frame, x, y))
- if draw_image_scaled is called without x/y/width/height arguments, the image will be scaled to fit the window without transparent background
------------------------
+2 -2
View File
@@ -394,8 +394,8 @@ void __stdcall DialogOut(const char* text) {
push eax; // DisplayMsg
mov al, byte ptr ds:[0x6AB718];
push eax; // ColorIndex
push 0x74; // y
mov ecx, 0xC0; // x
push 116; // y
mov ecx, 192; // x
mov eax, text; // DisplayText
xor ebx, ebx; // ?
xor edx, edx; // ?
+23 -44
View File
@@ -151,46 +151,11 @@ void __declspec(naked) op_resume_game() {
}
}
void __declspec(naked) op_create_message_window() {
__asm {
pushad
mov ebx, dword ptr ds:[FO_VAR_curr_font_num];
cmp ebx, 0x65;
je end;
mov ecx, eax;
call fo::funcoffs::interpretPopShort_;
mov edx, eax;
mov eax, ecx;
call fo::funcoffs::interpretPopLong_;
cmp dx, VAR_TYPE_STR2;
jz next;
cmp dx, VAR_TYPE_STR;
jnz end;
next:
mov ebx, eax;
mov eax, ecx;
call fo::funcoffs::interpretGetString_;
mov esi, eax;
mov ecx, eax;
mov eax, 3;
push 1; // arg10
mov al, byte ptr ds:[0x6AB718];
push eax; // a9
push 0; // *DisplayText
push eax; // ColorIndex
push 0x74; // y
mov ecx, 0xC0; // x
mov eax, esi; // text
xor ebx, ebx; // ?
xor edx, edx; // ?
call fo::funcoffs::dialog_out_;
//xor eax, eax;
end:
popad;
ret;
}
void sf_create_message_window(OpcodeContext &ctx) {
const char* str = ctx.arg(0).strValue();
if (!str || str[0] == 0) return;
//if (fo::var::curr_font_num == 101) return;
fo::func::DialogOut(str);
}
void __declspec(naked) op_get_viewport_x() {
@@ -422,7 +387,7 @@ static void DrawImage(OpcodeContext& ctx, bool isScaled) {
}
fo::FrmFile* frmPtr = nullptr;
if (fo::func::load_frame(file, &frmPtr)) {
ctx.printOpcodeError("%s() - can't open the file: %s", ctx.getMetaruleName(), file);
ctx.printOpcodeError("%s() - cannot open the file: %s", ctx.getMetaruleName(), file);
return;
}
fo::FrmFrameData* framePtr = (fo::FrmFrameData*)&frmPtr->width;
@@ -446,10 +411,24 @@ static void DrawImage(OpcodeContext& ctx, bool isScaled) {
} else {
int x = ctx.arg(2).rawValue(), y = ctx.arg(3).rawValue();
if (isScaled) { // draw to scale
long s_width = (ctx.numArgs() > 4) ? ctx.arg(4).rawValue() : framePtr->width;
long s_height = (ctx.numArgs() > 5) ? ctx.arg(5).rawValue() : framePtr->height;
long s_width, s_height;
if (ctx.numArgs() < 5) {
s_width = framePtr->width;
s_height = framePtr->height;
} else {
s_width = ctx.arg(4).rawValue();
s_height = (ctx.numArgs() > 5) ? ctx.arg(5).rawValue() : -1;
}
// scale with aspect ratio if w or h is set to -1
if (s_width <= -1 && s_height > 0) {
s_width = s_height * framePtr->width / framePtr->height;
} else if (s_height <= -1 && s_width > 0) {
s_height = s_width * framePtr->height / framePtr->width;
}
if (s_width <= 0 || s_height <= 0) return;
long w_width = fo::func::windowWidth();
long xy_pos = (x * w_width) + y;
long xy_pos = (y * w_width) + x;
fo::func::trans_cscale(framePtr->width, framePtr->height, s_width, s_height, xy_pos, w_width, framePtr->data); // custom scaling
} else { // with x/y frame offsets
fo::func::windowDisplayBuf(x + frmPtr->xshift[direction], framePtr->width, y + frmPtr->yshift[direction], framePtr->height, framePtr->data, ctx.arg(4).rawValue());
+1 -1
View File
@@ -57,7 +57,7 @@ void __declspec() op_stop_game();
void __declspec() op_resume_game();
//Create a message window with given string
void __declspec() op_create_message_window();
void sf_create_message_window(OpcodeContext&);
void __declspec() op_get_viewport_x();
+1 -1
View File
@@ -135,6 +135,7 @@ static SfallOpcodeInfo opcodeInfoArray[] = {
{0x21a, "set_weapon_ammo_count", sf_set_weapon_ammo_count, 2, false, {ARG_OBJECT, ARG_INT}},
{0x21e, "get_mouse_buttons", sf_get_mouse_buttons, 0, true},
{0x224, "create_message_window", sf_create_message_window, 1, false, {ARG_STRING}},
{0x22d, "create_array", sf_create_array, 2, true, {ARG_INT, ARG_INT}},
{0x22e, "set_array", sf_set_array, 3, false, {ARG_OBJECT, ARG_ANY, ARG_ANY}},
{0x22f, "get_array", sf_get_array, 2, true, {ARG_ANY, ARG_ANY}}, // can also be used on strings
@@ -384,7 +385,6 @@ void InitNewOpcodes() {
opcodes[0x221] = op_get_screen_height;
opcodes[0x222] = op_stop_game;
opcodes[0x223] = op_resume_game;
opcodes[0x224] = op_create_message_window;
opcodes[0x225] = op_remove_trait;
opcodes[0x226] = op_get_light_level;
opcodes[0x227] = op_refresh_pc_art;