mirror of
https://github.com/sfall-team/sfall.git
synced 2026-07-27 16:52:34 -07:00
Rewrote and rename "dialog_box" to "message_box"
Added support for '\n' control character to create_message_window. Fix the playback of the speech sound file for the death screen.
This commit is contained in:
@@ -244,7 +244,6 @@
|
||||
#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)
|
||||
#define critter_inven_obj2(obj, type) sfall_func2("critter_inven_obj2", obj, type)
|
||||
#define dialog_box(text) sfall_func1("dialog_box", text)
|
||||
#define dialog_obj sfall_func0("dialog_obj")
|
||||
#define display_stats sfall_func0("display_stats")
|
||||
#define draw_image(pathFile, frame, x, y, noTrans) sfall_func5("draw_image", pathFile, frame, x, y, noTrans)
|
||||
@@ -273,6 +272,7 @@
|
||||
#define item_weight(obj) sfall_func1("item_weight", obj)
|
||||
#define lock_is_jammed(obj) sfall_func1("lock_is_jammed", obj)
|
||||
#define loot_obj sfall_func0("loot_obj")
|
||||
#define message_box(text) sfall_func1("message_box", text)
|
||||
#define metarule_exist(metaruleName) sfall_func1("metarule_exist", metaruleName)
|
||||
#define npc_engine_level_up(toggle) sfall_func1("npc_engine_level_up", toggle)
|
||||
#define obj_under_cursor(onlyCritter, includeDude) sfall_func2("obj_under_cursor", onlyCritter, includeDude)
|
||||
|
||||
@@ -623,12 +623,13 @@ optional arguments:
|
||||
- sets a floating text for a town on the world map when hovering the cursor over the player's marker
|
||||
- areaID: the ID number of the town from city.txt
|
||||
|
||||
> int sfall_func1("dialog_box", string text1)
|
||||
> int sfall_func2("dialog_box", string text1, string text2)
|
||||
> int sfall_func3("dialog_box", string text1, string text2, string text3)
|
||||
- creates a dialog box with text and returns the result of pressing the button: 0 - No, 1 - Yes
|
||||
- text1/text2/text3: corresponding text in the dialog box for the first, second, and third lines
|
||||
> int sfall_func4("message_box", string message, int flags, int color1, int color2)
|
||||
- creates a dialog box with text and returns the result of pressing the button: 0 - No, 1 - Yes/Done
|
||||
- returns -1 if for some reason the dialog box cannot be created
|
||||
- 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 DIALOGOUT_* constants in define_extra.h). Pass -1 to skip setting the flags (default flags are DIALOGOUT_NORMAL|DIALOGOUT_YESNO)
|
||||
- color1/2: 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)
|
||||
|
||||
------------------------
|
||||
------ MORE INFO -------
|
||||
|
||||
@@ -2474,6 +2474,14 @@ endLoop:
|
||||
}
|
||||
}
|
||||
|
||||
static void __declspec(naked) main_death_scene_hook() {
|
||||
__asm {
|
||||
mov eax, 100;
|
||||
call block_for_tocks_;
|
||||
jmp get_time_;
|
||||
}
|
||||
}
|
||||
|
||||
void BugFixesInit()
|
||||
{
|
||||
#ifndef NDEBUG
|
||||
@@ -3115,4 +3123,7 @@ void BugFixesInit()
|
||||
|
||||
// Fix for party member's equipped weapon being placed in the incorrect item slot after leveling up
|
||||
MakeCall(0x495FD9, partyMemberCopyLevelInfo_hack, 1);
|
||||
|
||||
// Fix the playback of the speech sound file for the death screen
|
||||
HookCall(0x481409, main_death_scene_hook);
|
||||
}
|
||||
|
||||
+14
-12
@@ -1083,35 +1083,37 @@ long __stdcall WinRegisterButton(DWORD winRef, long xPos, long yPos, long width,
|
||||
}
|
||||
}
|
||||
|
||||
void __stdcall DialogOut(const char* text) {
|
||||
void __fastcall DialogOut(const char* text, const char** textEx, long lines) {
|
||||
__asm {
|
||||
push 1; // DIALOGOUT_NORMAL flag
|
||||
xor eax, eax;
|
||||
push eax; // ColorMsg
|
||||
push eax; // DisplayMsg (unknown)
|
||||
mov al, byte ptr ds:[0x6AB718];
|
||||
push eax; // ColorMsg
|
||||
push 0; // DisplayMsg (unknown)
|
||||
push eax; // ColorIndex
|
||||
mov eax, ecx; // DisplayText
|
||||
push 116; // y
|
||||
mov ecx, 192; // x
|
||||
mov eax, text; // DisplayText
|
||||
xor ebx, ebx;
|
||||
xor edx, edx;
|
||||
mov ebx, lines; // count text lines 0-5
|
||||
call dialog_out_;
|
||||
}
|
||||
}
|
||||
|
||||
long __fastcall DialogOutEx(const char* text, const char** textEx, long count, long flags) {
|
||||
long __fastcall DialogOutEx(const char* text, const char** textEx, long lines, long flags, long colors) {
|
||||
__asm {
|
||||
mov eax, 145; // Color index
|
||||
xor eax, eax;
|
||||
mov ebx, colors;// Color index
|
||||
mov al, bh;
|
||||
push flags; // flag
|
||||
and ebx, 0xFF
|
||||
push eax; // ColorMsg2
|
||||
push 0; // DisplayMsg (unknown)
|
||||
push eax; // ColorMsg1
|
||||
mov eax, ecx; // DisplayText first line
|
||||
push 116; // y
|
||||
push ebx; // ColorMsg1
|
||||
mov ecx, 192; // x
|
||||
mov ebx, count; // count text lines 0-2
|
||||
call dialog_out_; // edx - DisplayText second/third line
|
||||
push 116; // y
|
||||
mov ebx, lines; // count text lines 0-5
|
||||
call dialog_out_; // edx - DisplayText second and later lines
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1186,9 +1186,9 @@ long __fastcall CreateWindowFunc(const char* winName, DWORD x, DWORD y, DWORD wi
|
||||
// creates a button
|
||||
long __stdcall WinRegisterButton(DWORD winRef, long xPos, long yPos, long width, long height, long hoverOn, long hoverOff, long buttonDown, long buttonUp, BYTE* pictureUp, BYTE* pictureDown, long arg12, long buttonType);
|
||||
|
||||
void __stdcall DialogOut(const char* text);
|
||||
void __fastcall DialogOut(const char* text, const char** textEx, long lines);
|
||||
|
||||
long __fastcall DialogOutEx(const char* text, const char** textEx, long count, long flags);
|
||||
long __fastcall DialogOutEx(const char* text, const char** textEx, long lines, long flags, long colors);
|
||||
|
||||
void __fastcall WindowDisplayBuf(long x, long width, long y, long height, void* data, long noTrans);
|
||||
|
||||
|
||||
@@ -417,11 +417,12 @@ static const SfallOpcodeMetadata opcodeMetaArray[] = {
|
||||
{sf_add_g_timer_event, "add_g_timer_event", {DATATYPE_MASK_INT, DATATYPE_MASK_INT}},
|
||||
{sf_add_trait, "add_trait", {DATATYPE_MASK_INT}},
|
||||
{sf_create_win, "create_win", {DATATYPE_MASK_STR, DATATYPE_MASK_INT, DATATYPE_MASK_INT, DATATYPE_MASK_INT, DATATYPE_MASK_INT, DATATYPE_MASK_INT}},
|
||||
{sf_dialog_box, "dialog_box", {DATATYPE_MASK_STR, DATATYPE_MASK_STR, DATATYPE_MASK_STR}},
|
||||
{sf_draw_image, "draw_image", {DATATYPE_MASK_INT | DATATYPE_MASK_STR, DATATYPE_MASK_INT, DATATYPE_MASK_INT, DATATYPE_MASK_INT, DATATYPE_MASK_INT}},
|
||||
{sf_draw_image_scaled, "draw_image_scaled", {DATATYPE_MASK_INT | DATATYPE_MASK_STR, DATATYPE_MASK_INT, DATATYPE_MASK_INT, DATATYPE_MASK_INT, DATATYPE_MASK_INT, DATATYPE_MASK_INT}},
|
||||
{sf_get_window_attribute, "get_window_attribute", {DATATYPE_MASK_INT, DATATYPE_MASK_INT}},
|
||||
{sf_hide_window, "hide_window", {DATATYPE_MASK_STR}},
|
||||
{sf_inventory_redraw, "inventory_redraw", {DATATYPE_MASK_INT}},
|
||||
{sf_message_box, "message_box", {DATATYPE_MASK_STR, DATATYPE_MASK_INT, DATATYPE_MASK_INT, DATATYPE_MASK_INT}},
|
||||
{sf_remove_timer_event, "remove_timer_event", {DATATYPE_MASK_INT}},
|
||||
{sf_set_cursor_mode, "set_cursor_mode", {DATATYPE_MASK_INT}},
|
||||
{sf_set_flags, "set_flags", {DATATYPE_MASK_VALID_OBJ, DATATYPE_MASK_INT}},
|
||||
|
||||
@@ -168,6 +168,20 @@ static void __declspec(naked) resume_game() {
|
||||
}
|
||||
}
|
||||
|
||||
// copy and split
|
||||
static void _stdcall SplitToBuffer(const char* str, const char** str_ptr, long &lines) {
|
||||
size_t i = 0;
|
||||
do {
|
||||
if (str[i] == '\n' && lines < 4) {
|
||||
gTextBuffer[i] = '\0';
|
||||
str_ptr[lines++] = &gTextBuffer[++i];
|
||||
} else {
|
||||
gTextBuffer[i] = str[i++];
|
||||
}
|
||||
} while (str[i]);
|
||||
gTextBuffer[i] = '\0';
|
||||
}
|
||||
|
||||
static void _stdcall create_message_window2() {
|
||||
const ScriptValue &strArg = opHandler.arg(0);
|
||||
if (strArg.isString()) {
|
||||
@@ -177,8 +191,12 @@ static void _stdcall create_message_window2() {
|
||||
const char* str = strArg.strValue();
|
||||
if (!str || str[0] == 0) return;
|
||||
|
||||
long lines = 0;
|
||||
const char* str_ptr[4];
|
||||
SplitToBuffer(str, str_ptr, lines);
|
||||
|
||||
dialogShow = true;
|
||||
DialogOut(str);
|
||||
DialogOut(gTextBuffer, str_ptr, lines);
|
||||
dialogShow = false;
|
||||
} else {
|
||||
OpcodeInvalidArgs("create_message_window");
|
||||
@@ -189,23 +207,28 @@ static void __declspec(naked) create_message_window() {
|
||||
_WRAP_OPCODE(create_message_window2, 1, 0)
|
||||
}
|
||||
|
||||
static void sf_dialog_box() {
|
||||
const char* str = opHandler.arg(0).strValue();
|
||||
if (!str || str[0] == 0) return;
|
||||
static void sf_message_box() {
|
||||
static u_short dialogShowCount = 0;
|
||||
|
||||
const char* str2[2];
|
||||
long lines = 0;
|
||||
if (opHandler.numArgs() > 1) {
|
||||
++lines;
|
||||
str2[0] = opHandler.arg(1).strValue();
|
||||
}
|
||||
const char* str_ptr[4];
|
||||
SplitToBuffer(opHandler.arg(0).asString(), str_ptr, lines);
|
||||
|
||||
long colors = 0x9191, flags = DIALOGOUT_NORMAL | DIALOGOUT_YESNO;
|
||||
if (opHandler.numArgs() > 1 && opHandler.arg(1).rawValue() != -1) flags = opHandler.arg(1).rawValue();
|
||||
if (opHandler.numArgs() > 2) {
|
||||
++lines;
|
||||
str2[1] = opHandler.arg(2).strValue();
|
||||
colors &= 0xFF00;
|
||||
colors |= (opHandler.arg(2).rawValue() & 0xFF);
|
||||
}
|
||||
if (opHandler.numArgs() > 3) {
|
||||
colors &= 0xFF;
|
||||
colors |= (opHandler.arg(3).rawValue() & 0xFF) << 8;
|
||||
}
|
||||
dialogShowCount++;
|
||||
*(DWORD*)_script_engine_running = 0;
|
||||
long result = DialogOutEx(str, str2, lines, DIALOGOUT_NORMAL | DIALOGOUT_YESNO);
|
||||
*(DWORD*)_script_engine_running = 1;
|
||||
long result = DialogOutEx(gTextBuffer, str_ptr, lines, flags, colors);
|
||||
if (--dialogShowCount == 0) *(DWORD*)_script_engine_running = 1;
|
||||
|
||||
opHandler.setReturn(result);
|
||||
}
|
||||
|
||||
@@ -715,43 +738,33 @@ static void sf_unwield_slot() {
|
||||
}
|
||||
|
||||
void sf_get_window_attribute() {
|
||||
const ScriptValue &winArg = opHandler.arg(0);
|
||||
if (winArg.isInt()) {
|
||||
long attr = 0;
|
||||
if (opHandler.numArgs() > 1) {
|
||||
const ScriptValue &attrArg = opHandler.arg(1);
|
||||
if (!attrArg.isInt()) goto invalidArgs;
|
||||
attr = attrArg.rawValue();
|
||||
}
|
||||
WINinfo* win = GetUIWindow(winArg.rawValue());
|
||||
if (win == nullptr) {
|
||||
if (attr != 0) {
|
||||
opHandler.printOpcodeError("get_window_attribute() - failed to get the interface window.");
|
||||
opHandler.setReturn(-1);
|
||||
}
|
||||
return;
|
||||
}
|
||||
if ((long)win == -1) {
|
||||
opHandler.printOpcodeError("get_window_attribute() - invalid window type number.");
|
||||
long attr = 0;
|
||||
if (opHandler.numArgs() > 1) attr = opHandler.arg(1).rawValue();
|
||||
|
||||
WINinfo* win = GetUIWindow(opHandler.arg(0).rawValue());
|
||||
if (win == nullptr) {
|
||||
if (attr != 0) {
|
||||
opHandler.printOpcodeError("get_window_attribute() - failed to get the interface window.");
|
||||
opHandler.setReturn(-1);
|
||||
return;
|
||||
}
|
||||
long result = 0;
|
||||
switch (attr) {
|
||||
case 0: // check if window exists
|
||||
result = 1;
|
||||
break;
|
||||
case 1: // x
|
||||
result = win->wRect.left;
|
||||
break;
|
||||
case 2: // y
|
||||
result = win->wRect.top;
|
||||
break;
|
||||
}
|
||||
opHandler.setReturn(result);
|
||||
} else {
|
||||
invalidArgs:
|
||||
OpcodeInvalidArgs("get_window_attribute");
|
||||
opHandler.setReturn(0);
|
||||
return;
|
||||
}
|
||||
if ((long)win == -1) {
|
||||
opHandler.printOpcodeError("get_window_attribute() - invalid window type number.");
|
||||
opHandler.setReturn(-1);
|
||||
return;
|
||||
}
|
||||
long result = 0;
|
||||
switch (attr) {
|
||||
case 0: // check if window exists
|
||||
result = 1;
|
||||
break;
|
||||
case 1: // x
|
||||
result = win->wRect.left;
|
||||
break;
|
||||
case 2: // y
|
||||
result = win->wRect.top;
|
||||
break;
|
||||
}
|
||||
opHandler.setReturn(result);
|
||||
}
|
||||
|
||||
@@ -126,7 +126,6 @@ static const SfallMetarule metaruleArray[] = {
|
||||
{"create_win", sf_create_win, 5, 6},
|
||||
{"critter_inven_obj2", sf_critter_inven_obj2, 2, 2},
|
||||
{"dialog_obj", sf_get_dialog_object, 0, 0},
|
||||
{"dialog_box", sf_dialog_box, 1, 3},
|
||||
{"display_stats", sf_display_stats, 0, 0}, // refresh
|
||||
{"draw_image", sf_draw_image, 1, 5},
|
||||
{"draw_image_scaled", sf_draw_image_scaled, 1, 6},
|
||||
@@ -152,6 +151,7 @@ static const SfallMetarule metaruleArray[] = {
|
||||
{"item_weight", sf_item_weight, 1, 1},
|
||||
{"lock_is_jammed", sf_lock_is_jammed, 1, 1},
|
||||
{"loot_obj", sf_get_loot_object, 0, 0},
|
||||
{"message_box", sf_message_box, 1, 4},
|
||||
{"metarule_exist", sf_metarule_exist, 1, 1},
|
||||
{"npc_engine_level_up", sf_npc_engine_level_up, 1, 1},
|
||||
{"obj_under_cursor", sf_obj_under_cursor, 2, 2},
|
||||
|
||||
Reference in New Issue
Block a user