mirror of
https://github.com/sfall-team/sfall.git
synced 2026-07-27 16:52:34 -07:00
Added "draw_image" and "draw_image_scaled" script functions.
This commit is contained in:
+1
-1
@@ -630,7 +630,7 @@ DontTurnOffSneakIfYouRun=0
|
||||
;Set to 0 to disable switching. (Default is 3)
|
||||
UseWalkDistance=3
|
||||
|
||||
;Set to 1 to fix the bug that unable to sell used geiger counters or stealth boys
|
||||
;Set to 1 to fix the bug of being unable to sell used geiger counters or stealth boys
|
||||
CanSellUsedGeiger=1
|
||||
|
||||
;Set to 1 to fix the issue with being able to charge the car by using cells on other scenary/critters
|
||||
|
||||
@@ -249,6 +249,8 @@
|
||||
#define dialog_message(text) sfall_func1("dialog_message", text)
|
||||
#define dialog_obj sfall_func0("dialog_obj")
|
||||
#define display_stats sfall_func0("display_stats")
|
||||
#define draw_image(frmFile, frame, x, y, transparent) sfall_func5("draw_image", frmFile, frame, x, y, transparent)
|
||||
#define draw_image_scaled(frmFile, frame, x, y, w, h) sfall_func6("draw_image_scaled", frmFile, frame, x, y, w, h)
|
||||
#define exec_map_update_scripts sfall_func0("exec_map_update_scripts")
|
||||
#define floor2(value) sfall_func1("floor2", value)
|
||||
#define get_can_rest_on_map(map, elev) sfall_func2("get_can_rest_on_map", map, elev)
|
||||
|
||||
@@ -587,6 +587,17 @@ Some utility/math functions are available:
|
||||
- there is also a unique ID number range for the player and party members from 18000 to 83535
|
||||
- to assign a new ID number generated by the engine to the object (i.e. unassign a unique ID), call the function with two arguments and pass -1 for the flag argument
|
||||
|
||||
> void sfall_func5("draw_image", string/int pathFile/artId, int frame, int x, int y, bool transparent)
|
||||
> void sfall_func6("draw_image_scaled", string/int pathFile/artId, int frame, int x, int y, int width, int height)
|
||||
- displays the specified FRM image in the active window created by vanilla CreateWin or sfall's create_win script function
|
||||
- pathFile/artId: path to the FRM file (e.g. "art\\inven\\5mmap.frm"), or its FRM ID number (e.g. 117440550, see specification of the FID format)
|
||||
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
|
||||
- transparent: pass true to display an image with transparent background
|
||||
- NOTE: calling the functions without creating a window first will crash the game
|
||||
|
||||
------------------------
|
||||
------ MORE INFO -------
|
||||
------------------------
|
||||
|
||||
@@ -417,6 +417,7 @@ void __fastcall DrawWinLine(int winRef, DWORD startXPos, DWORD endXPos, DWORD st
|
||||
}
|
||||
}
|
||||
|
||||
// draws an image to the buffer without scaling and with possible transparency
|
||||
void __fastcall windowDisplayBuf(long x, long width, long y, long height, void* data, long isTrans) {
|
||||
__asm {
|
||||
push height;
|
||||
@@ -430,6 +431,7 @@ void __fastcall windowDisplayBuf(long x, long width, long y, long height, void*
|
||||
}
|
||||
}
|
||||
|
||||
// draws an image in the window and scales it to fit the window
|
||||
void __fastcall displayInWindow(long w_here, long width, long height, void* data) {
|
||||
__asm {
|
||||
mov ebx, height;
|
||||
|
||||
@@ -2320,9 +2320,9 @@ void BugFixes::init()
|
||||
MakeCall(0x4130E5, action_explode_hack1);
|
||||
dlogr(" Done", DL_INIT);
|
||||
|
||||
// Fix for unable to sell used geiger counters or stealth boys
|
||||
// Fix for being unable to sell used geiger counters or stealth boys
|
||||
if (GetConfigInt("Misc", "CanSellUsedGeiger", 1)) {
|
||||
dlog("Applying fix for unable to sell used geiger counters or stealth boys.", DL_INIT);
|
||||
dlog("Applying fix for being unable to sell used geiger counters or stealth boys.", DL_INIT);
|
||||
SafeWrite8(0x478115, 0xBA);
|
||||
SafeWrite8(0x478138, 0xBA);
|
||||
MakeJump(0x474D22, barter_attempt_transaction_hack);
|
||||
@@ -2487,7 +2487,7 @@ void BugFixes::init()
|
||||
SafeWrite8(0x4C1015, 0x90);
|
||||
HookCall(0x4C1042, wmSetupRandomEncounter_hook);
|
||||
|
||||
// Fix for unable to sell/give items in the barter screen when the player/party member is overloaded
|
||||
// Fix for being unable to sell/give items in the barter screen when the player/party member is overloaded
|
||||
HookCalls(barter_attempt_transaction_hook_weight, {0x474C73, 0x474CCA});
|
||||
|
||||
// Fix for the underline position in the inventory display window when the item name is longer than one line
|
||||
|
||||
@@ -398,5 +398,72 @@ void sf_create_win(OpcodeContext& ctx) {
|
||||
}
|
||||
}
|
||||
|
||||
static void DrawImage(OpcodeContext& ctx, bool isScaled) {
|
||||
long rotation = 0;
|
||||
const char* file = nullptr;
|
||||
if (ctx.arg(0).isInt()) { // art id
|
||||
long fid = ctx.arg(0).rawValue();
|
||||
if (fid == -1) return;
|
||||
long _fid = fid & 0xFFFFFFF;
|
||||
file = fo::func::art_get_name(_fid); // .frm
|
||||
if (_fid >> 24 == fo::OBJ_TYPE_CRITTER) {
|
||||
rotation = (fid >> 28);
|
||||
DWORD sz;
|
||||
if (rotation && fo::func::db_file_exist(file, &sz)) {
|
||||
file = fo::func::art_get_name(fid); // .fr#
|
||||
}
|
||||
}
|
||||
} else {
|
||||
file = ctx.arg(0).strValue(); // path to frm file
|
||||
}
|
||||
fo::FrmFile* frmPtr = nullptr;
|
||||
if (fo::func::load_frame(file, &frmPtr)) {
|
||||
ctx.printOpcodeError("%s() - can't open the file '%s'.", ctx.getMetaruleName(), file);
|
||||
return;
|
||||
}
|
||||
fo::FrmFrameData* framePtr = (fo::FrmFrameData*)&frmPtr->width;
|
||||
if (rotation > 0 && rotation < 6) {
|
||||
BYTE* offsOriFrame = (BYTE*)framePtr;
|
||||
offsOriFrame += frmPtr->oriFrameOffset[rotation];
|
||||
framePtr = (fo::FrmFrameData*)offsOriFrame;
|
||||
}
|
||||
int frameno = ctx.arg(1).rawValue();
|
||||
if (frameno > 0) {
|
||||
int maxFrames = frmPtr->frames - 1;
|
||||
if (frameno > maxFrames) frameno = maxFrames;
|
||||
while (frameno-- > 0) {
|
||||
BYTE* offsFrame = (BYTE*)framePtr;
|
||||
offsFrame += framePtr->size + (sizeof(fo::FrmFrameData) - 1);
|
||||
framePtr = (fo::FrmFrameData*)offsFrame;
|
||||
}
|
||||
}
|
||||
if (isScaled && ctx.numArgs() < 3) {
|
||||
fo::func::displayInWindow(framePtr->width, framePtr->width, framePtr->height, framePtr->data); // scaled to window size
|
||||
} 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 w_width = fo::func::windowWidth();
|
||||
long xy_pos = (x * w_width) + y;
|
||||
fo::func::trans_cscale(framePtr->width, framePtr->height, s_width, s_height, xy_pos, w_width, framePtr->data); // custom scaling
|
||||
} else {
|
||||
fo::func::windowDisplayBuf(x + frmPtr->xshift[rotation], framePtr->width, y + frmPtr->yshift[rotation], framePtr->height, framePtr->data, ctx.arg(4).rawValue());
|
||||
}
|
||||
}
|
||||
__asm {
|
||||
mov eax, frmPtr;
|
||||
call fo::funcoffs::mem_free_;
|
||||
}
|
||||
}
|
||||
|
||||
void sf_draw_image(OpcodeContext& ctx) {
|
||||
DrawImage(ctx, false);
|
||||
}
|
||||
|
||||
void sf_draw_image_scaled(OpcodeContext& ctx) {
|
||||
DrawImage(ctx, true);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -99,5 +99,9 @@ void sf_dialog_message(OpcodeContext&);
|
||||
|
||||
void sf_create_win(OpcodeContext&);
|
||||
|
||||
void sf_draw_image(OpcodeContext&);
|
||||
|
||||
void sf_draw_image_scaled(OpcodeContext&);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -54,7 +54,7 @@ static MetaruleTableType metaruleTable;
|
||||
{ name, handler, minArgs, maxArgs, {arg1, arg2, ...} }
|
||||
- name - name of function that will be used in scripts,
|
||||
- handler - pointer to handler function (see examples below),
|
||||
- minArgs/maxArgs - minimum and maximum number of arguments allowed for this function
|
||||
- minArgs/maxArgs - minimum and maximum number of arguments allowed for this function (max 6)
|
||||
- arg1, arg2, ... - argument types for automatic validation
|
||||
*/
|
||||
static const SfallMetarule metarules[] = {
|
||||
@@ -66,7 +66,9 @@ static const SfallMetarule metarules[] = {
|
||||
{"critter_inven_obj2", sf_critter_inven_obj2, 2, 2, {ARG_OBJECT, ARG_INT}},
|
||||
{"dialog_message", sf_dialog_message, 1, 1, {ARG_STRING}},
|
||||
{"dialog_obj", sf_get_dialog_object, 0, 0},
|
||||
{"display_stats", sf_display_stats, 0, 0},
|
||||
{"display_stats", sf_display_stats, 0, 0}, // refresh
|
||||
{"draw_image", sf_draw_image, 1, 5, {ARG_INTSTR, ARG_INT, ARG_INT, ARG_INT, ARG_INT}},
|
||||
{"draw_image_scaled", sf_draw_image_scaled, 1, 6, {ARG_INTSTR, ARG_INT, ARG_INT, ARG_INT, ARG_INT, ARG_INT}},
|
||||
{"exec_map_update_scripts", sf_exec_map_update_scripts, 0, 0},
|
||||
{"floor2", sf_floor2, 1, 1, {ARG_NUMBER}},
|
||||
{"get_can_rest_on_map", sf_get_rest_on_map, 2, 2, {ARG_INT, ARG_INT}},
|
||||
|
||||
Reference in New Issue
Block a user