From b0d7f98ff4a3ad3072b7119c63f5c1472b496d8a Mon Sep 17 00:00:00 2001 From: MegaMech <7255464+MegaMech@users.noreply.github.com> Date: Wed, 4 Dec 2024 11:18:57 -0700 Subject: [PATCH] Reimplement penguins --- src/code_80057C60.c | 2 + src/code_80057C60_var.c | 2 +- src/engine/World.cpp | 8 + src/engine/World.h | 4 + src/engine/courses/SherbetLand.cpp | 66 ++++- src/engine/courses/YoshiValley.cpp | 6 + src/engine/vehicles/OPenguin.cpp | 383 +++++++++++++++++++++++++++++ src/engine/vehicles/OPenguin.h | 68 +++++ src/port/Game.cpp | 18 ++ src/port/Game.h | 4 + src/render_objects.c | 9 - 11 files changed, 556 insertions(+), 14 deletions(-) create mode 100644 src/engine/vehicles/OPenguin.cpp create mode 100644 src/engine/vehicles/OPenguin.h diff --git a/src/code_80057C60.c b/src/code_80057C60.c index bc0000bd6..96cf3e171 100644 --- a/src/code_80057C60.c +++ b/src/code_80057C60.c @@ -703,6 +703,7 @@ void render_object_for_player(s32 cameraId) { CourseManager_RenderCourseObjects(cameraId); CourseManager_TrainSmokeDraw(cameraId); CourseManager_DrawThwomps(cameraId); + CourseManager_DrawPenguins(cameraId); // switch (gCurrentCourseId) { // case COURSE_MARIO_RACEWAY: @@ -1580,6 +1581,7 @@ void update_object(void) { CourseManager_UpdateCourseObjects(); CourseManager_TrainSmokeTick(); + CourseManager_TickPenguins(); // switch (gCurrentCourseId) { // case COURSE_MARIO_RACEWAY: diff --git a/src/code_80057C60_var.c b/src/code_80057C60_var.c index b06899cd3..fda4d187c 100644 --- a/src/code_80057C60_var.c +++ b/src/code_80057C60_var.c @@ -17,7 +17,7 @@ f32 D_8018D00C; s16 D_8018D010; UNUSED s32 D_8018D014; s16 D_8018D018; -f32 xOrientation; +f32 xOrientation; // For mirror/extra mode s16 D_8018D020; f32 D_8018D028[8]; s16 D_8018D048; diff --git a/src/engine/World.cpp b/src/engine/World.cpp index aae7f3568..b8371b2c8 100644 --- a/src/engine/World.cpp +++ b/src/engine/World.cpp @@ -47,6 +47,7 @@ static size_t tankerTrucks; static size_t cars; static size_t boats; static size_t thwomps; +static size_t penguins; /** * Note that you can only remove the tender if there are no carriages @@ -104,6 +105,13 @@ void World::AddThwomp(s16 x, s16 z, s16 direction, f32 scale, s16 behaviour, s16 gNumActiveThwomps = thwomps; } +std::shared_ptr World::AddPenguin(Vec3f pos, u16 direction, OPenguin::PenguinType type, OPenguin::Behaviour behaviour) { + auto penguin = std::make_shared(penguins, pos, direction, type, behaviour); + Penguins.push_back(penguin); + penguins++; + return penguin; +} + u32 World::GetCupIndex() { return this->CupIndex; } diff --git a/src/engine/World.h b/src/engine/World.h index a5d9770a5..c339801d9 100644 --- a/src/engine/World.h +++ b/src/engine/World.h @@ -10,6 +10,7 @@ #include "vehicles/Train.h" #include "TrainCrossing.h" #include "vehicles/OThwomp.h" +#include "vehicles/OPenguin.h" #include #include "Actor.h" @@ -145,6 +146,9 @@ public: std::vector> Thwomps; void AddThwomp(s16 x, s16 z, s16 direction, f32 scale, s16 behaviour, s16 primAlpha, u16 boundingBoxSize = 7); + std::vector> Penguins; + std::shared_ptr AddPenguin(Vec3f pos, u16 direction, OPenguin::PenguinType type, OPenguin::Behaviour behaviour); + TrainCrossing* AddCrossing(Vec3f position, u32 waypointMin, u32 waypointMax, f32 approachRadius, f32 exitRadius); std::vector> Crossings; diff --git a/src/engine/courses/SherbetLand.cpp b/src/engine/courses/SherbetLand.cpp index 19bfa573e..d483d966c 100644 --- a/src/engine/courses/SherbetLand.cpp +++ b/src/engine/courses/SherbetLand.cpp @@ -150,23 +150,81 @@ void SherbetLand::MinimapSettings() { } void SherbetLand::InitCourseObjects() { - for (size_t i = 0; i < NUM_PENGUINS; i++) { - init_object(indexObjectList1[i], 0); + //! @bug Skip spawning penguins due to animation crash for now + if (gGamestate == CREDITS_SEQUENCE) { + return; } + +// Originally, multiplayer did not spawn the big penguin +// if (gPlayerCountSelection1 == 1) { + Vec3f pos = {-383.0f, 2.0f, -690.0f}; + gWorldInstance.AddPenguin(pos, 0, OPenguin::PenguinType::EMPEROR, OPenguin::Behaviour::STRUT); +// } + + + Vec3f pos2 = {-2960.0f, -80.0f, 1521.0f}; + auto penguin = gWorldInstance.AddPenguin(pos2, 0x150, OPenguin::PenguinType::ADULT, OPenguin::Behaviour::CIRCLE); + auto penguin2 = gWorldInstance.AddPenguin(pos2, 0x150, OPenguin::PenguinType::ADULT, OPenguin::Behaviour::CIRCLE); + penguin->Diameter = penguin2->Diameter = 100.0f; + + Vec3f pos3 = {-2490.0f, -80.0f, 1612.0f}; + auto penguin3 = gWorldInstance.AddPenguin(pos3, 0x100, OPenguin::PenguinType::ADULT, OPenguin::Behaviour::CIRCLE); + auto penguin4 = gWorldInstance.AddPenguin(pos3, 0x100, OPenguin::PenguinType::ADULT, OPenguin::Behaviour::CIRCLE); + penguin3->Diameter = penguin4->Diameter = 80.0f; + + Vec3f pos4 = {-2098.0f, -80.0f, 1624.0f}; + auto penguin5 = gWorldInstance.AddPenguin(pos4, 0xFF00, OPenguin::PenguinType::ADULT, OPenguin::Behaviour::CIRCLE); + auto penguin6 = gWorldInstance.AddPenguin(pos4, 0xFF00, OPenguin::PenguinType::ADULT, OPenguin::Behaviour::CIRCLE); + penguin5->Diameter = penguin6->Diameter = 80.0f; + + + Vec3f pos5 = {-2080.0f, -80.0f, 1171.0f}; + auto penguin7 = gWorldInstance.AddPenguin(pos5, 0x150, OPenguin::PenguinType::ADULT, OPenguin::Behaviour::CIRCLE); + auto penguin8 = gWorldInstance.AddPenguin(pos5, 0x150, OPenguin::PenguinType::ADULT, OPenguin::Behaviour::CIRCLE); + penguin7->Diameter = penguin8->Diameter = 80.0f; + + + if (gGamestate == CREDITS_SEQUENCE) { + Vec3f pos6 = {380.0, 0.0f, -535.0f}; + auto penguin9 = gWorldInstance.AddPenguin(pos6, 0x9000, OPenguin::PenguinType::CREDITS, OPenguin::Behaviour::SLIDE3); + penguin9->MirrorModeAngleOffset = -0x4000; + } else { + Vec3f pos6 = {146.0f, 0.0f, -380.0f}; + auto penguin9 = gWorldInstance.AddPenguin(pos6, 0x9000, OPenguin::PenguinType::CHICK, OPenguin::Behaviour::SLIDE3); + penguin9->MirrorModeAngleOffset = -0x4000; + } + + Vec3f pos7 = {380.0f, 0.0f, -766.0f}; + auto penguin10 = gWorldInstance.AddPenguin(pos7, 0x5000, OPenguin::PenguinType::CHICK, OPenguin::Behaviour::SLIDE4); + penguin10->MirrorModeAngleOffset = 0x8000; + + Vec3f pos8 = {-2300.0f, 0.0f, -210.0f}; + auto penguin11 = gWorldInstance.AddPenguin(pos8, 0xC000, OPenguin::PenguinType::CHICK, OPenguin::Behaviour::SLIDE6); + penguin11->MirrorModeAngleOffset = 0x8000; + + Vec3f pos9 = {-2500.0f, 0.0f, -250.0f}; + auto penguin12 = gWorldInstance.AddPenguin(pos9, 0x4000, OPenguin::PenguinType::CHICK, OPenguin::Behaviour::SLIDE6); + penguin12->MirrorModeAngleOffset = 0x8000; + + Vec3f pos10 = {-535.0f, 0.0f, 875.0f}; + auto penguin13 = gWorldInstance.AddPenguin(pos10, 0x8000, OPenguin::PenguinType::CHICK, OPenguin::Behaviour::SLIDE6); + penguin13->MirrorModeAngleOffset = -0x4000; + + Vec3f pos11 = {-250.0f, 0.0f, 953.0f}; + auto penguin14 = gWorldInstance.AddPenguin(pos11, 0x9000, OPenguin::PenguinType::CHICK, OPenguin::Behaviour::SLIDE6); + penguin14->MirrorModeAngleOffset = -0x4000; } void SherbetLand::UpdateCourseObjects() { if (gGamestate != CREDITS_SEQUENCE) { func_800842C8(); } - update_penguins(); } void SherbetLand::RenderCourseObjects(s32 cameraId) { if (gGamestate != CREDITS_SEQUENCE) { func_80052E30(cameraId); } - render_object_train_penguins(cameraId); } void SherbetLand::SomeSounds() { diff --git a/src/engine/courses/YoshiValley.cpp b/src/engine/courses/YoshiValley.cpp index 3c0a195f4..474d3f3d2 100644 --- a/src/engine/courses/YoshiValley.cpp +++ b/src/engine/courses/YoshiValley.cpp @@ -141,6 +141,12 @@ void YoshiValley::MinimapSettings() { void YoshiValley::InitCourseObjects() { size_t objectId; size_t i; + + //! @bug Skip spawning due to animation crash for now + if (gGamestate == CREDITS_SEQUENCE) { + return; + } + for (i = 0; i < NUM_YV_FLAG_POLES; i++) { init_object(indexObjectList1[i], 0); } diff --git a/src/engine/vehicles/OPenguin.cpp b/src/engine/vehicles/OPenguin.cpp new file mode 100644 index 000000000..e8d97116a --- /dev/null +++ b/src/engine/vehicles/OPenguin.cpp @@ -0,0 +1,383 @@ +#include +#include +#include "engine/vehicles/OPenguin.h" +#include + +#include "port/Game.h" + +extern "C" { +#include "macros.h" +#include "main.h" +#include "actors.h" +#include "math_util.h" +#include "sounds.h" +#include "update_objects.h" +#include "render_player.h" +#include "external.h" +#include "bomb_kart.h" +#include "collision.h" +#include "code_80086E70.h" +#include "render_objects.h" +#include "code_80057C60.h" +#include "defines.h" +#include "code_80005FD0.h" +#include "math_util_2.h" +#include "collision.h" +#include "assets/bowsers_castle_data.h" +#include "ceremony_and_credits.h" +#include "objects.h" +#include "update_objects.h" +#include "render_objects.h" +#include "course_offsets.h" +#include "data/some_data.h" +extern s8 gPlayerCount; +} + +OPenguin::OPenguin(s32 i, Vec3f pos, u16 direction, PenguinType type, Behaviour behaviour) { + if (i >= 32) { + printf("MAX penguin REACHED (32), skipping\n"); + return; + } + _idx = i; + _type = type; + _bhv = behaviour; + + s32 objectIndex = indexObjectList1[i]; + init_object(objectIndex, 0); + + Object *object = &gObjectList[objectIndex]; + object->origin_pos[0] = pos[0] * xOrientation; + object->origin_pos[1] = pos[1]; + object->origin_pos[2] = pos[2]; + object->unk_0C6 = direction; + + switch(type) { + case PenguinType::CHICK: + object->surfaceHeight = 5.0f; + object->sizeScaling = 0.04f; + object->boundingBoxSize = 4; + break; + case PenguinType::ADULT: + object->surfaceHeight = -80.0f; + object->sizeScaling = 0.08f; + object->boundingBoxSize = 4; + break; + case PenguinType::CREDITS: + object->surfaceHeight = -80.0f; + object->sizeScaling = 0.08f; + object->sizeScaling = 0.15f; + break; + case PenguinType::EMPEROR: + object->sizeScaling = 0.2f; + object->boundingBoxSize = 0x000C; + break; + } + +} + +void OPenguin::Tick(void) { + s32 objectIndex; + + objectIndex = indexObjectList1[_idx]; + if (gObjectList[objectIndex].state != 0) { + if (_type == PenguinType::EMPEROR) { + OPenguin::EmperorPenguin(objectIndex); + } else { + OPenguin::OtherPenguin(objectIndex); + } + + OPenguin::Behaviours(objectIndex, _idx); + } + if (func_80072320(objectIndex, 1) != 0) { + func_80089820(objectIndex, 1.75f, 1.5f, 0x1900A046U); + } else if (func_80072320(objectIndex, 8) != 0) { + func_80089820(objectIndex, 1.3f, 1.0f, 0x1900A046U); + } else { + func_80089820(objectIndex, 1.5f, 1.25f, 0x1900A046U); + } + if ((is_obj_flag_status_active(objectIndex, 0x02000000) != 0) && + (func_80072354(objectIndex, 0x00000020) != 0)) { + func_800722A4(objectIndex, 0x00000060); + set_object_flag_status_false(objectIndex, 0x02000000); + } +} + +void OPenguin::Draw(s32 cameraId) { + s32 objectIndex; + s32 temp_s1; + s32 drawDistance; + u16 var_s1; + u32 var_s3; + + if (gPlayerCountSelection1 == 1) { + var_s3 = 0x0003D090; + } else if (gPlayerCountSelection1 == 2) { + var_s3 = 0x00027100; + } else { + var_s3 = 0x00015F90; + } + + objectIndex = indexObjectList1[_idx]; + if (gObjectList[objectIndex].state >= 2) { + if (gPlayerCountSelection1 == 1) { + var_s1 = 0x4000; + if (_idx == 0) { + drawDistance = 0x000005DC; + } else if (func_80072320(objectIndex, 8) != 0) { + drawDistance = 0x00000320; + } else { + drawDistance = 0x000003E8; + } + } else { + if (func_80072320(objectIndex, 8) != 0) { + drawDistance = 0x000001F4; + var_s1 = 0x4000; + } else { + drawDistance = 0x00000258; + var_s1 = 0x5555; + } + } + temp_s1 = func_8008A364(objectIndex, cameraId, var_s1, drawDistance); + if (is_obj_flag_status_active(objectIndex, VISIBLE) != 0) { + func_800557B4(objectIndex, (u32) temp_s1, var_s3); + } + } +} + +void OPenguin::Behaviours(s32 objectIndex, s32 arg1) { + Object* object; + + object = &gObjectList[objectIndex]; + switch (_bhv) { + case 1: // emperor + func_80085080(objectIndex); + break; + case 2: + func_8008502C(objectIndex, arg1); + break; + case 3: + func_80084D2C(objectIndex, 0); + break; + case 4: + func_80084D2C(objectIndex, 1); + break; + case 5: + func_80084D2C(objectIndex, 2); + break; + case 6: + func_80084D2C(objectIndex, 3); + break; + } + if (func_80072320(objectIndex, 0x00000020) != 0) { + if (func_80072320(objectIndex, 0x00000040) != 0) { + func_800722CC(objectIndex, 0x00000040); + object->unk_084[6] = 0; + object->unk_084[7] = 0x0096; + } + if (object->unk_084[7] == 0) { + func_800722CC(objectIndex, 0x00000020); + } else { + object->unk_084[7]--; + object->orientation[0] = object->direction_angle[0]; + object->orientation[1] += 0x2000; + object->orientation[2] = object->direction_angle[2]; + } + } else { + object->orientation[0] = object->direction_angle[0]; + object->orientation[1] = object->direction_angle[1]; + object->orientation[2] = object->direction_angle[2]; + } +} + +void OPenguin::EmperorPenguin(s32 objectIndex) { + switch (gObjectList[objectIndex].state) { + case 0: + break; + case 1: + OPenguin::InitEmperorPenguin(objectIndex); + break; + case 2: + func_80072E54(objectIndex, 0, gObjectList[objectIndex].type, 1, 0, -1); + break; + } +} + +void OPenguin::InitEmperorPenguin(s32 objectIndex) { + Object* object; + + object = &gObjectList[objectIndex]; + object->unk_0D8 = 0; + object->model = (Gfx*) d_course_sherbet_land_unk_data1; + object->vertex = (Vtx*) d_course_sherbet_land_unk_data11; + //object->sizeScaling = 0.2f; + //object->boundingBoxSize = 0x000C; + object->unk_09C = 1; + set_obj_direction_angle(objectIndex, 0U, 0U, 0U); + object->unk_0DD = 1; + func_80086EF0(objectIndex); + object->spline = D_800E672C[0]; + set_object_flag_status_true(objectIndex, 0x04000800); + object->type = get_animation_length(d_course_sherbet_land_unk_data11, 0); + object_next_state(objectIndex); +} + +void OPenguin::OtherPenguin(s32 objectIndex) { + Object* object; + + object = &gObjectList[objectIndex]; + switch (object->state) { + case 0: + break; + case 1: + OPenguin::InitOtherPenguin(objectIndex); + break; + case 2: + func_80072E54(objectIndex, 0, (s32) object->type, (s32) object->unk_09C, 0, -1); + if (func_80072354(objectIndex, 0x00000020) != 0) { + if (object->unk_084[6] == 0) { + object->unk_084[6] = random_int(0x005AU) + 0x5A; + func_800722A4(objectIndex, 0x00000080); + } else { + object->unk_084[6]--; + } + } + break; + case 3: + func_80072E54(objectIndex, 0, object->type, 1, 0, 0); + break; + case 4: + func_800722CC(objectIndex, 2); + object_next_state(objectIndex); + break; + } + if (func_80072320(objectIndex, 0x00000020) != 0) { + if (object->unk_084[6] == 0) { + func_800722A4(objectIndex, 0x00000080); + object->unk_084[6] = 0x0010; + } else { + object->unk_084[6]--; + } + } + if (func_80072320(objectIndex, 0x00000080) != 0) { + func_800722CC(objectIndex, 0x00000080); + if (func_80072320(objectIndex, 0x00000010) != 0) { + func_800C98B8(object->pos, object->velocity, SOUND_ARG_LOAD(0x19, 0x00, 0x70, 0x49)); + } else { + func_800C98B8(object->pos, object->velocity, SOUND_ARG_LOAD(0x19, 0x00, 0x70, 0x17)); + } + } +} + +void OPenguin::InitOtherPenguin(s32 objectIndex) { + Object* object; + + object = &gObjectList[objectIndex]; + object->unk_0D8 = 0; + object->model = (Gfx*) d_course_sherbet_land_unk_data1; + object->vertex = (Vtx*) d_course_sherbet_land_unk_data11; + //object->boundingBoxSize = 4; + object->unk_09C = 2; + object->unk_04C = random_int(0x012CU); + set_object_flag_status_true(objectIndex, 0x04000220); + + switch(_bhv) { + case Behaviour::CIRCLE: + object->unk_01C[1] = Diameter; + object->unk_0C4 = (_idx << 0xF) & 0xFFFF; + //object->unk_0DD = 2; + func_800722A4(objectIndex, 8); + break; + case Behaviour::SLIDE3: + case Behaviour::SLIDE4: + case Behaviour::SLIDE6: + case Behaviour::STRUT: + + if (gIsMirrorMode) { + object->unk_0C6 = MirrorModeAngleOffset; + } + + set_obj_direction_angle(objectIndex, 0U, object->unk_0C6 + 0x8000, 0U); + func_800722A4(objectIndex, 20); + break; + } + + if ((_idx > 0) && (_idx < 9)) { + if ((_idx == 1) || (_idx == 2)) { + //object->unk_0C6 = 0x0150; + //object->unk_01C[1] = 100.0f; + } else if ((_idx == 3) || (_idx == 4)) { + //object->unk_0C6 = 0x0100; + //object->unk_01C[1] = 80.0f; + } else if ((_idx == 5) || (_idx == 6)) { + //object->unk_0C6 = 0xFF00; + //object->unk_01C[1] = 80.0f; + } else if ((_idx == 7) || (_idx == 8)) { + //object->unk_0C6 = 0x0150; + //object->unk_01C[1] = 80.0f; + } + //object->unk_0C4 = (_idx << 0xF) & 0xFFFF; + //object->surfaceHeight = -80.0f; + //object->sizeScaling = 0.08f; + //object->unk_0DD = 2; + //func_800722A4(objectIndex, 8); + } else if ((_idx > 8) && (_idx < 15)) { + switch (_idx) { + case 9: + if (gGamestate != CREDITS_SEQUENCE) { + } else { + //object->sizeScaling = 0.15f; + } + //object->unk_0C6 = 0x9000; + if (gIsMirrorMode != 0) { + //object->unk_0C6 -= 0x4000; + } + //object->unk_0DD = 3; + break; + case 10: + //object->unk_0C6 = 0x5000; + if (gIsMirrorMode != 0) { + //object->unk_0C6 += 0x8000; + } + //object->unk_0DD = 4; + break; + case 11: + //object->unk_0C6 = 0xC000; + //object->unk_0DD = 6; + if (gIsMirrorMode != 0) { + //object->unk_0C6 += 0x8000; + } + break; + case 12: + //object->unk_0C6 = 0x4000; + //object->unk_0DD = 6; + if (gIsMirrorMode != 0) { + //object->unk_0C6 += 0x8000; + } + break; + case 13: + // object->unk_0C6 = 0x8000; + //object->unk_0DD = 6; + if (gIsMirrorMode != 0) { + //object->unk_0C6 -= 0x4000; + } + break; + case 14: + //object->unk_0C6 = 0x9000; + //object->unk_0DD = 6; + if (gIsMirrorMode != 0) { + //object->unk_0C6 -= 0x4000; + } + break; + default: + break; + } + //set_obj_direction_angle(objectIndex, 0U, object->unk_0C6 + 0x8000, 0U); + //object->surfaceHeight = 5.0f; + //object->sizeScaling = 0.04f; + //func_800722A4(objectIndex, 0x00000014); + } + func_80086EF0(objectIndex); + object->unk_034 = 0.0f; + object->type = get_animation_length(d_course_sherbet_land_unk_data11, 0); + object_next_state(objectIndex); +} diff --git a/src/engine/vehicles/OPenguin.h b/src/engine/vehicles/OPenguin.h new file mode 100644 index 000000000..007baf551 --- /dev/null +++ b/src/engine/vehicles/OPenguin.h @@ -0,0 +1,68 @@ +#pragma once + +#include +#include +#include "engine/vehicles/OPenguin.h" + +extern "C" { +#include "macros.h" +#include "main.h" +#include "vehicles.h" +#include "waypoints.h" +#include "common_structs.h" +#include "objects.h" +} + +//! @todo Make shadow size bigger if thwomp is scaled up +//! @todo make adjustable properties for squishSize and boundingBoxSize + + /** + * Thwomp GameObject + * + * The game automatically places the actor on the ground so you do not need to provide a Y coordinate value. + * + * @arg direction the rotational direction the thwomp is facing. + * @arg behaviour the behaviour of the thwomp, uses values 1-6. + * @arg primAlpha unknown + * @arg boundingBoxSize optional. The size of the bounding box for the thwomp. Default value is 12 + */ +class OPenguin { +public: + enum PenguinType : uint32_t { + CHICK, + ADULT, + CREDITS, + EMPEROR + }; + + enum Behaviour : uint16_t { + DISABLED, + STRUT, // Emperor penguin + CIRCLE, // Waddle in a circle + SLIDE3, + SLIDE4, + UNK, // unused + SLIDE6, + }; + +public: + f32 Diameter = 0.0f; // Waddle in a circle around the spawn point at this diameter. + uint16_t MirrorModeAngleOffset; + + explicit OPenguin(s32 i, Vec3f pos, u16 direction, PenguinType type, Behaviour behaviour); + + void Tick(); + void Draw(s32 playerId); +private: + void Behaviours(s32 objectIndex, s32 arg1); + void EmperorPenguin(s32 objectIndex); + void InitEmperorPenguin(s32 objectIndex); + void OtherPenguin(s32 objectIndex); + void InitOtherPenguin(s32 objectIndex); + + s32 _idx; + PenguinType _type; + Behaviour _bhv; + + +}; diff --git a/src/port/Game.cpp b/src/port/Game.cpp index 8a8c0b7cb..445e1b805 100644 --- a/src/port/Game.cpp +++ b/src/port/Game.cpp @@ -295,8 +295,10 @@ extern "C" { void CourseManager_ClearVehicles(void) { gWorldInstance.ClearVehicles(); + gWorldInstance.Crossings.clear(); gWorldInstance.BombKarts.clear(); gWorldInstance.Thwomps.clear(); + gWorldInstance.Penguins.clear(); } void CourseManager_CrossingTrigger() { @@ -501,6 +503,22 @@ extern "C" { } } + void CourseManager_TickPenguins(void) { + for (auto& penguin : gWorldInstance.Penguins) { + if (penguin) { + penguin->Tick(); + } + } + } + + void CourseManager_DrawPenguins(s32 cameraId) { + for (auto& penguin : gWorldInstance.Penguins) { + if (penguin) { + penguin->Draw(cameraId); + } + } + } + size_t GetCupCursorPosition() { return gWorldInstance.CurrentCup->CursorPosition; } diff --git a/src/port/Game.h b/src/port/Game.h index d2762c08f..c35e933e2 100644 --- a/src/port/Game.h +++ b/src/port/Game.h @@ -98,6 +98,10 @@ void CourseManager_DrawThwomps(s32 cameraId); void CourseManager_TickThwomps(); +void CourseManager_DrawPenguins(s32 cameraId); + +void CourseManager_TickPenguins(); + void CourseManager_CrossingTrigger(); void CourseManager_VehiclesCollision(s32 playerId, Player* player); diff --git a/src/render_objects.c b/src/render_objects.c index 7a34c47b5..48dc1b536 100644 --- a/src/render_objects.c +++ b/src/render_objects.c @@ -3637,7 +3637,6 @@ void func_80052D70(s32 playerId) { void func_80052E30(UNUSED s32 arg0) { s32 var_s0; - // Lights1 D_800E4620l = *(Lights1 *) LOAD_ASSET(D_800E4620); D_800E4620.l[0].l.dir[0] = D_80165840[0]; D_800E4620.l[0].l.dir[1] = D_80165840[1]; D_800E4620.l[0].l.dir[2] = D_80165840[2]; @@ -3760,20 +3759,12 @@ void render_lakitu(s32 cameraId) { void translate_thwomp_lights(UNUSED s32 arg0) { func_800419F8(); - // Lights1 *D_800E4638l = (Lights1 *) LOAD_ASSET(D_800E4638); D_800E4638.l[0].l.dir[0] = D_80165840[0]; D_800E4638.l[0].l.dir[1] = D_80165840[1]; D_800E4638.l[0].l.dir[2] = D_80165840[2]; } void thwomp_lights(s32 objectIndex) { - - // Lights1 *D_800E4638l = (Lights1 *) LOAD_ASSET(D_800E4638); - // Lights1 *D_800E4650l = (Lights1 *) LOAD_ASSET(D_800E4650); - // Lights1 *D_800E4668l = (Lights1 *) LOAD_ASSET(D_800E4668); - // Lights1 *D_800E4680l = (Lights1 *) LOAD_ASSET(D_800E4680); - // Lights1 *D_800E4698l = (Lights1 *) LOAD_ASSET(D_800E4698); - // Why these don't just use `gSPSetLights1` calls... switch (gObjectList[objectIndex].type) { // hmm very strange 80165C18 case 0: