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:
phobos2077
2017-04-03 23:27:33 +07:00
parent 116c522bdc
commit e2a383511d
4 changed files with 35 additions and 69 deletions
+1 -1
View File
@@ -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")
+3
View File
@@ -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)
+23 -60
View File
@@ -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);
} }
+8 -8
View File
@@ -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},