Fix more possible crashes

This commit is contained in:
MysterD 2023-05-11 00:19:01 -07:00
parent af01a214ee
commit f785050ccb
19 changed files with 807 additions and 44 deletions

View file

@ -1,4 +1,4 @@
#!/usr/bin/bash #!/usr/bin/bash
python3 ./autogen/convert_structs.py python3 ./autogen/convert_structs.py $1
python3 ./autogen/convert_functions.py python3 ./autogen/convert_functions.py $1
python3 ./autogen/convert_constants.py python3 ./autogen/convert_constants.py $1

View file

@ -614,6 +614,12 @@ def build_function(function, do_extern):
else: else:
s += 'int smlua_func_%s(lua_State* L) {\n' % function['identifier'] s += 'int smlua_func_%s(lua_State* L) {\n' % function['identifier']
# make sure the bhv functions have a current object
fname = function['filename']
if fname == 'behavior_actions.h' or fname == 'obj_behaviors_2.h' or fname == 'obj_behaviors.h':
if 'bhv_' in fid:
s += ' if (!gCurrentObject) { return 0; }\n'
s += """ if (L == NULL) { return 0; }\n s += """ if (L == NULL) { return 0; }\n
int top = lua_gettop(L); int top = lua_gettop(L);
if (top != %d) { if (top != %d) {
@ -659,6 +665,7 @@ def build_functions(processed_files):
s += gen_comment_header(processed_file['filename']) s += gen_comment_header(processed_file['filename'])
for function in processed_file['functions']: for function in processed_file['functions']:
function['filename'] = processed_file['filename']
s += build_function(function, processed_file['extern']) s += build_function(function, processed_file['extern'])
return s return s
@ -792,28 +799,51 @@ def process_files():
############################################################################ ############################################################################
def output_nuke_function(fname, function): fuzz_functions = ""
def output_fuzz_function(fname, function):
first = True first = True
comment = '' comment = ' -- '
fid = function['identifier'] fid = function['identifier']
print(fid + '(', end='')
line = ' ' + fid + '('
for param in function['params']: for param in function['params']:
if first: if first:
first = False first = False
else: else:
print(', ', end='') line += ', '
comment += ', ' comment += ', '
pid = param['identifier'] pid = param['identifier']
ptype = param['type'] ptype = param['type']
ptype, plink = translate_type_to_lua(ptype) ptype, plink = translate_type_to_lua(ptype)
if ptype == '`integer`' or ptype == '`number`' or 'enum' in ptype: if 'enum ' in ptype:
print('0', end='') ptype = 'integer'
else: line += 'rnd_' + ptype.strip().replace('`', '').replace(' ', '').split('<')[-1].split('>')[0].split('(')[0] + '()'
print('nil', end='')
#if ptype == '`integer`' or ptype == '`number`' or 'enum' in ptype:
# print('0', end='')
#else:
# print('nil', end='')
comment += ptype comment += ptype
print(') -- ' + comment) line += ')'
if len(line) >= 80:
line = line + '\n ' + comment + '\n'
else:
line = line.ljust(80) + comment + '\n'
global fuzz_functions
fuzz_functions += line
def output_fuzz_file():
global fuzz_functions
with open('./autogen/fuzz_template.lua') as f:
file_str = f.read()
with open('/home/djoslin/.local/share/sm64ex-coop/mods/test-fuzz.lua', 'w') as f:
f.write(file_str.replace('-- $[FUNCS]', fuzz_functions))
############################################################################ ############################################################################
@ -877,7 +907,8 @@ def doc_function(fname, function):
return '' return ''
# debug print out lua nuke functions # debug print out lua nuke functions
# output_nuke_function(fname, function) if len(sys.argv) >= 2 and sys.argv[1] == 'fuzz':
output_fuzz_function(fname, function)
if not doc_should_document(fname, function['identifier']): if not doc_should_document(fname, function['identifier']):
return '' return ''
@ -1073,5 +1104,8 @@ def main():
global total_functions global total_functions
print('Total functions: ' + str(total_functions)) print('Total functions: ' + str(total_functions))
if len(sys.argv) >= 2 and sys.argv[1] == 'fuzz':
output_fuzz_file()
if __name__ == '__main__': if __name__ == '__main__':
main() main()

View file

@ -242,6 +242,27 @@ def parse_structs(extracted):
############################################################################ ############################################################################
def output_fuzz_struct(struct):
sid = struct['identifier']
print('function Nuke' + sid + "(struct)")
for field in struct['fields']:
fid, ftype, fimmutable, lvt, lot = get_struct_field_info(struct, field)
if fimmutable == 'true':
continue
if sid in override_field_invisible:
if fid in override_field_invisible[sid]:
continue
if lvt == 'LVT_COBJECT':
print(' Fuzz' + ftype.replace('struct ', '') + '(struct.' + fid + ')')
elif lvt == 'LVT_COBJECT_P':
print(' struct.' + fid + ' = nil')
else:
print(' struct.' + fid + ' = 0')
print('end')
print('')
############################################################################
sLuaObjectTable = [] sLuaObjectTable = []
sLotAutoGenList = [] sLotAutoGenList = []
@ -272,28 +293,10 @@ def get_struct_field_info(struct, field):
return fid, ftype, fimmutable, lvt, lot return fid, ftype, fimmutable, lvt, lot
def output_nuke_struct(struct):
sid = struct['identifier']
print('function Nuke' + sid + "(struct)")
for field in struct['fields']:
fid, ftype, fimmutable, lvt, lot = get_struct_field_info(struct, field)
if fimmutable == 'true':
continue
if sid in override_field_invisible:
if fid in override_field_invisible[sid]:
continue
if lvt == 'LVT_COBJECT':
print(' Nuke' + ftype.replace('struct ', '') + '(struct.' + fid + ')')
elif lvt == 'LVT_COBJECT_P':
print(' struct.' + fid + ' = nil')
else:
print(' struct.' + fid + ' = 0')
print('end')
print('')
def build_struct(struct): def build_struct(struct):
# debug print out lua nuke functions # debug print out lua fuzz functions
# output_nuke_struct(struct) if len(sys.argv) >= 2 and sys.argv[1] == 'fuzz':
output_fuzz_struct(struct)
sid = struct['identifier'] sid = struct['identifier']

141
autogen/fuzz_template.lua Normal file
View file

@ -0,0 +1,141 @@
-- $[STRUCTS]
--------
function FuzzVec3s(struct)
struct.x = 0
struct.y = 0
struct.z = 0
end
function FuzzVec3f(struct)
struct.x = 0
struct.y = 0
struct.z = 0
end
function FuzzVec4s(struct)
struct.x = 0
struct.y = 0
struct.z = 0
struct.w = 0
end
function FuzzVec4f(struct)
struct.x = 0
struct.y = 0
struct.z = 0
struct.w = 0
end
function FuzzMat4(struct)
struct.a = 0
struct.b = 0
struct.c = 0
struct.d = 0
struct.e = 0
struct.f = 0
struct.g = 0
struct.h = 0
struct.i = 0
struct.j = 0
struct.k = 0
struct.l = 0
struct.m = 0
struct.n = 0
struct.o = 0
struct.p = 0
end
--------
function rnd_string()
t = { 0, "test", "this is a very long string this is a very long string this is a very long string this is a very long string this is a very long string this is a very long string this is a very long string this is a very long string this is a very long string this is a very long string this is a very long string this is a very long string this is a very long string" }
return t[math.random(#t)]
end
function rnd_integer()
t = { 0, math.random(1, 10), math.random(-2147483648, 2147483647) }
return t[math.random(#t)]
end
function rnd_number()
t = { 0, math.random(), (math.random() - 0.5) * 2 * 4294967296 }
return t[math.random(#t)]
end
function rnd_Vec3s()
t = { nil, { x = rnd_integer(), y = rnd_integer(), z = rnd_integer() } }
return t[math.random(#t)]
end
function rnd_Vec3f()
t = { nil, { x = rnd_number(), y = rnd_number(), z = rnd_number() } }
return t[math.random(#t)]
end
function rnd_Vec4s()
t = { nil, { x = rnd_integer(), y = rnd_integer(), z = rnd_integer(), w = rnd_integer() } }
return t[math.random(#t)]
end
function rnd_Vec4f()
t = { nil, { x = rnd_number(), y = rnd_number(), z = rnd_number(), w = rnd_number() } }
return t[math.random(#t)]
end
function rnd_Mat4()
t = { nil, { a = rnd_integer(), b = rnd_integer(), c = rnd_integer(), d = rnd_integer(), e = rnd_integer(), f = rnd_integer(), g = rnd_integer(), h = rnd_integer(), i = rnd_integer(), j = rnd_integer(), k = rnd_integer(), l = rnd_integer(), m = rnd_integer(), n = rnd_integer(), o = rnd_integer(), p = rnd_integer() } }
return t[math.random(#t)]
end
function rnd_Object()
t = { nil, gMarioStates[0].marioObj, gMarioStates[1].marioObj }
return t[math.random(#t)]
end
function rnd_MarioState()
t = { nil, gMarioStates[math.random(0, MAX_PLAYERS)] }
return t[math.random(#t)]
end
function rnd_NetworkPlayer()
t = { nil, gNetworkPlayers[math.random(0, MAX_PLAYERS)] }
return t[math.random(#t)]
end
function rnd_SpawnParticlesInfo()
t = { nil, obj_get_temp_spawn_particles_info(math.random(0, E_MODEL_MAX)) }
return t[math.random(#t)]
end
function rnd_BehaviorScript()
t = { nil, get_behavior_from_id(math.random(0, id_bhv_max_count)) }
return t[math.random(#t)]
end
function rnd_Camera()
t = { nil, gMarioStates[0].area.camera }
return t[math.random(#t)]
end
function rnd_PlayerGeometry()
t = { nil, {} }
return t[math.random(#t)]
end
--------
function fuzz_functions()
-- $[FUNCS]
end
--------
function fuzz_structs()
end
hook_chat_command('fuzz-funcs', 'funcs', fuzz_functions)
hook_chat_command('fuzz-structs', 'structs', fuzz_structs)
fuzz_functions()
print('!')

View file

@ -52,7 +52,7 @@ u16 random_u16(void) {
if (gOverrideRngPosition != NULL) { if (gOverrideRngPosition != NULL) {
// override this function for rng positions // override this function for rng positions
gRandomSeed16 = gOverrideRngPosition->seed; gRandomSeed16 = gOverrideRngPosition->seed;
} else if (gCurrentObject->oSyncID != 0) { } else if (gCurrentObject && gCurrentObject->oSyncID != 0) {
// override this function for synchronized entities // override this function for synchronized entities
so = sync_object_get(gCurrentObject->oSyncID); so = sync_object_get(gCurrentObject->oSyncID);
if (so != NULL && so->o == gCurrentObject) { if (so != NULL && so->o == gCurrentObject) {

View file

@ -1,6 +1,7 @@
// chuckya.c.inc // chuckya.c.inc
void common_anchor_mario_behavior(f32 sp28, f32 sp2C, s32 sp30) { void common_anchor_mario_behavior(f32 sp28, f32 sp2C, s32 sp30) {
if (!o) { return; }
for (s32 i = 0; i < MAX_PLAYERS; i++) { for (s32 i = 0; i < MAX_PLAYERS; i++) {
if (!is_player_active(&gMarioStates[i])) { continue; } if (!is_player_active(&gMarioStates[i])) { continue; }
struct MarioState* marioState = &gMarioStates[i]; struct MarioState* marioState = &gMarioStates[i];
@ -38,6 +39,7 @@ void bhv_chuckya_anchor_mario_loop(void) {
} }
s32 unknown_chuckya_function(s32 sp20, f32 sp24, f32 sp28, s32 sp2C) { s32 unknown_chuckya_function(s32 sp20, f32 sp24, f32 sp28, s32 sp2C) {
if (!o) { return 0; }
struct Object* player = nearest_player_to_object(o); struct Object* player = nearest_player_to_object(o);
s32 distanceToPlayer = player ? dist_between_objects(o, player) : 10000; s32 distanceToPlayer = player ? dist_between_objects(o, player) : 10000;
s32 angleToPlayer = player ? obj_angle_to_object(o, player) : 0; s32 angleToPlayer = player ? obj_angle_to_object(o, player) : 0;
@ -82,6 +84,7 @@ s32 approach_forward_vel(f32 *arr, f32 spC, f32 sp10) {
} }
void chuckya_act_0(void) { void chuckya_act_0(void) {
if (!o) { return; }
struct Object* player = nearest_player_to_object(o); struct Object* player = nearest_player_to_object(o);
s32 angleToPlayer = player ? obj_angle_to_object(o, player) : 0; s32 angleToPlayer = player ? obj_angle_to_object(o, player) : 0;
s32 sp3C = 0; s32 sp3C = 0;
@ -137,6 +140,7 @@ void chuckya_act_0(void) {
} }
void chuckya_act_1(void) { void chuckya_act_1(void) {
if (!o) { return; }
if (o->oSubAction == 0) { if (o->oSubAction == 0) {
if (cur_obj_init_animation_and_check_if_near_end(0)) if (cur_obj_init_animation_and_check_if_near_end(0))
o->oSubAction++; o->oSubAction++;
@ -174,6 +178,7 @@ void chuckya_act_1(void) {
} }
void chuckya_act_3(void) { void chuckya_act_3(void) {
if (!o) { return; }
o->oForwardVel = 0; o->oForwardVel = 0;
o->oVelY = 0; o->oVelY = 0;
cur_obj_init_animation_with_sound(4); cur_obj_init_animation_with_sound(4);
@ -182,6 +187,7 @@ void chuckya_act_3(void) {
} }
void chuckya_act_2(void) { void chuckya_act_2(void) {
if (!o) { return; }
if (o->oMoveFlags & (OBJ_MOVE_HIT_WALL | OBJ_MOVE_MASK_IN_WATER | OBJ_MOVE_LANDED)) { if (o->oMoveFlags & (OBJ_MOVE_HIT_WALL | OBJ_MOVE_MASK_IN_WATER | OBJ_MOVE_LANDED)) {
obj_mark_for_deletion(o); obj_mark_for_deletion(o);
obj_spawn_loot_yellow_coins(o, 5, 20.0f); obj_spawn_loot_yellow_coins(o, 5, 20.0f);
@ -192,6 +198,7 @@ void chuckya_act_2(void) {
void (*sChuckyaActions[])(void) = { chuckya_act_0, chuckya_act_1, chuckya_act_2, chuckya_act_3 }; void (*sChuckyaActions[])(void) = { chuckya_act_0, chuckya_act_1, chuckya_act_2, chuckya_act_3 };
void chuckya_move(void) { void chuckya_move(void) {
if (!o) { return; }
cur_obj_update_floor_and_walls(); cur_obj_update_floor_and_walls();
CUR_OBJ_CALL_ACTION_FUNCTION(sChuckyaActions); CUR_OBJ_CALL_ACTION_FUNCTION(sChuckyaActions);
cur_obj_move_standard(-30); cur_obj_move_standard(-30);

View file

@ -1,6 +1,7 @@
// grand_star.c.inc // grand_star.c.inc
s32 arc_to_goal_pos(Vec3f empty, Vec3f pos, f32 yVel, f32 gravity) { s32 arc_to_goal_pos(Vec3f empty, Vec3f pos, f32 yVel, f32 gravity) {
if (!o) { return 0; }
f32 dx = empty[0] - pos[0]; f32 dx = empty[0] - pos[0];
f32 dz = empty[2] - pos[2]; f32 dz = empty[2] - pos[2];
f32 planarDist = sqrtf(dx * dx + dz * dz); f32 planarDist = sqrtf(dx * dx + dz * dz);
@ -13,6 +14,7 @@ s32 arc_to_goal_pos(Vec3f empty, Vec3f pos, f32 yVel, f32 gravity) {
} }
void grand_star_zero_velocity(void) { void grand_star_zero_velocity(void) {
if (!o) { return; }
o->oGravity = 0.0f; o->oGravity = 0.0f;
o->oVelY = 0.0f; o->oVelY = 0.0f;
o->oForwardVel = 0.0f; o->oForwardVel = 0.0f;

View file

@ -25,7 +25,7 @@ void spawn_smoke_with_velocity(void) {
// TODO Fix name // TODO Fix name
void clear_particle_flags(u32 flags) { void clear_particle_flags(u32 flags) {
if (o->parentObj) { if (o && o->parentObj) {
o->parentObj->oActiveParticleFlags &= flags ^ -1; // Clear the flags given (could just be ~flags) o->parentObj->oActiveParticleFlags &= flags ^ -1; // Clear the flags given (could just be ~flags)
} }
} }

View file

@ -4,6 +4,7 @@ void spawn_child_obj_relative(struct Object *parent, s16 xOffset, s16 yOffset, s
s16 yawOffset, s16 rollOffset, s16 forwardVel, s16 yawOffset, s16 rollOffset, s16 forwardVel,
s32 model, const BehaviorScript *behavior) { s32 model, const BehaviorScript *behavior) {
struct Object *sp1C = spawn_object(parent, model, behavior); struct Object *sp1C = spawn_object(parent, model, behavior);
if (!sp1C) { return; }
sp1C->header.gfx.animInfo.animFrame = random_float() * 6.f; sp1C->header.gfx.animInfo.animFrame = random_float() * 6.f;
sp1C->oEndBirdUnk104 = sCutsceneVars[9].point[0]; sp1C->oEndBirdUnk104 = sCutsceneVars[9].point[0];

View file

@ -13,6 +13,7 @@ struct ObjectHitbox sMetalBoxHitbox = {
}; };
s32 check_if_moving_over_floor(f32 a0, f32 a1) { s32 check_if_moving_over_floor(f32 a0, f32 a1) {
if (!o) { return 0; }
struct Surface *sp24; struct Surface *sp24;
f32 sp20 = o->oPosX + sins(o->oMoveAngleYaw) * a1; f32 sp20 = o->oPosX + sins(o->oMoveAngleYaw) * a1;
f32 floorHeight; f32 floorHeight;

View file

@ -27,17 +27,19 @@ void spawn_star_number(void) {
// Check if the star already has a number // Check if the star already has a number
struct Object *starNumber = obj_get_first_with_behavior_id(id_bhvStarNumber); struct Object *starNumber = obj_get_first_with_behavior_id(id_bhvStarNumber);
u32 sanityDepth = 0;
for (; starNumber; starNumber = obj_get_next_with_same_behavior_id(starNumber)) { for (; starNumber; starNumber = obj_get_next_with_same_behavior_id(starNumber)) {
if (++sanityDepth >= 10000) { break; }
if (!starNumber || starNumber->parentObj == o) { if (!starNumber || starNumber->parentObj == o) {
break; break;
} }
} }
// If not, spawn a number // If not, spawn a number
if (!starNumber) { if (!starNumber && o) {
starNumber = spawn_object(o, MODEL_NUMBER, bhvStarNumber); starNumber = spawn_object(o, MODEL_NUMBER, bhvStarNumber);
} }
if (starNumber) { if (starNumber && o) {
starNumber->parentObj = o; starNumber->parentObj = o;
starNumber->activeFlags |= ACTIVE_FLAG_INITIATED_TIME_STOP; // to make sure it's updated even during time stop starNumber->activeFlags |= ACTIVE_FLAG_INITIATED_TIME_STOP; // to make sure it's updated even during time stop
starNumber->oStarBehavior = (const void *) smlua_override_behavior(o->behavior); starNumber->oStarBehavior = (const void *) smlua_override_behavior(o->behavior);
@ -208,6 +210,7 @@ struct Object *spawn_default_star(f32 x, f32 y, f32 z) {
} }
struct Object *spawn_red_coin_cutscene_star(f32 x, f32 y, f32 z) { struct Object *spawn_red_coin_cutscene_star(f32 x, f32 y, f32 z) {
if (!o) { return NULL; }
u32 behParams = o->oBehParams; u32 behParams = o->oBehParams;
// de-duplication checking // de-duplication checking
@ -225,6 +228,7 @@ struct Object *spawn_red_coin_cutscene_star(f32 x, f32 y, f32 z) {
} }
struct Object *spawn_no_exit_star(f32 x, f32 y, f32 z) { struct Object *spawn_no_exit_star(f32 x, f32 y, f32 z) {
if (!o) { return NULL; }
u32 behParams = o->oBehParams; u32 behParams = o->oBehParams;
// de-duplication checking // de-duplication checking

View file

@ -9,12 +9,13 @@ s8 D_8032F948[] = { 4, 1, 4, 1, 4, 1, 4, 1, 4, 1, 2, 5, 1, 5, 1, 5, 1, 5,
s8 *D_8032F96C[] = { D_8032F8F0, D_8032F924, D_8032F948 }; s8 *D_8032F96C[] = { D_8032F8F0, D_8032F924, D_8032F948 };
void tox_box_shake_screen(void) { void tox_box_shake_screen(void) {
if (o->oDistanceToMario < 3000.0f) if (o && o->oDistanceToMario < 3000.0f)
cur_obj_shake_screen(SHAKE_POS_SMALL); cur_obj_shake_screen(SHAKE_POS_SMALL);
} }
void tox_box_move(f32 forwardVel, f32 a1, s16 deltaPitch, s16 deltaRoll) void tox_box_move(f32 forwardVel, f32 a1, s16 deltaPitch, s16 deltaRoll)
{ {
if (!o) { return; }
o->oPosY = 99.41124 * sins((f32)(o->oTimer + 1) / 8 * 0x8000) + o->oHomeY + 3.0f; o->oPosY = 99.41124 * sins((f32)(o->oTimer + 1) / 8 * 0x8000) + o->oHomeY + 3.0f;
o->oForwardVel = forwardVel; o->oForwardVel = forwardVel;
o->oUnkC0 = a1; o->oUnkC0 = a1;
@ -47,6 +48,7 @@ void tox_box_act_7(void) {
} }
void tox_box_act_1(void) { void tox_box_act_1(void) {
if (!o) { return; }
o->oForwardVel = 0.0f; o->oForwardVel = 0.0f;
if (o->oTimer == 0) if (o->oTimer == 0)
tox_box_shake_screen(); tox_box_shake_screen();
@ -56,16 +58,19 @@ void tox_box_act_1(void) {
} }
void tox_box_act_2(void) { void tox_box_act_2(void) {
if (!o) { return; }
if (o->oTimer == 20) if (o->oTimer == 20)
o->oAction = cur_obj_progress_direction_table(); o->oAction = cur_obj_progress_direction_table();
} }
void tox_box_act_3(void) { void tox_box_act_3(void) {
if (!o) { return; }
if (o->oTimer == 20) if (o->oTimer == 20)
o->oAction = cur_obj_progress_direction_table(); o->oAction = cur_obj_progress_direction_table();
} }
void tox_box_act_0(void) { void tox_box_act_0(void) {
if (!o) { return; }
if (!BHV_ARR_CHECK(D_8032F96C, o->oBehParams2ndByte, s8*)) { return; } if (!BHV_ARR_CHECK(D_8032F96C, o->oBehParams2ndByte, s8*)) { return; }
s8 *sp1C = D_8032F96C[o->oBehParams2ndByte]; s8 *sp1C = D_8032F96C[o->oBehParams2ndByte];
o->oAction = cur_obj_set_direction_table(sp1C); o->oAction = cur_obj_set_direction_table(sp1C);

View file

@ -2,7 +2,7 @@
void play_penguin_walking_sound(s32 walk) { void play_penguin_walking_sound(s32 walk) {
s32 sound; s32 sound;
if (o->oSoundStateID == 0) { if (o && o->oSoundStateID == 0) {
if (walk == PENGUIN_WALK_BABY) if (walk == PENGUIN_WALK_BABY)
sound = SOUND_OBJ_BABY_PENGUIN_WALK; sound = SOUND_OBJ_BABY_PENGUIN_WALK;
else // PENGUIN_WALK_BIG else // PENGUIN_WALK_BIG

View file

@ -5410,6 +5410,7 @@ void warp_camera(f32 displacementX, f32 displacementY, f32 displacementZ) {
* unless smooth movement is off, in which case the y coordinate is simply set to `goal` * unless smooth movement is off, in which case the y coordinate is simply set to `goal`
*/ */
void approach_camera_height(struct Camera *c, f32 goal, f32 inc) { void approach_camera_height(struct Camera *c, f32 goal, f32 inc) {
if (!c) { return; }
if (sStatusFlags & CAM_FLAG_SMOOTH_MOVEMENT) { if (sStatusFlags & CAM_FLAG_SMOOTH_MOVEMENT) {
if (c->pos[1] < goal) { if (c->pos[1] < goal) {
if ((c->pos[1] += inc) > goal) { if ((c->pos[1] += inc) > goal) {

View file

@ -106,7 +106,7 @@ struct Object *gMarioObjects[MAX_PLAYERS];
* This object is used frequently in object behavior code, and so is often * This object is used frequently in object behavior code, and so is often
* aliased as "o". * aliased as "o".
*/ */
struct Object *gCurrentObject; struct Object *gCurrentObject = NULL;
/** /**
* The next object behavior command to be executed. * The next object behavior command to be executed.
@ -350,6 +350,7 @@ s32 update_objects_starting_at(struct ObjectNode *objList, struct ObjectNode *fi
if (!firstObj) { return 0; } if (!firstObj) { return 0; }
s32 count = 0; s32 count = 0;
struct Object* prevObject = gCurrentObject;
while (objList != firstObj) { while (objList != firstObj) {
gCurrentObject = (struct Object *) firstObj; gCurrentObject = (struct Object *) firstObj;
@ -362,6 +363,8 @@ s32 update_objects_starting_at(struct ObjectNode *objList, struct ObjectNode *fi
count += 1; count += 1;
} }
gCurrentObject = prevObject;
return count; return count;
} }
@ -378,6 +381,7 @@ s32 update_objects_during_time_stop(struct ObjectNode *objList, struct ObjectNod
if (!firstObj) { return 0; } if (!firstObj) { return 0; }
s32 count = 0; s32 count = 0;
s32 unfrozen; s32 unfrozen;
struct Object* prevObject = gCurrentObject;
while (objList != firstObj) { while (objList != firstObj) {
gCurrentObject = (struct Object *) firstObj; gCurrentObject = (struct Object *) firstObj;
@ -414,6 +418,8 @@ s32 update_objects_during_time_stop(struct ObjectNode *objList, struct ObjectNod
count++; count++;
} }
gCurrentObject = prevObject;
return count; return count;
} }
@ -440,6 +446,7 @@ s32 update_objects_in_list(struct ObjectNode *objList) {
s32 unload_deactivated_objects_in_list(struct ObjectNode *objList) { s32 unload_deactivated_objects_in_list(struct ObjectNode *objList) {
if (!objList) { return 0; } if (!objList) { return 0; }
struct ObjectNode *obj = objList->next; struct ObjectNode *obj = objList->next;
struct Object* prevObject = gCurrentObject;
while (objList != obj) { while (objList != obj) {
gCurrentObject = (struct Object *) obj; gCurrentObject = (struct Object *) obj;
@ -458,6 +465,8 @@ s32 unload_deactivated_objects_in_list(struct ObjectNode *objList) {
} }
} }
gCurrentObject = prevObject;
return 0; return 0;
} }

File diff suppressed because it is too large Load diff

View file

@ -123,10 +123,12 @@ struct Object *obj_get_first(enum ObjectList objList) {
struct Object *obj_get_first_with_behavior_id(enum BehaviorId behaviorId) { struct Object *obj_get_first_with_behavior_id(enum BehaviorId behaviorId) {
const BehaviorScript* behavior = get_behavior_from_id(behaviorId); const BehaviorScript* behavior = get_behavior_from_id(behaviorId);
u32 sanityDepth = 0;
behavior = smlua_override_behavior(behavior); behavior = smlua_override_behavior(behavior);
if (behavior) { if (behavior) {
enum ObjectList objList = get_object_list_from_behavior(behavior); enum ObjectList objList = get_object_list_from_behavior(behavior);
for (struct Object *obj = obj_get_first(objList); obj != NULL; obj = obj_get_next(obj)) { for (struct Object *obj = obj_get_first(objList); obj != NULL; obj = obj_get_next(obj)) {
if (++sanityDepth > 10000) { break; }
if (obj->behavior == behavior && obj->activeFlags != ACTIVE_FLAG_DEACTIVATED) { if (obj->behavior == behavior && obj->activeFlags != ACTIVE_FLAG_DEACTIVATED) {
return obj; return obj;
} }
@ -137,10 +139,12 @@ struct Object *obj_get_first_with_behavior_id(enum BehaviorId behaviorId) {
struct Object *obj_get_first_with_behavior_id_and_field_s32(enum BehaviorId behaviorId, s32 fieldIndex, s32 value) { struct Object *obj_get_first_with_behavior_id_and_field_s32(enum BehaviorId behaviorId, s32 fieldIndex, s32 value) {
const BehaviorScript* behavior = get_behavior_from_id(behaviorId); const BehaviorScript* behavior = get_behavior_from_id(behaviorId);
u32 sanityDepth = 0;
behavior = smlua_override_behavior(behavior); behavior = smlua_override_behavior(behavior);
if (behavior) { if (behavior) {
enum ObjectList objList = get_object_list_from_behavior(behavior); enum ObjectList objList = get_object_list_from_behavior(behavior);
for (struct Object *obj = obj_get_first(objList); obj != NULL; obj = obj_get_next(obj)) { for (struct Object *obj = obj_get_first(objList); obj != NULL; obj = obj_get_next(obj)) {
if (++sanityDepth > 10000) { break; }
if (obj->behavior == behavior && obj->activeFlags != ACTIVE_FLAG_DEACTIVATED && obj->OBJECT_FIELD_S32(fieldIndex) == value) { if (obj->behavior == behavior && obj->activeFlags != ACTIVE_FLAG_DEACTIVATED && obj->OBJECT_FIELD_S32(fieldIndex) == value) {
return obj; return obj;
} }

View file

@ -216,9 +216,11 @@ void network_receive_level_macro(struct Packet* p) {
u8 mask = ((o2->oBehParams2ndByte & GOOMBA_BP_TRIPLET_FLAG_MASK) >> 2); u8 mask = ((o2->oBehParams2ndByte & GOOMBA_BP_TRIPLET_FLAG_MASK) >> 2);
if (info & mask) { if (info & mask) {
extern void mark_goomba_as_dead(void); extern void mark_goomba_as_dead(void);
struct Object* prevObject = gCurrentObject;
gCurrentObject = o2; gCurrentObject = o2;
mark_goomba_as_dead(); mark_goomba_as_dead();
obj_mark_for_deletion(o2); obj_mark_for_deletion(o2);
gCurrentObject = prevObject;
} }
} }
LOG_INFO("rx macro special: goomba triplet"); LOG_INFO("rx macro special: goomba triplet");

View file

@ -68,6 +68,7 @@ void network_receive_spawn_star(struct Packet* p) {
} }
void network_send_spawn_star_nle(struct Object* o, u32 params) { void network_send_spawn_star_nle(struct Object* o, u32 params) {
if (!o) { return; }
u8 globalIndex = UNKNOWN_GLOBAL_INDEX; u8 globalIndex = UNKNOWN_GLOBAL_INDEX;
if (o->behavior == smlua_override_behavior(bhvMario)) { if (o->behavior == smlua_override_behavior(bhvMario)) {
u8 localIndex = o->oBehParams - 1; u8 localIndex = o->oBehParams - 1;