From 70ca0af987be1132abe2c3cb44c942cd6e33b9ca Mon Sep 17 00:00:00 2001 From: uncletrunks Date: Thu, 14 May 2020 20:31:52 -0500 Subject: [PATCH] adds cylindrical billboarding, enables it for trees. --- data/behavior_data.c | 14 +-- src/engine/behavior_script.c | 159 +++++++++++++++++--------------- src/engine/graph_node.h | 3 +- src/engine/math_util.c | 20 ++++ src/engine/math_util.h | 1 + src/game/behaviors/cannon.inc.c | 10 +- src/game/object_helpers.c | 6 +- src/game/object_helpers.h | 1 + src/game/rendering_graph_node.c | 9 +- 9 files changed, 134 insertions(+), 89 deletions(-) diff --git a/data/behavior_data.c b/data/behavior_data.c index 13212d3b..8fc3d518 100644 --- a/data/behavior_data.c +++ b/data/behavior_data.c @@ -114,7 +114,7 @@ // Often used to end behavior scripts that do not contain an infinite loop. #define BREAK() \ BC_B(0x0A) - + // Exits the behavior script, unused. #define BREAK_UNUSED() \ BC_B(0x0B) @@ -175,15 +175,15 @@ #define ADD_INT_RAND_RSHIFT(field, min, rshift) \ BC_BBH(0x17, field, min), \ BC_H(rshift) - + // No operation. Unused. #define CMD_NOP_1(field) \ BC_BB(0x18, field) - + // No operation. Unused. #define CMD_NOP_2(field) \ BC_BB(0x19, field) - + // No operation. Unused. #define CMD_NOP_3(field) \ BC_BB(0x1A, field) @@ -219,6 +219,9 @@ #define BILLBOARD() \ BC_B(0x21) +#define CYLBOARD() \ + BC_B(0x38) + // Hides the current object. #define HIDE() \ BC_B(0x22) @@ -3181,6 +3184,7 @@ const BehaviorScript bhvFloorTrapInCastle[] = { const BehaviorScript bhvTree[] = { BEGIN(OBJ_LIST_POLELIKE), BILLBOARD(), + CYLBOARD(), OR_INT(oFlags, OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE), SET_INT(oInteractType, INTERACT_POLE), SET_HITBOX(/*Radius*/ 80, /*Height*/ 500), @@ -6105,5 +6109,3 @@ const BehaviorScript bhvIntroScene[] = { CALL_NATIVE(bhv_intro_scene_loop), END_LOOP(), }; - - diff --git a/src/engine/behavior_script.c b/src/engine/behavior_script.c index feb6fefd..539f3a32 100644 --- a/src/engine/behavior_script.c +++ b/src/engine/behavior_script.c @@ -98,10 +98,10 @@ static void cur_obj_bhv_stack_push(uintptr_t bhvAddr) { // Retrieve the last behavior command address from the object's behavior stack. static uintptr_t cur_obj_bhv_stack_pop(void) { uintptr_t bhvAddr; - + gCurrentObject->bhvStackIndex--; bhvAddr = gCurrentObject->bhvStack[gCurrentObject->bhvStackIndex]; - + return bhvAddr; } @@ -115,7 +115,7 @@ static void stub_behavior_script_1(void) { // Usage: HIDE() static s32 bhv_cmd_hide(void) { cur_obj_hide(); - + gCurBhvCommand++; return BHV_PROC_CONTINUE; } @@ -124,7 +124,7 @@ static s32 bhv_cmd_hide(void) { // Usage: DISABLE_RENDERING() static s32 bhv_cmd_disable_rendering(void) { gCurrentObject->header.gfx.node.flags &= ~GRAPH_RENDER_ACTIVE; - + gCurBhvCommand++; return BHV_PROC_CONTINUE; } @@ -133,7 +133,15 @@ static s32 bhv_cmd_disable_rendering(void) { // Usage: BILLBOARD() static s32 bhv_cmd_billboard(void) { gCurrentObject->header.gfx.node.flags |= GRAPH_RENDER_BILLBOARD; - + + gCurBhvCommand++; + return BHV_PROC_CONTINUE; +} + +// Command 0x +static s32 bhv_cmd_cylboard(void) { + gCurrentObject->header.gfx.node.flags |= GRAPH_RENDER_CYLBOARD; + gCurBhvCommand++; return BHV_PROC_CONTINUE; } @@ -142,9 +150,9 @@ static s32 bhv_cmd_billboard(void) { // Usage: SET_MODEL(modelID) static s32 bhv_cmd_set_model(void) { s32 modelID = BHV_CMD_GET_2ND_S16(0); - + gCurrentObject->header.gfx.sharedChild = gLoadedGraphNodes[modelID]; - + gCurBhvCommand++; return BHV_PROC_CONTINUE; } @@ -216,7 +224,7 @@ static s32 bhv_cmd_break_unused(void) { static s32 bhv_cmd_call(void) { const BehaviorScript *jumpAddress; gCurBhvCommand++; - + cur_obj_bhv_stack_push(BHV_CMD_GET_ADDR_OF_CMD(1)); // Store address of the next bhv command in the stack. jumpAddress = segmented_to_virtual(BHV_CMD_GET_VPTR(0)); gCurBhvCommand = jumpAddress; // Jump to the new address. @@ -300,7 +308,7 @@ static s32 bhv_cmd_begin_repeat(void) { static s32 bhv_cmd_end_repeat(void) { u32 count = cur_obj_bhv_stack_pop(); // Retrieve loop count from the stack. count--; - + if (count != 0) { gCurBhvCommand = (const BehaviorScript *) cur_obj_bhv_stack_pop(); // Jump back to the first command in the loop // Save address and count to the stack again @@ -320,7 +328,7 @@ static s32 bhv_cmd_end_repeat(void) { static s32 bhv_cmd_end_repeat_continue(void) { u32 count = cur_obj_bhv_stack_pop(); count--; - + if (count != 0) { gCurBhvCommand = (const BehaviorScript *) cur_obj_bhv_stack_pop(); // Jump back to the first command in the loop // Save address and count to the stack again @@ -546,7 +554,7 @@ static s32 bhv_cmd_drop_to_floor(void) { f32 x = gCurrentObject->oPosX; f32 y = gCurrentObject->oPosY; f32 z = gCurrentObject->oPosZ; - + f32 floor = find_floor_height(x, y + 200.0f, z); gCurrentObject->oPosY = floor; gCurrentObject->oMoveFlags |= OBJ_MOVE_ON_GROUND; @@ -665,7 +673,7 @@ static s32 bhv_cmd_nop_4(void) { static s32 bhv_cmd_begin(void) { // These objects were likely very early objects, which is why this code is here // instead of in the respective behavior scripts. - + // Initiate the room if the object is a haunted chair or the mad piano. if (cur_obj_has_behavior(bhvHauntedChair)) { bhv_init_room(); @@ -696,7 +704,7 @@ static void bhv_cmd_set_int_random_from_table(s32 tableSize) { } cur_obj_set_int(field, table[(s32)(tableSize * random_float())]); - + // Does not increment gCurBhvCommand or return a bhv status } @@ -719,7 +727,7 @@ static s32 bhv_cmd_set_int_random_from_table(void) { // Set the field to a random entry of the table. cur_obj_set_int(field, table[(s32)(tableSize * random_float())]); - + gCurBhvCommand += (tableSize / 2) + 1; return BHV_PROC_CONTINUE; } @@ -729,9 +737,9 @@ static s32 bhv_cmd_set_int_random_from_table(void) { // Usage: LOAD_COLLISION_DATA(collisionData) static s32 bhv_cmd_load_collision_data(void) { u32 *collisionData = segmented_to_virtual(BHV_CMD_GET_VPTR(1)); - + gCurrentObject->collisionData = collisionData; - + gCurBhvCommand += 2; return BHV_PROC_CONTINUE; } @@ -742,7 +750,7 @@ static s32 bhv_cmd_set_home(void) { gCurrentObject->oHomeX = gCurrentObject->oPosX; gCurrentObject->oHomeY = gCurrentObject->oPosY; gCurrentObject->oHomeZ = gCurrentObject->oPosZ; - + gCurBhvCommand++; return BHV_PROC_CONTINUE; } @@ -815,9 +823,9 @@ static s32 bhv_cmd_parent_bit_clear(void) { // Usage: SPAWN_WATER_DROPLET(dropletParams) static s32 bhv_cmd_spawn_water_droplet(void) { struct WaterDropletParams *dropletParams = BHV_CMD_GET_VPTR(1); - + spawn_water_droplet(gCurrentObject, dropletParams); - + gCurBhvCommand += 2; return BHV_PROC_CONTINUE; } @@ -842,62 +850,63 @@ void stub_behavior_script_2(void) { typedef s32 (*BhvCommandProc)(void); static BhvCommandProc BehaviorCmdTable[] = { - bhv_cmd_begin, - bhv_cmd_delay, - bhv_cmd_call, - bhv_cmd_return, - bhv_cmd_goto, - bhv_cmd_begin_repeat, - bhv_cmd_end_repeat, - bhv_cmd_end_repeat_continue, - bhv_cmd_begin_loop, - bhv_cmd_end_loop, - bhv_cmd_break, - bhv_cmd_break_unused, - bhv_cmd_call_native, - bhv_cmd_add_float, - bhv_cmd_set_float, - bhv_cmd_add_int, - bhv_cmd_set_int, - bhv_cmd_or_int, - bhv_cmd_bit_clear, - bhv_cmd_set_int_rand_rshift, - bhv_cmd_set_random_float, - bhv_cmd_set_random_int, - bhv_cmd_add_random_float, - bhv_cmd_add_int_rand_rshift, - bhv_cmd_nop_1, - bhv_cmd_nop_2, - bhv_cmd_nop_3, - bhv_cmd_set_model, - bhv_cmd_spawn_child, - bhv_cmd_deactivate, - bhv_cmd_drop_to_floor, - bhv_cmd_sum_float, - bhv_cmd_sum_int, - bhv_cmd_billboard, - bhv_cmd_hide, - bhv_cmd_set_hitbox, - bhv_cmd_nop_4, - bhv_cmd_delay_var, - bhv_cmd_begin_repeat_unused, - bhv_cmd_load_animations, - bhv_cmd_animate, - bhv_cmd_spawn_child_with_param, - bhv_cmd_load_collision_data, - bhv_cmd_set_hitbox_with_offset, - bhv_cmd_spawn_obj, - bhv_cmd_set_home, - bhv_cmd_set_hurtbox, - bhv_cmd_set_interact_type, - bhv_cmd_set_obj_physics, - bhv_cmd_set_interact_subtype, - bhv_cmd_scale, - bhv_cmd_parent_bit_clear, - bhv_cmd_animate_texture, - bhv_cmd_disable_rendering, - bhv_cmd_set_int_unused, - bhv_cmd_spawn_water_droplet, + bhv_cmd_begin, //00 + bhv_cmd_delay, //01 + bhv_cmd_call, //02 + bhv_cmd_return, //03 + bhv_cmd_goto, //04 + bhv_cmd_begin_repeat, //05 + bhv_cmd_end_repeat, //06 + bhv_cmd_end_repeat_continue, //07 + bhv_cmd_begin_loop, //08 + bhv_cmd_end_loop, //09 + bhv_cmd_break, //0A + bhv_cmd_break_unused, //0B + bhv_cmd_call_native, //0C + bhv_cmd_add_float, //0D + bhv_cmd_set_float, //0E + bhv_cmd_add_int, //0F + bhv_cmd_set_int, //10 + bhv_cmd_or_int, //11 + bhv_cmd_bit_clear, //12 + bhv_cmd_set_int_rand_rshift, //13 + bhv_cmd_set_random_float, //14 + bhv_cmd_set_random_int, //15 + bhv_cmd_add_random_float, //16 + bhv_cmd_add_int_rand_rshift, //17 + bhv_cmd_nop_1, //18 + bhv_cmd_nop_2, //19 + bhv_cmd_nop_3, //1A + bhv_cmd_set_model, //1B + bhv_cmd_spawn_child, //1C + bhv_cmd_deactivate, //1D + bhv_cmd_drop_to_floor, //1E + bhv_cmd_sum_float, //1F + bhv_cmd_sum_int, //20 + bhv_cmd_billboard, //21 + bhv_cmd_hide, //22 + bhv_cmd_set_hitbox, //23 + bhv_cmd_nop_4, //24 + bhv_cmd_delay_var, //25 + bhv_cmd_begin_repeat_unused, //26 + bhv_cmd_load_animations, //27 + bhv_cmd_animate, //28 + bhv_cmd_spawn_child_with_param, //29 + bhv_cmd_load_collision_data, //2A + bhv_cmd_set_hitbox_with_offset, //2B + bhv_cmd_spawn_obj, //2C + bhv_cmd_set_home, //2D + bhv_cmd_set_hurtbox, //2E + bhv_cmd_set_interact_type, //2F + bhv_cmd_set_obj_physics, //30 + bhv_cmd_set_interact_subtype, //31 + bhv_cmd_scale, //32 + bhv_cmd_parent_bit_clear, //33 + bhv_cmd_animate_texture, //34 + bhv_cmd_disable_rendering, //35 + bhv_cmd_set_int_unused, //36 + bhv_cmd_spawn_water_droplet, //37 + bhv_cmd_cylboard //38 }; // Execute the behavior script of the current object, process the object flags, and other miscellaneous code for updating objects. diff --git a/src/engine/graph_node.h b/src/engine/graph_node.h index ac05ed14..c99e5f32 100644 --- a/src/engine/graph_node.h +++ b/src/engine/graph_node.h @@ -30,12 +30,13 @@ extern Vec3s gVec3sOne; #define GRAPH_RENDER_Z_BUFFER (1 << 3) #define GRAPH_RENDER_INVISIBLE (1 << 4) #define GRAPH_RENDER_HAS_ANIMATION (1 << 5) +#define GRAPH_RENDER_CYLBOARD (1 << 6) // Whether the node type has a function pointer of type GraphNodeFunc #define GRAPH_NODE_TYPE_FUNCTIONAL 0x100 // Type used for Bowser and an unused geo function in obj_behaviors.c -#define GRAPH_NODE_TYPE_400 0x400 +#define GRAPH_NODE_TYPE_400 0x400 // The discriminant for different types of geo nodes #define GRAPH_NODE_TYPE_ROOT 0x001 diff --git a/src/engine/math_util.c b/src/engine/math_util.c index 8643f5e0..8ce410d6 100644 --- a/src/engine/math_util.c +++ b/src/engine/math_util.c @@ -377,6 +377,26 @@ void mtxf_billboard(Mat4 dest, Mat4 mtx, Vec3f position, s16 angle) { dest[3][3] = 1; } +void mtxf_cylboard(Mat4 dest, Mat4 mtx, Vec3f position, s16 angle) { //straight up mtxf_billboard but minus the dest[1][n] lines. transform for cylindrical billboards + dest[0][0] = coss(angle); + dest[0][1] = sins(angle); + dest[0][2] = 0; + dest[0][3] = 0; + + dest[2][0] = 0; + dest[2][1] = 0; + dest[2][2] = 1; + dest[2][3] = 0; + + dest[3][0] = + mtx[0][0] * position[0] + mtx[1][0] * position[1] + mtx[2][0] * position[2] + mtx[3][0]; + dest[3][1] = + mtx[0][1] * position[0] + mtx[1][1] * position[1] + mtx[2][1] * position[2] + mtx[3][1]; + dest[3][2] = + mtx[0][2] * position[0] + mtx[1][2] * position[1] + mtx[2][2] * position[2] + mtx[3][2]; + dest[3][3] = 1; +} + /** * Set 'dest' to a transformation matrix that aligns an object with the terrain * based on the normal. Used for enemies. diff --git a/src/engine/math_util.h b/src/engine/math_util.h index 650fe973..b8b7f1b8 100644 --- a/src/engine/math_util.h +++ b/src/engine/math_util.h @@ -56,6 +56,7 @@ void mtxf_lookat(f32 mtx[4][4], Vec3f b, Vec3f c, s16 d); void mtxf_rotate_zxy_and_translate(f32 mtx[4][4], Vec3f b, Vec3s c); void mtxf_rotate_xyz_and_translate(f32 mtx[4][4], Vec3f b, Vec3s c); void mtxf_billboard(f32 mtx1[4][4], f32 mtx2[4][4], Vec3f c, s16 d); +void mtxf_cylboard(f32 mtx1[4][4], f32 mtx2[4][4], Vec3f c, s16 d); void mtxf_align_terrain_normal(f32 mtx[4][4], Vec3f b, Vec3f c, s16 d); void mtxf_align_terrain_triangle(f32 mtx[4][4], Vec3f b, s16 c, f32 d); void mtxf_mul(f32 dest[4][4], f32 a[4][4], f32 b[4][4]); diff --git a/src/game/behaviors/cannon.inc.c b/src/game/behaviors/cannon.inc.c index 5f55ca83..a8cfcab3 100644 --- a/src/game/behaviors/cannon.inc.c +++ b/src/game/behaviors/cannon.inc.c @@ -17,9 +17,11 @@ void opened_cannon_act_0(void) { cur_obj_enable_rendering(); cur_obj_become_tangible(); } + cur_obj_become_tangible(); + cur_obj_enable_rendering(); if (o->oDistanceToMario < 500.0f) { - cur_obj_become_tangible(); - cur_obj_enable_rendering(); + //cur_obj_become_tangible(); + //cur_obj_enable_rendering(); if (o->oInteractStatus & INT_STATUS_INTERACTED && (!(o->oInteractStatus & INT_STATUS_TOUCHED_BOB_OMB))) // bob-omb explodes when it gets into a cannon @@ -30,8 +32,8 @@ void opened_cannon_act_0(void) { } else o->oInteractStatus = 0; } else { - cur_obj_become_intangible(); - cur_obj_disable_rendering(); + //cur_obj_become_intangible(); + //cur_obj_disable_rendering(); o->oCannonUnk10C = 0; } } diff --git a/src/game/object_helpers.c b/src/game/object_helpers.c index 42ad0e57..e05f7743 100644 --- a/src/game/object_helpers.c +++ b/src/game/object_helpers.c @@ -984,7 +984,7 @@ BAD_RETURN(s16) cur_obj_reverse_animation(void) { BAD_RETURN(s32) cur_obj_extend_animation_if_at_end(void) { s32 sp4 = o->header.gfx.unk38.animFrame; s32 sp0 = o->header.gfx.unk38.curAnim->unk08 - 2; - + if (sp4 == sp0) o->header.gfx.unk38.animFrame--; } @@ -1595,6 +1595,10 @@ void obj_set_billboard(struct Object *obj) { obj->header.gfx.node.flags |= GRAPH_RENDER_BILLBOARD; } +void obj_set_cylboard(struct Object *obj) { + obj->header.gfx.node.flags |= GRAPH_RENDER_CYLBOARD; +} + void cur_obj_set_hitbox_radius_and_height(f32 radius, f32 height) { o->hitboxRadius = radius; o->hitboxHeight = height; diff --git a/src/game/object_helpers.h b/src/game/object_helpers.h index 80806bde..577f8f66 100644 --- a/src/game/object_helpers.h +++ b/src/game/object_helpers.h @@ -292,6 +292,7 @@ extern void cur_obj_shake_y(f32); void cur_obj_start_cam_event(struct Object *obj, s32 cameraEvent); // extern ? set_mario_interact_hoot_if_in_range(?); void obj_set_billboard(struct Object *a0); +void obj_set_cylboard(struct Object *a0); void cur_obj_set_hitbox_radius_and_height(f32,f32); void cur_obj_set_hurtbox_radius_and_height(f32,f32); // extern ? obj_spawn_loot_coins(?); diff --git a/src/game/rendering_graph_node.c b/src/game/rendering_graph_node.c index 93a9a8a3..dd66b033 100644 --- a/src/game/rendering_graph_node.c +++ b/src/game/rendering_graph_node.c @@ -803,8 +803,13 @@ static void geo_process_object(struct Object *node) { mtxf_mul(gMatStack[gMatStackIndex + 1], (void *) node->header.gfx.throwMatrix, gMatStack[gMatStackIndex]); } else if (node->header.gfx.node.flags & GRAPH_RENDER_BILLBOARD) { - mtxf_billboard(gMatStack[gMatStackIndex + 1], gMatStack[gMatStackIndex], - node->header.gfx.pos, gCurGraphNodeCamera->roll); + if (node->header.gfx.node.flags & GRAPH_RENDER_CYLBOARD){ + mtxf_cylboard(gMatStack[gMatStackIndex + 1], gMatStack[gMatStackIndex], + node->header.gfx.pos, gCurGraphNodeCamera->roll); + } else { + mtxf_billboard(gMatStack[gMatStackIndex + 1], gMatStack[gMatStackIndex], + node->header.gfx.pos, gCurGraphNodeCamera->roll); + } } else { mtxf_rotate_zxy_and_translate(mtxf, node->header.gfx.pos, node->header.gfx.angle); mtxf_mul(gMatStack[gMatStackIndex + 1], mtxf, gMatStack[gMatStackIndex]);