mirror of
https://github.com/sfall-team/sfall.git
synced 2026-07-27 16:52:34 -07:00
Added "string_format" script function
Rewrote ASM code of opcode handlers in MemoryOp.hpp.
This commit is contained in:
@@ -277,6 +277,7 @@
|
||||
#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 string_format(format, a1, a2) sfall_func3("string_format", format, a1, a2)
|
||||
#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)
|
||||
|
||||
@@ -248,7 +248,7 @@ Some utility/math functions are available:
|
||||
- you can use this to search for a substring in a string like this: strlen(get_array(string_split(haystack, needle), 0))
|
||||
|
||||
> string substr(string, start, length)
|
||||
- cuts a substring from a string starting at "start" up to "length" characters. The first character position starts with 0 (zero).
|
||||
- cuts a substring from a string starting at "start" up to "length" characters. The first character position is 0 (zero).
|
||||
- If start is negative - it indicates starting position from the end of the string (for example substr("test", -2, 2) will return last 2 charactes: "st").
|
||||
- If length is negative - it means so many characters will be omitted from the end of string (example: substr("test", 0, -2) will return string without last 2 characters: "te").
|
||||
- If length is zero - it will return a string from the starting position to the end of the string **New behavior** for sfall 4.2.2/3.8.22
|
||||
@@ -588,6 +588,10 @@ optional arguments:
|
||||
- codePage: code page number to properly compare national characters in the range 128-255 of the ASCII code table
|
||||
available encodings: 1250-1252, 866
|
||||
|
||||
> string sfall_func3("string_format", string format, any val1, any val2, ...)
|
||||
- formats given value using standard syntax of C printf function (google "printf" for format details). However it is limited to formatting up to 4 values
|
||||
- formatting is only supported for %s and %d. The format string is limited to 1024 characters
|
||||
|
||||
------------------------
|
||||
------ MORE INFO -------
|
||||
------------------------
|
||||
|
||||
@@ -979,11 +979,10 @@ DWORD __stdcall InterpretAddString(TProgram* scriptPtr, const char* strval) {
|
||||
}
|
||||
}
|
||||
|
||||
const char* __stdcall InterpretGetString(TProgram* scriptPtr, DWORD strId, DWORD dataType) {
|
||||
const char* __fastcall InterpretGetString(TProgram* scriptPtr, DWORD dataType, DWORD strId) {
|
||||
__asm {
|
||||
mov edx, dataType;
|
||||
mov ebx, strId;
|
||||
mov eax, scriptPtr;
|
||||
mov eax, ecx;
|
||||
call interpretGetString_;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1084,7 +1084,7 @@ void __stdcall InterpretPushLong(TProgram* scriptPtr, DWORD val);
|
||||
// pushes value type to Data stack (must be preceded by InterpretPushLong)
|
||||
void __stdcall InterpretPushShort(TProgram* scriptPtr, DWORD valType);
|
||||
|
||||
const char* __stdcall InterpretGetString(TProgram* scriptPtr, DWORD strId, DWORD dataType);
|
||||
const char* __fastcall InterpretGetString(TProgram* scriptPtr, DWORD dataType, DWORD strId);
|
||||
|
||||
DWORD __stdcall InterpretAddString(TProgram* scriptPtr, const char* str);
|
||||
|
||||
|
||||
@@ -337,7 +337,7 @@ public:
|
||||
|
||||
// retrieve string argument
|
||||
if (type == DATATYPE_STR) {
|
||||
_args[i] = InterpretGetString(program, rawValue, rawValueType);
|
||||
_args[i] = InterpretGetString(program, rawValueType, rawValue);
|
||||
} else {
|
||||
_args[i] = ScriptValue(type, rawValue);
|
||||
}
|
||||
|
||||
@@ -42,6 +42,7 @@
|
||||
Gets argument from stack to eax and puts its type to edx register
|
||||
eax register must contain the script_ptr
|
||||
jlabel - name of the jump label in case the value type is not INT
|
||||
return: eax - arg value
|
||||
*/
|
||||
#define _GET_ARG_INT(jlabel) __asm { \
|
||||
__asm mov edx, eax \
|
||||
@@ -131,6 +132,13 @@ notstring##num:
|
||||
__asm call interpretPushShort_ \
|
||||
}
|
||||
|
||||
#define _J_RET_VAL_TYPE(type) __asm { \
|
||||
__asm call interpretPushLong_ \
|
||||
__asm mov edx, type \
|
||||
__asm mov eax, ebx \
|
||||
__asm jmp interpretPushShort_ \
|
||||
}
|
||||
|
||||
/*
|
||||
handle return value which may be of any type
|
||||
num - any unique number
|
||||
|
||||
+213
-280
File diff suppressed because it is too large
Load Diff
@@ -169,6 +169,7 @@ static const SfallMetarule metaruleArray[] = {
|
||||
{"show_window", sf_show_window, 0, 1},
|
||||
{"spatial_radius", sf_spatial_radius, 1, 1},
|
||||
{"string_compare", sf_string_compare, 2, 3},
|
||||
{"string_format", sf_string_format, 2, 5},
|
||||
{"tile_refresh_display", sf_tile_refresh_display, 0, 0},
|
||||
{"unjam_lock", sf_unjam_lock, 1, 1},
|
||||
{"unwield_slot", sf_unwield_slot, 2, 2},
|
||||
|
||||
@@ -591,7 +591,7 @@ char* _stdcall Substring(const char* str, int startPos, int length) {
|
||||
if (length < 0) {
|
||||
length += len - startPos; // cutoff at end
|
||||
if (length == 0) return "";
|
||||
abs(length); // length can't be negative
|
||||
length = abs(length); // length can't be negative
|
||||
}
|
||||
// check position
|
||||
if (startPos >= len) return ""; // start position is out of string length, return empty string
|
||||
@@ -782,6 +782,76 @@ fail:
|
||||
}
|
||||
}
|
||||
|
||||
static void sf_string_format() {
|
||||
const ScriptValue &fmtArg = opHandler.arg(0);
|
||||
|
||||
if (!fmtArg.isString()) {
|
||||
OpcodeInvalidArgs("string_format");
|
||||
opHandler.setReturn(0);
|
||||
return;
|
||||
}
|
||||
|
||||
const char* format = fmtArg.strValue();
|
||||
|
||||
int fmtLen = strlen(format);
|
||||
if (fmtLen == 0) {
|
||||
opHandler.setReturn(format);
|
||||
return;
|
||||
}
|
||||
if (fmtLen > 1024) {
|
||||
opHandler.printOpcodeError("string_format() - the format string exceeds maximum length of 1024 characters.");
|
||||
opHandler.setReturn("Error");
|
||||
} else {
|
||||
char* newFmt = new char[fmtLen + 1];
|
||||
newFmt[fmtLen] = '\0';
|
||||
// parse format to make it safe
|
||||
int i = 0, arg = 0, totalArg = opHandler.numArgs(); // total passed args
|
||||
do {
|
||||
char c = format[i];
|
||||
if (c == '%') {
|
||||
char cf = format[i + 1];
|
||||
if (cf != '%') {
|
||||
if (arg >= 0) {
|
||||
arg++;
|
||||
if (arg == totalArg) arg = -1; // format '%' prefixes in the format string exceed the number of passed value args
|
||||
}
|
||||
if (arg < 0) { // have % more than passed value args
|
||||
c = '^'; // delete %
|
||||
}
|
||||
// check string is valid or replace unsupported format
|
||||
else if ((cf == 's' && (arg > 0 && !opHandler.arg(arg).isString())) || (cf != 's' && cf != 'd')) {
|
||||
newFmt[i++] = c;
|
||||
c = 'd'; // replace with %d
|
||||
}
|
||||
} else {
|
||||
newFmt[i++] = cf; // skip %%
|
||||
}
|
||||
}
|
||||
newFmt[i] = c;
|
||||
} while (++i < fmtLen);
|
||||
|
||||
const long bufMaxLen = GlblTextBufferSize() - 1;
|
||||
|
||||
switch (totalArg) {
|
||||
case 2 :
|
||||
_snprintf(gTextBuffer, bufMaxLen, newFmt, opHandler.arg(1).rawValue());
|
||||
break;
|
||||
case 3 :
|
||||
_snprintf(gTextBuffer, bufMaxLen, newFmt, opHandler.arg(1).rawValue(), opHandler.arg(2).rawValue());
|
||||
break;
|
||||
case 4 :
|
||||
_snprintf(gTextBuffer, bufMaxLen, newFmt, opHandler.arg(1).rawValue(), opHandler.arg(2).rawValue(), opHandler.arg(3).rawValue());
|
||||
break;
|
||||
case 5 :
|
||||
_snprintf(gTextBuffer, bufMaxLen, newFmt, opHandler.arg(1).rawValue(), opHandler.arg(2).rawValue(), opHandler.arg(3).rawValue(), opHandler.arg(4).rawValue());
|
||||
}
|
||||
gTextBuffer[bufMaxLen] = '\0'; // just in case
|
||||
|
||||
delete[] newFmt;
|
||||
opHandler.setReturn(gTextBuffer);
|
||||
}
|
||||
}
|
||||
|
||||
static void funcPow2() {
|
||||
const ScriptValue &base = opHandler.arg(0),
|
||||
&power = opHandler.arg(1);
|
||||
|
||||
@@ -268,6 +268,7 @@ end:
|
||||
retn;
|
||||
}
|
||||
}
|
||||
|
||||
static void __declspec(naked) get_critter_skill_points() {
|
||||
__asm {
|
||||
pushad;
|
||||
|
||||
Reference in New Issue
Block a user