mirror of
https://github.com/sfall-team/sfall.git
synced 2026-07-27 16:52:34 -07:00
Refactor opcodes in Objects.cpp
- Added missing argument type checks - Replace asm blocks with wrapper function calls - Use GameObject instead of DWORD
This commit is contained in:
@@ -213,7 +213,7 @@
|
|||||||
#define exec_map_update_scripts sfall_func0("exec_map_update_scripts")
|
#define exec_map_update_scripts sfall_func0("exec_map_update_scripts")
|
||||||
#define set_outline(obj, color) sfall_func2("set_outline", obj, color)
|
#define set_outline(obj, color) sfall_func2("set_outline", obj, color)
|
||||||
#define get_outline(obj) sfall_func1("get_outline", obj)
|
#define get_outline(obj) sfall_func1("get_outline", obj)
|
||||||
#define set_flags(obj, color) sfall_func2("set_flags", obj, color)
|
#define set_flags(obj, flags) sfall_func2("set_flags", obj, flags)
|
||||||
#define get_flags(obj) sfall_func1("get_flags", obj)
|
#define get_flags(obj) sfall_func1("get_flags", obj)
|
||||||
#define tile_refresh_display sfall_func0("tile_refresh_display")
|
#define tile_refresh_display sfall_func0("tile_refresh_display")
|
||||||
#define outlined_object sfall_func0("outlined_object")
|
#define outlined_object sfall_func0("outlined_object")
|
||||||
|
|||||||
@@ -32,6 +32,7 @@ WRAP_WATCOM_FUNC2(long, db_fwriteByte, DbFile*, file, long, value)
|
|||||||
WRAP_WATCOM_FUNC2(long, db_fwriteInt, DbFile*, file, long, value)
|
WRAP_WATCOM_FUNC2(long, db_fwriteInt, DbFile*, file, long, value)
|
||||||
// perform combat turn for a given critter
|
// perform combat turn for a given critter
|
||||||
WRAP_WATCOM_FUNC2(long, combat_turn, GameObject*, critter, long, isDudeTurn)
|
WRAP_WATCOM_FUNC2(long, combat_turn, GameObject*, critter, long, isDudeTurn)
|
||||||
|
WRAP_WATCOM_FUNC1(long, critter_is_dead, GameObject*, critter)
|
||||||
WRAP_WATCOM_FUNC1(long, gmouse_set_cursor, long, picNum)
|
WRAP_WATCOM_FUNC1(long, gmouse_set_cursor, long, picNum)
|
||||||
WRAP_WATCOM_FUNC1(Window*, GNW_find, long, winRef)
|
WRAP_WATCOM_FUNC1(Window*, GNW_find, long, winRef)
|
||||||
WRAP_WATCOM_FUNC0(long, intface_is_item_right_hand)
|
WRAP_WATCOM_FUNC0(long, intface_is_item_right_hand)
|
||||||
@@ -45,6 +46,8 @@ WRAP_WATCOM_FUNC2(long, light_get_tile, long, elevation, long, tileNum)
|
|||||||
WRAP_WATCOM_FUNC2(void, mouse_get_position, long*, outX, long*, outY)
|
WRAP_WATCOM_FUNC2(void, mouse_get_position, long*, outX, long*, outY)
|
||||||
WRAP_WATCOM_FUNC0(void, mouse_show)
|
WRAP_WATCOM_FUNC0(void, mouse_show)
|
||||||
WRAP_WATCOM_FUNC0(void, mouse_hide)
|
WRAP_WATCOM_FUNC0(void, mouse_hide)
|
||||||
|
// calculates path and returns it's length
|
||||||
|
WRAP_WATCOM_FUNC6(long, make_path_func, GameObject*, objectFrom, long, tileFrom, long, tileTo, char*, pathDataBuffer, long, arg5, void*, blockingFunc)
|
||||||
// calculates bounding box (rectangle) for a given object
|
// calculates bounding box (rectangle) for a given object
|
||||||
WRAP_WATCOM_FUNC2(void, obj_bound, GameObject*, object, BoundRect*, boundRect)
|
WRAP_WATCOM_FUNC2(void, obj_bound, GameObject*, object, BoundRect*, boundRect)
|
||||||
WRAP_WATCOM_FUNC3(long, register_object_animate, GameObject*, object, long, anim, long, delay)
|
WRAP_WATCOM_FUNC3(long, register_object_animate, GameObject*, object, long, anim, long, delay)
|
||||||
|
|||||||
@@ -217,7 +217,7 @@ static DWORD _stdcall obj_blocking_at_wrapper(DWORD obj, DWORD tile, DWORD eleva
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static DWORD _stdcall make_straight_path_func_wrapper(DWORD obj, DWORD tileFrom, DWORD a3, DWORD tileTo, DWORD* result, DWORD a6, DWORD func) {
|
static DWORD _stdcall make_straight_path_func_wrapper(fo::GameObject* obj, DWORD tileFrom, DWORD a3, DWORD tileTo, DWORD* result, DWORD a6, DWORD func) {
|
||||||
__asm {
|
__asm {
|
||||||
mov eax, obj;
|
mov eax, obj;
|
||||||
mov edx, tileFrom;
|
mov edx, tileFrom;
|
||||||
@@ -253,45 +253,28 @@ static DWORD getBlockingFunc(DWORD type) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void sf_make_straight_path(OpcodeContext& ctx) {
|
void sf_make_straight_path(OpcodeContext& ctx) {
|
||||||
DWORD objFrom = ctx.arg(0).asInt(),
|
auto objFrom = ctx.arg(0).asObject();
|
||||||
tileTo = ctx.arg(1).asInt(),
|
DWORD tileTo = ctx.arg(1).asInt(),
|
||||||
type = ctx.arg(2).asInt(),
|
type = ctx.arg(2).asInt(),
|
||||||
resultObj, arg6;
|
resultObj, arg6;
|
||||||
arg6 = (type == BLOCKING_TYPE_SHOOT) ? 32 : 0;
|
arg6 = (type == BLOCKING_TYPE_SHOOT) ? 32 : 0;
|
||||||
make_straight_path_func_wrapper(objFrom, *(DWORD*)(objFrom + 4), 0, tileTo, &resultObj, arg6, getBlockingFunc(type));
|
make_straight_path_func_wrapper(objFrom, objFrom->tile, 0, tileTo, &resultObj, arg6, getBlockingFunc(type));
|
||||||
ctx.setReturn(resultObj, DataType::INT);
|
ctx.setReturn(resultObj, DataType::INT);
|
||||||
}
|
}
|
||||||
|
|
||||||
void sf_make_path(OpcodeContext& ctx) {
|
void sf_make_path(OpcodeContext& ctx) {
|
||||||
DWORD objFrom = ctx.arg(0).asInt(),
|
auto objFrom = ctx.arg(0).asObject();
|
||||||
tileFrom = 0,
|
auto tileTo = ctx.arg(1).asInt(),
|
||||||
tileTo = ctx.arg(1).asInt(),
|
type = ctx.arg(2).asInt();
|
||||||
type = ctx.arg(2).asInt(),
|
auto func = getBlockingFunc(type);
|
||||||
func = getBlockingFunc(type),
|
|
||||||
arr;
|
|
||||||
long pathLength, a5 = 1;
|
long pathLength, a5 = 1;
|
||||||
if (!objFrom) {
|
|
||||||
ctx.setReturn(0, DataType::INT);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
tileFrom = *(DWORD*)(objFrom + 4);
|
|
||||||
char pathData[800];
|
char pathData[800];
|
||||||
char* pathDataPtr = pathData;
|
pathLength = fo::func::make_path_func(objFrom, objFrom->tile, tileTo, pathData, a5, (void*)func);
|
||||||
__asm {
|
auto arrayId = TempArray(pathLength, 0);
|
||||||
mov eax, objFrom;
|
|
||||||
mov edx, tileFrom;
|
|
||||||
mov ecx, pathDataPtr;
|
|
||||||
mov ebx, tileTo;
|
|
||||||
push func;
|
|
||||||
push a5;
|
|
||||||
call fo::funcoffs::make_path_func_;
|
|
||||||
mov pathLength, eax;
|
|
||||||
}
|
|
||||||
arr = TempArray(pathLength, 0);
|
|
||||||
for (int i = 0; i < pathLength; i++) {
|
for (int i = 0; i < pathLength; i++) {
|
||||||
arrays[arr].val[i].set((long)pathData[i]);
|
arrays[arrayId].val[i].set((long)pathData[i]);
|
||||||
}
|
}
|
||||||
ctx.setReturn(arr, DataType::INT);
|
ctx.setReturn(arrayId, DataType::INT);
|
||||||
}
|
}
|
||||||
|
|
||||||
void sf_obj_blocking_at(OpcodeContext& ctx) {
|
void sf_obj_blocking_at(OpcodeContext& ctx) {
|
||||||
@@ -309,46 +292,26 @@ void sf_obj_blocking_at(OpcodeContext& ctx) {
|
|||||||
|
|
||||||
void sf_tile_get_objects(OpcodeContext& ctx) {
|
void sf_tile_get_objects(OpcodeContext& ctx) {
|
||||||
DWORD tile = ctx.arg(0).asInt(),
|
DWORD tile = ctx.arg(0).asInt(),
|
||||||
elevation = ctx.arg(1).asInt(),
|
elevation = ctx.arg(1).asInt();
|
||||||
obj;
|
|
||||||
DWORD arrayId = TempArray(0, 4);
|
DWORD arrayId = TempArray(0, 4);
|
||||||
__asm {
|
auto obj = fo::func::obj_find_first_at_tile(elevation, tile);
|
||||||
mov eax, elevation;
|
|
||||||
mov edx, tile;
|
|
||||||
call fo::funcoffs::obj_find_first_at_tile_;
|
|
||||||
mov obj, eax;
|
|
||||||
}
|
|
||||||
while (obj) {
|
while (obj) {
|
||||||
arrays[arrayId].push_back((long)obj);
|
arrays[arrayId].push_back(reinterpret_cast<long>(obj));
|
||||||
__asm {
|
obj = fo::func::obj_find_next_at_tile();
|
||||||
call fo::funcoffs::obj_find_next_at_tile_;
|
|
||||||
mov obj, eax;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
ctx.setReturn(arrayId, DataType::INT);
|
ctx.setReturn(arrayId, DataType::INT);
|
||||||
}
|
}
|
||||||
|
|
||||||
void sf_get_party_members(OpcodeContext& ctx) {
|
void sf_get_party_members(OpcodeContext& ctx) {
|
||||||
DWORD obj, mode = ctx.arg(0).asInt(), isDead;
|
auto includeHidden = ctx.arg(0).asInt();
|
||||||
int i, actualCount = fo::var::partyMemberCount;
|
int actualCount = fo::var::partyMemberCount;
|
||||||
DWORD arrayId = TempArray(0, 4);
|
DWORD arrayId = TempArray(0, 4);
|
||||||
DWORD* partyMemberList = fo::var::partyMemberList;
|
auto partyMemberList = fo::var::partyMemberList;
|
||||||
for (i = 0; i < actualCount; i++) {
|
for (int i = 0; i < actualCount; i++) {
|
||||||
obj = partyMemberList[i * 4];
|
auto obj = reinterpret_cast<fo::GameObject*>(partyMemberList[i * 4]);
|
||||||
if (mode == 0) { // mode 0 will act just like op_party_member_count in fallout2
|
if (includeHidden || (obj->type() == fo::OBJ_TYPE_CRITTER && !fo::func::critter_is_dead(obj) && !(obj->flags & fo::ObjectFlag::Mouse_3d))) {
|
||||||
if ((*(DWORD*)(obj + 100) >> 24) != fo::OBJ_TYPE_CRITTER) // obj type != critter
|
arrays[arrayId].push_back((long)obj);
|
||||||
continue;
|
|
||||||
__asm {
|
|
||||||
mov eax, obj;
|
|
||||||
call fo::funcoffs::critter_is_dead_;
|
|
||||||
mov isDead, eax;
|
|
||||||
}
|
|
||||||
if (isDead)
|
|
||||||
continue;
|
|
||||||
if (*(DWORD*)(obj + 36) & 1) // no idea..
|
|
||||||
continue;
|
|
||||||
}
|
}
|
||||||
arrays[arrayId].push_back((long)obj);
|
|
||||||
}
|
}
|
||||||
ctx.setReturn(arrayId, DataType::INT);
|
ctx.setReturn(arrayId, DataType::INT);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -130,14 +130,14 @@ static SfallOpcodeInfo opcodeInfoArray[] = {
|
|||||||
{0x26b, "message_str_game", sf_message_str_game, 2, true, {ARG_INT, ARG_INT}},
|
{0x26b, "message_str_game", sf_message_str_game, 2, true, {ARG_INT, ARG_INT}},
|
||||||
{0x26c, "sneak_success", sf_sneak_success, 0, true},
|
{0x26c, "sneak_success", sf_sneak_success, 0, true},
|
||||||
{0x26d, "tile_light", sf_tile_light, 2, true, {ARG_INT, ARG_INT}},
|
{0x26d, "tile_light", sf_tile_light, 2, true, {ARG_INT, ARG_INT}},
|
||||||
{0x26e, "obj_blocking_line", sf_make_straight_path, 3, true},
|
{0x26e, "obj_blocking_line", sf_make_straight_path, 3, true, {ARG_OBJECT, ARG_INT, ARG_INT}},
|
||||||
{0x26f, "obj_blocking_tile", sf_obj_blocking_at, 3, true},
|
{0x26f, "obj_blocking_tile", sf_obj_blocking_at, 3, true, {ARG_INT, ARG_INT, ARG_INT}},
|
||||||
{0x270, "tile_get_objs", sf_tile_get_objects, 2, true},
|
{0x270, "tile_get_objs", sf_tile_get_objects, 2, true, {ARG_INT, ARG_INT}},
|
||||||
{0x271, "party_member_list", sf_get_party_members, 1, true},
|
{0x271, "party_member_list", sf_get_party_members, 1, true, {ARG_INT}},
|
||||||
{0x272, "path_find_to", sf_make_path, 3, true},
|
{0x272, "path_find_to", sf_make_path, 3, true, {ARG_OBJECT, ARG_INT, ARG_INT}},
|
||||||
{0x273, "create_spatial", sf_create_spatial, 4, true},
|
{0x273, "create_spatial", sf_create_spatial, 4, true, {ARG_INT, ARG_INT, ARG_INT, ARG_INT}},
|
||||||
{0x274, "art_exists", sf_art_exists, 1, true},
|
{0x274, "art_exists", sf_art_exists, 1, true, {ARG_INT}},
|
||||||
{0x275, "obj_is_carrying_obj", sf_obj_is_carrying_obj, 2, true},
|
{0x275, "obj_is_carrying_obj", sf_obj_is_carrying_obj, 2, true, {ARG_OBJECT, ARG_OBJECT}},
|
||||||
|
|
||||||
// universal opcodes:
|
// universal opcodes:
|
||||||
{0x276, "sfall_func0", HandleMetarule, 1, true},
|
{0x276, "sfall_func0", HandleMetarule, 1, true},
|
||||||
|
|||||||
Reference in New Issue
Block a user