mirror of
https://github.com/sfall-team/sfall.git
synced 2026-07-27 16:52:34 -07:00
Added "get_text_width" and "string_compare" script functions
Fixed the return value of charcode script function for characters in the extended ASCII character set. Rewrote set_dm/df_model, set_movie_path functions in C++.
This commit is contained in:
@@ -280,6 +280,7 @@
|
||||
#define get_outline(obj) sfall_func1("get_outline", obj)
|
||||
#define get_sfall_arg_at(argNum) sfall_func1("get_sfall_arg_at", argNum)
|
||||
#define get_string_pointer(text) sfall_func1("get_string_pointer", text)
|
||||
#define get_text_width(text) sfall_func1("get_text_width", text)
|
||||
#define has_fake_perk_npc(npc, perk) sfall_func2("has_fake_perk_npc", npc, perk)
|
||||
#define has_fake_trait_npc(npc, trait) sfall_func2("has_fake_trait_npc", npc, trait)
|
||||
#define hide_window(winName) sfall_func1("hide_window", winName)
|
||||
@@ -313,13 +314,15 @@
|
||||
#define set_rest_heal_time(time) sfall_func1("set_rest_heal_time", time)
|
||||
#define set_rest_mode(mode) sfall_func1("set_rest_mode", mode)
|
||||
#define set_unique_id(obj) sfall_func1("set_unique_id", obj)
|
||||
#define unset_unique_id(obj) sfall_func2("set_unique_id", obj, -1)
|
||||
#define set_unjam_locks_time(time) sfall_func1("set_unjam_locks_time", time)
|
||||
#define set_window_flag(winID, flag, value) sfall_func3("set_window_flag", winID, flag, value)
|
||||
#define show_window(winName) sfall_func1("show_window", winName)
|
||||
#define spatial_radius(obj) sfall_func1("spatial_radius", obj)
|
||||
#define string_compare(str1, str2) sfall_func2("string_compare", str1, str2)
|
||||
#define string_compare_locale(str1, str2, codePage) sfall_func3("string_compare", str1, str2, codePage)
|
||||
#define tile_refresh_display sfall_func0("tile_refresh_display")
|
||||
#define unjam_lock(obj) sfall_func1("unjam_lock", obj)
|
||||
#define unset_unique_id(obj) sfall_func2("set_unique_id", obj, -1)
|
||||
#define unwield_slot(critter, slot) sfall_func2("unwield_slot", critter, slot)
|
||||
|
||||
#define set_fake_perk_npc(npc, perk, level, image, desc) sfall_func5("set_fake_perk_npc", npc, perk, level, image, desc)
|
||||
|
||||
@@ -601,8 +601,8 @@ Some utility/math functions are available:
|
||||
|
||||
> void sfall_func5("draw_image", string/int pathFile/artId, int frame, int x, int y, bool noTransparent)
|
||||
> 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)
|
||||
- displays the specified PCX or FRM image in the active window created by vanilla CreateWin or sfall's create_win script function
|
||||
- pathFile/artId: path to the PCX/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
|
||||
@@ -669,6 +669,15 @@ optional argument:
|
||||
- flag: the flag to change (see WIN_FLAG_* constants in define_extra.h)
|
||||
- value: true - set the flag, false - unset the flag
|
||||
|
||||
> int sfall_func1("get_text_width", string text)
|
||||
- returns the text width in pixels for the currently set font
|
||||
|
||||
> bool sfall_func2("string_compare", string str1, string str2)
|
||||
> bool sfall_func3("string_compare", string str1, string str2, int codePage)
|
||||
- compares two strings case-insensitive, and returns True if the two strings are matched
|
||||
- codePage: code page number to properly compare national characters in the range 128-255 of the ASCII code table
|
||||
available encodings: 1250-1252, 866
|
||||
|
||||
------------------------
|
||||
------ MORE INFO -------
|
||||
------------------------
|
||||
|
||||
@@ -211,14 +211,11 @@ DWORD GetTextHeight() {
|
||||
|
||||
//---------------------------------------------------------
|
||||
//gets the length of a string using the currently selected font
|
||||
DWORD GetTextWidth(char *TextMsg) {
|
||||
DWORD TxtWidth;
|
||||
DWORD GetTextWidth(const char *TextMsg) {
|
||||
__asm {
|
||||
mov eax, TextMsg;
|
||||
call dword ptr ds:[FO_VAR_text_width]; //get text width
|
||||
mov TxtWidth, eax;
|
||||
}
|
||||
return TxtWidth;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------
|
||||
|
||||
@@ -81,7 +81,7 @@ void PrintText(char *displayText, BYTE colorIndex, DWORD x, DWORD y, DWORD textW
|
||||
// gets the height of the currently selected font
|
||||
DWORD GetTextHeight();
|
||||
// gets the length of a string using the currently selected font
|
||||
DWORD GetTextWidth(char *textMsg);
|
||||
DWORD GetTextWidth(const char *textMsg);
|
||||
// get width of Char for current font
|
||||
DWORD GetCharWidth(char charVal);
|
||||
// get maximum string length for current font - if all characters were maximum width
|
||||
|
||||
@@ -90,6 +90,7 @@ static const SfallMetarule metarules[] = {
|
||||
{"get_outline", sf_get_outline, 1, 1, {ARG_OBJECT}},
|
||||
{"get_sfall_arg_at", sf_get_sfall_arg_at, 1, 1, {ARG_INT}},
|
||||
{"get_string_pointer", sf_get_string_pointer, 1, 1, {ARG_STRING}},
|
||||
{"get_text_width", sf_get_text_width, 1, 1},
|
||||
{"has_fake_perk_npc", sf_has_fake_perk_npc, 2, 2, {ARG_OBJECT, ARG_STRING}},
|
||||
{"has_fake_trait_npc", sf_has_fake_trait_npc, 2, 2, {ARG_OBJECT, ARG_STRING}},
|
||||
{"hide_window", sf_hide_window, 0, 1, {ARG_STRING}},
|
||||
@@ -129,6 +130,7 @@ static const SfallMetarule metarules[] = {
|
||||
{"set_window_flag", sf_set_window_flag, 3, 3, {ARG_INTSTR, ARG_INT, ARG_INT}},
|
||||
{"show_window", sf_show_window, 0, 1, {ARG_STRING}},
|
||||
{"spatial_radius", sf_spatial_radius, 1, 1, {ARG_OBJECT}},
|
||||
{"string_compare", sf_string_compare, 2, 3, {ARG_STRING, ARG_STRING, ARG_INT}},
|
||||
{"tile_refresh_display", sf_tile_refresh_display, 0, 0},
|
||||
{"unjam_lock", sf_unjam_lock, 1, 1, {ARG_OBJECT}},
|
||||
{"unwield_slot", sf_unwield_slot, 2, 2, {ARG_OBJECT, ARG_INT}},
|
||||
@@ -136,7 +138,7 @@ static const SfallMetarule metarules[] = {
|
||||
{"validate_test", sf_test, 2, 5, {ARG_INT, ARG_NUMBER, ARG_STRING, ARG_OBJECT, ARG_ANY}},
|
||||
#endif
|
||||
};
|
||||
//
|
||||
|
||||
// returns current contents of metarule table
|
||||
static void sf_get_metarule_table(OpcodeContext& ctx) {
|
||||
DWORD arrId = TempArray(metaruleTable.size(), 0);
|
||||
|
||||
@@ -42,129 +42,35 @@ namespace sfall
|
||||
namespace script
|
||||
{
|
||||
|
||||
static DWORD defaultMaleModelNamePtr = (DWORD)defaultMaleModelName;
|
||||
static DWORD defaultFemaleModelNamePtr = (DWORD)defaultFemaleModelName;
|
||||
static DWORD movieNamesPtr = (DWORD)MoviePaths;
|
||||
const char* stringTooLong = "%s() - the string length exceeds maximum of 64 characters.";
|
||||
|
||||
|
||||
//// *** End Helios *** ///
|
||||
static void _stdcall strcpy_p(char* to, const char* from) {
|
||||
strcpy_s(to, 64, from);
|
||||
void sf_set_dm_model(OpcodeContext& ctx) {
|
||||
auto model = ctx.arg(0).strValue();
|
||||
if (strlen(model) > 64) {
|
||||
ctx.printOpcodeError(stringTooLong, ctx.getOpcodeName());
|
||||
return;
|
||||
}
|
||||
strcpy(defaultMaleModelName, model);
|
||||
}
|
||||
|
||||
/************************************************************************/
|
||||
/* TODO: Rewrite these raw handlers using OpcodeContext */
|
||||
/************************************************************************/
|
||||
|
||||
void __declspec(naked) op_set_dm_model() {
|
||||
__asm {
|
||||
push ebx;
|
||||
push ecx;
|
||||
push edx;
|
||||
push edi;
|
||||
mov edi, eax;
|
||||
call fo::funcoffs::interpretPopShort_;
|
||||
mov edx, eax;
|
||||
mov eax, edi;
|
||||
call fo::funcoffs::interpretPopLong_;
|
||||
cmp dx, VAR_TYPE_STR2;
|
||||
jz next;
|
||||
cmp dx, VAR_TYPE_STR;
|
||||
jnz end;
|
||||
next:
|
||||
mov ebx, eax;
|
||||
mov eax, edi;
|
||||
call fo::funcoffs::interpretGetString_;
|
||||
push eax;
|
||||
push defaultMaleModelNamePtr;
|
||||
call strcpy_p;
|
||||
end:
|
||||
pop edi;
|
||||
pop edx;
|
||||
pop ecx;
|
||||
pop ebx;
|
||||
retn;
|
||||
void sf_set_df_model(OpcodeContext& ctx) {
|
||||
auto model = ctx.arg(0).strValue();
|
||||
if (strlen(model) > 64) {
|
||||
ctx.printOpcodeError(stringTooLong, ctx.getOpcodeName());
|
||||
return;
|
||||
}
|
||||
strcpy(defaultFemaleModelName, model);
|
||||
}
|
||||
|
||||
void __declspec(naked) op_set_df_model() {
|
||||
__asm {
|
||||
push ebx;
|
||||
push ecx;
|
||||
push edx;
|
||||
push edi;
|
||||
mov edi, eax;
|
||||
call fo::funcoffs::interpretPopShort_;
|
||||
mov edx, eax;
|
||||
mov eax, edi;
|
||||
call fo::funcoffs::interpretPopLong_;
|
||||
cmp dx, VAR_TYPE_STR2;
|
||||
jz next;
|
||||
cmp dx, VAR_TYPE_STR;
|
||||
jnz end;
|
||||
next:
|
||||
mov ebx, eax;
|
||||
mov eax, edi;
|
||||
call fo::funcoffs::interpretGetString_;
|
||||
push eax;
|
||||
push defaultFemaleModelNamePtr;
|
||||
call strcpy_p;
|
||||
end:
|
||||
pop edi;
|
||||
pop edx;
|
||||
pop ecx;
|
||||
pop ebx;
|
||||
retn;
|
||||
}
|
||||
}
|
||||
|
||||
void __declspec(naked) op_set_movie_path() {
|
||||
__asm {
|
||||
push ebx;
|
||||
push ecx;
|
||||
push edx;
|
||||
push edi;
|
||||
push esi;
|
||||
mov edi, eax;
|
||||
call fo::funcoffs::interpretPopShort_;
|
||||
mov ebx, eax;
|
||||
mov eax, edi;
|
||||
call fo::funcoffs::interpretPopLong_;
|
||||
mov esi, eax;
|
||||
mov eax, edi;
|
||||
call fo::funcoffs::interpretPopShort_;
|
||||
mov edx, eax;
|
||||
mov eax, edi;
|
||||
call fo::funcoffs::interpretPopLong_;
|
||||
cmp dx, VAR_TYPE_STR2;
|
||||
jz next;
|
||||
cmp dx, VAR_TYPE_STR;
|
||||
jnz end;
|
||||
next:
|
||||
cmp bx, VAR_TYPE_INT;
|
||||
jnz end;
|
||||
cmp esi, 0;
|
||||
jl end;
|
||||
cmp esi, MaxMovies;
|
||||
jge end;
|
||||
mov ebx, eax;
|
||||
mov eax, edi;
|
||||
call fo::funcoffs::interpretGetString_;
|
||||
push eax;
|
||||
mov eax, esi;
|
||||
mov esi, 65;
|
||||
mul si;
|
||||
add eax, movieNamesPtr;
|
||||
push eax;
|
||||
call strcpy_p;
|
||||
end:
|
||||
pop esi;
|
||||
pop edi;
|
||||
pop edx;
|
||||
pop ecx;
|
||||
pop ebx;
|
||||
retn;
|
||||
void sf_set_movie_path(OpcodeContext& ctx) {
|
||||
long movieID = ctx.arg(1).rawValue();
|
||||
if (movieID < 0 || movieID >= MaxMovies) return;
|
||||
auto fileName = ctx.arg(0).strValue();
|
||||
if (strlen(fileName) > 64) {
|
||||
ctx.printOpcodeError(stringTooLong, ctx.getOpcodeName());
|
||||
return;
|
||||
}
|
||||
strcpy(&MoviePaths[movieID * 65], fileName);
|
||||
}
|
||||
|
||||
void sf_get_year(OpcodeContext& ctx) {
|
||||
@@ -181,14 +87,12 @@ void sf_get_year(OpcodeContext& ctx) {
|
||||
void __declspec(naked) op_game_loaded() {
|
||||
__asm {
|
||||
push ecx;
|
||||
push edx;
|
||||
push eax;
|
||||
push eax; // script
|
||||
call ScriptHasLoaded;
|
||||
movzx edx, al;
|
||||
pop eax;
|
||||
_RET_VAL_INT(ecx);
|
||||
pop edx;
|
||||
pop ecx;
|
||||
retn;
|
||||
}
|
||||
@@ -197,15 +101,13 @@ void __declspec(naked) op_game_loaded() {
|
||||
void __declspec(naked) op_set_pipboy_available() {
|
||||
__asm {
|
||||
push ecx;
|
||||
push edx;
|
||||
_GET_ARG_INT(end);
|
||||
cmp eax, 0;
|
||||
jl end;
|
||||
cmp eax, 1;
|
||||
jg end;
|
||||
mov byte ptr ds:[FO_VAR_gmovie_played_list + 0x3], al;
|
||||
mov byte ptr ds:[FO_VAR_gmovie_played_list][0x3], al;
|
||||
end:
|
||||
pop edx;
|
||||
pop ecx;
|
||||
retn;
|
||||
}
|
||||
@@ -795,17 +697,6 @@ end:
|
||||
//numbers subgame functions
|
||||
void __declspec(naked) op_nb_create_char() {
|
||||
__asm {
|
||||
/*pushad;
|
||||
push eax;
|
||||
call NumbersCreateChar;
|
||||
mov edx, eax;
|
||||
pop eax;
|
||||
mov ecx, eax;
|
||||
call fo::funcoffs::interpretPushLong_;
|
||||
mov eax, ecx;
|
||||
mov edx, VAR_TYPE_INT;
|
||||
call fo::funcoffs::interpretPushShort_;
|
||||
popad;*/
|
||||
retn;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -29,13 +29,11 @@ namespace script
|
||||
|
||||
class OpcodeContext;
|
||||
|
||||
// TODO: rewrite all op_* functions using OpcodeContext
|
||||
void sf_set_dm_model(OpcodeContext&);
|
||||
|
||||
void __declspec() op_set_dm_model();
|
||||
void sf_set_df_model(OpcodeContext&);
|
||||
|
||||
void __declspec() op_set_df_model();
|
||||
|
||||
void __declspec() op_set_movie_path();
|
||||
void sf_set_movie_path(OpcodeContext&);
|
||||
|
||||
void sf_get_year(OpcodeContext&);
|
||||
|
||||
|
||||
@@ -19,6 +19,7 @@
|
||||
#include <cmath>
|
||||
|
||||
#include "..\..\..\FalloutEngine\Fallout2.h"
|
||||
#include "..\..\..\FalloutEngine\EngineUtils.h"
|
||||
#include "..\..\ScriptExtender.h"
|
||||
#include "..\..\FileSystem.h"
|
||||
#include "..\..\Message.h"
|
||||
@@ -33,6 +34,69 @@ namespace sfall
|
||||
namespace script
|
||||
{
|
||||
|
||||
// compares strings case-insensitive with specifics for Fallout
|
||||
static bool FalloutStringCompare(const char* str1, const char* str2, long codePage) {
|
||||
while (true) {
|
||||
unsigned char c1 = *str1;
|
||||
unsigned char c2 = *str2;
|
||||
if (c1 == 0 && c2 == 0) return true; // end - strings are equal
|
||||
if (c1 == 0 || c2 == 0) return false; // strings are not equal
|
||||
str1++;
|
||||
str2++;
|
||||
if (c1 == c2) continue;
|
||||
if (codePage == 866) {
|
||||
// replace Russian 'x' to English (Fallout specific)
|
||||
if (c1 == 229) c1 -= 229 - 'x';
|
||||
if (c2 == 229) c2 -= 229 - 'x';
|
||||
}
|
||||
|
||||
// 0 - 127 (standard ASCII)
|
||||
// upper to lower case
|
||||
if (c1 >= 'A' && c1 <= 'Z') c1 |= 32;
|
||||
if (c2 >= 'A' && c2 <= 'Z') c2 |= 32;
|
||||
if (c1 == c2) continue;
|
||||
if (c1 < 128 || c2 < 128) return false;
|
||||
|
||||
// 128 - 255 (international/extended)
|
||||
switch (codePage) {
|
||||
case 866:
|
||||
if (c1 != 149 && c2 != 149) {
|
||||
// upper to lower case
|
||||
if (c1 >= 0x80 && c1 <= 0x9F) {
|
||||
c1 |= 32;
|
||||
} else if (c1 >= 224 && c1 <= 239) {
|
||||
c1 -= 48; // shift lower range
|
||||
} else if (c1 == 240) {
|
||||
c1++;
|
||||
}
|
||||
if (c2 >= 0x80 && c2 <= 0x9F) {
|
||||
c2 |= 32;
|
||||
} else if (c2 >= 224 && c2 <= 239) {
|
||||
c2 -= 48; // shift lower range
|
||||
} else if (c2 == 240) {
|
||||
c2++;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 1251:
|
||||
// upper to lower case
|
||||
if (c1 >= 0xC0 && c1 <= 0xDF) c1 |= 32;
|
||||
if (c2 >= 0xC0 && c2 <= 0xDF) c2 |= 32;
|
||||
if (c1 == 0xA8) c1 += 16;
|
||||
if (c2 == 0xA8) c2 += 16;
|
||||
break;
|
||||
case 1250:
|
||||
case 1252:
|
||||
if (c1 != 0xD7 && c1 != 0xF7 && c2 != 0xD7 && c2 != 0xF7) {
|
||||
if (c1 >= 0xC0 && c1 <= 0xDE) c1 |= 32;
|
||||
if (c2 >= 0xC0 && c2 <= 0xDE) c2 |= 32;
|
||||
}
|
||||
break;
|
||||
}
|
||||
if (c1 != c2) return false; // strings are not equal
|
||||
}
|
||||
}
|
||||
|
||||
void sf_sqrt(OpcodeContext& ctx) {
|
||||
ctx.setReturn(sqrt(ctx.arg(0).asFloat()));
|
||||
}
|
||||
@@ -68,22 +132,22 @@ void sf_strlen(OpcodeContext& ctx) {
|
||||
}
|
||||
|
||||
void sf_atoi(OpcodeContext& ctx) {
|
||||
auto str = ctx.arg(0).asString();
|
||||
auto str = ctx.arg(0).strValue();
|
||||
ctx.setReturn(
|
||||
static_cast<int>(strtol(str, (char**)nullptr, 0)) // auto-determine radix
|
||||
);
|
||||
}
|
||||
|
||||
void sf_atof(OpcodeContext& ctx) {
|
||||
auto str = ctx.arg(0).asString();
|
||||
auto str = ctx.arg(0).strValue();
|
||||
ctx.setReturn(
|
||||
static_cast<float>(atof(str))
|
||||
);
|
||||
}
|
||||
|
||||
void sf_ord(OpcodeContext& ctx) {
|
||||
char firstChar = ctx.arg(0).asString()[0];
|
||||
ctx.setReturn(static_cast<int>(firstChar));
|
||||
unsigned char firstChar = ctx.arg(0).strValue()[0];
|
||||
ctx.setReturn(static_cast<unsigned long>(firstChar));
|
||||
}
|
||||
|
||||
void sf_typeof(OpcodeContext& ctx) {
|
||||
@@ -123,10 +187,10 @@ static int _stdcall StringSplit(const char* str, const char* split) {
|
||||
}
|
||||
|
||||
void sf_string_split(OpcodeContext& ctx) {
|
||||
ctx.setReturn(StringSplit(ctx.arg(0).asString(), ctx.arg(1).asString()));
|
||||
ctx.setReturn(StringSplit(ctx.arg(0).strValue(), ctx.arg(1).strValue()));
|
||||
}
|
||||
|
||||
char* _stdcall Substring(const char* str, int pos, int length) {
|
||||
char* Substring(const char* str, int pos, int length) {
|
||||
char* newstr;
|
||||
int srclen;
|
||||
srclen = strlen(str);
|
||||
@@ -138,7 +202,7 @@ char* _stdcall Substring(const char* str, int pos, int length) {
|
||||
length = 0;
|
||||
else if (length + pos > srclen)
|
||||
length = srclen - pos;
|
||||
newstr = new char[length + 1];
|
||||
newstr = new char[length + 1]; // memory leak!!!
|
||||
if (length > 0)
|
||||
memcpy(newstr, &str[pos], length);
|
||||
newstr[length] = '\0';
|
||||
@@ -147,10 +211,20 @@ char* _stdcall Substring(const char* str, int pos, int length) {
|
||||
|
||||
void sf_substr(OpcodeContext& ctx) {
|
||||
ctx.setReturn(
|
||||
Substring(ctx.arg(0).asString(), ctx.arg(1).asInt(), ctx.arg(2).asInt())
|
||||
Substring(ctx.arg(0).strValue(), ctx.arg(1).rawValue(), ctx.arg(2).rawValue())
|
||||
);
|
||||
}
|
||||
|
||||
void sf_string_compare(OpcodeContext& ctx) {
|
||||
if (ctx.numArgs() < 3) {
|
||||
ctx.setReturn(
|
||||
(_stricmp(ctx.arg(0).strValue(), ctx.arg(1).strValue()) ? 0 : 1)
|
||||
);
|
||||
} else {
|
||||
ctx.setReturn(FalloutStringCompare(ctx.arg(0).strValue(), ctx.arg(1).strValue(), ctx.arg(2).rawValue()));
|
||||
}
|
||||
}
|
||||
|
||||
static char* sprintfbuf = nullptr;
|
||||
// A safer version of sprintf for using in user scripts.
|
||||
static char* _stdcall sprintf_lite(const char* format, ScriptValue value) {
|
||||
@@ -232,7 +306,7 @@ static char* _stdcall sprintf_lite(const char* format, ScriptValue value) {
|
||||
|
||||
void sf_sprintf(OpcodeContext& ctx) {
|
||||
ctx.setReturn(
|
||||
sprintf_lite(ctx.arg(0).asString(), ctx.arg(1))
|
||||
sprintf_lite(ctx.arg(0).strValue(), ctx.arg(1))
|
||||
);
|
||||
}
|
||||
|
||||
@@ -315,7 +389,11 @@ void sf_floor2(OpcodeContext& ctx) {
|
||||
}
|
||||
|
||||
void sf_get_string_pointer(OpcodeContext& ctx) {
|
||||
ctx.setReturn(reinterpret_cast<long>(ctx.arg(0).asString()), DataType::INT);
|
||||
ctx.setReturn(reinterpret_cast<long>(ctx.arg(0).strValue()), DataType::INT);
|
||||
}
|
||||
|
||||
void sf_get_text_width(OpcodeContext& ctx) {
|
||||
ctx.setReturn(fo::GetTextWidth(ctx.arg(0).asString()));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -23,6 +23,8 @@ namespace sfall
|
||||
namespace script
|
||||
{
|
||||
|
||||
char* Substring(const char* str, int pos, int length);
|
||||
|
||||
class OpcodeContext;
|
||||
|
||||
void sf_sqrt(OpcodeContext&);
|
||||
@@ -47,6 +49,8 @@ void sf_substr(OpcodeContext&);
|
||||
|
||||
void sf_strlen(OpcodeContext&);
|
||||
|
||||
void sf_string_compare(OpcodeContext&);
|
||||
|
||||
void sf_sprintf(OpcodeContext&);
|
||||
|
||||
void sf_ord(OpcodeContext&);
|
||||
@@ -71,7 +75,7 @@ void sf_floor2(OpcodeContext&);
|
||||
|
||||
void sf_get_string_pointer(OpcodeContext&);
|
||||
|
||||
char* _stdcall Substring(const char* str, int pos, int length);
|
||||
void sf_get_text_width(OpcodeContext&);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -33,10 +33,10 @@ OpcodeContext::OpcodeContext(fo::Program* program, DWORD opcode, int argNum, boo
|
||||
assert(argNum < OP_MAX_ARGUMENTS);
|
||||
}
|
||||
|
||||
OpcodeContext::OpcodeContext(fo::Program* program, DWORD opcode, int argNum, bool hasReturn, const char* opcodeName)
|
||||
: OpcodeContext::OpcodeContext(program, opcode, argNum, hasReturn)
|
||||
OpcodeContext::OpcodeContext(fo::Program* program, const SfallOpcodeInfo* info)
|
||||
: _program(program), _opcode(info->opcode), _numArgs(info->argNum), _hasReturn(info->hasReturn), _opcodeName(info->name), _argShift(0)
|
||||
{
|
||||
_opcodeName = opcodeName;
|
||||
assert(_numArgs < OP_MAX_ARGUMENTS);
|
||||
}
|
||||
|
||||
const char* OpcodeContext::getOpcodeName() const {
|
||||
|
||||
@@ -92,7 +92,7 @@ public:
|
||||
// hasReturn - true if opcode has return value (is expression)
|
||||
// opcodeName - name of a function (for logging)
|
||||
OpcodeContext(fo::Program* program, DWORD opcode, int argNum, bool hasReturn);
|
||||
OpcodeContext(fo::Program* program, DWORD opcode, int argNum, bool hasReturn, const char* opcodeName);
|
||||
OpcodeContext(fo::Program* program, const SfallOpcodeInfo* info);
|
||||
|
||||
const char* getOpcodeName() const;
|
||||
const char* getMetaruleName() const;
|
||||
|
||||
@@ -74,6 +74,9 @@ static SfallOpcodeInfo opcodeInfoArray[] = {
|
||||
{0x163, "get_year", sf_get_year, 0, true},
|
||||
{0x16c, "key_pressed", sf_key_pressed, 1, true, {ARG_INT}},
|
||||
{0x171, "force_encounter", sf_force_encounter, 1, false, {ARG_INT}},
|
||||
{0x175, "set_dm_model", sf_set_dm_model, 1, false, {ARG_STRING}},
|
||||
{0x176, "set_df_model", sf_set_df_model, 1, false, {ARG_STRING}},
|
||||
{0x177, "set_movie_path", sf_set_movie_path, 2, false, {ARG_STRING, ARG_INT}},
|
||||
|
||||
{0x190, "get_perk_available", sf_get_perk_available, 1, true, {ARG_INT}},
|
||||
{0x195, "set_weapon_knockback", sf_set_object_knockback, 3, false, {ARG_OBJECT, ARG_INT, ARG_NUMBER}},
|
||||
@@ -165,7 +168,7 @@ static SfallOpcodeInfo opcodeInfoArray[] = {
|
||||
{0x241, "get_npc_level", sf_get_npc_level, 1, true, {ARG_INTSTR}},
|
||||
|
||||
{0x24e, "substr", sf_substr, 3, true, {ARG_STRING, ARG_INT, ARG_INT}},
|
||||
{0x24f, "strlen", sf_strlen, 1, true, {ARG_STRING}},
|
||||
{0x24f, "strlen", sf_strlen, 1, true},
|
||||
{0x250, "sprintf", sf_sprintf, 2, true, {ARG_STRING, ARG_ANY}},
|
||||
{0x251, "charcode", sf_ord, 1, true, {ARG_STRING}},
|
||||
// 0x252 // RESERVED
|
||||
@@ -238,7 +241,7 @@ void __fastcall defaultOpcodeHandlerCall(fo::Program* program, DWORD opcodeOffse
|
||||
auto iter = opcodeInfoMap.find(opcode);
|
||||
if (iter != opcodeInfoMap.end()) {
|
||||
auto info = iter->second;
|
||||
OpcodeContext ctx(program, opcode, info->argNum, info->hasReturn, info->name);
|
||||
OpcodeContext ctx(program, info);
|
||||
ctx.handleOpcode(info->handler, info->argValidation);
|
||||
} else {
|
||||
fo::func::interpretError("Unknown opcode: %d", opcode);
|
||||
@@ -298,9 +301,7 @@ void InitNewOpcodes() {
|
||||
opcodes[0x172] = op_set_world_map_pos;
|
||||
opcodes[0x173] = op_get_world_map_x_pos;
|
||||
opcodes[0x174] = op_get_world_map_y_pos;
|
||||
opcodes[0x175] = op_set_dm_model;
|
||||
opcodes[0x176] = op_set_df_model;
|
||||
opcodes[0x177] = op_set_movie_path;
|
||||
|
||||
for (int i = 0x178; i < 0x189; i++) {
|
||||
opcodes[i] = op_set_perk_value;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user