mirror of
https://github.com/fallout2-ce/fallout2-ce.git
synced 2026-07-27 16:47:11 -07:00
Implement all remaining sfall string functions (#184)
Implement string_to_case, and add comments for missing metarules/opcodes
string_find
string_compare
charcode
This should complete all string functions listed here that aren't deprecated.
* chore: auto-format with clang-format
* PR feedback
---------
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
This commit is contained in:
co-authored by
github-actions[bot]
parent
04e93cabd7
commit
41dd2ccd81
@@ -64,5 +64,19 @@ procedure start begin
|
||||
REPEAT_1024,
|
||||
REPEAT_1024)), 5119);
|
||||
|
||||
call assertEquals("string_tolower", string_tolower("miXeD CaSe"), "mixed case");
|
||||
call assertEquals("string_toupper", string_toupper("miXeD CaSe"), "MIXED CASE");
|
||||
|
||||
call assertEquals("string_find ok", string_find("Hello World", "World"), 6);
|
||||
call assertEquals("string_find missing", string_find("Hello World", "Zebra"), -1);
|
||||
call assertEquals("string_find_from", string_find_from("Hello World", "o", 6), 7);
|
||||
|
||||
call assertEquals("string_compare ok", string_compare("Hello World", "HeLlO WoRld"), 1);
|
||||
call assertEquals("string_compare neq", string_compare("Hello World", "HeLlO WoRld!"), 0);
|
||||
call assertEquals("string_compare_locale", string_compare_locale("Hello World", "HeLlO WoRld", 866), 1); // TODO: would be nice to compare cyrillic
|
||||
|
||||
call assertEquals("charcode", charcode("A"), 65);
|
||||
call assertEquals("charcode empty", charcode(""), 0);
|
||||
|
||||
call report_test_results("sprintf");
|
||||
end
|
||||
+221
-1
@@ -3,6 +3,7 @@
|
||||
#include <algorithm>
|
||||
#include <memory>
|
||||
#include <string.h>
|
||||
#include <string>
|
||||
|
||||
#include "combat.h"
|
||||
#include "debug.h"
|
||||
@@ -12,6 +13,7 @@
|
||||
#include "interface.h"
|
||||
#include "inventory.h"
|
||||
#include "object.h"
|
||||
#include "platform_compat.h"
|
||||
#include "sfall_ini.h"
|
||||
#include "text_font.h"
|
||||
#include "tile.h"
|
||||
@@ -48,28 +50,115 @@ static void mf_set_ini_setting(Program* program, int args);
|
||||
static void mf_set_outline(Program* program, int args);
|
||||
static void mf_show_window(Program* program, int args);
|
||||
static void mf_tile_refresh_display(Program* program, int args);
|
||||
static void mf_string_compare(Program* program, int args);
|
||||
static void mf_string_find(Program* program, int args);
|
||||
static void mf_string_to_case(Program* program, int args);
|
||||
static void mf_string_format(Program* program, int args);
|
||||
|
||||
// ref. https://github.com/sfall-team/sfall/blob/42556141127895c27476cd5242a73739cbb0fade/sfall/Modules/Scripting/Handlers/Metarule.cpp#L72
|
||||
constexpr MetaruleInfo kMetarules[] = {
|
||||
// {"add_extra_msg_file", mf_add_extra_msg_file, 1, 2, -1, {ARG_STRING, ARG_INT}},
|
||||
// {"add_iface_tag", mf_add_iface_tag, 0, 0},
|
||||
// {"add_g_timer_event", mf_add_g_timer_event, 2, 2, -1, {ARG_INT, ARG_INT}},
|
||||
// {"add_trait", mf_add_trait, 1, 1, -1, {ARG_INT}},
|
||||
// {"art_cache_clear", mf_art_cache_flush, 0, 0},
|
||||
// {"art_frame_data", mf_art_frame_data, 1, 3, 0, {ARG_INTSTR, ARG_INT, ARG_INT}},
|
||||
// {"attack_is_aimed", mf_attack_is_aimed, 0, 0},
|
||||
{ "car_gas_amount", mf_car_gas_amount, 0, 0 },
|
||||
{ "combat_data", mf_combat_data, 0, 0 },
|
||||
// {"create_win", mf_create_win, 5, 6, -1, {ARG_STRING, ARG_INT, ARG_INT, ARG_INT, ARG_INT, ARG_INT}},
|
||||
{ "critter_inven_obj2", mf_critter_inven_obj2, 2, 2 },
|
||||
// {"dialog_message", mf_dialog_message, 1, 1, -1, {ARG_STRING}},
|
||||
{ "dialog_obj", mf_dialog_obj, 0, 0 },
|
||||
// {"display_stats", mf_display_stats, 0, 0}, // refresh
|
||||
// {"draw_image", mf_draw_image, 1, 5, -1, {ARG_INTSTR, ARG_INT, ARG_INT, ARG_INT, ARG_INT}},
|
||||
// {"draw_image_scaled", mf_draw_image_scaled, 1, 6, -1, {ARG_INTSTR, ARG_INT, ARG_INT, ARG_INT, ARG_INT, ARG_INT}},
|
||||
// {"exec_map_update_scripts", mf_exec_map_update_scripts, 0, 0},
|
||||
// {"floor2", mf_floor2, 1, 1, 0, {ARG_NUMBER}},
|
||||
// {"get_can_rest_on_map", mf_get_rest_on_map, 2, 2, -1, {ARG_INT, ARG_INT}},
|
||||
// {"get_combat_free_move", mf_get_combat_free_move, 0, 0},
|
||||
// {"get_current_inven_size", mf_get_current_inven_size, 1, 1, 0, {ARG_OBJECT}},
|
||||
{ "get_cursor_mode", mf_get_cursor_mode, 0, 0 },
|
||||
{ "get_flags", mf_get_flags, 1, 1 },
|
||||
// {"get_ini_config", mf_get_ini_config, 2, 2, 0, {ARG_STRING, ARG_INT}},
|
||||
// {"get_ini_section", mf_get_ini_section, 2, 2, -1, {ARG_STRING, ARG_STRING}},
|
||||
// {"get_ini_sections", mf_get_ini_sections, 1, 1, -1, {ARG_STRING}},
|
||||
// {"get_inven_ap_cost", mf_get_inven_ap_cost, 0, 0},
|
||||
// {"get_map_enter_position", mf_get_map_enter_position, 0, 0},
|
||||
// {"get_metarule_table", mf_get_metarule_table, 0, 0},
|
||||
// {"get_object_ai_data", mf_get_object_ai_data, 2, 2, -1, {ARG_OBJECT, ARG_INT}},
|
||||
{ "get_object_data", mf_get_object_data, 2, 2 },
|
||||
// {"get_outline", mf_get_outline, 1, 1, 0, {ARG_OBJECT}},
|
||||
// {"get_sfall_arg_at", mf_get_sfall_arg_at, 1, 1, 0, {ARG_INT}},
|
||||
// {"get_stat_max", mf_get_stat_max, 1, 2, 0, {ARG_INT, ARG_INT}},
|
||||
// {"get_stat_min", mf_get_stat_min, 1, 2, 0, {ARG_INT, ARG_INT}},
|
||||
// {"get_string_pointer", mf_get_string_pointer, 1, 1, 0, {ARG_STRING}}, // note: deprecated; do not implement
|
||||
// {"get_terrain_name", mf_get_terrain_name, 0, 2, -1, {ARG_INT, ARG_INT}},
|
||||
{ "get_text_width", mf_get_text_width, 1, 1 },
|
||||
// {"get_window_attribute", mf_get_window_attribute, 1, 2, -1, {ARG_INT, ARG_INT}},
|
||||
// {"has_fake_perk_npc", mf_has_fake_perk_npc, 2, 2, 0, {ARG_OBJECT, ARG_STRING}},
|
||||
// {"has_fake_trait_npc", mf_has_fake_trait_npc, 2, 2, 0, {ARG_OBJECT, ARG_STRING}},
|
||||
// {"hide_window", mf_hide_window, 0, 1, -1, {ARG_STRING}},
|
||||
// {"interface_art_draw", mf_interface_art_draw, 4, 6, -1, {ARG_INT, ARG_INTSTR, ARG_INT, ARG_INT, ARG_INT, ARG_INT}},
|
||||
// {"interface_overlay", mf_interface_overlay, 2, 6, -1, {ARG_INT, ARG_INT, ARG_INT, ARG_INT, ARG_INT, ARG_INT}},
|
||||
// {"interface_print", mf_interface_print, 5, 6, -1, {ARG_STRING, ARG_INT, ARG_INT, ARG_INT, ARG_INT, ARG_INT}},
|
||||
// {"intface_hide", mf_intface_hide, 0, 0},
|
||||
// {"intface_is_hidden", mf_intface_is_hidden, 0, 0},
|
||||
{ "intface_redraw", mf_intface_redraw, 0, 1 },
|
||||
// {"intface_show", mf_intface_show, 0, 0},
|
||||
// {"inventory_redraw", mf_inventory_redraw, 0, 1, -1, {ARG_INT}},
|
||||
// {"item_make_explosive", mf_item_make_explosive, 3, 4, -1, {ARG_INT, ARG_INT, ARG_INT, ARG_INT}},
|
||||
// {"item_weight", mf_item_weight, 1, 1, 0, {ARG_OBJECT}},
|
||||
// {"lock_is_jammed", mf_lock_is_jammed, 1, 1, 0, {ARG_OBJECT}},
|
||||
{ "loot_obj", mf_loot_obj, 0, 0 },
|
||||
// {"message_box", mf_message_box, 1, 4, -1, {ARG_STRING, ARG_INT, ARG_INT, ARG_INT}},
|
||||
{ "metarule_exist", mf_metarule_exist, 1, 1 },
|
||||
// {"npc_engine_level_up", mf_npc_engine_level_up, 1, 1},
|
||||
// {"obj_is_openable", mf_obj_is_openable, 1, 1, 0, {ARG_OBJECT}},
|
||||
// {"obj_under_cursor", mf_obj_under_cursor, 2, 2, 0, {ARG_INT, ARG_INT}},
|
||||
// {"objects_in_radius", mf_objects_in_radius, 3, 4, 0, {ARG_INT, ARG_INT, ARG_INT, ARG_INT}},
|
||||
{ "outlined_object", mf_outlined_object, 0, 0 },
|
||||
// {"real_dude_obj", mf_real_dude_obj, 0, 0},
|
||||
// {"reg_anim_animate_and_move", mf_reg_anim_animate_and_move, 4, 4, -1, {ARG_OBJECT, ARG_INT, ARG_INT, ARG_INT}},
|
||||
// {"remove_timer_event", mf_remove_timer_event, 0, 1, -1, {ARG_INT}},
|
||||
// {"set_spray_settings", mf_set_spray_settings, 4, 4, -1, {ARG_INT, ARG_INT, ARG_INT, ARG_INT}},
|
||||
// {"set_can_rest_on_map", mf_set_rest_on_map, 3, 3, -1, {ARG_INT, ARG_INT, ARG_INT}},
|
||||
// {"set_car_intface_art", mf_set_car_intface_art, 1, 1, -1, {ARG_INT}},
|
||||
// {"set_combat_free_move", mf_set_combat_free_move, 1, 1, -1, {ARG_INT}},
|
||||
{ "set_cursor_mode", mf_set_cursor_mode, 1, 1 },
|
||||
// {"set_drugs_data", mf_set_drugs_data, 3, 3, -1, {ARG_INT, ARG_INT, ARG_INT}},
|
||||
// {"set_dude_obj", mf_set_dude_obj, 1, 1, -1, {ARG_INT}},
|
||||
// {"set_fake_perk_npc", mf_set_fake_perk_npc, 5, 5, -1, {ARG_OBJECT, ARG_STRING, ARG_INT, ARG_INT, ARG_STRING}},
|
||||
// {"set_fake_trait_npc", mf_set_fake_trait_npc, 5, 5, -1, {ARG_OBJECT, ARG_STRING, ARG_INT, ARG_INT, ARG_STRING}},
|
||||
{ "set_flags", mf_set_flags, 2, 2 },
|
||||
// {"set_iface_tag_text", mf_set_iface_tag_text, 3, 3, -1, {ARG_INT, ARG_STRING, ARG_INT}},
|
||||
{ "set_ini_setting", mf_set_ini_setting, 2, 2 },
|
||||
// {"set_map_enter_position", mf_set_map_enter_position, 3, 3, -1, {ARG_INT, ARG_INT, ARG_INT}},
|
||||
// {"set_object_data", mf_set_object_data, 3, 3, -1, {ARG_OBJECT, ARG_INT, ARG_INT}},
|
||||
{ "set_outline", mf_set_outline, 2, 2 },
|
||||
// {"set_quest_failure_value", mf_set_quest_failure_value, 2, 2, -1, {ARG_INT, ARG_INT}},
|
||||
// {"set_rest_heal_time", mf_set_rest_heal_time, 1, 1, -1, {ARG_INT}},
|
||||
// {"set_worldmap_heal_time", mf_set_worldmap_heal_time, 1, 1, -1, {ARG_INT}},
|
||||
// {"set_rest_mode", mf_set_rest_mode, 1, 1, -1, {ARG_INT}},
|
||||
// {"set_scr_name", mf_set_scr_name, 0, 1, -1, {ARG_STRING}},
|
||||
// {"set_selectable_perk_npc", mf_set_selectable_perk_npc, 5, 5, -1, {ARG_OBJECT, ARG_STRING, ARG_INT, ARG_INT, ARG_STRING}},
|
||||
// {"set_terrain_name", mf_set_terrain_name, 3, 3, -1, {ARG_INT, ARG_INT, ARG_STRING}},
|
||||
// {"set_town_title", mf_set_town_title, 2, 2, -1, {ARG_INT, ARG_STRING}},
|
||||
// {"set_unique_id", mf_set_unique_id, 1, 2, -1, {ARG_OBJECT, ARG_INT}},
|
||||
// {"set_unjam_locks_time", mf_set_unjam_locks_time, 1, 1, -1, {ARG_INT}},
|
||||
// {"set_window_flag", mf_set_window_flag, 3, 3, -1, {ARG_INTSTR, ARG_INT, ARG_INT}},
|
||||
{ "show_window", mf_show_window, 0, 1 },
|
||||
{ "tile_refresh_display", mf_tile_refresh_display, 0, 0 },
|
||||
// {"signal_close_game", mf_signal_close_game, 0, 0},
|
||||
// {"spatial_radius", mf_spatial_radius, 1, 1, 0, {ARG_OBJECT}},
|
||||
{ "string_compare", mf_string_compare, 2, 3 }, // {ARG_STRING, ARG_STRING, ARG_INT}},
|
||||
{ "string_find", mf_string_find, 2, 3 }, // {ARG_STRING, ARG_STRING, ARG_INT}},
|
||||
{ "string_format", mf_string_format, 2, 8 },
|
||||
{ "string_to_case", mf_string_to_case, 2, 2 }, // {ARG_STRING, ARG_INT}}
|
||||
// {"tile_by_position", mf_tile_by_position, 2, 2, -1, {ARG_INT, ARG_INT}},
|
||||
{ "tile_refresh_display", mf_tile_refresh_display, 0, 0 },
|
||||
// {"unjam_lock", mf_unjam_lock, 1, 1, -1, {ARG_OBJECT}},
|
||||
// {"unwield_slot", mf_unwield_slot, 2, 2, -1, {ARG_OBJECT, ARG_INT}},
|
||||
// {"win_fill_color", mf_win_fill_color, 0, 5, -1, {ARG_INT, ARG_INT, ARG_INT, ARG_INT, ARG_INT}},
|
||||
};
|
||||
|
||||
constexpr int kMetarulesMax = sizeof(kMetarules) / sizeof(kMetarules[0]);
|
||||
@@ -259,6 +348,137 @@ void mf_tile_refresh_display(Program* program, int args)
|
||||
programStackPushInteger(program, -1);
|
||||
}
|
||||
|
||||
// compares strings case-insensitive with specifics for Fallout
|
||||
// from sfall: https://github.com/sfall-team/sfall/blob/71ecec3d405bd5e945f157954618b169e60068fe/sfall/Modules/Scripting/Handlers/Utils.cpp#L34
|
||||
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' with 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) { // code used for the 'bullet' character in Fallout font (the Russian letter 'X' uses Latin letter)
|
||||
// upper to lower case
|
||||
if (c1 >= 128 && c1 <= 159) {
|
||||
c1 |= 32;
|
||||
} else if (c1 >= 224 && c1 <= 239) {
|
||||
c1 -= 48; // shift lower range
|
||||
} else if (c1 == 240) {
|
||||
c1++;
|
||||
}
|
||||
if (c2 >= 128 && c2 <= 159) {
|
||||
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 mf_string_compare(Program* program, int args)
|
||||
{
|
||||
// compare str1 to str3 case insensitively
|
||||
// if args == 3, use FalloutStringCompare
|
||||
const char* str1 = programStackPopString(program);
|
||||
const char* str2 = programStackPopString(program);
|
||||
int codePage = 0;
|
||||
if (args == 3) {
|
||||
codePage = programStackPopInteger(program);
|
||||
}
|
||||
bool result = false;
|
||||
if (args < 3) {
|
||||
// default case-insensitive comparison
|
||||
result = compat_stricmp(str1, str2) == 0;
|
||||
} else {
|
||||
// Fallout specific case-insensitive comparison
|
||||
result = FalloutStringCompare(str1, str2, codePage);
|
||||
}
|
||||
if (result) {
|
||||
programStackPushInteger(program, 1); // strings are equal
|
||||
} else {
|
||||
programStackPushInteger(program, 0); // strings are not equal
|
||||
}
|
||||
}
|
||||
|
||||
void mf_string_find(Program* program, int args)
|
||||
{
|
||||
const char* str = programStackPopString(program);
|
||||
const char* substr = programStackPopString(program);
|
||||
int startPos = 0;
|
||||
|
||||
if (args == 3) {
|
||||
startPos = programStackPopInteger(program);
|
||||
}
|
||||
|
||||
if (startPos < 0 || startPos >= strlen(str)) {
|
||||
debugPrint("string_find: invalid start position %d", startPos);
|
||||
programStackPushInteger(program, -1);
|
||||
return;
|
||||
}
|
||||
|
||||
const char* found = strstr(str + startPos, substr);
|
||||
if (found) {
|
||||
programStackPushInteger(program, found - str);
|
||||
} else {
|
||||
programStackPushInteger(program, -1);
|
||||
}
|
||||
}
|
||||
|
||||
void mf_string_to_case(Program* program, int args)
|
||||
{
|
||||
auto buf = programStackPopString(program);
|
||||
std::string s(buf);
|
||||
auto caseType = programStackPopInteger(program);
|
||||
if (caseType == 1) {
|
||||
std::transform(s.begin(), s.end(), s.begin(), ::toupper);
|
||||
} else if (caseType == 0) {
|
||||
std::transform(s.begin(), s.end(), s.begin(), ::tolower);
|
||||
} else {
|
||||
debugPrint("string_to_case: invalid case type %d", caseType);
|
||||
}
|
||||
programStackPushString(program, s.c_str());
|
||||
}
|
||||
|
||||
void mf_string_format(Program* program, int args)
|
||||
{
|
||||
sprintf_lite(program, args, "string_format");
|
||||
|
||||
@@ -1098,9 +1098,21 @@ static void op_sprintf(Program* program)
|
||||
sprintf_lite(program, 2, "op_sprintf");
|
||||
}
|
||||
|
||||
static void op_charcode(Program* program)
|
||||
{
|
||||
const char* str = programStackPopString(program);
|
||||
if (str != nullptr && str[0] != '\0') {
|
||||
programStackPushInteger(program, static_cast<int>(str[0]));
|
||||
} else {
|
||||
programStackPushInteger(program, 0);
|
||||
}
|
||||
}
|
||||
|
||||
void sfallOpcodesInit()
|
||||
{
|
||||
// ref. https://github.com/sfall-team/sfall/blob/71ecec3d405bd5e945f157954618b169e60068fe/artifacts/scripting/sfall%20opcode%20list.txt#L145
|
||||
interpreterRegisterOpcode(0x8156, op_read_byte);
|
||||
// missing: read_short, read_int, read_string
|
||||
interpreterRegisterOpcode(0x815A, op_set_pc_base_stat);
|
||||
interpreterRegisterOpcode(0x815B, op_set_pc_bonus_stat);
|
||||
interpreterRegisterOpcode(0x815C, op_get_pc_base_stat);
|
||||
@@ -1112,46 +1124,74 @@ void sfallOpcodesInit()
|
||||
interpreterRegisterOpcode(0x8162, op_tap_key);
|
||||
interpreterRegisterOpcode(0x8163, op_get_year);
|
||||
interpreterRegisterOpcode(0x8164, op_game_loaded);
|
||||
// missing: graphics_funcs_available, load_shader, free_shader, activate_shader, deactivate_shader
|
||||
interpreterRegisterOpcode(0x816A, op_set_global_script_repeat);
|
||||
// missing: input_funcs_available
|
||||
interpreterRegisterOpcode(0x816C, op_key_pressed);
|
||||
// missing: set_shader_int, set_shader_float, set_shader_vector
|
||||
interpreterRegisterOpcode(0x8170, op_in_world_map);
|
||||
interpreterRegisterOpcode(0x8171, op_force_encounter);
|
||||
interpreterRegisterOpcode(0x8172, op_set_world_map_pos);
|
||||
// missing: many set_perk, kill_counter, critter_ap, dm/df_model functions
|
||||
interpreterRegisterOpcode(0x8193, op_get_current_hand);
|
||||
// missing: toggle_active_hand, 6 knockback functions
|
||||
interpreterRegisterOpcode(0x819B, op_set_global_script_type);
|
||||
interpreterRegisterOpcode(0x819D, op_set_sfall_global);
|
||||
interpreterRegisterOpcode(0x819E, op_get_sfall_global_int);
|
||||
// missing: get_sfall_global_float, skill_max, eax, npc_level, viewport, mod
|
||||
interpreterRegisterOpcode(0x81AC, op_get_ini_setting);
|
||||
// missing: get_shader_version, get_shader_mode
|
||||
interpreterRegisterOpcode(0x81AF, op_get_game_mode);
|
||||
interpreterRegisterOpcode(0x81B3, op_get_uptime);
|
||||
// missing: set_stat_max, set_stat_min
|
||||
interpreterRegisterOpcode(0x81B6, op_set_car_current_town);
|
||||
// missing: set_pc/npc_stat_max/min, many fake_perk, fake_trait functions
|
||||
// missing: set_critter/base_hit_chance_mod
|
||||
// missing: write_byte/short/int
|
||||
// missing: call_offset_v/r0-4
|
||||
// missing: show/hide_iface_tag, is_face_tag_active
|
||||
interpreterRegisterOpcode(0x81DF, op_get_bodypart_hit_modifier);
|
||||
interpreterRegisterOpcode(0x81E0, op_set_bodypart_hit_modifier);
|
||||
// missing: set/get/reset_critical_table
|
||||
// missing: get_sfall_arg, set_sfall_return
|
||||
// missing: set/get_unspend_ap_bonus/ebonus
|
||||
// missing: init_hook
|
||||
interpreterRegisterOpcode(0x81EB, op_get_ini_string);
|
||||
interpreterRegisterOpcode(0x81EC, op_sqrt);
|
||||
interpreterRegisterOpcode(0x81ED, op_abs);
|
||||
// missing: sin, cos, tan, atan
|
||||
// missing: set_palette
|
||||
// missing: remove_script, set_script
|
||||
interpreterRegisterOpcode(0x81F5, op_get_script);
|
||||
// missing: nb_create_char, fs_*
|
||||
interpreterRegisterOpcode(0x8204, op_get_proto_data);
|
||||
interpreterRegisterOpcode(0x8205, op_set_proto_data);
|
||||
interpreterRegisterOpcode(0x8206, op_set_self);
|
||||
// missing: register_hook, more fs_*
|
||||
interpreterRegisterOpcode(0x820D, op_list_begin);
|
||||
interpreterRegisterOpcode(0x820E, op_list_next);
|
||||
interpreterRegisterOpcode(0x820F, op_list_end);
|
||||
interpreterRegisterOpcode(0x8210, op_get_version_major);
|
||||
interpreterRegisterOpcode(0x8211, op_get_version_minor);
|
||||
interpreterRegisterOpcode(0x8212, op_get_version_patch);
|
||||
// missing: hero_select_win, set_hero_race, set_hero_style, set_critter_burst_disable
|
||||
interpreterRegisterOpcode(0x8217, op_get_weapon_ammo_pid);
|
||||
interpreterRegisterOpcode(0x8218, op_set_weapon_ammo_pid);
|
||||
interpreterRegisterOpcode(0x8219, op_get_weapon_ammo_count);
|
||||
interpreterRegisterOpcode(0x821A, op_set_weapon_ammo_count);
|
||||
// missing: write_string
|
||||
interpreterRegisterOpcode(0x821C, op_get_mouse_x);
|
||||
interpreterRegisterOpcode(0x821D, op_get_mouse_y);
|
||||
interpreterRegisterOpcode(0x821E, op_get_mouse_buttons);
|
||||
// missing: get_window_under_mouse
|
||||
interpreterRegisterOpcode(0x8220, op_get_screen_width);
|
||||
interpreterRegisterOpcode(0x8221, op_get_screen_height);
|
||||
// missing: stop_game, resume_game
|
||||
interpreterRegisterOpcode(0x8224, op_create_message_window);
|
||||
// missing: remove_trait, get_light_level, refresh_pc_art
|
||||
interpreterRegisterOpcode(0x8228, op_get_attack_type);
|
||||
interpreterRegisterOpcode(0x8229, op_force_encounter_with_flags);
|
||||
// missing: set_map_time_multi, play_sfall_sound, stop_sfall_sound
|
||||
interpreterRegisterOpcode(0x822D, op_create_array);
|
||||
interpreterRegisterOpcode(0x822E, op_set_array);
|
||||
interpreterRegisterOpcode(0x822F, op_get_array);
|
||||
@@ -1165,21 +1205,34 @@ void sfallOpcodesInit()
|
||||
interpreterRegisterOpcode(0x8237, op_parse_int);
|
||||
interpreterRegisterOpcode(0x8238, op_atof);
|
||||
interpreterRegisterOpcode(0x8239, op_scan_array);
|
||||
// missing: modified_ini, get_sfall_args, set_sfall_arg, bunch of aimed shot, skillpoint, combat funcs
|
||||
interpreterRegisterOpcode(0x824B, op_tile_under_cursor);
|
||||
// missing: get_barter_mod, set_inven_ap_cost
|
||||
interpreterRegisterOpcode(0x824E, op_substr);
|
||||
interpreterRegisterOpcode(0x824F, op_get_string_length);
|
||||
interpreterRegisterOpcode(0x8250, op_sprintf);
|
||||
interpreterRegisterOpcode(0x8251, op_charcode);
|
||||
interpreterRegisterOpcode(0x8253, op_type_of);
|
||||
// missing: save_array, load_array
|
||||
interpreterRegisterOpcode(0x8256, op_get_array_key);
|
||||
interpreterRegisterOpcode(0x8257, op_stack_array);
|
||||
// missing: <reserved>x2, reg_anim_*
|
||||
interpreterRegisterOpcode(0x8261, op_explosions_metarule);
|
||||
// missing: register_hook_proc
|
||||
// missing: log
|
||||
interpreterRegisterOpcode(0x8263, op_power);
|
||||
// missing: ceil
|
||||
interpreterRegisterOpcode(0x8267, op_round);
|
||||
// 3 reserved opcodes
|
||||
interpreterRegisterOpcode(0x826B, op_get_message);
|
||||
// missing: sneak_success, tile_light
|
||||
interpreterRegisterOpcode(0x826E, op_make_straight_path);
|
||||
interpreterRegisterOpcode(0x826F, op_obj_blocking_at);
|
||||
// missing: tile_get_objects
|
||||
interpreterRegisterOpcode(0x8271, op_party_member_list);
|
||||
// missing: path_find, create_spatial
|
||||
interpreterRegisterOpcode(0x8274, op_art_exists);
|
||||
// missing: is_carrying_obj
|
||||
interpreterRegisterOpcode(0x8276, op_sfall_func0);
|
||||
interpreterRegisterOpcode(0x8277, op_sfall_func1);
|
||||
interpreterRegisterOpcode(0x8278, op_sfall_func2);
|
||||
@@ -1187,6 +1240,7 @@ void sfallOpcodesInit()
|
||||
interpreterRegisterOpcode(0x827A, op_sfall_func4);
|
||||
interpreterRegisterOpcode(0x827B, op_sfall_func5);
|
||||
interpreterRegisterOpcode(0x827C, op_sfall_func6);
|
||||
// missing: register_hook_proc2, reg_anim_callback
|
||||
interpreterRegisterOpcode(0x8280, op_sfall_func7);
|
||||
interpreterRegisterOpcode(0x8281, op_sfall_func8);
|
||||
interpreterRegisterOpcode(0x827F, op_div);
|
||||
|
||||
Reference in New Issue
Block a user