From 7628e98e37d72aa508aa1af276ef8e3485df339c Mon Sep 17 00:00:00 2001 From: MegaMech <7255464+MegaMech@users.noreply.github.com> Date: Wed, 4 Dec 2024 15:03:59 -0700 Subject: [PATCH 01/21] loadtile fix --- include/mk64.h | 33 +++++++++++++++++++++++++++++++++ src/code_80091750.c | 20 ++++++++++---------- src/render_objects.c | 12 ++++++------ 3 files changed, 49 insertions(+), 16 deletions(-) diff --git a/include/mk64.h b/include/mk64.h index 97d5ffb84..a3068f13b 100644 --- a/include/mk64.h +++ b/include/mk64.h @@ -138,6 +138,39 @@ void gSPDisplayListOffset(Gfx* pkt, Gfx* dl, int offset); void gSPVertex(Gfx* pkt, uintptr_t v, int n, int v0); void gSPInvalidateTexCache(Gfx* pkt, uintptr_t texAddr); +// Dumb hack to fix load tile size on higher than native resolutions +#define gMKLoadTextureTile(pkt, timg, fmt, siz, width, height, uls, ult, lrs, lrt, pal, cms, cmt, masks, maskt, \ + shifts, shiftt) \ + _DW({ \ + gDPSetTextureImage(pkt, fmt, siz, width, timg); \ + gDPSetTile(pkt, fmt, siz, (((((lrs) - (uls) + 1) * siz##_TILE_BYTES) + 7) >> 3), 0, G_TX_LOADTILE, 0, cmt, \ + maskt, shiftt, cms, masks, shifts); \ + gDPLoadSync(pkt); \ + gDPLoadTile(pkt, G_TX_LOADTILE, (uls) << G_TEXTURE_IMAGE_FRAC, (ult) << G_TEXTURE_IMAGE_FRAC, \ + (lrs) << G_TEXTURE_IMAGE_FRAC, (lrt + 2) << G_TEXTURE_IMAGE_FRAC); \ + gDPPipeSync(pkt); \ + gDPSetTile(pkt, fmt, siz, (((((lrs) - (uls) + 1) * siz##_LINE_BYTES) + 7) >> 3), 0, G_TX_RENDERTILE, pal, cmt, \ + maskt, shiftt, cms, masks, shifts); \ + gDPSetTileSize(pkt, G_TX_RENDERTILE, (uls) << G_TEXTURE_IMAGE_FRAC, (ult) << G_TEXTURE_IMAGE_FRAC, \ + (lrs) << G_TEXTURE_IMAGE_FRAC, (lrt) << G_TEXTURE_IMAGE_FRAC); \ + }) + +#define gMKLoadTextureTile_4b(pkt, timg, fmt, width, height, uls, ult, lrs, lrt, pal, cms, cmt, masks, maskt, shifts, \ + shiftt) \ + _DW({ \ + gDPSetTextureImage(pkt, fmt, G_IM_SIZ_8b, ((width) >> 1), timg); \ + gDPSetTile(pkt, fmt, G_IM_SIZ_8b, (((((lrs) - (uls) + 1) >> 1) + 7) >> 3), 0, G_TX_LOADTILE, 0, cmt, maskt, \ + shiftt, cms, masks, shifts); \ + gDPLoadSync(pkt); \ + gDPLoadTile(pkt, G_TX_LOADTILE, (uls) << (G_TEXTURE_IMAGE_FRAC - 1), (ult) << (G_TEXTURE_IMAGE_FRAC), \ + (lrs) << (G_TEXTURE_IMAGE_FRAC - 1), (lrt + 2) << (G_TEXTURE_IMAGE_FRAC)); \ + gDPPipeSync(pkt); \ + gDPSetTile(pkt, fmt, G_IM_SIZ_4b, (((((lrs) - (uls) + 1) >> 1) + 7) >> 3), 0, G_TX_RENDERTILE, pal, cmt, \ + maskt, shiftt, cms, masks, shifts); \ + gDPSetTileSize(pkt, G_TX_RENDERTILE, (uls) << G_TEXTURE_IMAGE_FRAC, (ult) << G_TEXTURE_IMAGE_FRAC, \ + (lrs) << G_TEXTURE_IMAGE_FRAC, (lrt) << G_TEXTURE_IMAGE_FRAC); \ + }) + #ifdef __cplusplus } #endif diff --git a/src/code_80091750.c b/src/code_80091750.c index b632abe39..266f7e43e 100644 --- a/src/code_80091750.c +++ b/src/code_80091750.c @@ -2617,7 +2617,7 @@ func_80095BD0_label2: func_80095AE0(&gGfxPool->mtxEffect[gMatrixEffectCount], arg2, arg3, arg6, arg7); gSPMatrix(displayListHead++, VIRTUAL_TO_PHYSICAL(&gGfxPool->mtxEffect[gMatrixEffectCount++]), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); - gDPLoadTextureTile_4b(displayListHead++, arg1, G_IM_FMT_I, arg4, 0, 0, 0, arg4, arg5, 0, G_TX_NOMIRROR | G_TX_WRAP, + gMKLoadTextureTile_4b(displayListHead++, arg1, G_IM_FMT_I, arg4, 0, 0, 0, arg4, arg5, 0, G_TX_NOMIRROR | G_TX_WRAP, G_TX_NOMIRROR | G_TX_WRAP, G_TX_NOMASK, G_TX_NOMASK, G_TX_NOLOD, G_TX_NOLOD); switch (arg4) { default: @@ -2715,7 +2715,7 @@ Gfx* func_80095E10(Gfx* displayListHead, s8 arg1, s32 arg2, s32 arg3, s32 arg4, } else { var_s2 = var_t0; } - gDPLoadTextureTile(displayListHead++, argA, arg1, G_IM_SIZ_16b, argB, 0, var_a1_2, var_s3, + gMKLoadTextureTile(displayListHead++, argA, arg1, G_IM_SIZ_16b, argB, 0, var_a1_2, var_s3, var_a1_2 + var_s2, var_s3 + var_s4, 0, G_TX_NOMIRROR | G_TX_WRAP, G_TX_NOMIRROR | G_TX_WRAP, sp68, sp64, G_TX_NOLOD, G_TX_NOLOD); gSPTextureRectangle(displayListHead++, arg8 * 4, arg9 * 4, (arg8 + var_s2) * 4, (arg9 + var_s4) * 4, 0, @@ -2814,7 +2814,7 @@ Gfx* func_800963F0(Gfx* displayListHead, s8 arg1, s32 arg2, s32 arg3, f32 arg4, } a = var_s2 * arg4; - gDPLoadTextureTile(displayListHead++, argC, arg1, G_IM_SIZ_16b, argD, argE, var_a1_2, var_s3, + gMKLoadTextureTile(displayListHead++, argC, arg1, G_IM_SIZ_16b, argD, argE, var_a1_2, var_s3, var_a1_2 + var_s2, var_s3 + var_s4, 0, G_TX_NOMIRROR | G_TX_WRAP, G_TX_NOMIRROR | G_TX_WRAP, sp68, sp64, G_TX_NOLOD, G_TX_NOLOD); gSPTextureRectangle(displayListHead++, argA * 4, argB * 4, (argA + a) * 4, (argB + b) * 4, 0, @@ -2921,7 +2921,7 @@ Gfx* func_80096CD8(Gfx* displayListHead, s32 arg1, s32 arg2, u32 width, u32 arg4 } else { var_a1 = var_ra; } - gDPLoadTextureTile(displayListHead++, D_0B002A00 + (random_int(128) * 2), G_IM_FMT_IA, G_IM_SIZ_16b, width, + gMKLoadTextureTile(displayListHead++, D_0B002A00 + (random_int(128) * 2), G_IM_FMT_IA, G_IM_SIZ_16b, width, arg4, var_s1_3, var_fp, var_s1_3 + var_a1, var_fp + var_v0, 0, G_TX_NOMIRROR | G_TX_WRAP, G_TX_NOMIRROR | G_TX_WRAP, masks, maskt, G_TX_NOLOD, G_TX_NOLOD); @@ -3075,14 +3075,14 @@ Gfx* func_80097AE4(Gfx* displayListHead, s8 fmt, s32 arg2, s32 arg3, u8* arg4, s for (i = 0; i < 64; i += 32) { temp = 0; dsdx = 0x8000 / (32 - width); - gDPLoadTextureTile(displayListHead++, arg4, fmt, G_IM_SIZ_16b, 64, 64, temp, i, temp + 32, i + 32, 0, + gMKLoadTextureTile(displayListHead++, arg4, fmt, G_IM_SIZ_16b, 64, 64, temp, i, temp + 32, i + 32, 0, G_TX_NOMIRROR | G_TX_WRAP, G_TX_NOMIRROR | G_TX_WRAP, 5, 5, G_TX_NOLOD, G_TX_NOLOD); gSPTextureRectangle(displayListHead++, (arg2 + width) << 2, arg3 << 2, (arg2 + 32) << 2, (arg3 + 32) << 2, 0, 0, 0, dsdx, 1024); arg2 += 32; - gDPLoadTextureTile(displayListHead++, arg4, fmt, G_IM_SIZ_16b, 64, 64, temp + 32, i, temp + 64, i + 32, 0, + gMKLoadTextureTile(displayListHead++, arg4, fmt, G_IM_SIZ_16b, 64, 64, temp + 32, i, temp + 64, i + 32, 0, G_TX_NOMIRROR | G_TX_WRAP, G_TX_NOMIRROR | G_TX_WRAP, 5, 5, G_TX_NOLOD, G_TX_NOLOD); gSPTextureRectangle(displayListHead++, arg2 << 2, arg3 << 2, ((arg2 - width) + 32) << 2, (arg3 + 32) << 2, 0, 0, 0, dsdx, 1024); @@ -3126,7 +3126,7 @@ Gfx* func_80097E58(Gfx* displayListHead, s8 fmt, u32 arg2, u32 arg3, u32 arg4, u temp_v1 = ((32 * lrs) << 10) / (lrs * (32 - width)); // Renders the left side - gDPLoadTextureTile(displayListHead++, someTexture, fmt, G_IM_SIZ_16b, arg9, argA, temp, ult, temp + lrs, + gMKLoadTextureTile(displayListHead++, someTexture, fmt, G_IM_SIZ_16b, arg9, argA, temp, ult, temp + lrs, ult + var_s2, 0, G_TX_NOMIRROR | G_TX_WRAP, G_TX_NOMIRROR | G_TX_WRAP, 5, 5, G_TX_NOLOD, G_TX_NOLOD); gSPTextureRectangle(displayListHead++, (arg6 + lrs * (width) / 32) << 2, arg7 << 2, (((arg6) + lrs) << 2), @@ -3134,7 +3134,7 @@ Gfx* func_80097E58(Gfx* displayListHead, s8 fmt, u32 arg2, u32 arg3, u32 arg4, u arg6 += lrs; temp_v1 = ((32 * spDC) << 10) / (spDC * (32 - width)); // Renders the right side - gDPLoadTextureTile(displayListHead++, someTexture, fmt, G_IM_SIZ_16b, arg9, argA, temp + lrs, ult, temp + arg9, + gMKLoadTextureTile(displayListHead++, someTexture, fmt, G_IM_SIZ_16b, arg9, argA, temp + lrs, ult, temp + arg9, ult + var_s2, 0, G_TX_NOMIRROR | G_TX_WRAP, G_TX_NOMIRROR | G_TX_WRAP, 5, 5, G_TX_NOLOD, G_TX_NOLOD); gSPTextureRectangle(displayListHead++, arg6 << 2, arg7 << 2, ((arg6 + spDC * (32 - (width)) / 32) << 2), @@ -3154,7 +3154,7 @@ Gfx* func_80098558(Gfx* displayListHead, u32 arg1, u32 arg2, u32 arg3, u32 arg4, arg5Copy = arg5; for (var_v0 = arg2; var_v0 < arg4; var_v0 += 0x20) { for (var_a3 = arg1; var_a3 < arg3; var_a3 += 0x20) { - gDPLoadTextureTile(displayListHead++, D_8018D9B0, G_IM_FMT_RGBA, G_IM_SIZ_16b, arg8, 0, var_a3, var_v0, + gMKLoadTextureTile(displayListHead++, D_8018D9B0, G_IM_FMT_RGBA, G_IM_SIZ_16b, arg8, 0, var_a3, var_v0, var_a3 + 0x20, var_v0 + 0x20, 0, G_TX_NOMIRROR | G_TX_WRAP, G_TX_NOMIRROR | G_TX_WRAP, 5, 5, G_TX_NOLOD, G_TX_NOLOD); gSPTextureRectangle(displayListHead++, arg5 << 2, arg6 << 2, (arg5 + 0x20) << 2, (arg6 + 0x20) << 2, 0, 0, @@ -3188,7 +3188,7 @@ Gfx* func_800987D0(Gfx* displayListHead, u32 arg1, u32 arg2, u32 width, u32 heig columnCopy = column; for (var_v0_2 = arg2; (u32) var_v0_2 < height; var_v0_2 += 0x20) { for (var_a2 = arg1; (u32) var_a2 < width; var_a2 += 0x20) { - gDPLoadTextureTile(displayListHead++, D_8018D9B0, G_IM_FMT_RGBA, G_IM_SIZ_16b, textureWidth, 0, var_a2, + gMKLoadTextureTile(displayListHead++, D_8018D9B0, G_IM_FMT_RGBA, G_IM_SIZ_16b, textureWidth, 0, var_a2, var_v0_2, var_a2 + 0x20, var_v0_2 + 0x20, 0, G_TX_NOMIRROR | G_TX_WRAP, G_TX_NOMIRROR | G_TX_WRAP, 5, 5, G_TX_NOLOD, G_TX_NOLOD); temp_f6 = (temp_f18 * ((temp_f0 * (column - 0xA0)) + (temp_f24 * (row - 0x78)))) + 160.0f; diff --git a/src/render_objects.c b/src/render_objects.c index 48dc1b536..70a8613ad 100644 --- a/src/render_objects.c +++ b/src/render_objects.c @@ -210,7 +210,7 @@ void load_texture_block_rgba32_nomirror(u8* texture, s32 width, s32 height) { } void load_texture_tile_rgba32_nomirror(u8* texture, s32 width, s32 height) { - gDPLoadTextureTile(gDisplayListHead++, texture, G_IM_FMT_RGBA, G_IM_SIZ_32b, width, height, 0, 0, width - 1, + gMKLoadTextureTile(gDisplayListHead++, texture, G_IM_FMT_RGBA, G_IM_SIZ_32b, width, height, 0, 0, width - 1, height - 1, 0, G_TX_NOMIRROR | G_TX_CLAMP, G_TX_NOMIRROR | G_TX_CLAMP, G_TX_NOMASK, G_TX_NOMASK, G_TX_NOLOD, G_TX_NOLOD); } @@ -228,7 +228,7 @@ void load_texture_block_rgba16_nomirror(u8* texture, s32 width, s32 height, s32 } void load_texture_tile_rgba16_nomirror(u8* texture, s32 width, s32 height) { - gDPLoadTextureTile(gDisplayListHead++, texture, G_IM_FMT_RGBA, G_IM_SIZ_16b, width, height, 0, 0, width - 1, + gMKLoadTextureTile(gDisplayListHead++, texture, G_IM_FMT_RGBA, G_IM_SIZ_16b, width, height, 0, 0, width - 1, height - 1, 0, G_TX_NOMIRROR | G_TX_CLAMP, G_TX_NOMIRROR | G_TX_CLAMP, G_TX_NOMASK, G_TX_NOMASK, G_TX_NOLOD, G_TX_NOLOD); } @@ -240,7 +240,7 @@ void load_texture_block_ia16_nomirror(u8* texture, s32 width, s32 height) { } void load_texture_tile_ia16_nomirror(u8* texture, s32 width, s32 height) { - gDPLoadTextureTile(gDisplayListHead++, texture, G_IM_FMT_IA, G_IM_SIZ_16b, width, height, 0, 0, width - 1, + gMKLoadTextureTile(gDisplayListHead++, texture, G_IM_FMT_IA, G_IM_SIZ_16b, width, height, 0, 0, width - 1, height - 1, 0, G_TX_NOMIRROR | G_TX_CLAMP, G_TX_NOMIRROR | G_TX_CLAMP, G_TX_NOMASK, G_TX_NOMASK, G_TX_NOLOD, G_TX_NOLOD); } @@ -252,7 +252,7 @@ void load_texture_block_ia8_nomirror(u8* texture, s32 width, s32 height) { } void load_texture_tile_ia8_nomirror(u8* texture, s32 width, s32 height) { - gDPLoadTextureTile(gDisplayListHead++, texture, G_IM_FMT_IA, G_IM_SIZ_8b, width, height, 0, 0, width - 1, + gMKLoadTextureTile(gDisplayListHead++, texture, G_IM_FMT_IA, G_IM_SIZ_8b, width, height, 0, 0, width - 1, height - 1, 0, G_TX_NOMIRROR | G_TX_CLAMP, G_TX_NOMIRROR | G_TX_CLAMP, G_TX_NOMASK, G_TX_NOMASK, G_TX_NOLOD, G_TX_NOLOD); } @@ -286,7 +286,7 @@ void func_80044924(u8* texture, s32 width, s32 height) { } UNUSED void func_80044AB8(u8* texture, s32 width, s32 height) { - gDPLoadTextureTile_4b(gDisplayListHead++, texture, G_IM_FMT_IA, width, height, 0, 0, width - 1, height - 1, 0, + gMKLoadTextureTile_4b(gDisplayListHead++, texture, G_IM_FMT_IA, width, height, 0, 0, width - 1, height - 1, 0, G_TX_NOMIRROR | G_TX_CLAMP, G_TX_NOMIRROR | G_TX_CLAMP, G_TX_NOMASK, G_TX_NOMASK, G_TX_NOLOD, G_TX_NOLOD); } @@ -376,7 +376,7 @@ void rsp_load_texture_mask(u8* texture, s32 width, s32 height, s32 someMask) { } UNUSED void func_80045614(u8* texture, s32 width, s32 height) { - gDPLoadTextureTile(gDisplayListHead++, texture, G_IM_FMT_CI, G_IM_SIZ_8b, width, height, 0, 0, width - 1, + gMKLoadTextureTile(gDisplayListHead++, texture, G_IM_FMT_CI, G_IM_SIZ_8b, width, height, 0, 0, width - 1, height - 1, 0, G_TX_NOMIRROR | G_TX_CLAMP, G_TX_NOMIRROR | G_TX_CLAMP, G_TX_NOMASK, G_TX_NOMASK, G_TX_NOLOD, G_TX_NOLOD); } From 19135c9ee83643ea863d5725c22319e502938cac Mon Sep 17 00:00:00 2001 From: MegaMech <7255464+MegaMech@users.noreply.github.com> Date: Thu, 5 Dec 2024 21:41:58 -0700 Subject: [PATCH 02/21] load course dl textures from otr and move objects --- CMakeLists.txt | 4 +- courses/all_course_offsets.h | 21 --- courses/banshee_boardwalk/course_offsets.c | 26 --- courses/big_donut/course_offsets.c | 6 +- courses/block_fort/course_offsets.c | 7 - courses/bowsers_castle/course_offsets.c | 32 ---- courses/choco_mountain/course_offsets.c | 24 --- courses/dks_jungle_parkway/course_offsets.c | 28 --- courses/double_deck/course_offsets.c | 6 - courses/frappe_snowland/course_offsets.c | 8 - courses/kalimari_desert/course_offsets.c | 16 -- courses/koopa_troopa_beach/course_offsets.c | 20 -- courses/luigi_raceway/course_offsets.c | 44 ----- courses/mario_raceway/course_offsets.c | 34 ---- courses/moo_moo_farm/course_offsets.c | 32 ---- courses/rainbow_road/course_offsets.c | 9 - courses/royal_raceway/course_offsets.c | 47 ----- courses/sherbet_land/course_offsets.c | 9 - courses/skyscraper/course_offsets.c | 29 --- courses/toads_turnpike/course_offsets.c | 23 --- courses/wario_stadium/course_offsets.c | 24 --- courses/yoshi_valley/course_offsets.c | 18 -- src/actors/kiwano_fruit/render.inc.c | 18 +- src/engine/Engine.h | 2 + src/engine/GameObject.cpp | 28 +-- src/engine/GameObject.h | 36 ++-- src/engine/World.cpp | 41 ++-- src/engine/World.h | 13 +- src/engine/courses/BansheeBoardwalk.cpp | 32 +++- src/engine/courses/BigDonut.cpp | 11 +- src/engine/courses/BlockFort.cpp | 13 +- src/engine/courses/BowsersCastle.cpp | 37 +++- src/engine/courses/ChocoMountain.cpp | 30 ++- src/engine/courses/Course.cpp | 10 +- src/engine/courses/Course.h | 1 + src/engine/courses/DKJungle.cpp | 33 +++- src/engine/courses/DoubleDeck.cpp | 11 +- src/engine/courses/FrappeSnowland.cpp | 14 +- src/engine/courses/KalimariDesert.cpp | 21 ++- src/engine/courses/KoopaTroopaBeach.cpp | 25 ++- src/engine/courses/LuigiRaceway.cpp | 49 ++++- src/engine/courses/MarioRaceway.cpp | 39 +++- src/engine/courses/MooMooFarm.cpp | 37 +++- src/engine/courses/PodiumCeremony.cpp | 52 +++++- src/engine/courses/RainbowRoad.cpp | 15 +- src/engine/courses/RoyalRaceway.cpp | 52 +++++- src/engine/courses/SherbetLand.cpp | 15 +- src/engine/courses/Skyscraper.cpp | 32 +++- src/engine/courses/TestCourse.cpp | 3 +- src/engine/courses/ToadsTurnpike.cpp | 28 ++- src/engine/courses/WarioStadium.cpp | 29 ++- src/engine/courses/YoshiValley.cpp | 24 ++- .../{vehicles => objects}/OBombKart.cpp | 2 +- src/engine/{vehicles => objects}/OBombKart.h | 2 +- src/engine/{vehicles => objects}/OPenguin.cpp | 2 +- src/engine/{vehicles => objects}/OPenguin.h | 2 +- src/engine/{vehicles => objects}/OThwomp.cpp | 2 +- src/engine/{vehicles => objects}/OThwomp.h | 0 src/port/Game.cpp | 2 +- src/racing/memory.c | 176 +++--------------- 60 files changed, 654 insertions(+), 752 deletions(-) delete mode 100644 courses/skyscraper/course_offsets.c rename src/engine/{vehicles => objects}/OBombKart.cpp (99%) rename src/engine/{vehicles => objects}/OBombKart.h (97%) rename src/engine/{vehicles => objects}/OPenguin.cpp (99%) rename src/engine/{vehicles => objects}/OPenguin.h (97%) rename src/engine/{vehicles => objects}/OThwomp.cpp (99%) rename src/engine/{vehicles => objects}/OThwomp.h (100%) diff --git a/CMakeLists.txt b/CMakeLists.txt index d83379ac0..3cc7f64b9 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -96,9 +96,9 @@ include_directories( ${CMAKE_CURRENT_SOURCE_DIR}/src/networking ${CMAKE_CURRENT_SOURCE_DIR}/src/engine ${CMAKE_CURRENT_SOURCE_DIR}/src/engine/courses + ${CMAKE_CURRENT_SOURCE_DIR}/src/engine/objects ${CMAKE_CURRENT_SOURCE_DIR}/src/enhancements ${CMAKE_CURRENT_SOURCE_DIR}/src/enhancements/freecam - ${CMAKE_CURRENT_SOURCE_DIR}/src/engine ) # Collect source files to build the executable @@ -142,6 +142,8 @@ file(GLOB_RECURSE ALL_FILES RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} "src/engine/*.h" "src/engine/courses/*.c" "src/engine/courses/*.h" + "src/engine/objects/*.cpp" + "src/engine/objects/*.h" "src/enhancements/*.c" "src/enhancements/*.h" "src/enhancements/freecam/*.c" diff --git a/courses/all_course_offsets.h b/courses/all_course_offsets.h index 3deb7e79a..a94f34483 100644 --- a/courses/all_course_offsets.h +++ b/courses/all_course_offsets.h @@ -34,25 +34,4 @@ extern Gfx* sherbet_land_dls_2[]; extern Gfx* wario_stadium_dls[]; #endif -extern const course_texture banshee_boardwalk_textures[]; -extern const course_texture big_donut_textures[]; -extern const course_texture block_fort_textures[]; -extern const course_texture bowsers_castle_textures[]; -extern const course_texture choco_mountain_textures[]; -extern const course_texture double_deck_textures[]; -extern const course_texture frappe_snowland_textures[]; -extern const course_texture kalimari_desert_textures[]; -extern const course_texture koopa_troopa_beach_textures[]; -extern const course_texture luigi_raceway_textures[]; -extern const course_texture mario_raceway_textures[]; -extern const course_texture moo_moo_farm_textures[]; -extern const course_texture rainbow_road_textures[]; -extern const course_texture royal_raceway_textures[]; -extern const course_texture sherbet_land_textures[]; -extern const course_texture skyscraper_textures[]; -extern const course_texture toads_turnpike_textures[]; -extern const course_texture wario_stadium_textures[]; -extern const course_texture yoshi_valley_textures[]; -extern const course_texture dks_jungle_parkway_textures[]; - #endif diff --git a/courses/banshee_boardwalk/course_offsets.c b/courses/banshee_boardwalk/course_offsets.c index 3ddce786a..3ccec5dd7 100644 --- a/courses/banshee_boardwalk/course_offsets.c +++ b/courses/banshee_boardwalk/course_offsets.c @@ -9,32 +9,6 @@ #include #include -const course_texture banshee_boardwalk_textures[] = { - { gTexture6447C4, 0x0106, 0x0800, 0x0 }, - { gTexture676FB0, 0x0525, 0x0800, 0x0 }, - { gTexture643B3C, 0x0798, 0x0800, 0x0 }, - { gTexture64BB60, 0x0169, 0x0800, 0x0 }, - { gTexture64BCCC, 0x0450, 0x0800, 0x0 }, - { gTexture64FBF4, 0x0274, 0x0800, 0x0 }, - { gTexture651B20, 0x041D, 0x0800, 0x0 }, - { gTexture66262C, 0x02F7, 0x0800, 0x0 }, - { gTexture668728, 0x01F5, 0x0800, 0x0 }, - { gTexture66A3DC, 0x07C5, 0x0800, 0x0 }, - { gTexture66CA98, 0x02C9, 0x0800, 0x0 }, - { gTexture66CD64, 0x02C0, 0x0800, 0x0 }, - { gTexture66D698, 0x0370, 0x0800, 0x0 }, - { gTexture66E608, 0x05E8, 0x0800, 0x0 }, - { gTexture67B388, 0x03D2, 0x0800, 0x0 }, - { gTextureSignWelcome0, 0x0A2E, 0x1000, 0x0 }, - { gTextureSignWelcome1, 0x0A0A, 0x1000, 0x0 }, - { gTextureSignWoodenBack0, 0x06EF, 0x1000, 0x0 }, - { gTextureSignWoodenBack1, 0x06D1, 0x1000, 0x0 }, - { gTextureSignWoodRedArrow, 0x04E1, 0x1000, 0x0 }, - { gTexture68D940, 0x057D, 0x0800, 0x0 }, - { gTexture685AC0, 0x07CC, 0x1000, 0x0 }, - { 0x00000000, 0x0000, 0x0000, 0x0 }, -}; - const Gfx* banshee_boardwalk_dls[] = { d_course_banshee_boardwalk_dl_A0, d_course_banshee_boardwalk_dl_210, d_course_banshee_boardwalk_dl_160, d_course_banshee_boardwalk_dl_270, d_course_banshee_boardwalk_dl_358, d_course_banshee_boardwalk_dl_4F0, diff --git a/courses/big_donut/course_offsets.c b/courses/big_donut/course_offsets.c index e17299856..6ff63f913 100644 --- a/courses/big_donut/course_offsets.c +++ b/courses/big_donut/course_offsets.c @@ -1,8 +1,4 @@ #include #include "course_offsets.h" -const course_texture big_donut_textures[] = { - { gTexture66ABA4, 0x0312, 0x0800, 0x0 }, { gTexture6747C4, 0x0145, 0x0800, 0x0 }, - { gTexture67490C, 0x021C, 0x0800, 0x0 }, { gTexture64BA50, 0x0110, 0x0800, 0x0 }, - { 0x00000000, 0x0000, 0x0000, 0x0 }, -}; + diff --git a/courses/block_fort/course_offsets.c b/courses/block_fort/course_offsets.c index facb98715..03416690a 100644 --- a/courses/block_fort/course_offsets.c +++ b/courses/block_fort/course_offsets.c @@ -1,10 +1,3 @@ #include #include "course_offsets.h" #include - -const course_texture block_fort_textures[] = { - { gTexture64286C, 0x010A, 0x0800, 0x0 }, { gTextureGrayCheckerboard, 0x010C, 0x0800, 0x0 }, - { gTextureGrayCobblestone, 0x010C, 0x0800, 0x0 }, { gTexture64275C, 0x0110, 0x0800, 0x0 }, - { gTexture642978, 0x010D, 0x0800, 0x0 }, { gTexture6747C4, 0x0145, 0x0800, 0x0 }, - { gTexture6442D4, 0x0138, 0x0800, 0x0 }, { 0x00000000, 0x0000, 0x0000, 0x0 }, -}; diff --git a/courses/bowsers_castle/course_offsets.c b/courses/bowsers_castle/course_offsets.c index 1ca988f68..1565c754c 100644 --- a/courses/bowsers_castle/course_offsets.c +++ b/courses/bowsers_castle/course_offsets.c @@ -2,38 +2,6 @@ #include "course_offsets.h" #include -const course_texture bowsers_castle_textures[] = { - { gTexture64313C, 0x01B8, 0x0800, 0x0 }, - { gTexture6528DC, 0x0278, 0x0800, 0x0 }, - { gTexture66ED38, 0x010E, 0x0800, 0x0 }, - { gTexture676C6C, 0x0110, 0x0800, 0x0 }, - { gTexture676EA8, 0x0108, 0x0800, 0x0 }, - { gTexture679D34, 0x0106, 0x0800, 0x0 }, - { gTextureGrass6, 0x023B, 0x0800, 0x0 }, - { gTexture6522E0, 0x05FC, 0x0800, 0x0 }, - { gTexture651F40, 0x039F, 0x0800, 0x0 }, - { gTextureRoofTile, 0x0129, 0x0800, 0x0 }, - { gTextureSignBowser0, 0x07D0, 0x1000, 0x0 }, - { gTextureSignBowser1, 0x064D, 0x1000, 0x0 }, - { gTexture66ABA4, 0x0312, 0x0800, 0x0 }, - { gTexture66EBF0, 0x0146, 0x0800, 0x0 }, - { gTexture6733CC, 0x020E, 0x0800, 0x0 }, - { gTexture673118, 0x02B1, 0x0800, 0x0 }, - { gTexture673FF8, 0x035B, 0x0800, 0x0 }, - { gTexture674B28, 0x0230, 0x0800, 0x0 }, - { gTextureSignGreenArrow, 0x025B, 0x1000, 0x0 }, - { gTexture68D834, 0x010A, 0x0800, 0x0 }, - { gTexture676D7C, 0x012C, 0x0800, 0x0 }, - { gTexture67ADF0, 0x0595, 0x0800, 0x0 }, - { gTexture67EFEC, 0x016F, 0x0800, 0x0 }, - { gTexture653DB0, 0x06AE, 0x0800, 0x0 }, - { gTexture66CA98, 0x02C9, 0x0800, 0x0 }, - { gTexture673990, 0x02D8, 0x0800, 0x0 }, - { gTexture67A370, 0x05AA, 0x0800, 0x0 }, - { gTexture67A91C, 0x04D1, 0x0800, 0x0 }, - { 0x00000000, 0x0000, 0x0000, 0x0 }, -}; - const Gfx* bowsers_castle_dls[] = { d_course_bowsers_castle_dl_0, d_course_bowsers_castle_dl_230, d_course_bowsers_castle_dl_110, d_course_bowsers_castle_dl_398, d_course_bowsers_castle_dl_428, d_course_bowsers_castle_dl_640, diff --git a/courses/choco_mountain/course_offsets.c b/courses/choco_mountain/course_offsets.c index 198d346a9..99babf668 100644 --- a/courses/choco_mountain/course_offsets.c +++ b/courses/choco_mountain/course_offsets.c @@ -2,30 +2,6 @@ #include "course_offsets.h" #include -const course_texture choco_mountain_textures[] = { - { gTexture64619C, 0x0124, 0x0800, 0x0 }, - { gTexture64647C, 0x0829, 0x1000, 0x0 }, - { gTexture647F4C, 0x05BC, 0x1000, 0x0 }, - { gTexture64FBF4, 0x0274, 0x0800, 0x0 }, - { gTexture653DB0, 0x06AE, 0x0800, 0x0 }, - { gTexture652B54, 0x0606, 0x0800, 0x0 }, - { gTexture65315C, 0x04A9, 0x0800, 0x0 }, - { gTexture6684F8, 0x010D, 0x0800, 0x0 }, - { gTextureSignLuigis0, 0x0287, 0x1000, 0x0 }, - { gTextureSignLuigis1, 0x02AF, 0x1000, 0x0 }, - { gTextureSignNintendoRed0, 0x02A6, 0x1000, 0x0 }, - { gTextureSignNintendoRed1, 0x02F7, 0x1000, 0x0 }, - { gTexture6774D8, 0x0113, 0x0800, 0x0 }, - { gTextureSignFallingRocks, 0x012C, 0x0800, 0x0 }, - { gTextureSignBackside, 0x011E, 0x0800, 0x0 }, - { gTexture679C04, 0x012F, 0x0800, 0x0 }, - { gTexture67B864, 0x014C, 0x0800, 0x0 }, - { gTexture67DC20, 0x03EF, 0x0800, 0x0 }, - { gTextureSignYoshi, 0x04DF, 0x1000, 0x0 }, - { gTextureCheckerboardBlueGray, 0x04A1, 0x1000, 0x0 }, - { 0x00000000, 0x0000, 0x0000, 0x0 }, -}; - const Gfx* choco_mountain_dls[] = { d_course_choco_mountain_dl_0, d_course_choco_mountain_dl_150, d_course_choco_mountain_dl_B0, d_course_choco_mountain_dl_208, d_course_choco_mountain_dl_2A8, d_course_choco_mountain_dl_410, diff --git a/courses/dks_jungle_parkway/course_offsets.c b/courses/dks_jungle_parkway/course_offsets.c index 347fe7277..587df1c59 100644 --- a/courses/dks_jungle_parkway/course_offsets.c +++ b/courses/dks_jungle_parkway/course_offsets.c @@ -2,34 +2,6 @@ #include "course_offsets.h" #include -const course_texture dks_jungle_parkway_textures[] = { - { gTexture648508, 0x01FE, 0x1000, 0x0 }, - { gTexture6684F8, 0x010D, 0x0800, 0x0 }, - { gTextureWoodBridgeSlats, 0x0DAB, 0x1000, 0x0 }, - { gTexture654460, 0x0B12, 0x1000, 0x0 }, - { gTexture654F74, 0x0A24, 0x1000, 0x0 }, - { gTexture655998, 0x059F, 0x0800, 0x0 }, - { gTexture655F38, 0x0BB9, 0x1000, 0x0 }, - { gTexture656AF4, 0x0AD3, 0x1000, 0x0 }, - { gTexture6575C8, 0x0DA7, 0x1000, 0x0 }, - { gTexture658370, 0x0DBA, 0x1000, 0x0 }, - { gTexture65912C, 0x0DBC, 0x1000, 0x0 }, - { gTexture659EE8, 0x0EF5, 0x1000, 0x0 }, - { gTexture65ADE0, 0x0D5A, 0x1000, 0x0 }, - { gTexture65BB3C, 0x0D9E, 0x1000, 0x0 }, - { gTexture65C8DC, 0x0CF5, 0x1000, 0x0 }, - { gTexture65D5D4, 0x0D18, 0x1000, 0x0 }, - { gTexture65E2EC, 0x02B0, 0x0800, 0x0 }, - { gTexture65EAEC, 0x034A, 0x0800, 0x0 }, - { gTexture65E59C, 0x054F, 0x1000, 0x0 }, - { gTexture65EE38, 0x0CDE, 0x1000, 0x0 }, - { gTexture65FB18, 0x03EE, 0x0800, 0x0 }, - { gTextureSignPinkArrow, 0x0198, 0x0800, 0x0 }, - { gTextureWaves0, 0x04D0, 0x0800, 0x0 }, - { gTexture683844, 0x0655, 0x0800, 0x0 }, - { 0x00000000, 0x0000, 0x0000, 0x0 }, -}; - const Gfx* d_course_dks_jungle_parkway_unknown_dl_list[] = { d_course_dks_jungle_parkway_dl_20, d_course_dks_jungle_parkway_dl_210, d_course_dks_jungle_parkway_dl_180, d_course_dks_jungle_parkway_dl_310, d_course_dks_jungle_parkway_dl_400, d_course_dks_jungle_parkway_dl_628, diff --git a/courses/double_deck/course_offsets.c b/courses/double_deck/course_offsets.c index 66f70ded3..9a8b4abc6 100644 --- a/courses/double_deck/course_offsets.c +++ b/courses/double_deck/course_offsets.c @@ -1,8 +1,2 @@ #include #include "course_offsets.h" - -const course_texture double_deck_textures[] = { - { gTextureGrayCobblestone, 0x010C, 0x0800, 0x0 }, - { gTexture642978, 0x010D, 0x0800, 0x0 }, - { 0x00000000, 0x0000, 0x0000, 0x0 }, -}; diff --git a/courses/frappe_snowland/course_offsets.c b/courses/frappe_snowland/course_offsets.c index 76f5b4458..f832eb03e 100644 --- a/courses/frappe_snowland/course_offsets.c +++ b/courses/frappe_snowland/course_offsets.c @@ -2,14 +2,6 @@ #include "course_offsets.h" #include -const course_texture frappe_snowland_textures[] = { - { gTexture6684F8, 0x010D, 0x0800, 0x0 }, { gTexture66CA98, 0x02C9, 0x0800, 0x0 }, - { gTexture66EBF0, 0x0146, 0x0800, 0x0 }, { gTexture675434, 0x0245, 0x0800, 0x0 }, - { gTexture677F04, 0x0213, 0x0800, 0x0 }, { gTexture678118, 0x0314, 0x0800, 0x0 }, - { gTexture679258, 0x04E3, 0x1000, 0x0 }, { gTexture67973C, 0x04C6, 0x1000, 0x0 }, - { 0x00000000, 0x0000, 0x0000, 0x0 }, -}; - const Gfx* d_course_frappe_snowland_dl_list[] = { d_course_frappe_snowland_dl_0, d_course_frappe_snowland_dl_1B8, d_course_frappe_snowland_dl_C8, d_course_frappe_snowland_dl_298, d_course_frappe_snowland_dl_398, d_course_frappe_snowland_dl_540, diff --git a/courses/kalimari_desert/course_offsets.c b/courses/kalimari_desert/course_offsets.c index 78642e55b..2f7f876bd 100644 --- a/courses/kalimari_desert/course_offsets.c +++ b/courses/kalimari_desert/course_offsets.c @@ -2,22 +2,6 @@ #include "course_offsets.h" #include -const course_texture kalimari_desert_textures[] = { - { gTexture6684F8, 0x010D, 0x0800, 0x0 }, { gTextureSignLuigis0, 0x0287, 0x1000, 0x0 }, - { gTextureSignLuigis1, 0x02AF, 0x1000, 0x0 }, { gTextureSignMarioStar0, 0x02D2, 0x1000, 0x0 }, - { gTextureSignMarioStar1, 0x02B1, 0x1000, 0x0 }, { gTextureSignNintendoRed0, 0x02A6, 0x1000, 0x0 }, - { gTextureSignNintendoRed1, 0x02F7, 0x1000, 0x0 }, { gTexture67490C, 0x021C, 0x0800, 0x0 }, - { gTextureSignYoshi, 0x04DF, 0x1000, 0x0 }, { gTextureCheckerboardBlueGray, 0x04A1, 0x1000, 0x0 }, - { gTexture646CA8, 0x073A, 0x1000, 0x0 }, { gTexture6473E4, 0x05AD, 0x1000, 0x0 }, - { gTexture647994, 0x05B5, 0x1000, 0x0 }, { gTexture668920, 0x03D9, 0x0800, 0x0 }, - { gTextureRailroadTrack, 0x0B5B, 0x1000, 0x0 }, { gTextureRailroadCrossingTrack, 0x0208, 0x1000, 0x0 }, - { gTexture67291C, 0x059C, 0x0800, 0x0 }, { gTextureFenceBarbedWire, 0x021E, 0x1000, 0x0 }, - { gTexture67D304, 0x091C, 0x1000, 0x0 }, { gTexture67E010, 0x0415, 0x0800, 0x0 }, - { gTexture67EEAC, 0x0140, 0x0800, 0x0 }, { gTextureSignShellShot0, 0x038C, 0x1000, 0x0 }, - { gTextureSignShellShot1, 0x0247, 0x1000, 0x0 }, { gTextureSignKoopaAir0, 0x0360, 0x1000, 0x0 }, - { gTextureSignKoopaAir1, 0x0304, 0x1000, 0x0 }, { 0x00000000, 0x0000, 0x0000, 0x0 }, -}; - const Gfx* kalimari_desert_dls[] = { d_course_kalimari_desert_dl_0, d_course_kalimari_desert_dl_258, d_course_kalimari_desert_dl_100, d_course_kalimari_desert_dl_310, d_course_kalimari_desert_dl_4A0, d_course_kalimari_desert_dl_778, diff --git a/courses/koopa_troopa_beach/course_offsets.c b/courses/koopa_troopa_beach/course_offsets.c index 13a187933..50ab4c90c 100644 --- a/courses/koopa_troopa_beach/course_offsets.c +++ b/courses/koopa_troopa_beach/course_offsets.c @@ -3,26 +3,6 @@ #include #include "animation.h" -const course_texture koopa_troopa_beach_textures[] = { - { gTexture643B3C, 0x0798, 0x0800, 0x0 }, - { gTexture66A3DC, 0x07C5, 0x0800, 0x0 }, - { gTextureSignWoodRedArrow, 0x04E1, 0x1000, 0x0 }, - { gTexture66DD38, 0x0330, 0x1000, 0x0 }, - { gTexture643430, 0x0604, 0x0800, 0x0 }, - { gTexture660D8C, 0x0126, 0x0800, 0x0 }, - { gTexture6609D0, 0x03BB, 0x1000, 0x0 }, - { gTextureGrass12, 0x0874, 0x0800, 0x0 }, - { gTexture66CA98, 0x02C9, 0x0800, 0x0 }, - { gTexture66EBF0, 0x0146, 0x0800, 0x0 }, - { gTexture67BEE8, 0x02D0, 0x0800, 0x0 }, - { gTextureSandFinish, 0x022E, 0x0800, 0x0 }, - { gTextureWheelSteamEngine, 0x020F, 0x0800, 0x0 }, - { gTexture669570, 0x0E6B, 0x1000, 0x0 }, - { gTextureWaves1, 0x05C4, 0x0800, 0x0 }, - { gTextureWaves2, 0x0488, 0x0800, 0x0 }, - { 0x00000000, 0x0000, 0x0000, 0x0 }, -}; - Gfx* d_course_koopa_troopa_beach_dl_list1[] = { d_course_koopa_troopa_beach_dl_90, d_course_koopa_troopa_beach_dl_278, d_course_koopa_troopa_beach_dl_188, d_course_koopa_troopa_beach_dl_3C0, d_course_koopa_troopa_beach_dl_4B0, d_course_koopa_troopa_beach_dl_6E0, diff --git a/courses/luigi_raceway/course_offsets.c b/courses/luigi_raceway/course_offsets.c index 38abdbd7e..b740bcccd 100644 --- a/courses/luigi_raceway/course_offsets.c +++ b/courses/luigi_raceway/course_offsets.c @@ -2,50 +2,6 @@ #include "course_offsets.h" #include -const course_texture luigi_raceway_textures[] = { - { gTextureSignShellShot0, 0x038C, 0x1000, 0x0 }, - { gTextureSignShellShot1, 0x0247, 0x1000, 0x0 }, - { gTextureCheckerboardYellowBlue, 0x013A, 0x0800, 0x0 }, - { gTexture64619C, 0x0124, 0x0800, 0x0 }, - { gTextureCheckerboardBlueGreen, 0x0139, 0x0800, 0x0 }, - { gTextureGrass3, 0x0372, 0x0800, 0x0 }, - { gTextureFlagRed, 0x019E, 0x0800, 0x0 }, - { gTexture65100C, 0x0120, 0x0800, 0x0 }, - { gTexture65112C, 0x0150, 0x0800, 0x0 }, - { gTexture653608, 0x07A7, 0x0800, 0x0 }, - { gTextureGrass11, 0x01F8, 0x0800, 0x0 }, - { gTextureSignLuigiFace0, 0x05C9, 0x1000, 0x0 }, - { gTextureSignLuigiFace1, 0x065F, 0x1000, 0x0 }, - { gTexture66C7A8, 0x0149, 0x0800, 0x0 }, - { gTexture670AC8, 0x0FBF, 0x1000, 0x0 }, - { gTexture671A88, 0x012D, 0x0800, 0x0 }, - { gTexture6735DC, 0x03B1, 0x0800, 0x0 }, - { gTexture673C68, 0x038D, 0x0800, 0x0 }, - { gTexture6747C4, 0x0145, 0x0800, 0x0 }, - { gTextureRoad1, 0x02D2, 0x1000, 0x0 }, - { gTextureRoad2, 0x02AE, 0x1000, 0x0 }, - { gTextureRoadFinish1, 0x026B, 0x1000, 0x0 }, - { gTexture67BBD8, 0x0310, 0x0800, 0x0 }, - { gTexture68272C, 0x01F9, 0x1000, 0x0 }, - { gTexture682928, 0x01F9, 0x1000, 0x0 }, - { gTexture682B24, 0x01F9, 0x1000, 0x0 }, - { gTexture682D20, 0x01F9, 0x1000, 0x0 }, - { gTexture682F1C, 0x01F9, 0x1000, 0x0 }, - { gTexture683118, 0x01F9, 0x1000, 0x0 }, - { gTextureSignBlue64, 0x0567, 0x1000, 0x0 }, - { gTextureSignKoopaAir0, 0x0360, 0x1000, 0x0 }, - { gTextureSignKoopaAir1, 0x0304, 0x1000, 0x0 }, - { gTextureSignLuigis0, 0x0287, 0x1000, 0x0 }, - { gTextureSignLuigis1, 0x02AF, 0x1000, 0x0 }, - { gTextureSignMarioStar0, 0x02D2, 0x1000, 0x0 }, - { gTextureSignMarioStar1, 0x02B1, 0x1000, 0x0 }, - { gTextureSignNintendoRed0, 0x02A6, 0x1000, 0x0 }, - { gTextureSignNintendoRed1, 0x02F7, 0x1000, 0x0 }, - { gTextureSignYoshi, 0x04DF, 0x1000, 0x0 }, - { gTextureCheckerboardBlueGray, 0x04A1, 0x1000, 0x0 }, - { 0x00000000, 0x0000, 0x0000, 0x0 }, -}; - const Gfx* luigi_raceway_dls[] = { d_course_luigi_raceway_dl_0, d_course_luigi_raceway_dl_328, d_course_luigi_raceway_dl_1A8, d_course_luigi_raceway_dl_480, d_course_luigi_raceway_dl_6E0, d_course_luigi_raceway_dl_9F8, diff --git a/courses/mario_raceway/course_offsets.c b/courses/mario_raceway/course_offsets.c index 2a2526ad8..cc81a4dc9 100644 --- a/courses/mario_raceway/course_offsets.c +++ b/courses/mario_raceway/course_offsets.c @@ -2,40 +2,6 @@ #include "course_offsets.h" #include -const course_texture mario_raceway_textures[] = { - { gTextureCheckerboardYellowPink, 0x0149, 0x0800, 0x0 }, - { gTexture64619C, 0x0124, 0x0800, 0x0 }, - { gTextureGrass1, 0x0125, 0x0800, 0x0 }, - { gTexture64BB60, 0x0169, 0x0800, 0x0 }, - { gTextureGrass7, 0x05DE, 0x0800, 0x0 }, - { gTextureGrass5, 0x023F, 0x0800, 0x0 }, - { gTextureFlagRed, 0x019E, 0x0800, 0x0 }, - { gTexture663F90, 0x0122, 0x0800, 0x0 }, - { gTexture6642A4, 0x0162, 0x0800, 0x0 }, - { gTexture6640B4, 0x01EF, 0x0800, 0x0 }, - { gTextureGrass10, 0x01F8, 0x0800, 0x0 }, - { gTexture6684F8, 0x010D, 0x0800, 0x0 }, - { gTextureSignLuigis0, 0x0287, 0x1000, 0x0 }, - { gTextureSignLuigis1, 0x02AF, 0x1000, 0x0 }, - { gTextureSignMarioStar0, 0x02D2, 0x1000, 0x0 }, - { gTextureSignMarioStar1, 0x02B1, 0x1000, 0x0 }, - { gTexture66C8F4, 0x01A1, 0x0800, 0x0 }, - { gTextureSignNintendoRed0, 0x02A6, 0x1000, 0x0 }, - { gTextureSignNintendoRed1, 0x02F7, 0x1000, 0x0 }, - { gTexture670AC8, 0x0FBF, 0x1000, 0x0 }, - { gTexture674354, 0x046F, 0x0800, 0x0 }, - { gTextureRoad0, 0x0300, 0x1000, 0x0 }, - { gTextureRoadFinish0, 0x0338, 0x1000, 0x0 }, - { gTexture67B9B0, 0x0225, 0x0800, 0x0 }, - { gTextureSignYoshi, 0x04DF, 0x1000, 0x0 }, - { gTextureCheckerboardBlueGray, 0x04A1, 0x1000, 0x0 }, - { gTextureSignShellShot0, 0x038C, 0x1000, 0x0 }, - { gTextureSignShellShot1, 0x0247, 0x1000, 0x0 }, - { gTextureSignKoopaAir0, 0x0360, 0x1000, 0x0 }, - { gTextureSignKoopaAir1, 0x0304, 0x1000, 0x0 }, - { 0x00000000, 0x0000, 0x0000, 0x0 }, -}; - #ifndef TARGET_N64 const char* mario_raceway_dls[] = { #else diff --git a/courses/moo_moo_farm/course_offsets.c b/courses/moo_moo_farm/course_offsets.c index b5c43fc3e..32f40dfda 100644 --- a/courses/moo_moo_farm/course_offsets.c +++ b/courses/moo_moo_farm/course_offsets.c @@ -2,38 +2,6 @@ #include "course_offsets.h" #include -const course_texture moo_moo_farm_textures[] = { - { gTextureWoodDoor0, 0x0294, 0x1000, 0x0 }, - { gTextureGrass2, 0x0415, 0x0800, 0x0 }, - { gTexture64AF50, 0x0140, 0x0800, 0x0 }, - { gTexture64B090, 0x0365, 0x0800, 0x0 }, - { gTexture64B54C, 0x038C, 0x0800, 0x0 }, - { gTexture64B3F8, 0x0153, 0x0800, 0x0 }, - { gTextureSignNintendo0, 0x0541, 0x1000, 0x0 }, - { gTextureSignNintendo1, 0x0512, 0x1000, 0x0 }, - { gTexture6684F8, 0x010D, 0x0800, 0x0 }, - { gTextureSignLuigis0, 0x0287, 0x1000, 0x0 }, - { gTextureSignLuigis1, 0x02AF, 0x1000, 0x0 }, - { gTextureSignMarioStar0, 0x02D2, 0x1000, 0x0 }, - { gTextureSignMarioStar1, 0x02B1, 0x1000, 0x0 }, - { gTexture674D58, 0x030C, 0x1000, 0x0 }, - { gTexture675064, 0x01BB, 0x0800, 0x0 }, - { gTexture675220, 0x0212, 0x0800, 0x0 }, - { gTexture6775EC, 0x0233, 0x1000, 0x0 }, - { gTexture683314, 0x02DC, 0x1000, 0x0 }, - { gTexture68CDA0, 0x0110, 0x0800, 0x0 }, - { gTexture6442D4, 0x0138, 0x0800, 0x0 }, - { gTexture64440C, 0x029D, 0x1000, 0x0 }, - { gTexture6446AC, 0x0116, 0x0800, 0x0 }, - { gTextureMooMooFarmSignLeft, 0x0A66, 0x1000, 0x0 }, - { gTextureMooMooFarmSignRight, 0x0A64, 0x1000, 0x0 }, - { gTexture64ACAC, 0x02A3, 0x0800, 0x0 }, - { gTexture66D698, 0x0370, 0x0800, 0x0 }, - { gTexture66EBF0, 0x0146, 0x0800, 0x0 }, - { gTextureWheelSteamEngineReal, 0x022F, 0x1000, 0x0 }, - { 0x00000000, 0x0000, 0x0000, 0x0 }, -}; - const Gfx* moo_moo_farm_dls[] = { d_course_moo_moo_farm_dl_88, d_course_moo_moo_farm_dl_598, d_course_moo_moo_farm_dl_338, d_course_moo_moo_farm_dl_8A0, d_course_moo_moo_farm_dl_B00, d_course_moo_moo_farm_dl_FE0, diff --git a/courses/rainbow_road/course_offsets.c b/courses/rainbow_road/course_offsets.c index f7a6d8da5..579c5fef1 100644 --- a/courses/rainbow_road/course_offsets.c +++ b/courses/rainbow_road/course_offsets.c @@ -2,15 +2,6 @@ #include "course_offsets.h" #include -const course_texture rainbow_road_textures[] = { - { gTextureStarOutline, 0x037A, 0x0800, 0x0 }, - { gTexture67A1B8, 0x01B7, 0x0800, 0x0 }, - { gTextureCheckerboardBlackWhite, 0x0107, 0x0800, 0x0 }, - { gTexture662A34, 0x0106, 0x0800, 0x0 }, - { gTextureRainbow, 0x025D, 0x1000, 0x0 }, - { 0x00000000, 0x0000, 0x0000, 0x0 }, -}; - Gfx* rainbow_road_dls[] = { d_course_rainbow_road_dl_D8, d_course_rainbow_road_dl_210, d_course_rainbow_road_dl_178, d_course_rainbow_road_dl_288, d_course_rainbow_road_dl_338, d_course_rainbow_road_dl_4A0, diff --git a/courses/royal_raceway/course_offsets.c b/courses/royal_raceway/course_offsets.c index 94f362ffd..108ee5825 100644 --- a/courses/royal_raceway/course_offsets.c +++ b/courses/royal_raceway/course_offsets.c @@ -2,53 +2,6 @@ #include "course_offsets.h" #include -const course_texture royal_raceway_textures[] = { - { gTexture64619C, 0x0124, 0x0800, 0x0 }, - { gTexture645134, 0x052C, 0x0800, 0x0 }, - { gTextureWoodDoor1, 0x0903, 0x1000, 0x0 }, - { gTexture64BB60, 0x0169, 0x0800, 0x0 }, - { gTextureGrass3, 0x0372, 0x0800, 0x0 }, - { gTexture64F9E8, 0x020B, 0x1000, 0x0 }, - { gTextureFlagRed, 0x019E, 0x0800, 0x0 }, - { gTextureCrownJewelBlue, 0x0301, 0x0800, 0x0 }, - { gTextureCrown, 0x0106, 0x0800, 0x0 }, - { gTextureCrownJewelPink, 0x0313, 0x0800, 0x0 }, - { gTextureSignKoopaAir0, 0x0360, 0x1000, 0x0 }, - { gTextureSignKoopaAir1, 0x0304, 0x1000, 0x0 }, - { gTexture6684F8, 0x010D, 0x0800, 0x0 }, - { gTextureSignLuigis0, 0x0287, 0x1000, 0x0 }, - { gTextureSignLuigis1, 0x02AF, 0x1000, 0x0 }, - { gTextureSignMarioStar0, 0x02D2, 0x1000, 0x0 }, - { gTextureSignMarioStar1, 0x02B1, 0x1000, 0x0 }, - { gTexture66CA98, 0x02C9, 0x0800, 0x0 }, - { gTextureCheckerboardPink, 0x0157, 0x0800, 0x0 }, - { gTexture670AC8, 0x0FBF, 0x1000, 0x0 }, - { gTextureRoad0, 0x0300, 0x1000, 0x0 }, - { gTextureRoadFinish0, 0x0338, 0x1000, 0x0 }, - { gTextureSignYoshi, 0x04DF, 0x1000, 0x0 }, - { gTextureCheckerboardBlueGray, 0x04A1, 0x1000, 0x0 }, - { gTextureCastleBricks, 0x0B33, 0x1000, 0x0 }, - { gTextureCastleBridge, 0x0428, 0x0800, 0x0 }, - { gTextureGrass8, 0x02CB, 0x0800, 0x0 }, - { gTextureGrass9, 0x0421, 0x0800, 0x0 }, - { gTexture6646B8, 0x0298, 0x1000, 0x0 }, - { gTexture664408, 0x02AE, 0x1000, 0x0 }, - { gTextureBricksRed, 0x0C55, 0x1000, 0x0 }, - { gTexture665C0C, 0x059D, 0x0800, 0x0 }, - { gTexture6661AC, 0x01F7, 0x0800, 0x0 }, - { gTexture6663A4, 0x05F6, 0x0800, 0x0 }, - { gTexture667BAC, 0x067A, 0x0800, 0x0 }, - { gTextureFlagRed2, 0x0186, 0x0800, 0x0 }, - { gTexture66DB60, 0x01D6, 0x0800, 0x0 }, - { gTextureStainglassPeach0, 0x0ED1, 0x1000, 0x0 }, - { gTextureStainglassPeach1, 0x0DA9, 0x1000, 0x0 }, - { gTextureFencePostWooden, 0x083D, 0x1000, 0x0 }, - { gTexture648508, 0x01FE, 0x1000, 0x0 }, - { gTexture6449D4, 0x075D, 0x0800, 0x0 }, - { gTexture67FE0C, 0x02DE, 0x0800, 0x0 }, - { 0x00000000, 0x0000, 0x0000, 0x0 }, -}; - const Gfx* royal_raceway_dls[] = { d_course_royal_raceway_dl_0, d_course_royal_raceway_dl_360, d_course_royal_raceway_dl_258, d_course_royal_raceway_dl_470, d_course_royal_raceway_dl_6D0, d_course_royal_raceway_dl_A48, diff --git a/courses/sherbet_land/course_offsets.c b/courses/sherbet_land/course_offsets.c index b597ee828..b81dba828 100644 --- a/courses/sherbet_land/course_offsets.c +++ b/courses/sherbet_land/course_offsets.c @@ -3,15 +3,6 @@ #include #include "animation.h" -const course_texture sherbet_land_textures[] = { - { gTexture643B3C, 0x0798, 0x0800, 0x0 }, { gTexture66D024, 0x04EA, 0x0800, 0x0 }, - { gTexture678118, 0x0314, 0x0800, 0x0 }, { gTextureSignWoodRedArrow, 0x04E1, 0x1000, 0x0 }, - { gTexture678CC8, 0x058E, 0x0800, 0x0 }, { gTexture67842C, 0x050E, 0x0800, 0x0 }, - { gTexture67893C, 0x038B, 0x0800, 0x0 }, { gTexture651984, 0x019C, 0x0800, 0x0 }, - { gTexture651428, 0x055B, 0x0800, 0x0 }, { gTexture662924, 0x0110, 0x0800, 0x0 }, - { 0x00000000, 0x0000, 0x0000, 0x0 }, -}; - const Gfx* sherbet_land_dls[] = { d_course_sherbet_land_dl_0, d_course_sherbet_land_dl_158, d_course_sherbet_land_dl_C0, d_course_sherbet_land_dl_1A8, d_course_sherbet_land_dl_280, d_course_sherbet_land_dl_3B8, diff --git a/courses/skyscraper/course_offsets.c b/courses/skyscraper/course_offsets.c deleted file mode 100644 index c0c12aa88..000000000 --- a/courses/skyscraper/course_offsets.c +++ /dev/null @@ -1,29 +0,0 @@ -#include -#include "course_offsets.h" - -const course_texture skyscraper_textures[] = { - { gTexture6457D8, 0x0160, 0x0800, 0x0 }, - { gTexture6462C0, 0x01B9, 0x0800, 0x0 }, - { gTexture6864E8, 0x0807, 0x1000, 0x0 }, - { gTexture686CF0, 0x08B7, 0x1000, 0x0 }, - { gTexture6875A8, 0x093F, 0x1000, 0x0 }, - { gTexture687EE8, 0x0883, 0x1000, 0x0 }, - { gTexture68876C, 0x0AC2, 0x1000, 0x0 }, - { gTexture689230, 0x09CE, 0x1000, 0x0 }, - { gTexture689C00, 0x0884, 0x1000, 0x0 }, - { gTexture68A484, 0x07D6, 0x1000, 0x0 }, - { gTexture68AC5C, 0x0A47, 0x1000, 0x0 }, - { gTexture68B6A4, 0x07C5, 0x1000, 0x0 }, - { gTexture68BE6C, 0x04A1, 0x1000, 0x0 }, - { gTexture68C310, 0x030D, 0x1000, 0x0 }, - { gTexture64B8D8, 0x0177, 0x0800, 0x0 }, - { gTexture645660, 0x0176, 0x0800, 0x0 }, - { gTextureNumberYellowBlue1, 0x01AE, 0x0800, 0x0 }, - { gTextureNumberYellowBlue2, 0x01C6, 0x0800, 0x0 }, - { gTextureNumberYellowBlue3, 0x01CC, 0x0800, 0x0 }, - { gTextureNumberYellowBlue4, 0x01E4, 0x0800, 0x0 }, - { gTexture668608, 0x0120, 0x0800, 0x0 }, - { gTexture67B75C, 0x0108, 0x0800, 0x0 }, - { gTexture6835F0, 0x0252, 0x1000, 0x0 }, - { 0x00000000, 0x0000, 0x0000, 0x0 }, -}; diff --git a/courses/toads_turnpike/course_offsets.c b/courses/toads_turnpike/course_offsets.c index b702ab56e..885d06bed 100644 --- a/courses/toads_turnpike/course_offsets.c +++ b/courses/toads_turnpike/course_offsets.c @@ -3,29 +3,6 @@ #include "course_offsets.h" #include -const course_texture toads_turnpike_textures[] = { - { gTexture645134, 0x052C, 0x0800, 0x0 }, - { gTexture64FE68, 0x0258, 0x1000, 0x0 }, - { gTexture6607C0, 0x0105, 0x0800, 0x0 }, - { gTexture6608C8, 0x0106, 0x0800, 0x0 }, - { gTextureGrass11, 0x01F8, 0x0800, 0x0 }, - { gTextureSignNintendoRed0, 0x02A6, 0x1000, 0x0 }, - { gTextureSignNintendoRed1, 0x02F7, 0x1000, 0x0 }, - { gTexture671A88, 0x012D, 0x0800, 0x0 }, - { gTextureRoad2, 0x02AE, 0x1000, 0x0 }, - { gTextureRoad3, 0x0286, 0x1000, 0x0 }, - { gTextureRoad4, 0x0282, 0x1000, 0x0 }, - { gTextureRoadFinish0, 0x0338, 0x1000, 0x0 }, - { gTextureSignToadYellow, 0x0723, 0x1000, 0x0 }, - { gTextureSignToadGreen, 0x071F, 0x1000, 0x0 }, - { gTextureSignMergingLanes, 0x0118, 0x0800, 0x0 }, - { gTexture65127C, 0x01AB, 0x0800, 0x0 }, - { gTextureRoad5, 0x02B9, 0x1000, 0x0 }, - { gTextureSignToadRed, 0x0610, 0x1000, 0x0 }, - { gTexture668228, 0x0130, 0x0800, 0x0 }, - { 0x00000000, 0x0000, 0x0000, 0x0 }, -}; - Gfx* d_course_toads_turnpike_dl_list[] = { d_course_toads_turnpike_dl_80, d_course_toads_turnpike_dl_1F8, d_course_toads_turnpike_dl_158, d_course_toads_turnpike_dl_2D0, d_course_toads_turnpike_dl_380, d_course_toads_turnpike_dl_4E8, diff --git a/courses/wario_stadium/course_offsets.c b/courses/wario_stadium/course_offsets.c index 137d468cf..3111bcba9 100644 --- a/courses/wario_stadium/course_offsets.c +++ b/courses/wario_stadium/course_offsets.c @@ -2,30 +2,6 @@ #include "course_offsets.h" #include -const course_texture wario_stadium_textures[] = { - { gTexture67F15C, 0x02F1, 0x0800, 0x0 }, - { gTexture67F450, 0x0194, 0x0800, 0x0 }, - { gTextureSignWarioFace, 0x0825, 0x1000, 0x0 }, - { gTexture670AC8, 0x0FBF, 0x1000, 0x0 }, - { gTextureCheckerboardBlackWhite, 0x0107, 0x0800, 0x0 }, - { gTexture64C11C, 0x0695, 0x0800, 0x0 }, - { gTexture64C7B4, 0x046C, 0x0800, 0x0 }, - { gTexture668228, 0x0130, 0x0800, 0x0 }, - { gTexture668358, 0x01A0, 0x0800, 0x0 }, - { gTexture66AEB8, 0x0201, 0x0800, 0x0 }, - { gTexture677A40, 0x0275, 0x0800, 0x0 }, - { gTexture67E428, 0x0A81, 0x1000, 0x0 }, - { gTexture643A34, 0x0106, 0x0800, 0x0 }, - { gTexture66EBF0, 0x0146, 0x0800, 0x0 }, - { gTexture68272C, 0x01F9, 0x1000, 0x0 }, - { gTexture682928, 0x01F9, 0x1000, 0x0 }, - { gTexture682B24, 0x01F9, 0x1000, 0x0 }, - { gTexture682D20, 0x01F9, 0x1000, 0x0 }, - { gTexture682F1C, 0x01F9, 0x1000, 0x0 }, - { gTexture683118, 0x01F9, 0x1000, 0x0 }, - { 0x00000000, 0x0000, 0x0000, 0x0 }, -}; - const Gfx* wario_stadium_dls[] = { d_course_wario_stadium_dl_0, d_course_wario_stadium_dl_158, d_course_wario_stadium_dl_B8, d_course_wario_stadium_dl_1B8, d_course_wario_stadium_dl_2A0, d_course_wario_stadium_dl_440, diff --git a/courses/yoshi_valley/course_offsets.c b/courses/yoshi_valley/course_offsets.c index 7518ece5d..b6b229ad3 100644 --- a/courses/yoshi_valley/course_offsets.c +++ b/courses/yoshi_valley/course_offsets.c @@ -20,24 +20,6 @@ extern u8 gTextureSignWoodRedArrow[]; extern u8 gTexture68DEC0[]; #endif -const course_texture yoshi_valley_textures[] = { - { gTexture66EBF0, 0x0146, 0x0800, 0x0 }, - { gTextureWoodBridgeSlats, 0x0DAB, 0x1000, 0x0 }, - { gTexture65E2EC, 0x02B0, 0x0800, 0x0 }, - { gTexture6846DC, 0x04EA, 0x0800, 0x0 }, - { gTextureFenceRope, 0x0540, 0x0800, 0x0 }, - { gTexture685108, 0x04D4, 0x0800, 0x0 }, - { gTexture64CC20, 0x0EC3, 0x1000, 0x0 }, - { gTextureGrass4, 0x05C3, 0x0800, 0x0 }, - { gTexture6775EC, 0x0233, 0x1000, 0x0 }, - { gTexture68E2D0, 0x087F, 0x0800, 0x0 }, - { gTextureCheckerboardBlackWhite, 0x0107, 0x0800, 0x0 }, - { gTexture643B3C, 0x0798, 0x0800, 0x0 }, - { gTextureSignWoodRedArrow, 0x04E1, 0x1000, 0x0 }, - { gTexture68DEC0, 0x0410, 0x0800, 0x0 }, - { 0x00000000, 0x0000, 0x0000, 0x0 }, -}; - Gfx* d_course_yoshi_valley_dl_list[] = { d_course_yoshi_valley_dl_40, d_course_yoshi_valley_dl_3F0, d_course_yoshi_valley_dl_290, d_course_yoshi_valley_dl_4E8, d_course_yoshi_valley_dl_7A0, d_course_yoshi_valley_dl_BC0, diff --git a/src/actors/kiwano_fruit/render.inc.c b/src/actors/kiwano_fruit/render.inc.c index 137eda99e..0ecfacf29 100644 --- a/src/actors/kiwano_fruit/render.inc.c +++ b/src/actors/kiwano_fruit/render.inc.c @@ -1,6 +1,7 @@ #include #include #include +#include "assets/other_textures.h" // #include /** @@ -28,7 +29,22 @@ void render_actor_kiwano_fruit(UNUSED Camera* camera, Mat4 arg1, struct Actor* a return; } - addr = segmented_texture_to_virtual((actor->rot[0] << 0xA) + 0x03009000); + // Animate actor by creating an index from rot[0]. Divide by texture size to get whole number 0-2. + // All three animated textures need to be the same size for this to work. + size_t idx = (actor->rot[0] << 0xA) / ResourceGetTexSizeByName(gTextureDksJungleParkwayKiwanoFruit1); + switch(idx) { + case 0: + addr = gTextureDksJungleParkwayKiwanoFruit1; + break; + case 1: + addr = gTextureDksJungleParkwayKiwanoFruit2; + break; + case 2: + addr = gTextureDksJungleParkwayKiwanoFruit3; + break; + } + + //addr = segmented_texture_to_virtual((actor->rot[0] << 0xA) + 0x03009000); gDPLoadTextureBlock(gDisplayListHead++, VIRTUAL_TO_PHYSICAL(addr), G_IM_FMT_CI, G_IM_SIZ_8b, 32, 32, 0, G_TX_NOMIRROR | G_TX_CLAMP, G_TX_NOMIRROR | G_TX_CLAMP, G_TX_NOMASK, G_TX_NOMASK, G_TX_NOLOD, G_TX_NOLOD); diff --git a/src/engine/Engine.h b/src/engine/Engine.h index 5af480c23..c25afa79c 100644 --- a/src/engine/Engine.h +++ b/src/engine/Engine.h @@ -7,6 +7,7 @@ #include "path_spawn_metadata.h" #include "waypoints.h" #include "sounds.h" +#include "course_offsets.h" typedef struct { RGB8 TopRight; @@ -45,6 +46,7 @@ typedef struct { s32 MinimapFinishlineX; s32 MinimapFinishlineY; SkyboxColours Skybox; + const course_texture *textures; enum MusicSeq Sequence; } CProperties; diff --git a/src/engine/GameObject.cpp b/src/engine/GameObject.cpp index eb2127fcc..fc7c03344 100644 --- a/src/engine/GameObject.cpp +++ b/src/engine/GameObject.cpp @@ -1,20 +1,20 @@ -#include "GameObject.h" -#include +// #include +// #include "GameObject.h" -#include "World.h" +// #include "World.h" -extern "C" { - #include "camera.h" -} +// extern "C" { +// #include "camera.h" +// } - //GameActor() +// //GameActor() -GameObject::GameObject() {} +// GameObject::GameObject() {} - // Virtual functions to be overridden by derived classes -void GameObject::Tick() { } -void GameObject::Draw(Camera* camera) { } -void GameObject::Collision() {} -void GameObject::Expire() { } -void GameObject::Destroy() { } +// // Virtual functions to be overridden by derived classes +// void GameObject::Tick() { } +// void GameObject::Draw(Camera* camera) { } +// void GameObject::Collision() {} +// void GameObject::Expire() { } +// void GameObject::Destroy() { } diff --git a/src/engine/GameObject.h b/src/engine/GameObject.h index 19d5301cd..b6ac8c559 100644 --- a/src/engine/GameObject.h +++ b/src/engine/GameObject.h @@ -1,24 +1,24 @@ -#pragma once +// #pragma once -#include +// #include -extern "C" { - #include "camera.h" - #include "objects.h" -} +// extern "C" { +// #include "camera.h" +// #include "objects.h" +// } -class GameObject { -public: - uint8_t uuid[16]; - Object o; +// class GameObject { +// public: +// uint8_t uuid[16]; +// Object o; - virtual ~GameObject() = default; +// virtual ~GameObject() = default; - explicit GameObject(); +// explicit GameObject(); - virtual void Tick(); - virtual void Draw(Camera* camera); - virtual void Collision(); - virtual void Expire(); - virtual void Destroy(); -}; +// virtual void Tick(); +// virtual void Draw(Camera* camera); +// virtual void Collision(); +// virtual void Expire(); +// virtual void Destroy(); +// }; diff --git a/src/engine/World.cpp b/src/engine/World.cpp index b8371b2c8..ecaad485d 100644 --- a/src/engine/World.cpp +++ b/src/engine/World.cpp @@ -9,10 +9,11 @@ #include "vehicles/Bus.h" #include "vehicles/TankerTruck.h" #include "vehicles/Car.h" -#include "vehicles/OBombKart.h" +#include "objects/OBombKart.h" +#include "objects/OPenguin.h" #include "TrainCrossing.h" #include - +//#include "objects/GameObject.h" extern "C" { #include "camera.h" @@ -184,11 +185,11 @@ void World::PreviousCourse() { gWorldInstance.CurrentCourse = Courses[CourseIndex]; } -Object* World::AddObject(std::unique_ptr object) { - GameObject* rawPtr = object.get(); - GameObjects.push_back(std::move(object)); - return &rawPtr->o; -} +// Object* World::AddObject(std::unique_ptr object) { +// GameObject* rawPtr = object.get(); +// GameObjects.push_back(std::move(object)); +// return &rawPtr->o; +// } AActor* World::AddActor(AActor* actor) { Actors.push_back(actor); @@ -240,22 +241,22 @@ void RemoveExpiredActors() { } void World::TickObjects() { - for (const auto& object : this->GameObjects) { - object->Tick(); - } + //for (const auto& object : this->GameObjects) { + // object->Tick(); + //} } void World::DrawObjects(Camera *camera) { - for (const auto& object : this->GameObjects) { - object->Draw(camera); - } + //for (const auto& object : this->GameObjects) { + // object->Draw(camera); + //} } void World::ExpiredObjects() { - this->GameObjects.erase( - std::remove_if(this->GameObjects.begin(), this->GameObjects.end(), - [](const std::unique_ptr& object) { return object->uuid == 0; }), // Example condition - this->GameObjects.end()); + //this->GameObjects.erase( + // std::remove_if(this->GameObjects.begin(), this->GameObjects.end(), + // [](const std::unique_ptr& object) { return object->uuid == 0; }), // Example condition + // this->GameObjects.end()); } void World::DestroyObjects() { @@ -263,9 +264,9 @@ void World::DestroyObjects() { } Object* World::GetObjectByIndex(size_t index) { - if (index < this->GameObjects.size()) { + //if (index < this->GameObjects.size()) { // Assuming GameActor::a is accessible, use reinterpret_cast if needed - return reinterpret_cast(&this->GameObjects[index]->o); - } + // return reinterpret_cast(&this->GameObjects[index]->o); + //} return nullptr; // Or handle the error as needed } diff --git a/src/engine/World.h b/src/engine/World.h index b6801a668..0df9e7278 100644 --- a/src/engine/World.h +++ b/src/engine/World.h @@ -1,16 +1,16 @@ #pragma once #include -#include "GameObject.h" +//#include "objects/GameObject.h" #include "Cup.h" #include "vehicles/Vehicle.h" #include "vehicles/Train.h" #include "vehicles/Car.h" -#include "vehicles/OBombKart.h" +#include "objects/OBombKart.h" #include "vehicles/Train.h" #include "TrainCrossing.h" -#include "vehicles/OThwomp.h" -#include "vehicles/OPenguin.h" +#include "objects/OThwomp.h" +#include "objects/OPenguin.h" #include #include "Actor.h" @@ -20,6 +20,7 @@ extern "C" { #include "engine/Engine.h" }; +//class GameObject; class Cup; // <-- Forward declaration class Course; class AVehicle; @@ -92,7 +93,7 @@ public: AActor* ConvertActorToAActor(Actor* actor); Actor* ConvertAActorToActor(AActor* actor); - Object* AddObject(std::unique_ptr object); +// Object* AddObject(std::unique_ptr object); CProperties* GetCourseProps(); void TickObjects(); @@ -128,7 +129,7 @@ public: size_t CupIndex = 1; std::vector Actors; - std::vector> GameObjects; +// std::vector> GameObjects; /** Actors */ void AddBoat(f32 speed, uint32_t waypoint); diff --git a/src/engine/courses/BansheeBoardwalk.cpp b/src/engine/courses/BansheeBoardwalk.cpp index f1dc8287c..04ed6caf0 100644 --- a/src/engine/courses/BansheeBoardwalk.cpp +++ b/src/engine/courses/BansheeBoardwalk.cpp @@ -4,10 +4,9 @@ #include #include "BansheeBoardwalk.h" -#include "GameObject.h" #include "World.h" #include "engine/actors/AFinishline.h" -#include "engine/vehicles/OBombKart.h" +#include "engine/objects/OBombKart.h" #include "assets/banshee_boardwalk_data.h" #include "assets/boo_frames.h" @@ -31,14 +30,41 @@ extern "C" { #include "actors.h" #include "collision.h" #include "memory.h" + #include "course_offsets.h" extern const char *banshee_boardwalk_dls[]; } +const course_texture banshee_boardwalk_textures[] = { + { gTexture6447C4, 0x0106, 0x0800, 0x0 }, + { gTexture676FB0, 0x0525, 0x0800, 0x0 }, + { gTexture643B3C, 0x0798, 0x0800, 0x0 }, + { gTexture64BB60, 0x0169, 0x0800, 0x0 }, + { gTexture64BCCC, 0x0450, 0x0800, 0x0 }, + { gTexture64FBF4, 0x0274, 0x0800, 0x0 }, + { gTexture651B20, 0x041D, 0x0800, 0x0 }, + { gTexture66262C, 0x02F7, 0x0800, 0x0 }, + { gTexture668728, 0x01F5, 0x0800, 0x0 }, + { gTexture66A3DC, 0x07C5, 0x0800, 0x0 }, + { gTexture66CA98, 0x02C9, 0x0800, 0x0 }, + { gTexture66CD64, 0x02C0, 0x0800, 0x0 }, + { gTexture66D698, 0x0370, 0x0800, 0x0 }, + { gTexture66E608, 0x05E8, 0x0800, 0x0 }, + { gTexture67B388, 0x03D2, 0x0800, 0x0 }, + { gTextureSignWelcome0, 0x0A2E, 0x1000, 0x0 }, + { gTextureSignWelcome1, 0x0A0A, 0x1000, 0x0 }, + { gTextureSignWoodenBack0, 0x06EF, 0x1000, 0x0 }, + { gTextureSignWoodenBack1, 0x06D1, 0x1000, 0x0 }, + { gTextureSignWoodRedArrow, 0x04E1, 0x1000, 0x0 }, + { gTexture68D940, 0x057D, 0x0800, 0x0 }, + { gTexture685AC0, 0x07CC, 0x1000, 0x0 }, + { 0x00000000, 0x0000, 0x0000, 0x0 }, +}; + BansheeBoardwalk::BansheeBoardwalk() { this->vtx = d_course_banshee_boardwalk_vertex; this->gfx = d_course_banshee_boardwalk_packed_dls; this->gfxSize = 3689; - this->textures = banshee_boardwalk_textures; + Props.textures = banshee_boardwalk_textures; Props.MinimapTexture = gTextureCourseOutlineBansheeBoardwalk; Props.D_800E5548[0] = 64; Props.D_800E5548[1] = 64; diff --git a/src/engine/courses/BigDonut.cpp b/src/engine/courses/BigDonut.cpp index 56ff61a66..d4597fe7b 100644 --- a/src/engine/courses/BigDonut.cpp +++ b/src/engine/courses/BigDonut.cpp @@ -4,9 +4,8 @@ #include #include "BigDonut.h" -#include "GameObject.h" #include "World.h" -#include "engine/vehicles/OBombKart.h" +#include "engine/objects/OBombKart.h" #include "assets/big_donut_data.h" extern "C" { @@ -33,11 +32,17 @@ extern "C" { extern s16 currentScreenSection; } +const course_texture big_donut_textures[] = { + { gTexture66ABA4, 0x0312, 0x0800, 0x0 }, { gTexture6747C4, 0x0145, 0x0800, 0x0 }, + { gTexture67490C, 0x021C, 0x0800, 0x0 }, { gTexture64BA50, 0x0110, 0x0800, 0x0 }, + { 0x00000000, 0x0000, 0x0000, 0x0 }, +}; + BigDonut::BigDonut() { this->vtx = d_course_big_donut_vertex; this->gfx = d_course_big_donut_packed_dls; this->gfxSize = 528; - this->textures = big_donut_textures; + Props.textures = big_donut_textures; Props.MinimapTexture = gTextureCourseOutlineBigDonut; Props.D_800E5548[0] = 64; Props.D_800E5548[1] = 64; diff --git a/src/engine/courses/BlockFort.cpp b/src/engine/courses/BlockFort.cpp index a61e26280..6178dcc5c 100644 --- a/src/engine/courses/BlockFort.cpp +++ b/src/engine/courses/BlockFort.cpp @@ -4,9 +4,8 @@ #include #include "BlockFort.h" -#include "GameObject.h" #include "World.h" -#include "engine/vehicles/OBombKart.h" +#include "engine/objects/OBombKart.h" #include "assets/block_fort_data.h" extern "C" { @@ -29,15 +28,23 @@ extern "C" { #include "actors.h" #include "collision.h" #include "memory.h" + #include "course_offsets.h" extern const char *block_fort_dls[]; extern s16 currentScreenSection; } +const course_texture block_fort_textures[] = { + { gTexture64286C, 0x010A, 0x0800, 0x0 }, { gTextureGrayCheckerboard, 0x010C, 0x0800, 0x0 }, + { gTextureGrayCobblestone, 0x010C, 0x0800, 0x0 }, { gTexture64275C, 0x0110, 0x0800, 0x0 }, + { gTexture642978, 0x010D, 0x0800, 0x0 }, { gTexture6747C4, 0x0145, 0x0800, 0x0 }, + { gTexture6442D4, 0x0138, 0x0800, 0x0 }, { 0x00000000, 0x0000, 0x0000, 0x0 }, +}; + BlockFort::BlockFort() { this->vtx = d_course_block_fort_vertex; this->gfx = d_course_block_fort_packed_dls; this->gfxSize = 699; - this->textures = block_fort_textures; + Props.textures = block_fort_textures; Props.MinimapTexture = gTextureCourseOutlineBlockFort; Props.D_800E5548[0] = 64; Props.D_800E5548[1] = 64; diff --git a/src/engine/courses/BowsersCastle.cpp b/src/engine/courses/BowsersCastle.cpp index 9098c62e9..9e9c85d61 100644 --- a/src/engine/courses/BowsersCastle.cpp +++ b/src/engine/courses/BowsersCastle.cpp @@ -4,10 +4,9 @@ #include #include "BowsersCastle.h" -#include "GameObject.h" #include "World.h" #include "engine/actors/AFinishline.h" -#include "engine/vehicles/OBombKart.h" +#include "engine/objects/OBombKart.h" #include "bowsers_castle_data.h" extern "C" { @@ -34,11 +33,43 @@ extern "C" { extern const char *bowsers_castle_dls[]; } +const course_texture bowsers_castle_textures[] = { + { gTexture64313C, 0x01B8, 0x0800, 0x0 }, + { gTexture6528DC, 0x0278, 0x0800, 0x0 }, + { gTexture66ED38, 0x010E, 0x0800, 0x0 }, + { gTexture676C6C, 0x0110, 0x0800, 0x0 }, + { gTexture676EA8, 0x0108, 0x0800, 0x0 }, + { gTexture679D34, 0x0106, 0x0800, 0x0 }, + { gTextureGrass6, 0x023B, 0x0800, 0x0 }, + { gTexture6522E0, 0x05FC, 0x0800, 0x0 }, + { gTexture651F40, 0x039F, 0x0800, 0x0 }, + { gTextureRoofTile, 0x0129, 0x0800, 0x0 }, + { gTextureSignBowser0, 0x07D0, 0x1000, 0x0 }, + { gTextureSignBowser1, 0x064D, 0x1000, 0x0 }, + { gTexture66ABA4, 0x0312, 0x0800, 0x0 }, + { gTexture66EBF0, 0x0146, 0x0800, 0x0 }, + { gTexture6733CC, 0x020E, 0x0800, 0x0 }, + { gTexture673118, 0x02B1, 0x0800, 0x0 }, + { gTexture673FF8, 0x035B, 0x0800, 0x0 }, + { gTexture674B28, 0x0230, 0x0800, 0x0 }, + { gTextureSignGreenArrow, 0x025B, 0x1000, 0x0 }, + { gTexture68D834, 0x010A, 0x0800, 0x0 }, + { gTexture676D7C, 0x012C, 0x0800, 0x0 }, + { gTexture67ADF0, 0x0595, 0x0800, 0x0 }, + { gTexture67EFEC, 0x016F, 0x0800, 0x0 }, + { gTexture653DB0, 0x06AE, 0x0800, 0x0 }, + { gTexture66CA98, 0x02C9, 0x0800, 0x0 }, + { gTexture673990, 0x02D8, 0x0800, 0x0 }, + { gTexture67A370, 0x05AA, 0x0800, 0x0 }, + { gTexture67A91C, 0x04D1, 0x0800, 0x0 }, + { 0x00000000, 0x0000, 0x0000, 0x0 }, +}; + BowsersCastle::BowsersCastle() { this->vtx = d_course_bowsers_castle_vertex; this->gfx = d_course_bowsers_castle_packed_dls; this->gfxSize = 4900; - this->textures = bowsers_castle_textures; + Props.textures = bowsers_castle_textures; Props.MinimapTexture = gTextureCourseOutlineBowsersCastle; Props.D_800E5548[0] = 64; Props.D_800E5548[1] = 64; diff --git a/src/engine/courses/ChocoMountain.cpp b/src/engine/courses/ChocoMountain.cpp index 71e147f2d..b497b2431 100644 --- a/src/engine/courses/ChocoMountain.cpp +++ b/src/engine/courses/ChocoMountain.cpp @@ -4,9 +4,8 @@ #include #include "ChocoMountain.h" -#include "GameObject.h" #include "World.h" -#include "engine/vehicles/OBombKart.h" +#include "engine/objects/OBombKart.h" #include "choco_mountain_data.h" #include "engine/actors/AFinishline.h" @@ -31,14 +30,39 @@ extern "C" { #include "collision.h" #include "code_8003DC40.h" #include "memory.h" + #include "course_offsets.h" extern const char *choco_mountain_dls[]; } +const course_texture choco_mountain_textures[] = { + { gTexture64619C, 0x0124, 0x0800, 0x0 }, + { gTexture64647C, 0x0829, 0x1000, 0x0 }, + { gTexture647F4C, 0x05BC, 0x1000, 0x0 }, + { gTexture64FBF4, 0x0274, 0x0800, 0x0 }, + { gTexture653DB0, 0x06AE, 0x0800, 0x0 }, + { gTexture652B54, 0x0606, 0x0800, 0x0 }, + { gTexture65315C, 0x04A9, 0x0800, 0x0 }, + { gTexture6684F8, 0x010D, 0x0800, 0x0 }, + { gTextureSignLuigis0, 0x0287, 0x1000, 0x0 }, + { gTextureSignLuigis1, 0x02AF, 0x1000, 0x0 }, + { gTextureSignNintendoRed0, 0x02A6, 0x1000, 0x0 }, + { gTextureSignNintendoRed1, 0x02F7, 0x1000, 0x0 }, + { gTexture6774D8, 0x0113, 0x0800, 0x0 }, + { gTextureSignFallingRocks, 0x012C, 0x0800, 0x0 }, + { gTextureSignBackside, 0x011E, 0x0800, 0x0 }, + { gTexture679C04, 0x012F, 0x0800, 0x0 }, + { gTexture67B864, 0x014C, 0x0800, 0x0 }, + { gTexture67DC20, 0x03EF, 0x0800, 0x0 }, + { gTextureSignYoshi, 0x04DF, 0x1000, 0x0 }, + { gTextureCheckerboardBlueGray, 0x04A1, 0x1000, 0x0 }, + { 0x00000000, 0x0000, 0x0000, 0x0 }, +}; + ChocoMountain::ChocoMountain() { this->vtx = d_course_choco_mountain_vertex; this->gfx = d_course_choco_mountain_packed_dls; this->gfxSize = 2910; - this->textures = choco_mountain_textures; + Props.textures = choco_mountain_textures; Props.MinimapTexture = gTextureCourseOutlineChocoMountain; Props.D_800E5548[0] = 64; Props.D_800E5548[1] = 64; diff --git a/src/engine/courses/Course.cpp b/src/engine/courses/Course.cpp index 022ee016e..26c549367 100644 --- a/src/engine/courses/Course.cpp +++ b/src/engine/courses/Course.cpp @@ -94,7 +94,7 @@ void Course::Load() { func_802A86A8(reinterpret_cast(LOAD_ASSET_RAW(this->vtx)), vtx, vtxSize / sizeof(Vtx)); // Load and allocate memory for course textures - const course_texture* asset = this->textures; + const course_texture* asset = this->Props.textures; u8* freeMemory = NULL; u8* texture = NULL; size_t size = 0; @@ -103,12 +103,14 @@ void Course::Load() { size = ResourceGetTexSizeByName(asset->addr); freeMemory = (u8*) allocate_memory(size); - texture = reinterpret_cast(LOAD_ASSET_RAW(asset->addr)); + texture = (u8*)(asset->addr); + printf("TEXTURE: 0x%llX\n",texture); if (texture) { - if (asset == &textures[0]) { + if (asset == &this->Props.textures[0]) { gSegmentTable[5] = reinterpret_cast(&freeMemory[0]); } - memcpy(freeMemory, texture, size); + strcpy(reinterpret_cast(freeMemory), asset->addr); + //memcpy(freeMemory, texture, size); texSegSize += size; // printf("Texture Addr: 0x%llX, size 0x%X\n", &freeMemory[0], size); } diff --git a/src/engine/courses/Course.h b/src/engine/courses/Course.h index e711dd510..72dd52639 100644 --- a/src/engine/courses/Course.h +++ b/src/engine/courses/Course.h @@ -75,6 +75,7 @@ public: int32_t MinimapFinishlineX; int32_t MinimapFinishlineY; SkyboxColours Skybox; + const course_texture *textures; MusicSeq Sequence; } Properties; diff --git a/src/engine/courses/DKJungle.cpp b/src/engine/courses/DKJungle.cpp index 479c23b02..ccf2af4b9 100644 --- a/src/engine/courses/DKJungle.cpp +++ b/src/engine/courses/DKJungle.cpp @@ -4,10 +4,9 @@ #include #include "DKJungle.h" -#include "GameObject.h" #include "World.h" #include "engine/actors/AFinishline.h" -#include "engine/vehicles/OBombKart.h" +#include "engine/objects/OBombKart.h" #include "assets/dks_jungle_parkway_data.h" #include "engine/vehicles/Utils.h" @@ -38,11 +37,39 @@ extern "C" { extern s16 currentScreenSection; } +const course_texture dks_jungle_parkway_textures[] = { + { gTexture648508, 0x01FE, 0x1000, 0x0 }, + { gTexture6684F8, 0x010D, 0x0800, 0x0 }, + { gTextureWoodBridgeSlats, 0x0DAB, 0x1000, 0x0 }, + { gTexture654460, 0x0B12, 0x1000, 0x0 }, + { gTexture654F74, 0x0A24, 0x1000, 0x0 }, + { gTexture655998, 0x059F, 0x0800, 0x0 }, + { gTexture655F38, 0x0BB9, 0x1000, 0x0 }, + { gTexture656AF4, 0x0AD3, 0x1000, 0x0 }, + { gTexture6575C8, 0x0DA7, 0x1000, 0x0 }, + { gTexture658370, 0x0DBA, 0x1000, 0x0 }, + { gTexture65912C, 0x0DBC, 0x1000, 0x0 }, + { gTexture659EE8, 0x0EF5, 0x1000, 0x0 }, + { gTexture65ADE0, 0x0D5A, 0x1000, 0x0 }, + { gTexture65BB3C, 0x0D9E, 0x1000, 0x0 }, + { gTexture65C8DC, 0x0CF5, 0x1000, 0x0 }, + { gTexture65D5D4, 0x0D18, 0x1000, 0x0 }, + { gTexture65E2EC, 0x02B0, 0x0800, 0x0 }, + { gTexture65EAEC, 0x034A, 0x0800, 0x0 }, + { gTexture65E59C, 0x054F, 0x1000, 0x0 }, + { gTexture65EE38, 0x0CDE, 0x1000, 0x0 }, + { gTexture65FB18, 0x03EE, 0x0800, 0x0 }, + { gTextureSignPinkArrow, 0x0198, 0x0800, 0x0 }, + { gTextureWaves0, 0x04D0, 0x0800, 0x0 }, + { gTexture683844, 0x0655, 0x0800, 0x0 }, + { 0x00000000, 0x0000, 0x0000, 0x0 }, +}; + DKJungle::DKJungle() { this->vtx = d_course_dks_jungle_parkway_vertex; this->gfx = d_course_dks_jungle_parkway_packed_dls; this->gfxSize = 4997; - this->textures = dks_jungle_parkway_textures; + Props.textures = dks_jungle_parkway_textures; Props.MinimapTexture = gTextureCourseOutlineDksJungleParkway; Props.D_800E5548[0] = 64; Props.D_800E5548[1] = 64; diff --git a/src/engine/courses/DoubleDeck.cpp b/src/engine/courses/DoubleDeck.cpp index 74fb7e714..37064a059 100644 --- a/src/engine/courses/DoubleDeck.cpp +++ b/src/engine/courses/DoubleDeck.cpp @@ -4,9 +4,8 @@ #include #include "DoubleDeck.h" -#include "GameObject.h" #include "World.h" -#include "engine/vehicles/OBombKart.h" +#include "engine/objects/OBombKart.h" #include "assets/double_deck_data.h" extern "C" { @@ -33,11 +32,17 @@ extern "C" { extern s16 currentScreenSection; } +const course_texture double_deck_textures[] = { + { gTextureGrayCobblestone, 0x010C, 0x0800, 0x0 }, + { gTexture642978, 0x010D, 0x0800, 0x0 }, + { 0x00000000, 0x0000, 0x0000, 0x0 }, +}; + DoubleDeck::DoubleDeck() { this->vtx = d_course_double_deck_vertex; this->gfx = d_course_double_deck_packed_dls; this->gfxSize = 699; - this->textures = double_deck_textures; + Props.textures = double_deck_textures; Props.MinimapTexture = gTextureCourseOutlineDoubleDeck; Props.D_800E5548[0] = 64; Props.D_800E5548[1] = 64; diff --git a/src/engine/courses/FrappeSnowland.cpp b/src/engine/courses/FrappeSnowland.cpp index a0e698152..23fa73460 100644 --- a/src/engine/courses/FrappeSnowland.cpp +++ b/src/engine/courses/FrappeSnowland.cpp @@ -4,10 +4,9 @@ #include #include "FrappeSnowland.h" -#include "GameObject.h" #include "World.h" #include "engine/actors/AFinishline.h" -#include "engine/vehicles/OBombKart.h" +#include "engine/objects/OBombKart.h" #include "assets/frappe_snowland_data.h" #include "assets/boo_frames.h" @@ -32,15 +31,24 @@ extern "C" { #include "collision.h" #include "memory.h" #include "update_objects.h" + #include "course_offsets.h" extern const char *d_course_frappe_snowland_dl_list[]; extern s8 gPlayerCount; } +const course_texture frappe_snowland_textures[] = { + { gTexture6684F8, 0x010D, 0x0800, 0x0 }, { gTexture66CA98, 0x02C9, 0x0800, 0x0 }, + { gTexture66EBF0, 0x0146, 0x0800, 0x0 }, { gTexture675434, 0x0245, 0x0800, 0x0 }, + { gTexture677F04, 0x0213, 0x0800, 0x0 }, { gTexture678118, 0x0314, 0x0800, 0x0 }, + { gTexture679258, 0x04E3, 0x1000, 0x0 }, { gTexture67973C, 0x04C6, 0x1000, 0x0 }, + { 0x00000000, 0x0000, 0x0000, 0x0 }, +}; + FrappeSnowland::FrappeSnowland() { this->vtx = d_course_frappe_snowland_vertex; this->gfx = d_course_frappe_snowland_packed_dls; this->gfxSize = 4140; - this->textures = frappe_snowland_textures; + Props.textures = frappe_snowland_textures; Props.MinimapTexture = gTextureCourseOutlineFrappeSnowland; Props.D_800E5548[0] = 64; Props.D_800E5548[1] = 64; diff --git a/src/engine/courses/KalimariDesert.cpp b/src/engine/courses/KalimariDesert.cpp index 2562ab8f8..405abbce4 100644 --- a/src/engine/courses/KalimariDesert.cpp +++ b/src/engine/courses/KalimariDesert.cpp @@ -4,10 +4,9 @@ #include #include "KalimariDesert.h" -#include "GameObject.h" #include "World.h" #include "engine/actors/AFinishline.h" -#include "engine/vehicles/OBombKart.h" +#include "engine/objects/OBombKart.h" #include "kalimari_desert_data.h" #include "engine/vehicles/Utils.h" @@ -36,11 +35,27 @@ extern "C" { extern const char *kalimari_desert_dls[]; } +const course_texture kalimari_desert_textures[] = { + { gTexture6684F8, 0x010D, 0x0800, 0x0 }, { gTextureSignLuigis0, 0x0287, 0x1000, 0x0 }, + { gTextureSignLuigis1, 0x02AF, 0x1000, 0x0 }, { gTextureSignMarioStar0, 0x02D2, 0x1000, 0x0 }, + { gTextureSignMarioStar1, 0x02B1, 0x1000, 0x0 }, { gTextureSignNintendoRed0, 0x02A6, 0x1000, 0x0 }, + { gTextureSignNintendoRed1, 0x02F7, 0x1000, 0x0 }, { gTexture67490C, 0x021C, 0x0800, 0x0 }, + { gTextureSignYoshi, 0x04DF, 0x1000, 0x0 }, { gTextureCheckerboardBlueGray, 0x04A1, 0x1000, 0x0 }, + { gTexture646CA8, 0x073A, 0x1000, 0x0 }, { gTexture6473E4, 0x05AD, 0x1000, 0x0 }, + { gTexture647994, 0x05B5, 0x1000, 0x0 }, { gTexture668920, 0x03D9, 0x0800, 0x0 }, + { gTextureRailroadTrack, 0x0B5B, 0x1000, 0x0 }, { gTextureRailroadCrossingTrack, 0x0208, 0x1000, 0x0 }, + { gTexture67291C, 0x059C, 0x0800, 0x0 }, { gTextureFenceBarbedWire, 0x021E, 0x1000, 0x0 }, + { gTexture67D304, 0x091C, 0x1000, 0x0 }, { gTexture67E010, 0x0415, 0x0800, 0x0 }, + { gTexture67EEAC, 0x0140, 0x0800, 0x0 }, { gTextureSignShellShot0, 0x038C, 0x1000, 0x0 }, + { gTextureSignShellShot1, 0x0247, 0x1000, 0x0 }, { gTextureSignKoopaAir0, 0x0360, 0x1000, 0x0 }, + { gTextureSignKoopaAir1, 0x0304, 0x1000, 0x0 }, { 0x00000000, 0x0000, 0x0000, 0x0 }, +}; + KalimariDesert::KalimariDesert() { this->vtx = d_course_kalimari_desert_vertex; this->gfx = d_course_kalimari_desert_packed_dls; this->gfxSize = 5328; - this->textures = kalimari_desert_textures; + Props.textures = kalimari_desert_textures; Props.MinimapTexture = gTextureCourseOutlineKalimariDesert; Props.D_800E5548[0] = 64; Props.D_800E5548[1] = 96; diff --git a/src/engine/courses/KoopaTroopaBeach.cpp b/src/engine/courses/KoopaTroopaBeach.cpp index 48f8c8b77..7fe30085b 100644 --- a/src/engine/courses/KoopaTroopaBeach.cpp +++ b/src/engine/courses/KoopaTroopaBeach.cpp @@ -4,10 +4,9 @@ #include #include "KoopaTroopaBeach.h" -#include "GameObject.h" #include "World.h" #include "engine/actors/AFinishline.h" -#include "engine/vehicles/OBombKart.h" +#include "engine/objects/OBombKart.h" #include "assets/koopa_troopa_beach_data.h" extern "C" { @@ -35,11 +34,31 @@ extern "C" { extern s8 gPlayerCount; } +const course_texture koopa_troopa_beach_textures[] = { + { gTexture643B3C, 0x0798, 0x0800, 0x0 }, + { gTexture66A3DC, 0x07C5, 0x0800, 0x0 }, + { gTextureSignWoodRedArrow, 0x04E1, 0x1000, 0x0 }, + { gTexture66DD38, 0x0330, 0x1000, 0x0 }, + { gTexture643430, 0x0604, 0x0800, 0x0 }, + { gTexture660D8C, 0x0126, 0x0800, 0x0 }, + { gTexture6609D0, 0x03BB, 0x1000, 0x0 }, + { gTextureGrass12, 0x0874, 0x0800, 0x0 }, + { gTexture66CA98, 0x02C9, 0x0800, 0x0 }, + { gTexture66EBF0, 0x0146, 0x0800, 0x0 }, + { gTexture67BEE8, 0x02D0, 0x0800, 0x0 }, + { gTextureSandFinish, 0x022E, 0x0800, 0x0 }, + { gTextureWheelSteamEngine, 0x020F, 0x0800, 0x0 }, + { gTexture669570, 0x0E6B, 0x1000, 0x0 }, + { gTextureWaves1, 0x05C4, 0x0800, 0x0 }, + { gTextureWaves2, 0x0488, 0x0800, 0x0 }, + { 0x00000000, 0x0000, 0x0000, 0x0 }, +}; + KoopaTroopaBeach::KoopaTroopaBeach() { this->vtx = d_course_koopa_troopa_beach_vertex; this->gfx = d_course_koopa_troopa_beach_packed_dls; this->gfxSize = 5720; - this->textures = koopa_troopa_beach_textures; + Props.textures = koopa_troopa_beach_textures; Props.MinimapTexture = gTextureCourseOutlineKoopaTroopaBeach; Props.D_800E5548[0] = 64; Props.D_800E5548[1] = 64; diff --git a/src/engine/courses/LuigiRaceway.cpp b/src/engine/courses/LuigiRaceway.cpp index f98ceab21..65506cd99 100644 --- a/src/engine/courses/LuigiRaceway.cpp +++ b/src/engine/courses/LuigiRaceway.cpp @@ -4,9 +4,8 @@ #include #include "LuigiRaceway.h" -#include "GameObject.h" #include "World.h" -#include "engine/vehicles/OBombKart.h" +#include "engine/objects/OBombKart.h" #include "assets/luigi_raceway_data.h" #include "engine/actors/AFinishline.h" @@ -38,11 +37,55 @@ extern "C" { extern s16 currentScreenSection; } +const course_texture luigi_raceway_textures[] = { + { gTextureSignShellShot0, 0x038C, 0x1000, 0x0 }, + { gTextureSignShellShot1, 0x0247, 0x1000, 0x0 }, + { gTextureCheckerboardYellowBlue, 0x013A, 0x0800, 0x0 }, + { gTexture64619C, 0x0124, 0x0800, 0x0 }, + { gTextureCheckerboardBlueGreen, 0x0139, 0x0800, 0x0 }, + { gTextureGrass3, 0x0372, 0x0800, 0x0 }, + { gTextureFlagRed, 0x019E, 0x0800, 0x0 }, + { gTexture65100C, 0x0120, 0x0800, 0x0 }, + { gTexture65112C, 0x0150, 0x0800, 0x0 }, + { gTexture653608, 0x07A7, 0x0800, 0x0 }, + { gTextureGrass11, 0x01F8, 0x0800, 0x0 }, + { gTextureSignLuigiFace0, 0x05C9, 0x1000, 0x0 }, + { gTextureSignLuigiFace1, 0x065F, 0x1000, 0x0 }, + { gTexture66C7A8, 0x0149, 0x0800, 0x0 }, + { gTexture670AC8, 0x0FBF, 0x1000, 0x0 }, + { gTexture671A88, 0x012D, 0x0800, 0x0 }, + { gTexture6735DC, 0x03B1, 0x0800, 0x0 }, + { gTexture673C68, 0x038D, 0x0800, 0x0 }, + { gTexture6747C4, 0x0145, 0x0800, 0x0 }, + { gTextureRoad1, 0x02D2, 0x1000, 0x0 }, + { gTextureRoad2, 0x02AE, 0x1000, 0x0 }, + { gTextureRoadFinish1, 0x026B, 0x1000, 0x0 }, + { gTexture67BBD8, 0x0310, 0x0800, 0x0 }, + { gTexture68272C, 0x01F9, 0x1000, 0x0 }, + { gTexture682928, 0x01F9, 0x1000, 0x0 }, + { gTexture682B24, 0x01F9, 0x1000, 0x0 }, + { gTexture682D20, 0x01F9, 0x1000, 0x0 }, + { gTexture682F1C, 0x01F9, 0x1000, 0x0 }, + { gTexture683118, 0x01F9, 0x1000, 0x0 }, + { gTextureSignBlue64, 0x0567, 0x1000, 0x0 }, + { gTextureSignKoopaAir0, 0x0360, 0x1000, 0x0 }, + { gTextureSignKoopaAir1, 0x0304, 0x1000, 0x0 }, + { gTextureSignLuigis0, 0x0287, 0x1000, 0x0 }, + { gTextureSignLuigis1, 0x02AF, 0x1000, 0x0 }, + { gTextureSignMarioStar0, 0x02D2, 0x1000, 0x0 }, + { gTextureSignMarioStar1, 0x02B1, 0x1000, 0x0 }, + { gTextureSignNintendoRed0, 0x02A6, 0x1000, 0x0 }, + { gTextureSignNintendoRed1, 0x02F7, 0x1000, 0x0 }, + { gTextureSignYoshi, 0x04DF, 0x1000, 0x0 }, + { gTextureCheckerboardBlueGray, 0x04A1, 0x1000, 0x0 }, + { 0x00000000, 0x0000, 0x0000, 0x0 }, +}; + LuigiRaceway::LuigiRaceway() { this->vtx = d_course_luigi_raceway_vertex; this->gfx = d_course_luigi_raceway_packed_dls; this->gfxSize = 6377; - this->textures = luigi_raceway_textures; + Props.textures = luigi_raceway_textures; Props.MinimapTexture = gTextureCourseOutlineLuigiRaceway; Props.D_800E5548[0] = 64; Props.D_800E5548[1] = 96; diff --git a/src/engine/courses/MarioRaceway.cpp b/src/engine/courses/MarioRaceway.cpp index bde10370d..f16caeeaf 100644 --- a/src/engine/courses/MarioRaceway.cpp +++ b/src/engine/courses/MarioRaceway.cpp @@ -4,10 +4,9 @@ #include #include "MarioRaceway.h" -#include "GameObject.h" #include "World.h" #include "engine/actors/AFinishline.h" -#include "engine/vehicles/OBombKart.h" +#include "engine/objects/OBombKart.h" extern "C" { #include "main.h" @@ -34,11 +33,45 @@ extern "C" { extern const char *mario_raceway_dls[]; } +const course_texture mario_raceway_textures[] = { + { gTextureCheckerboardYellowPink, 0x0149, 0x0800, 0x0 }, + { gTexture64619C, 0x0124, 0x0800, 0x0 }, + { gTextureGrass1, 0x0125, 0x0800, 0x0 }, + { gTexture64BB60, 0x0169, 0x0800, 0x0 }, + { gTextureGrass7, 0x05DE, 0x0800, 0x0 }, + { gTextureGrass5, 0x023F, 0x0800, 0x0 }, + { gTextureFlagRed, 0x019E, 0x0800, 0x0 }, + { gTexture663F90, 0x0122, 0x0800, 0x0 }, + { gTexture6642A4, 0x0162, 0x0800, 0x0 }, + { gTexture6640B4, 0x01EF, 0x0800, 0x0 }, + { gTextureGrass10, 0x01F8, 0x0800, 0x0 }, + { gTexture6684F8, 0x010D, 0x0800, 0x0 }, + { gTextureSignLuigis0, 0x0287, 0x1000, 0x0 }, + { gTextureSignLuigis1, 0x02AF, 0x1000, 0x0 }, + { gTextureSignMarioStar0, 0x02D2, 0x1000, 0x0 }, + { gTextureSignMarioStar1, 0x02B1, 0x1000, 0x0 }, + { gTexture66C8F4, 0x01A1, 0x0800, 0x0 }, + { gTextureSignNintendoRed0, 0x02A6, 0x1000, 0x0 }, + { gTextureSignNintendoRed1, 0x02F7, 0x1000, 0x0 }, + { gTexture670AC8, 0x0FBF, 0x1000, 0x0 }, + { gTexture674354, 0x046F, 0x0800, 0x0 }, + { gTextureRoad0, 0x0300, 0x1000, 0x0 }, + { gTextureRoadFinish0, 0x0338, 0x1000, 0x0 }, + { gTexture67B9B0, 0x0225, 0x0800, 0x0 }, + { gTextureSignYoshi, 0x04DF, 0x1000, 0x0 }, + { gTextureCheckerboardBlueGray, 0x04A1, 0x1000, 0x0 }, + { gTextureSignShellShot0, 0x038C, 0x1000, 0x0 }, + { gTextureSignShellShot1, 0x0247, 0x1000, 0x0 }, + { gTextureSignKoopaAir0, 0x0360, 0x1000, 0x0 }, + { gTextureSignKoopaAir1, 0x0304, 0x1000, 0x0 }, + { 0x00000000, 0x0000, 0x0000, 0x0 }, +}; + MarioRaceway::MarioRaceway() { this->vtx = d_course_mario_raceway_vertex; this->gfx = d_course_mario_raceway_packed_dls; this->gfxSize = 3367; - this->textures = mario_raceway_textures; + Props.textures = mario_raceway_textures; Props.MinimapTexture = gTextureCourseOutlineMarioRaceway; Props.D_800E5548[0] = 64; Props.D_800E5548[1] = 64; diff --git a/src/engine/courses/MooMooFarm.cpp b/src/engine/courses/MooMooFarm.cpp index d1b401342..1c7854c6c 100644 --- a/src/engine/courses/MooMooFarm.cpp +++ b/src/engine/courses/MooMooFarm.cpp @@ -4,10 +4,9 @@ #include #include "MooMooFarm.h" -#include "GameObject.h" #include "World.h" #include "engine/actors/AFinishline.h" -#include "engine/vehicles/OBombKart.h" +#include "engine/objects/OBombKart.h" #include "assets/moo_moo_farm_data.h" extern "C" { @@ -36,11 +35,43 @@ extern "C" { extern s8 gPlayerCount; } +const course_texture moo_moo_farm_textures[] = { + { gTextureWoodDoor0, 0x0294, 0x1000, 0x0 }, + { gTextureGrass2, 0x0415, 0x0800, 0x0 }, + { gTexture64AF50, 0x0140, 0x0800, 0x0 }, + { gTexture64B090, 0x0365, 0x0800, 0x0 }, + { gTexture64B54C, 0x038C, 0x0800, 0x0 }, + { gTexture64B3F8, 0x0153, 0x0800, 0x0 }, + { gTextureSignNintendo0, 0x0541, 0x1000, 0x0 }, + { gTextureSignNintendo1, 0x0512, 0x1000, 0x0 }, + { gTexture6684F8, 0x010D, 0x0800, 0x0 }, + { gTextureSignLuigis0, 0x0287, 0x1000, 0x0 }, + { gTextureSignLuigis1, 0x02AF, 0x1000, 0x0 }, + { gTextureSignMarioStar0, 0x02D2, 0x1000, 0x0 }, + { gTextureSignMarioStar1, 0x02B1, 0x1000, 0x0 }, + { gTexture674D58, 0x030C, 0x1000, 0x0 }, + { gTexture675064, 0x01BB, 0x0800, 0x0 }, + { gTexture675220, 0x0212, 0x0800, 0x0 }, + { gTexture6775EC, 0x0233, 0x1000, 0x0 }, + { gTexture683314, 0x02DC, 0x1000, 0x0 }, + { gTexture68CDA0, 0x0110, 0x0800, 0x0 }, + { gTexture6442D4, 0x0138, 0x0800, 0x0 }, + { gTexture64440C, 0x029D, 0x1000, 0x0 }, + { gTexture6446AC, 0x0116, 0x0800, 0x0 }, + { gTextureMooMooFarmSignLeft, 0x0A66, 0x1000, 0x0 }, + { gTextureMooMooFarmSignRight, 0x0A64, 0x1000, 0x0 }, + { gTexture64ACAC, 0x02A3, 0x0800, 0x0 }, + { gTexture66D698, 0x0370, 0x0800, 0x0 }, + { gTexture66EBF0, 0x0146, 0x0800, 0x0 }, + { gTextureWheelSteamEngineReal, 0x022F, 0x1000, 0x0 }, + { 0x00000000, 0x0000, 0x0000, 0x0 }, +}; + MooMooFarm::MooMooFarm() { this->vtx = d_course_moo_moo_farm_vertex; this->gfx = d_course_moo_moo_farm_packed_dls; this->gfxSize = 3304; - this->textures = moo_moo_farm_textures; + Props.textures = moo_moo_farm_textures; Props.MinimapTexture = gTextureCourseOutlineMooMooFarm; Props.D_800E5548[0] = 64; Props.D_800E5548[1] = 64; diff --git a/src/engine/courses/PodiumCeremony.cpp b/src/engine/courses/PodiumCeremony.cpp index 86bf403b3..e2e5a1262 100644 --- a/src/engine/courses/PodiumCeremony.cpp +++ b/src/engine/courses/PodiumCeremony.cpp @@ -4,9 +4,8 @@ #include #include "PodiumCeremony.h" -#include "GameObject.h" #include "World.h" -#include "engine/vehicles/OBombKart.h" +#include "engine/objects/OBombKart.h" #include "assets/royal_raceway_data.h" #include "assets/ceremony_data.h" @@ -34,11 +33,58 @@ extern "C" { extern const char *royal_raceway_dls[]; } +const course_texture podium_ceremony_textures[] = { + { gTexture64619C, 0x0124, 0x0800, 0x0 }, + { gTexture645134, 0x052C, 0x0800, 0x0 }, + { gTextureWoodDoor1, 0x0903, 0x1000, 0x0 }, + { gTexture64BB60, 0x0169, 0x0800, 0x0 }, + { gTextureGrass3, 0x0372, 0x0800, 0x0 }, + { gTexture64F9E8, 0x020B, 0x1000, 0x0 }, + { gTextureFlagRed, 0x019E, 0x0800, 0x0 }, + { gTextureCrownJewelBlue, 0x0301, 0x0800, 0x0 }, + { gTextureCrown, 0x0106, 0x0800, 0x0 }, + { gTextureCrownJewelPink, 0x0313, 0x0800, 0x0 }, + { gTextureSignKoopaAir0, 0x0360, 0x1000, 0x0 }, + { gTextureSignKoopaAir1, 0x0304, 0x1000, 0x0 }, + { gTexture6684F8, 0x010D, 0x0800, 0x0 }, + { gTextureSignLuigis0, 0x0287, 0x1000, 0x0 }, + { gTextureSignLuigis1, 0x02AF, 0x1000, 0x0 }, + { gTextureSignMarioStar0, 0x02D2, 0x1000, 0x0 }, + { gTextureSignMarioStar1, 0x02B1, 0x1000, 0x0 }, + { gTexture66CA98, 0x02C9, 0x0800, 0x0 }, + { gTextureCheckerboardPink, 0x0157, 0x0800, 0x0 }, + { gTexture670AC8, 0x0FBF, 0x1000, 0x0 }, + { gTextureRoad0, 0x0300, 0x1000, 0x0 }, + { gTextureRoadFinish0, 0x0338, 0x1000, 0x0 }, + { gTextureSignYoshi, 0x04DF, 0x1000, 0x0 }, + { gTextureCheckerboardBlueGray, 0x04A1, 0x1000, 0x0 }, + { gTextureCastleBricks, 0x0B33, 0x1000, 0x0 }, + { gTextureCastleBridge, 0x0428, 0x0800, 0x0 }, + { gTextureGrass8, 0x02CB, 0x0800, 0x0 }, + { gTextureGrass9, 0x0421, 0x0800, 0x0 }, + { gTexture6646B8, 0x0298, 0x1000, 0x0 }, + { gTexture664408, 0x02AE, 0x1000, 0x0 }, + { gTextureBricksRed, 0x0C55, 0x1000, 0x0 }, + { gTexture665C0C, 0x059D, 0x0800, 0x0 }, + { gTexture6661AC, 0x01F7, 0x0800, 0x0 }, + { gTexture6663A4, 0x05F6, 0x0800, 0x0 }, + { gTexture667BAC, 0x067A, 0x0800, 0x0 }, + { gTextureFlagRed2, 0x0186, 0x0800, 0x0 }, + { gTexture66DB60, 0x01D6, 0x0800, 0x0 }, + { gTextureStainglassPeach0, 0x0ED1, 0x1000, 0x0 }, + { gTextureStainglassPeach1, 0x0DA9, 0x1000, 0x0 }, + { gTextureFencePostWooden, 0x083D, 0x1000, 0x0 }, + { gTexture648508, 0x01FE, 0x1000, 0x0 }, + { gTexture6449D4, 0x075D, 0x0800, 0x0 }, + { gTexture67FE0C, 0x02DE, 0x0800, 0x0 }, + { 0x00000000, 0x0000, 0x0000, 0x0 }, +}; + PodiumCeremony::PodiumCeremony() { this->vtx = d_course_royal_raceway_vertex; this->gfx = d_course_royal_raceway_packed_dls; this->gfxSize = 5670; - this->textures = royal_raceway_textures; + Props.textures = podium_ceremony_textures; Props.D_800E5548[0] = 0; Props.D_800E5548[1] = 0; diff --git a/src/engine/courses/RainbowRoad.cpp b/src/engine/courses/RainbowRoad.cpp index b8e9865c6..e13b3229b 100644 --- a/src/engine/courses/RainbowRoad.cpp +++ b/src/engine/courses/RainbowRoad.cpp @@ -4,10 +4,9 @@ #include #include "RainbowRoad.h" -#include "GameObject.h" #include "World.h" #include "engine/actors/AFinishline.h" -#include "engine/vehicles/OBombKart.h" +#include "engine/objects/OBombKart.h" #include "assets/rainbow_road_data.h" extern "C" { @@ -33,11 +32,21 @@ extern "C" { extern const char *rainbow_road_dls[]; } +const course_texture rainbow_road_textures[] = { + { gTextureStarOutline, 0x037A, 0x0800, 0x0 }, + { gTexture67A1B8, 0x01B7, 0x0800, 0x0 }, + { gTextureCheckerboardBlackWhite, 0x0107, 0x0800, 0x0 }, + { gTexture662A34, 0x0106, 0x0800, 0x0 }, + { gTextureRainbow, 0x025D, 0x1000, 0x0 }, + { 0x00000000, 0x0000, 0x0000, 0x0 }, +}; + + RainbowRoad::RainbowRoad() { this->vtx = d_course_rainbow_road_vertex; this->gfx = d_course_rainbow_road_packed_dls; this->gfxSize = 5670; - this->textures = rainbow_road_textures; + Props.textures = rainbow_road_textures; Props.MinimapTexture = gTextureCourseOutlineRainbowRoad; Props.D_800E5548[0] = 64; Props.D_800E5548[1] = 96; diff --git a/src/engine/courses/RoyalRaceway.cpp b/src/engine/courses/RoyalRaceway.cpp index c2f6b3c62..8fe5eec32 100644 --- a/src/engine/courses/RoyalRaceway.cpp +++ b/src/engine/courses/RoyalRaceway.cpp @@ -4,10 +4,9 @@ #include #include "RoyalRaceway.h" -#include "GameObject.h" #include "World.h" #include "engine/actors/AFinishline.h" -#include "engine/vehicles/OBombKart.h" +#include "engine/objects/OBombKart.h" #include "assets/royal_raceway_data.h" extern "C" { @@ -34,11 +33,58 @@ extern "C" { extern const char *royal_raceway_dls[]; } +const course_texture royal_raceway_textures[] = { + { gTexture64619C, 0x0124, 0x0800, 0x0 }, + { gTexture645134, 0x052C, 0x0800, 0x0 }, + { gTextureWoodDoor1, 0x0903, 0x1000, 0x0 }, + { gTexture64BB60, 0x0169, 0x0800, 0x0 }, + { gTextureGrass3, 0x0372, 0x0800, 0x0 }, + { gTexture64F9E8, 0x020B, 0x1000, 0x0 }, + { gTextureFlagRed, 0x019E, 0x0800, 0x0 }, + { gTextureCrownJewelBlue, 0x0301, 0x0800, 0x0 }, + { gTextureCrown, 0x0106, 0x0800, 0x0 }, + { gTextureCrownJewelPink, 0x0313, 0x0800, 0x0 }, + { gTextureSignKoopaAir0, 0x0360, 0x1000, 0x0 }, + { gTextureSignKoopaAir1, 0x0304, 0x1000, 0x0 }, + { gTexture6684F8, 0x010D, 0x0800, 0x0 }, + { gTextureSignLuigis0, 0x0287, 0x1000, 0x0 }, + { gTextureSignLuigis1, 0x02AF, 0x1000, 0x0 }, + { gTextureSignMarioStar0, 0x02D2, 0x1000, 0x0 }, + { gTextureSignMarioStar1, 0x02B1, 0x1000, 0x0 }, + { gTexture66CA98, 0x02C9, 0x0800, 0x0 }, + { gTextureCheckerboardPink, 0x0157, 0x0800, 0x0 }, + { gTexture670AC8, 0x0FBF, 0x1000, 0x0 }, + { gTextureRoad0, 0x0300, 0x1000, 0x0 }, + { gTextureRoadFinish0, 0x0338, 0x1000, 0x0 }, + { gTextureSignYoshi, 0x04DF, 0x1000, 0x0 }, + { gTextureCheckerboardBlueGray, 0x04A1, 0x1000, 0x0 }, + { gTextureCastleBricks, 0x0B33, 0x1000, 0x0 }, + { gTextureCastleBridge, 0x0428, 0x0800, 0x0 }, + { gTextureGrass8, 0x02CB, 0x0800, 0x0 }, + { gTextureGrass9, 0x0421, 0x0800, 0x0 }, + { gTexture6646B8, 0x0298, 0x1000, 0x0 }, + { gTexture664408, 0x02AE, 0x1000, 0x0 }, + { gTextureBricksRed, 0x0C55, 0x1000, 0x0 }, + { gTexture665C0C, 0x059D, 0x0800, 0x0 }, + { gTexture6661AC, 0x01F7, 0x0800, 0x0 }, + { gTexture6663A4, 0x05F6, 0x0800, 0x0 }, + { gTexture667BAC, 0x067A, 0x0800, 0x0 }, + { gTextureFlagRed2, 0x0186, 0x0800, 0x0 }, + { gTexture66DB60, 0x01D6, 0x0800, 0x0 }, + { gTextureStainglassPeach0, 0x0ED1, 0x1000, 0x0 }, + { gTextureStainglassPeach1, 0x0DA9, 0x1000, 0x0 }, + { gTextureFencePostWooden, 0x083D, 0x1000, 0x0 }, + { gTexture648508, 0x01FE, 0x1000, 0x0 }, + { gTexture6449D4, 0x075D, 0x0800, 0x0 }, + { gTexture67FE0C, 0x02DE, 0x0800, 0x0 }, + { 0x00000000, 0x0000, 0x0000, 0x0 }, +}; + RoyalRaceway::RoyalRaceway() { this->vtx = d_course_royal_raceway_vertex; this->gfx = d_course_royal_raceway_packed_dls; this->gfxSize = 5670; - this->textures = royal_raceway_textures; + Props.textures = royal_raceway_textures; Props.MinimapTexture = gTextureCourseOutlineRoyalRaceway; Props.D_800E5548[0] = 64; Props.D_800E5548[1] = 64; diff --git a/src/engine/courses/SherbetLand.cpp b/src/engine/courses/SherbetLand.cpp index be3cc7043..df2be3f2d 100644 --- a/src/engine/courses/SherbetLand.cpp +++ b/src/engine/courses/SherbetLand.cpp @@ -4,11 +4,11 @@ #include #include "SherbetLand.h" -#include "GameObject.h" #include "World.h" #include "engine/actors/AFinishline.h" -#include "engine/vehicles/OBombKart.h" +#include "engine/objects/OBombKart.h" #include "assets/sherbet_land_data.h" +#include "engine/objects/OPenguin.h" extern "C" { #include "main.h" @@ -34,11 +34,20 @@ extern "C" { extern const char *sherbet_land_dls_2[]; } +const course_texture sherbet_land_textures[] = { + { gTexture643B3C, 0x0798, 0x0800, 0x0 }, { gTexture66D024, 0x04EA, 0x0800, 0x0 }, + { gTexture678118, 0x0314, 0x0800, 0x0 }, { gTextureSignWoodRedArrow, 0x04E1, 0x1000, 0x0 }, + { gTexture678CC8, 0x058E, 0x0800, 0x0 }, { gTexture67842C, 0x050E, 0x0800, 0x0 }, + { gTexture67893C, 0x038B, 0x0800, 0x0 }, { gTexture651984, 0x019C, 0x0800, 0x0 }, + { gTexture651428, 0x055B, 0x0800, 0x0 }, { gTexture662924, 0x0110, 0x0800, 0x0 }, + { 0x00000000, 0x0000, 0x0000, 0x0 }, +}; + SherbetLand::SherbetLand() { this->vtx = d_course_sherbet_land_vertex; this->gfx = d_course_sherbet_land_packed_dls; this->gfxSize = 1803; - this->textures = sherbet_land_textures; + Props.textures = sherbet_land_textures; Props.MinimapTexture = gTextureCourseOutlineSherbetLand; Props.D_800E5548[0] = 64; Props.D_800E5548[1] = 64; diff --git a/src/engine/courses/Skyscraper.cpp b/src/engine/courses/Skyscraper.cpp index 7af4fd53f..b95c15899 100644 --- a/src/engine/courses/Skyscraper.cpp +++ b/src/engine/courses/Skyscraper.cpp @@ -4,9 +4,8 @@ #include #include "Skyscraper.h" -#include "GameObject.h" #include "World.h" -#include "engine/vehicles/OBombKart.h" +#include "engine/objects/OBombKart.h" #include "assets/skyscraper_data.h" extern "C" { @@ -33,11 +32,38 @@ extern "C" { extern s16 currentScreenSection; } +const course_texture skyscraper_textures[] = { + { gTexture6457D8, 0x0160, 0x0800, 0x0 }, + { gTexture6462C0, 0x01B9, 0x0800, 0x0 }, + { gTexture6864E8, 0x0807, 0x1000, 0x0 }, + { gTexture686CF0, 0x08B7, 0x1000, 0x0 }, + { gTexture6875A8, 0x093F, 0x1000, 0x0 }, + { gTexture687EE8, 0x0883, 0x1000, 0x0 }, + { gTexture68876C, 0x0AC2, 0x1000, 0x0 }, + { gTexture689230, 0x09CE, 0x1000, 0x0 }, + { gTexture689C00, 0x0884, 0x1000, 0x0 }, + { gTexture68A484, 0x07D6, 0x1000, 0x0 }, + { gTexture68AC5C, 0x0A47, 0x1000, 0x0 }, + { gTexture68B6A4, 0x07C5, 0x1000, 0x0 }, + { gTexture68BE6C, 0x04A1, 0x1000, 0x0 }, + { gTexture68C310, 0x030D, 0x1000, 0x0 }, + { gTexture64B8D8, 0x0177, 0x0800, 0x0 }, + { gTexture645660, 0x0176, 0x0800, 0x0 }, + { gTextureNumberYellowBlue1, 0x01AE, 0x0800, 0x0 }, + { gTextureNumberYellowBlue2, 0x01C6, 0x0800, 0x0 }, + { gTextureNumberYellowBlue3, 0x01CC, 0x0800, 0x0 }, + { gTextureNumberYellowBlue4, 0x01E4, 0x0800, 0x0 }, + { gTexture668608, 0x0120, 0x0800, 0x0 }, + { gTexture67B75C, 0x0108, 0x0800, 0x0 }, + { gTexture6835F0, 0x0252, 0x1000, 0x0 }, + { 0x00000000, 0x0000, 0x0000, 0x0 }, +}; + Skyscraper::Skyscraper() { this->vtx = d_course_skyscraper_vertex; this->gfx = d_course_skyscraper_packed_dls; this->gfxSize = 548; - this->textures = skyscraper_textures; + Props.textures = skyscraper_textures; Props.MinimapTexture = gTextureCourseOutlineSkyscraper; Props.D_800E5548[0] = 64; Props.D_800E5548[1] = 64; diff --git a/src/engine/courses/TestCourse.cpp b/src/engine/courses/TestCourse.cpp index 742dc6735..6b9907a12 100644 --- a/src/engine/courses/TestCourse.cpp +++ b/src/engine/courses/TestCourse.cpp @@ -4,10 +4,9 @@ #include #include "TestCourse.h" -#include "GameObject.h" #include "World.h" #include "engine/actors/AFinishline.h" -#include "engine/vehicles/OBombKart.h" +#include "engine/objects/OBombKart.h" #include "assets/mario_raceway_data.h" #include "assets/bowsers_castle_data.h" #include "assets/bowsers_castle_displaylists.h" diff --git a/src/engine/courses/ToadsTurnpike.cpp b/src/engine/courses/ToadsTurnpike.cpp index 7a19a54dc..cbac2d4e5 100644 --- a/src/engine/courses/ToadsTurnpike.cpp +++ b/src/engine/courses/ToadsTurnpike.cpp @@ -4,9 +4,8 @@ #include #include "ToadsTurnpike.h" -#include "GameObject.h" #include "World.h" -#include "engine/vehicles/OBombKart.h" +#include "engine/objects/OBombKart.h" #include "assets/toads_turnpike_data.h" #include "engine/actors/AFinishline.h" @@ -38,11 +37,34 @@ extern "C" { extern s8 gPlayerCount; } +const course_texture toads_turnpike_textures[] = { + { gTexture645134, 0x052C, 0x0800, 0x0 }, + { gTexture64FE68, 0x0258, 0x1000, 0x0 }, + { gTexture6607C0, 0x0105, 0x0800, 0x0 }, + { gTexture6608C8, 0x0106, 0x0800, 0x0 }, + { gTextureGrass11, 0x01F8, 0x0800, 0x0 }, + { gTextureSignNintendoRed0, 0x02A6, 0x1000, 0x0 }, + { gTextureSignNintendoRed1, 0x02F7, 0x1000, 0x0 }, + { gTexture671A88, 0x012D, 0x0800, 0x0 }, + { gTextureRoad2, 0x02AE, 0x1000, 0x0 }, + { gTextureRoad3, 0x0286, 0x1000, 0x0 }, + { gTextureRoad4, 0x0282, 0x1000, 0x0 }, + { gTextureRoadFinish0, 0x0338, 0x1000, 0x0 }, + { gTextureSignToadYellow, 0x0723, 0x1000, 0x0 }, + { gTextureSignToadGreen, 0x071F, 0x1000, 0x0 }, + { gTextureSignMergingLanes, 0x0118, 0x0800, 0x0 }, + { gTexture65127C, 0x01AB, 0x0800, 0x0 }, + { gTextureRoad5, 0x02B9, 0x1000, 0x0 }, + { gTextureSignToadRed, 0x0610, 0x1000, 0x0 }, + { gTexture668228, 0x0130, 0x0800, 0x0 }, + { 0x00000000, 0x0000, 0x0000, 0x0 }, +}; + ToadsTurnpike::ToadsTurnpike() { this->vtx = d_course_toads_turnpike_vertex; this->gfx = d_course_toads_turnpike_packed_dls; this->gfxSize = 3427; - this->textures = toads_turnpike_textures; + Props.textures = toads_turnpike_textures; Props.MinimapTexture = gTextureCourseOutlineToadsTurnpike; Props.D_800E5548[0] = 128; Props.D_800E5548[1] = 64; diff --git a/src/engine/courses/WarioStadium.cpp b/src/engine/courses/WarioStadium.cpp index 62c75143a..78bdf3079 100644 --- a/src/engine/courses/WarioStadium.cpp +++ b/src/engine/courses/WarioStadium.cpp @@ -4,9 +4,8 @@ #include #include "WarioStadium.h" -#include "GameObject.h" #include "World.h" -#include "engine/vehicles/OBombKart.h" +#include "engine/objects/OBombKart.h" #include "assets/wario_stadium_data.h" #include "engine/actors/AWarioSign.h" #include "engine/actors/AFinishline.h" @@ -37,11 +36,35 @@ extern "C" { extern s16 currentScreenSection; } +const course_texture wario_stadium_textures[] = { + { gTexture67F15C, 0x02F1, 0x0800, 0x0 }, + { gTexture67F450, 0x0194, 0x0800, 0x0 }, + { gTextureSignWarioFace, 0x0825, 0x1000, 0x0 }, + { gTexture670AC8, 0x0FBF, 0x1000, 0x0 }, + { gTextureCheckerboardBlackWhite, 0x0107, 0x0800, 0x0 }, + { gTexture64C11C, 0x0695, 0x0800, 0x0 }, + { gTexture64C7B4, 0x046C, 0x0800, 0x0 }, + { gTexture668228, 0x0130, 0x0800, 0x0 }, + { gTexture668358, 0x01A0, 0x0800, 0x0 }, + { gTexture66AEB8, 0x0201, 0x0800, 0x0 }, + { gTexture677A40, 0x0275, 0x0800, 0x0 }, + { gTexture67E428, 0x0A81, 0x1000, 0x0 }, + { gTexture643A34, 0x0106, 0x0800, 0x0 }, + { gTexture66EBF0, 0x0146, 0x0800, 0x0 }, + { gTexture68272C, 0x01F9, 0x1000, 0x0 }, + { gTexture682928, 0x01F9, 0x1000, 0x0 }, + { gTexture682B24, 0x01F9, 0x1000, 0x0 }, + { gTexture682D20, 0x01F9, 0x1000, 0x0 }, + { gTexture682F1C, 0x01F9, 0x1000, 0x0 }, + { gTexture683118, 0x01F9, 0x1000, 0x0 }, + { 0x00000000, 0x0000, 0x0000, 0x0 }, +}; + WarioStadium::WarioStadium() { this->vtx = d_course_wario_stadium_vertex; this->gfx = d_course_wario_stadium_packed_dls; this->gfxSize = 5272; - this->textures = wario_stadium_textures; + Props.textures = wario_stadium_textures; Props.MinimapTexture = gTextureCourseOutlineWarioStadium; Props.D_800E5548[0] = 64; Props.D_800E5548[1] = 64; diff --git a/src/engine/courses/YoshiValley.cpp b/src/engine/courses/YoshiValley.cpp index b372ec626..1d7bb0d6a 100644 --- a/src/engine/courses/YoshiValley.cpp +++ b/src/engine/courses/YoshiValley.cpp @@ -4,10 +4,9 @@ #include #include "YoshiValley.h" -#include "GameObject.h" #include "World.h" #include "engine/actors/AFinishline.h" -#include "engine/vehicles/OBombKart.h" +#include "engine/objects/OBombKart.h" #include "assets/yoshi_valley_data.h" #include "assets/boo_frames.h" @@ -34,11 +33,30 @@ extern "C" { extern const char *d_course_yoshi_valley_dl_list[]; } +const course_texture yoshi_valley_textures[] = { + { gTexture66EBF0, 0x0146, 0x0800, 0x0 }, + { gTextureWoodBridgeSlats, 0x0DAB, 0x1000, 0x0 }, + { gTexture65E2EC, 0x02B0, 0x0800, 0x0 }, + { gTexture6846DC, 0x04EA, 0x0800, 0x0 }, + { gTextureFenceRope, 0x0540, 0x0800, 0x0 }, + { gTexture685108, 0x04D4, 0x0800, 0x0 }, + { gTexture64CC20, 0x0EC3, 0x1000, 0x0 }, + { gTextureGrass4, 0x05C3, 0x0800, 0x0 }, + { gTexture6775EC, 0x0233, 0x1000, 0x0 }, + { gTexture68E2D0, 0x087F, 0x0800, 0x0 }, + { gTextureCheckerboardBlackWhite, 0x0107, 0x0800, 0x0 }, + { gTexture643B3C, 0x0798, 0x0800, 0x0 }, + { gTextureSignWoodRedArrow, 0x04E1, 0x1000, 0x0 }, + { gTexture68DEC0, 0x0410, 0x0800, 0x0 }, + { 0x00000000, 0x0000, 0x0000, 0x0 }, +}; + YoshiValley::YoshiValley() { this->vtx = d_course_yoshi_valley_vertex; this->gfx = d_course_yoshi_valley_packed_dls; this->gfxSize = 4140; - this->textures = yoshi_valley_textures; + Props.textures = yoshi_valley_textures; + Props.MinimapTexture = gTextureCourseOutlineYoshiValley; Props.D_800E5548[0] = 64; Props.D_800E5548[1] = 64; diff --git a/src/engine/vehicles/OBombKart.cpp b/src/engine/objects/OBombKart.cpp similarity index 99% rename from src/engine/vehicles/OBombKart.cpp rename to src/engine/objects/OBombKart.cpp index a73a89f84..e51340b8f 100644 --- a/src/engine/vehicles/OBombKart.cpp +++ b/src/engine/objects/OBombKart.cpp @@ -1,5 +1,5 @@ #include -#include "engine/vehicles/OBombKart.h" +#include "OBombKart.h" #include #include "port/Game.h" diff --git a/src/engine/vehicles/OBombKart.h b/src/engine/objects/OBombKart.h similarity index 97% rename from src/engine/vehicles/OBombKart.h rename to src/engine/objects/OBombKart.h index 8a331776c..4500e41c2 100644 --- a/src/engine/vehicles/OBombKart.h +++ b/src/engine/objects/OBombKart.h @@ -1,7 +1,7 @@ #pragma once #include -#include "Vehicle.h" +#include "src/engine/vehicles/Vehicle.h" #include #include "engine/Matrix.h" diff --git a/src/engine/vehicles/OPenguin.cpp b/src/engine/objects/OPenguin.cpp similarity index 99% rename from src/engine/vehicles/OPenguin.cpp rename to src/engine/objects/OPenguin.cpp index e8d97116a..f43a76ffc 100644 --- a/src/engine/vehicles/OPenguin.cpp +++ b/src/engine/objects/OPenguin.cpp @@ -1,6 +1,6 @@ #include #include -#include "engine/vehicles/OPenguin.h" +#include "OPenguin.h" #include #include "port/Game.h" diff --git a/src/engine/vehicles/OPenguin.h b/src/engine/objects/OPenguin.h similarity index 97% rename from src/engine/vehicles/OPenguin.h rename to src/engine/objects/OPenguin.h index 007baf551..111f629ba 100644 --- a/src/engine/vehicles/OPenguin.h +++ b/src/engine/objects/OPenguin.h @@ -2,7 +2,6 @@ #include #include -#include "engine/vehicles/OPenguin.h" extern "C" { #include "macros.h" @@ -11,6 +10,7 @@ extern "C" { #include "waypoints.h" #include "common_structs.h" #include "objects.h" +#include "course_offsets.h" } //! @todo Make shadow size bigger if thwomp is scaled up diff --git a/src/engine/vehicles/OThwomp.cpp b/src/engine/objects/OThwomp.cpp similarity index 99% rename from src/engine/vehicles/OThwomp.cpp rename to src/engine/objects/OThwomp.cpp index 5cca30623..e2700f015 100644 --- a/src/engine/vehicles/OThwomp.cpp +++ b/src/engine/objects/OThwomp.cpp @@ -1,6 +1,6 @@ #include #include -#include "engine/vehicles/OThwomp.h" +#include "OThwomp.h" #include #include "port/Game.h" diff --git a/src/engine/vehicles/OThwomp.h b/src/engine/objects/OThwomp.h similarity index 100% rename from src/engine/vehicles/OThwomp.h rename to src/engine/objects/OThwomp.h diff --git a/src/port/Game.cpp b/src/port/Game.cpp index 0b5e8a32f..f6918a2a4 100644 --- a/src/port/Game.cpp +++ b/src/port/Game.cpp @@ -31,7 +31,7 @@ #include "engine/courses/PodiumCeremony.h" #include "engine/TrainCrossing.h" -#include "engine/vehicles/OBombKart.h" +#include "src/engine/objects/OBombKart.h" #include "Smoke.h" diff --git a/src/racing/memory.c b/src/racing/memory.c index 2bf09b7f5..11e8d217c 100644 --- a/src/racing/memory.c +++ b/src/racing/memory.c @@ -821,6 +821,24 @@ void unpack_tile_sync(Gfx* gfx, u8* args, s8 opcode) { sGfxSeekPosition++; } +uintptr_t get_texture(size_t offset) { + course_texture *textures = CourseManager_GetProps()->textures; + size_t totalOffset = 0; + + while (textures->addr) { + if (totalOffset == offset) { + printf("FOUND TEXTURE: 0x%s\n", (textures->addr)); + return (textures->addr); + } + totalOffset += textures->data_size; + textures++; + } + + printf("memory.c: get_texture()\nTEXTURE NOT FOUND DURING DISPLAYLIST EXTRACT\n"); + printf("offset: 0x%X\n", offset); + return NULL; +} + void unpack_tile_load_sync(Gfx* gfx, u8* args, s8 opcode) { UNUSED uintptr_t var; Gfx tileSync[] = { gsDPTileSync() }; @@ -877,7 +895,7 @@ void unpack_tile_load_sync(Gfx* gfx, u8* args, s8 opcode) { var = args[sPackedSeekPosition]; // Generates a texture address. offset = args[sPackedSeekPosition++] << 11; - addr = SEGMENT_ADDR(0x05, offset); + sPackedSeekPosition++; arg = args[sPackedSeekPosition++]; siz = G_IM_SIZ_16b; @@ -885,10 +903,9 @@ void unpack_tile_load_sync(Gfx* gfx, u8* args, s8 opcode) { tile = (arg & 0xF0) >> 4; // Generate gfx - - lo = ((uintptr_t) (uint8_t) G_SETTIMG << 24) | (fmt << 21) | (siz << 19); + lo = ((uintptr_t) (uint8_t) G_SETTIMG_OTR_FILEPATH << 24) | (fmt << 21) | (siz << 19); gfx[sGfxSeekPosition].words.w0 = lo; - gfx[sGfxSeekPosition].words.w1 = segment5_to_virtual(offset); + gfx[sGfxSeekPosition].words.w1 = get_texture(offset); sGfxSeekPosition++; gfx[sGfxSeekPosition].words.w0 = tileSync->words.w0; @@ -1470,157 +1487,6 @@ Gfx* testaaa; * @brief Loads & DMAs course data. Vtx, textures, displaylists, etc. * @param courseId */ - -typedef struct { - char* data; - char* vtx; - size_t vtxSize; - course_texture* textures; - char* displaylists; - size_t dlSize; -} NewCourseTable; - -NewCourseTable gNewCourseTable[] = { { // mario_raceway - .data = d_course_mario_raceway_dl_0, - .vtx = d_course_mario_raceway_vertex, - .vtxSize = 5757, - .textures = mario_raceway_textures, - .displaylists = d_course_mario_raceway_packed_dls, - .dlSize = 3367 }, - { // choco_mountain - .data = d_course_choco_mountain_dl_0, - .vtx = d_course_choco_mountain_vertex, - .vtxSize = 5560, - .textures = choco_mountain_textures, - .displaylists = d_course_choco_mountain_packed_dls, - .dlSize = 2910 }, - { // bowser_castle - .data = d_course_bowsers_castle_dl_0, - .vtx = d_course_bowsers_castle_vertex, - .vtxSize = 9527, - .textures = bowsers_castle_textures, - .displaylists = d_course_bowsers_castle_packed_dls, - .dlSize = 4900 }, - { // banshee_boardwalk - .data = d_course_banshee_boardwalk_dl_0, - .vtx = d_course_banshee_boardwalk_vertex, - .vtxSize = 4945, - .textures = banshee_boardwalk_textures, - .displaylists = d_course_banshee_boardwalk_packed_dls, - .dlSize = 3689 }, - { // maze - .data = d_course_yoshi_valley_dl_0, - .vtx = d_course_yoshi_valley_vertex, - .vtxSize = 3720, - .textures = yoshi_valley_textures, - .displaylists = d_course_yoshi_valley_packed_dls, - .dlSize = 4140 }, - { // snow - .data = d_course_frappe_snowland_dl_0, - .vtx = d_course_frappe_snowland_vertex, - .vtxSize = 5529, - .textures = frappe_snowland_textures, - .displaylists = d_course_frappe_snowland_packed_dls, - .dlSize = 3274 }, - { // koopa_troopa_beach - .data = d_course_koopa_troopa_beach_dl_0, - .vtx = d_course_koopa_troopa_beach_vertex, - .vtxSize = 9376, - .textures = koopa_troopa_beach_textures, - .displaylists = d_course_koopa_troopa_beach_packed_dls, - .dlSize = 5720 }, - { // royal_raceway - .data = d_course_royal_raceway_dl_0, - .vtx = d_course_royal_raceway_vertex, - .vtxSize = 8306, - .textures = royal_raceway_textures, - .displaylists = d_course_royal_raceway_packed_dls, - .dlSize = 5670 }, - { // luigi_raceway - .data = d_course_luigi_raceway_dl_0, - .vtx = d_course_luigi_raceway_vertex, - .vtxSize = 5936, - .textures = luigi_raceway_textures, - .displaylists = d_course_luigi_raceway_packed_dls, - .dlSize = 6377 }, - { // moo_moo_farm - .data = d_course_moo_moo_farm_dl_0, - .vtx = d_course_moo_moo_farm_vertex, - .vtxSize = 7972, - .textures = moo_moo_farm_textures, - .displaylists = d_course_moo_moo_farm_packed_dls, - .dlSize = 3304 }, - { // highway - .data = d_course_toads_turnpike_dl_0, - .vtx = d_course_toads_turnpike_vertex, - .vtxSize = 6359, - .textures = toads_turnpike_textures, - .displaylists = d_course_toads_turnpike_packed_dls, - .dlSize = 3427 }, - { // kalimari_desert - .data = d_course_kalimari_desert_dl_0, - .vtx = d_course_kalimari_desert_vertex, - .vtxSize = 6393, - .textures = kalimari_desert_textures, - .displaylists = d_course_kalimari_desert_packed_dls, - .dlSize = 5328 }, - { // sherbet - .data = d_course_sherbet_land_dl_0, - .vtx = d_course_sherbet_land_vertex, - .vtxSize = 2678, - .textures = sherbet_land_textures, - .displaylists = d_course_sherbet_land_packed_dls, - .dlSize = 1803 }, - { // rainbow - .data = d_course_rainbow_road_dl_0, - .vtx = d_course_rainbow_road_vertex, - .vtxSize = 3111, - .textures = rainbow_road_textures, - .displaylists = d_course_rainbow_road_packed_dls, - .dlSize = 1057 }, - { // wario - .data = d_course_wario_stadium_dl_0, - .vtx = d_course_wario_stadium_vertex, - .vtxSize = 6067, - .textures = wario_stadium_textures, - .displaylists = d_course_wario_stadium_packed_dls, - .dlSize = 5272 }, - { // block fort - .data = d_course_block_fort_dl, - .vtx = d_course_block_fort_vertex, - .vtxSize = 1088, - .textures = block_fort_textures, - .displaylists = d_course_block_fort_packed_dls, - .dlSize = 699 }, - { // skyscraper - .data = d_course_skyscraper_dl, - .vtx = d_course_skyscraper_vertex, - .vtxSize = 1086, - .textures = skyscraper_textures, - .displaylists = d_course_skyscraper_packed_dls, - .dlSize = 548 }, - { // double decker - .data = d_course_double_deck_dl, - .vtx = d_course_double_deck_vertex, - .vtxSize = 555, - .textures = double_deck_textures, - .displaylists = d_course_double_deck_packed_dls, - .dlSize = 234 }, - { // dk jungle - .data = d_course_dks_jungle_parkway_dl_0, - .vtx = d_course_dks_jungle_parkway_vertex, - .vtxSize = 5679, - .textures = dks_jungle_parkway_textures, - .displaylists = d_course_dks_jungle_parkway_packed_dls, - .dlSize = 4997 }, - { // big donut - .data = d_course_big_donut_dl, - .vtx = d_course_big_donut_vertex, - .vtxSize = 1165, - .textures = big_donut_textures, - .displaylists = d_course_big_donut_packed_dls, - .dlSize = 528 } }; - u8* load_lakitu_tlut_x64(const char** textureList, size_t length) { // Calculate lakitu texture size to allocate size_t size = 0; From e0e1d601816677fe695fbbb3edf0b48218c4a083 Mon Sep 17 00:00:00 2001 From: MegaMech <7255464+MegaMech@users.noreply.github.com> Date: Fri, 6 Dec 2024 07:18:21 -0700 Subject: [PATCH 03/21] Fix minimap on custom courses --- src/code_8006E9C0.c | 5 ++--- src/code_80091750.c | 1 + src/engine/courses/TestCourse.cpp | 2 ++ src/render_objects.c | 2 +- 4 files changed, 6 insertions(+), 4 deletions(-) diff --git a/src/code_8006E9C0.c b/src/code_8006E9C0.c index 48d4ddda6..91fe49ee4 100644 --- a/src/code_8006E9C0.c +++ b/src/code_8006E9C0.c @@ -162,8 +162,7 @@ void init_item_window(s32 objectIndex) { } void func_8006EEE8(s32 courseId) { - D_8018D240 = (uintptr_t) dma_textures(CourseManager_GetProps()->MinimapTexture, D_800E5520[courseId], - ResourceGetTexSizeByName(CourseManager_GetProps()->MinimapTexture)); + D_8018D240 = (uintptr_t) CourseManager_GetProps()->MinimapTexture; // This is incredibly dumb. D_800E5548 ought to be something more like // `u16 D_800E5548[][2]` but that doesn't match for some insane reason D_8018D2B0 = CourseManager_GetProps()->D_800E5548[0]; // D_800E5548[courseId * 2]; @@ -179,7 +178,7 @@ void func_8006EF60(void) { wut = D_8018D9B4 + 0xFFFF0000; // clang-format off // God forgive me for my sins... - huh = 0x14; if (0) {} for (i = 0; i < huh; i++) { D_8018D248[i] = func_8006ED94(CourseManager_GetProps()->MinimapTexture, wut, ResourceGetTexSizeByName(CourseManager_GetProps()->MinimapTexture), D_800E5520[i]); wut += D_800E5520[i]; } + huh = 0x14; if (0) {} for (i = 0; i < huh; i++) { D_8018D248[i] = CourseManager_GetProps()->MinimapTexture; wut += ResourceGetTexSizeByName(CourseManager_GetProps()->MinimapTexture); } // clang-format on } diff --git a/src/code_80091750.c b/src/code_80091750.c index 266f7e43e..48e353058 100644 --- a/src/code_80091750.c +++ b/src/code_80091750.c @@ -6818,6 +6818,7 @@ void func_800A1924(struct_8018D9E0_entry* arg0) { gDisplayListHead = draw_flash_select_case_slow(gDisplayListHead, 0x57, 0x84, 0x96, 0x95); gDisplayListHead = func_8009BA74(gDisplayListHead, D_02004A0C, 0x57, 0x84); } + //! @bug todo: This function will not work in custom courses. func_8004EF9C(gCupCourseOrder[gTimeTrialDataCourseIndex / 4][gTimeTrialDataCourseIndex % 4]); do { gDPSetTextureFilter(gDisplayListHead++, G_TF_BILERP); diff --git a/src/engine/courses/TestCourse.cpp b/src/engine/courses/TestCourse.cpp index 6b9907a12..b636600ec 100644 --- a/src/engine/courses/TestCourse.cpp +++ b/src/engine/courses/TestCourse.cpp @@ -51,6 +51,8 @@ TestCourse::TestCourse() { this->gfxSize = 100; this->textures = NULL; Props.MinimapTexture = gTextureCourseOutlineMarioRaceway; + Props.D_800E5548[0] = 64; + Props.D_800E5548[1] = 64; Props.Id = "mk:test_course"; Props.Name = "Test Course"; diff --git a/src/render_objects.c b/src/render_objects.c index 70a8613ad..e7062e767 100644 --- a/src/render_objects.c +++ b/src/render_objects.c @@ -2587,7 +2587,7 @@ void func_8004EF9C(s32 arg0) { temp_v0 = CourseManager_GetProps()->D_800E5548[0]; // D_800E5548[arg0 * 2]; temp_t0 = CourseManager_GetProps()->D_800E5548[1]; // D_800E5548[arg0 * 2 + 1]; - func_8004D37C(0x00000104, 0x0000003C, D_8018D248[arg0], 0x000000FF, 0x000000FF, 0x000000FF, 0x000000FF, temp_v0, + func_8004D37C(0x00000104, 0x0000003C, CourseManager_GetProps()->MinimapTexture, 0x000000FF, 0x000000FF, 0x000000FF, 0x000000FF, temp_v0, temp_t0, temp_v0, temp_t0); } From 678b78905cbd618cbbb06bd7f6f2520e827758ea Mon Sep 17 00:00:00 2001 From: MegaMech <7255464+MegaMech@users.noreply.github.com> Date: Fri, 6 Dec 2024 07:18:55 -0700 Subject: [PATCH 04/21] strcpy dma_textures instead of memcpy --- src/racing/memory.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/racing/memory.c b/src/racing/memory.c index 11e8d217c..e2aed1a58 100644 --- a/src/racing/memory.c +++ b/src/racing/memory.c @@ -489,7 +489,7 @@ u8* dma_textures(const char* texture, size_t arg1, size_t arg2) { #ifdef TARGET_N64 temp_v0 = (u8*) gNextFreeMemoryAddress; #else - u8* tex = (u8*) LOAD_ASSET(texture); + //u8* tex = (u8*) LOAD_ASSET(texture); temp_v0 = (u8*) allocate_memory(arg2); #endif @@ -504,7 +504,8 @@ u8* dma_textures(const char* texture, size_t arg1, size_t arg2) { mio0decode((u8*) temp_a0, temp_v0); gNextFreeMemoryAddress += arg2; #else - memcpy(temp_v0, tex, arg2); + //memcpy(temp_v0, tex, arg2); + strcpy(temp_v0, texture); #endif return temp_v0; } From 821bb4eba27c9caca55513cf9509a4a70bf15c4c Mon Sep 17 00:00:00 2001 From: MegaMech <7255464+MegaMech@users.noreply.github.com> Date: Fri, 6 Dec 2024 13:38:17 -0700 Subject: [PATCH 05/21] Fix balloons --- src/code_80057C60.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/code_80057C60.c b/src/code_80057C60.c index 96cf3e171..c53f0f73b 100644 --- a/src/code_80057C60.c +++ b/src/code_80057C60.c @@ -6093,11 +6093,11 @@ void render_battle_balloon(Player* player, s8 arg1, s16 arg2, s8 arg3) { AA_EN | Z_CMP | Z_UPD | IM_RD | CVG_DST_WRAP | ZMODE_XLU | CVG_X_ALPHA | FORCE_BL | GBL_c2(G_BL_CLR_IN, G_BL_A_IN, G_BL_CLR_MEM, G_BL_1MA)); - gDPLoadTextureBlock(gDisplayListHead++, D_8018D4BC, G_IM_FMT_CI, G_IM_SIZ_8b, 64, 32, 0, G_TX_NOMIRROR | G_TX_CLAMP, + gDPLoadTextureBlock(gDisplayListHead++, gTextureBalloon1, G_IM_FMT_CI, G_IM_SIZ_8b, 64, 32, 0, G_TX_NOMIRROR | G_TX_CLAMP, G_TX_NOMIRROR | G_TX_CLAMP, G_TX_NOMASK, G_TX_NOMASK, G_TX_NOLOD, G_TX_NOLOD); gSPVertex(gDisplayListHead++, gBalloonVertexPlane1, 4, 0); gSPDisplayList(gDisplayListHead++, common_square_plain_render); - gDPLoadTextureBlock(gDisplayListHead++, D_8018D4C0 - 0x40, G_IM_FMT_CI, G_IM_SIZ_8b, 64, 32, 0, + gDPLoadTextureBlock(gDisplayListHead++, gTextureBalloon2, G_IM_FMT_CI, G_IM_SIZ_8b, 64, 32, 0, G_TX_NOMIRROR | G_TX_CLAMP, G_TX_NOMIRROR | G_TX_CLAMP, G_TX_NOMASK, G_TX_NOMASK, G_TX_NOLOD, G_TX_NOLOD); gSPVertex(gDisplayListHead++, gBalloonVertexPlane2, 4, 0); @@ -6215,13 +6215,13 @@ void render_balloon(Vec3f arg0, f32 arg1, s16 arg2, s16 arg3) { AA_EN | Z_CMP | Z_UPD | IM_RD | CVG_DST_WRAP | ZMODE_XLU | CVG_X_ALPHA | FORCE_BL | GBL_c2(G_BL_CLR_IN, G_BL_A_IN, G_BL_CLR_MEM, G_BL_1MA)); - gDPLoadTextureBlock(gDisplayListHead++, D_8018D4BC, G_IM_FMT_CI, G_IM_SIZ_8b, 64, 32, 0, G_TX_NOMIRROR | G_TX_CLAMP, + gDPLoadTextureBlock(gDisplayListHead++, gTextureBalloon1, G_IM_FMT_CI, G_IM_SIZ_8b, 64, 32, 0, G_TX_NOMIRROR | G_TX_CLAMP, G_TX_NOMIRROR | G_TX_CLAMP, G_TX_NOMASK, G_TX_NOMASK, G_TX_NOLOD, G_TX_NOLOD); gSPVertex(gDisplayListHead++, gBalloonVertexPlane1, 4, 0); gSPDisplayList(gDisplayListHead++, common_square_plain_render); // D_8018D4C0 is correct. But interestingly, IDO seems to set "-0x40" to a different register so the texture still // looks fine. - gDPLoadTextureBlock(gDisplayListHead++, D_8018D4C0 - 0x40, G_IM_FMT_CI, G_IM_SIZ_8b, 64, 32, 0, + gDPLoadTextureBlock(gDisplayListHead++, gTextureBalloon2, G_IM_FMT_CI, G_IM_SIZ_8b, 64, 32, 0, G_TX_NOMIRROR | G_TX_CLAMP, G_TX_NOMIRROR | G_TX_CLAMP, G_TX_NOMASK, G_TX_NOMASK, G_TX_NOLOD, G_TX_NOLOD); gSPVertex(gDisplayListHead++, gBalloonVertexPlane2, 4, 0); From f87ad2350098dee00b235d771d068d53559dff8c Mon Sep 17 00:00:00 2001 From: MegaMech <7255464+MegaMech@users.noreply.github.com> Date: Fri, 6 Dec 2024 13:38:50 -0700 Subject: [PATCH 06/21] Add warning if no finishline. Remove printfs --- src/engine/courses/Course.cpp | 1 - src/port/Game.cpp | 11 +++++++++++ src/port/Game.h | 2 ++ src/racing/actors.c | 9 +++++++++ src/racing/memory.c | 1 - 5 files changed, 22 insertions(+), 2 deletions(-) diff --git a/src/engine/courses/Course.cpp b/src/engine/courses/Course.cpp index 26c549367..e5c9a0498 100644 --- a/src/engine/courses/Course.cpp +++ b/src/engine/courses/Course.cpp @@ -104,7 +104,6 @@ void Course::Load() { freeMemory = (u8*) allocate_memory(size); texture = (u8*)(asset->addr); - printf("TEXTURE: 0x%llX\n",texture); if (texture) { if (asset == &this->Props.textures[0]) { gSegmentTable[5] = reinterpret_cast(&freeMemory[0]); diff --git a/src/port/Game.cpp b/src/port/Game.cpp index f6918a2a4..337321662 100644 --- a/src/port/Game.cpp +++ b/src/port/Game.cpp @@ -27,6 +27,7 @@ #include "engine/courses/DKJungle.h" #include "engine/courses/BigDonut.h" #include "engine/courses/TestCourse.h" +#include "engine/actors/AFinishline.h" #include "engine/courses/PodiumCeremony.h" @@ -377,6 +378,16 @@ extern "C" { } } + // Helps prevents users from forgetting to add a finishline to their course + bool cm_DoesFinishlineExist() { + for (AActor* actor : gWorldInstance.Actors) { + if (dynamic_cast(actor)) { + return true; + } + } + return false; + } + void CourseManager_InitClouds() { if (gWorldInstance.CurrentCourse) { gWorldInstance.CurrentCourse->InitClouds(); diff --git a/src/port/Game.h b/src/port/Game.h index c35e933e2..6e19b1b63 100644 --- a/src/port/Game.h +++ b/src/port/Game.h @@ -43,6 +43,8 @@ void CourseManager_RenderCredits(); void CourseManager_SpawnActors(); +bool cm_DoesFinishlineExist(); + void CourseManager_InitClouds(); void CourseManager_DrawActor(Camera* camera, struct Actor* actor); diff --git a/src/racing/actors.c b/src/racing/actors.c index d7b1168a0..bc031a568 100644 --- a/src/racing/actors.c +++ b/src/racing/actors.c @@ -1045,6 +1045,15 @@ void spawn_course_actors(void) { gNumPermanentActors = 0; CourseManager_SpawnActors(); + if (gModeSelection != BATTLE) { + if (!cm_DoesFinishlineExist()) { + printf("\n[actors.c] COURSE MISSING THE FINISHLINE\n"); + printf(" In the course class SpawnActors() function make sure to include:\n"); + printf(" gWorldInstance.AddActor(new AFinishline());\n\n"); + printf("\n Otherwise, course textures may glitch out or other strange issues may occur.\n"); + } + } + // switch (gCurrentCourseId) { // case COURSE_MARIO_RACEWAY: // // spawn_foliage(d_course_mario_raceway_tree_spawns); diff --git a/src/racing/memory.c b/src/racing/memory.c index e2aed1a58..4538fd1ec 100644 --- a/src/racing/memory.c +++ b/src/racing/memory.c @@ -828,7 +828,6 @@ uintptr_t get_texture(size_t offset) { while (textures->addr) { if (totalOffset == offset) { - printf("FOUND TEXTURE: 0x%s\n", (textures->addr)); return (textures->addr); } totalOffset += textures->data_size; From bcf4a7f384fdcecd813e61368685bed712299f6b Mon Sep 17 00:00:00 2001 From: MegaMech <7255464+MegaMech@users.noreply.github.com> Date: Fri, 6 Dec 2024 21:50:01 -0700 Subject: [PATCH 07/21] Put all thwomp code in thomp class --- src/camera.c | 1 + src/code_80057C60.c | 2 +- src/code_80086E70.c | 21 - src/data/some_data.c | 12 - src/data/some_data.h | 2 - src/engine/objects/OThwomp.cpp | 805 ++++++++++++++++++++- src/engine/objects/OThwomp.h | 35 +- src/render_objects.c | 131 ---- src/update_objects.c | 1237 -------------------------------- src/update_objects.h | 2 - 10 files changed, 822 insertions(+), 1426 deletions(-) diff --git a/src/camera.c b/src/camera.c index 732824944..8992371d6 100644 --- a/src/camera.c +++ b/src/camera.c @@ -191,6 +191,7 @@ void camera_init(f32 posX, f32 posY, f32 posZ, UNUSED s16 rot, u32 arg4, s32 cam func_802B7F7C(camera->pos, camera->lookAt, camera->rot); } +// Thwomp related void func_8001CA10(Camera* camera) { camera->unk_94.unk_8 = 0; camera->unk_94.unk_0 = 6.0f; diff --git a/src/code_80057C60.c b/src/code_80057C60.c index c53f0f73b..564a32d9d 100644 --- a/src/code_80057C60.c +++ b/src/code_80057C60.c @@ -1573,7 +1573,7 @@ void func_8005A3C0(void) { void func_8005A71C(void) { //if (GetCourse() == GetBowsersCastle()) { - func_80081210(); + //func_80081210(); //} } diff --git a/src/code_80086E70.c b/src/code_80086E70.c index a4eed4f2c..4f3393944 100644 --- a/src/code_80086E70.c +++ b/src/code_80086E70.c @@ -1403,27 +1403,6 @@ void func_8008A454(s32 objectIndex, s32 cameraId, s32 arg2) { } } -void func_8008A4CC(s32 objectIndex) { - s32 loopIndex; - Camera* camera; - - set_object_flag_status_false(objectIndex, 0x00070000); - for (loopIndex = 0, camera = camera1; loopIndex < gPlayerCountSelection1; loopIndex++, camera++) { - if (gObjectList[objectIndex].state != 0) { - if ((D_8018CF68[loopIndex] >= (gObjectList[objectIndex].unk_0DF - 1)) && - ((gObjectList[objectIndex].unk_0DF + 1) >= D_8018CF68[loopIndex])) { - set_object_flag_status_true(objectIndex, 0x00010000); - if (D_8018CF68[loopIndex] == gObjectList[objectIndex].unk_0DF) { - set_object_flag_status_true(objectIndex, 0x00020000); - } - if (is_object_visible_on_camera(objectIndex, camera, 0x2AABU) != 0) { - set_object_flag_status_true(objectIndex, VISIBLE); - } - } - } - } -} - UNUSED void func_8008A610(s32 objectIndex) { s32 loopIndex; Camera* camera; diff --git a/src/data/some_data.c b/src/data/some_data.c index da59d9bac..3b01da911 100644 --- a/src/data/some_data.c +++ b/src/data/some_data.c @@ -307,18 +307,6 @@ ThwompSpawn gThomwpSpawns150CC[] = { { 0x0596, 0xf92f, 0x0006, 0x0000 }, { 0x082a, 0xf9f2, 0x0005, 0x0000 }, { 0x073a, 0xf9f2, 0x0005, 0x0001 }, }; -f32 D_800E594C[][2] = { - { -8.0, 8.0 }, - { 8.0, 8.0 }, - { 0.0, 0.0 }, - { 8.0, -8.0 }, - { -8.0, -8.0 }, - // This feels super fake, but it matches - { -0.0, 0.0 }, -}; - -s16 D_800E597C[] = { 0x0000, 0x0000, 0x4000, 0x8000, 0x8000, 0xc000 }; - // Seems to be related to the Boos in Banshee Boardwalk SplineData D_800E5988 = { 0x0016, diff --git a/src/data/some_data.h b/src/data/some_data.h index 7c9667e7f..dc56a53fd 100644 --- a/src/data/some_data.h +++ b/src/data/some_data.h @@ -39,9 +39,7 @@ extern s16 D_800E57F8[]; extern ThwompSpawn gThomwpSpawns50CC[]; extern ThwompSpawn gThwompSpawns100CCExtra[]; extern ThwompSpawn gThomwpSpawns150CC[]; -extern f32 D_800E594C[][2]; extern u64 D_800E5974; -extern s16 D_800E597C[]; extern SplineData D_800E5988; extern SplineData D_800E5A44; extern SplineData D_800E5B08; diff --git a/src/engine/objects/OThwomp.cpp b/src/engine/objects/OThwomp.cpp index e2700f015..558b00534 100644 --- a/src/engine/objects/OThwomp.cpp +++ b/src/engine/objects/OThwomp.cpp @@ -28,9 +28,22 @@ extern "C" { #include "objects.h" #include "update_objects.h" #include "render_objects.h" +#include "some_data.h" extern s8 gPlayerCount; } +f32 D_800E594C[][2] = { + { -8.0, 8.0 }, + { 8.0, 8.0 }, + { 0.0, 0.0 }, + { 8.0, -8.0 }, + { -8.0, -8.0 }, + // This feels super fake, but it matches + { -0.0, 0.0 }, +}; + +s16 D_800E597C[] = { 0x0000, 0x0000, 0x4000, 0x8000, 0x8000, 0xc000 }; + OThwomp::OThwomp(s32 i, s16 x, s16 z, s16 direction, f32 scale, s16 behaviour, s16 primAlpha, u16 boundingBoxSize) { if (i >= 32) { printf("MAX THWOMPS REACHED (32), skipping\n"); @@ -63,7 +76,7 @@ void OThwomp::Tick() { // func_80081210 objectIndex = indexObjectList1[_idx]; func_800722CC(objectIndex, 0x00000010); - func_8008A4CC(objectIndex); + OThwomp::SetVisibility(objectIndex); OThwomp::func_8007F8D8(); @@ -101,14 +114,14 @@ void OThwomp::Tick() { // func_80081210 OThwomp::func_80080B28(objectIndex, var_s4); } if (is_obj_flag_status_active(objectIndex, 0x00020000) != 0) { - func_80080A14(objectIndex, player); + OThwomp::SetPlayerCrushedEffect(objectIndex, player); } if (is_obj_flag_status_active(objectIndex, 0x00010000) != 0) { - func_80080A4C(objectIndex, var_s4); + OThwomp::func_80080A4C(objectIndex, var_s4); } } - func_8007542C(3); + OThwomp::func_8007542C(3); objectIndex = indexObjectList1[_idx]; if (func_80072320(objectIndex, 0x00000020) == 0) { @@ -116,7 +129,7 @@ void OThwomp::Tick() { // func_80081210 } func_800722CC(objectIndex, 0x00000020); - func_80080FEC(objectIndex); + OThwomp::AddParticles(objectIndex); for (var_s4 = 0; var_s4 < gObjectParticle2_SIZE; var_s4++) { objectIndex = gObjectParticle2[var_s4]; @@ -126,7 +139,7 @@ void OThwomp::Tick() { // func_80081210 if (gObjectList[objectIndex].state == 0) { return; } - func_800810F4(objectIndex); + OThwomp::func_800810F4(objectIndex); if (gObjectList[objectIndex].state != 0) { return; } @@ -134,6 +147,181 @@ void OThwomp::Tick() { // func_80081210 } } +void OThwomp::func_800810F4(s32 objectIndex) { + switch (gObjectList[objectIndex].state) { /* irregular */ + case 0: + break; + case 1: + OThwomp::func_80081080(objectIndex); + break; + case 2: + object_add_velocity_offset_xz(objectIndex); + f32_step_up_towards(&gObjectList[objectIndex].offset[1], 14.0f, 0.5f); + func_8007415C(objectIndex, &gObjectList[objectIndex].sizeScaling, 0.25f, 0.75f, 0.025f, 1, 0); + if (func_80073B00(objectIndex, &gObjectList[objectIndex].primAlpha, 0x000000FF, 0, 4, 0, 0) != 0) { + object_next_state(objectIndex); + } + break; + case 3: + func_80072428(objectIndex); + break; + } + object_calculate_new_pos_offset(objectIndex); +} + +void OThwomp::func_80081080(s32 objectIndex) { + Object* object; + + object = &gObjectList[objectIndex]; + object->activeTexture = (const char*)D_8018D490; + object->textureList = (const char**)D_8018D490; + object->primAlpha = 0x00FF; + object->direction_angle[1] = 0; + object->orientation[0] = 0; + object->orientation[2] = 0; + object->offset[0] = 0.0f; + object->offset[1] = 0.0f; + object->offset[2] = 0.0f; + object->sizeScaling = 0.25f; + object_next_state(objectIndex); +} + +void OThwomp::AddParticles(s32 arg0) { + s32 objectIndex; + s32 i; + + for (i = 0; i < 6; i++) { + objectIndex = add_unused_obj_index(gObjectParticle2, &gNextFreeObjectParticle2, gObjectParticle2_SIZE); + if (objectIndex == NULL_OBJECT_ID) { + break; + } + OThwomp::func_80080E8C(objectIndex, arg0, i); + } +} + +#ifdef NON_MATCHING +// https://decomp.me/scratch/YMJDJ +// No idea what the problem is +void OThwomp::func_80080E8C(s32 objectIndex1, s32 objectIndex2, s32 arg2) { + u16 anAngle; + f32 thing0; + f32 thing1; + f32* temp_v1; + + init_object(objectIndex1, arg2); + temp_v1 = D_800E594C[arg2]; + gObjectList[objectIndex1].unk_0D5 = 2; + anAngle = gObjectList[objectIndex2].direction_angle[1]; + thing1 = func_800416D8(temp_v1[1], temp_v1[0], anAngle); + thing0 = func_80041724(temp_v1[1], temp_v1[0], anAngle); + gObjectList[objectIndex1].origin_pos[0] = gObjectList[objectIndex2].pos[0] + thing0; + gObjectList[objectIndex1].origin_pos[1] = gObjectList[objectIndex2].surfaceHeight - 9.0; + gObjectList[objectIndex1].origin_pos[2] = gObjectList[objectIndex2].pos[2] + thing1; + anAngle = D_800E597C[arg2] + gObjectList[objectIndex2].direction_angle[1]; + gObjectList[objectIndex1].velocity[0] = sins(anAngle) * 0.6; + gObjectList[objectIndex1].velocity[2] = coss(anAngle) * 0.6; +} +#else +GLOBAL_ASM("asm/non_matchings/update_objects/func_80080E8C.s") +#endif + +void OThwomp::SetPlayerCrushedEffect(s32 objectIndex, Player* player) { + if (is_within_horizontal_distance_of_player(objectIndex, player, 12.0f) != 0) { + player->tyres[FRONT_LEFT].unk_14 |= 3; + } +} + +void OThwomp::func_80080A4C(s32 objectIndex, s32 cameraPlayerId) { + Camera* camera = &camera1[cameraPlayerId]; + Player* player = &gPlayerOne[cameraPlayerId]; + + if (gScreenModeSelection != SCREEN_MODE_3P_4P_SPLITSCREEN) { + if ((func_80072320(objectIndex, 0x00000010) != 0) && + (is_within_horizontal_distance_of_player(objectIndex, player, 500.0f) != false)) { + func_8001CA10(camera); + func_800C98B8(gObjectList[objectIndex].pos, gObjectList[objectIndex].velocity, + SOUND_ARG_LOAD(0x19, 0x00, 0x80, 0x0F)); + } + } +} + +void OThwomp::func_8007542C(s32 arg0) { + s32 objectIndex; + s32 var_s2; + s32* var_s3; + Object* object; + + D_8016582C[0] += 0x2000; + D_8016582C[1] += 0x1000; + D_8016582C[2] += 0x1800; + for (var_s2 = 0; var_s2 < 0x80; var_s2++) { + switch (arg0) { /* irregular */ + case 1: + var_s3 = gObjectParticle1; + break; + case 2: + var_s3 = gObjectParticle2; + break; + case 3: + var_s3 = gObjectParticle3; + break; + } + objectIndex = var_s3[var_s2]; + if (objectIndex != DELETED_OBJECT_ID) { + object = &gObjectList[objectIndex]; + if (object->state != 0) { + OThwomp::func_80074FD8(objectIndex); + if (object->state == 0) { + delete_object_wrapper(&var_s3[var_s2]); + } + } + } + } +} + +void OThwomp::func_80074FD8(s32 objectIndex) { + switch (gObjectList[objectIndex].state) { /* irregular */ + case 0: + break; + case 1: + if (func_80087E08(objectIndex, gObjectList[objectIndex].velocity[1], 0.12f, + gObjectList[objectIndex].unk_034, gObjectList[objectIndex].direction_angle[1], + 0x00000064) != 0) { + object_next_state(objectIndex); + } + object_calculate_new_pos_offset(objectIndex); + gObjectList[objectIndex].orientation[0] += D_8016582C[0]; + gObjectList[objectIndex].orientation[1] += D_8016582C[1]; + gObjectList[objectIndex].orientation[2] += D_8016582C[2]; + break; + case 2: + func_80086F60(objectIndex); + func_80072428(objectIndex); + break; + } +} + +void OThwomp::SetVisibility(s32 objectIndex) { // func_8008A4CC + s32 loopIndex; + Camera* camera; + + set_object_flag_status_false(objectIndex, 0x00070000); + for (loopIndex = 0, camera = camera1; loopIndex < gPlayerCountSelection1; loopIndex++, camera++) { + if (gObjectList[objectIndex].state != 0) { + if ((D_8018CF68[loopIndex] >= (gObjectList[objectIndex].unk_0DF - 1)) && + ((gObjectList[objectIndex].unk_0DF + 1) >= D_8018CF68[loopIndex])) { + set_object_flag_status_true(objectIndex, 0x00010000); + if (D_8018CF68[loopIndex] == gObjectList[objectIndex].unk_0DF) { + set_object_flag_status_true(objectIndex, 0x00020000); + } + if (is_object_visible_on_camera(objectIndex, camera, 0x2AABU) != 0) { + set_object_flag_status_true(objectIndex, VISIBLE); + } + } + } + } +} + void OThwomp::func_8007F8D8() { Player* player; s32 objectIndex; @@ -180,19 +368,236 @@ s32 OThwomp::func_8007F75C(s32 playerId) { objectIndex = indexObjectList1[_idx]; if (gObjectList[objectIndex].unk_0D5 == 3) { var_s6 = 1; - func_8007F660(objectIndex, playerId, temp_s7); + OThwomp::func_8007F660(objectIndex, playerId, temp_s7); } } else if ((waypoint >= 0xD7) && (waypoint < 0xE2)) { objectIndex = indexObjectList1[_idx]; if (gObjectList[objectIndex].unk_0D5 == 3) { var_s6 = 1; - func_8007F6C4(objectIndex, playerId); + OThwomp::func_8007F6C4(objectIndex, playerId); } } return var_s6; } +s32 OThwomp::func_8007E50C(s32 objectIndex, Player* player, Camera* camera) { + s32 sp24; + + sp24 = 0; + if ((func_80072354(objectIndex, 4) != 0) && + (is_within_horizontal_distance_of_player(objectIndex, player, 300.0f) != 0) && + (func_8008A0B4(objectIndex, player, camera, 0x4000U) != 0) && + (func_8008A060(objectIndex, camera, 0x1555U) != 0)) { + func_800722A4(objectIndex, 4); + sp24 = 1; + } + return sp24; +} + +s32 OThwomp::func_8007E59C(s32 objectIndex) { + Camera* camera; + Player* player; + s32 temp_v0; + s32 someIndex; + + temp_v0 = 0; + player = gPlayerOne; + camera = camera1; + for (someIndex = 0; someIndex < gPlayerCountSelection1; someIndex++) { + temp_v0 = OThwomp::func_8007E50C(objectIndex, player++, camera++); + if (temp_v0 != 0) { + break; + } + } + return temp_v0; +} + +void OThwomp::func_8007F544(s32 objectIndex) { + switch (gObjectList[objectIndex].unk_0DD) { /* irregular */ + case 1: + OThwomp::func_8007EFBC(objectIndex); + break; + case 2: + OThwomp::func_8007F280(objectIndex); + break; + } +} + +void OThwomp::func_8007EFBC(s32 objectIndex) { + switch (gObjectList[objectIndex].unk_0AE) { + case 1: + if (func_80073E18(objectIndex, (u16*) &gObjectList[objectIndex].orientation[1], 0x0800U, 0x00008000) != 0) { + gObjectList[objectIndex].unk_01C[0] = (f32) ((f64) xOrientation * 200.0); + func_80086FD4(objectIndex); + } + break; + case 2: + if (f32_step_towards(gObjectList[objectIndex].offset, gObjectList[objectIndex].unk_01C[0], 4.0f) != 0) { + func_80086FD4(objectIndex); + } + break; + case 3: + if (func_80073E18(objectIndex, (u16*) &gObjectList[objectIndex].orientation[1], 0x0400U, 0x00008000) != 0) { + func_800726CC(objectIndex, 3); + func_80086FD4(objectIndex); + } + break; + case 5: + if (func_80073E18(objectIndex, (u16*) &gObjectList[objectIndex].orientation[1], 0x0400U, 0x0000C000) != 0) { + func_80086FD4(objectIndex); + } + break; + case 6: + if (f32_step_down_towards(&gObjectList[objectIndex].offset[2], -100.0f, 2.0f) != 0) { + func_80086FD4(objectIndex); + } + break; + case 7: + if (func_80073E18(objectIndex, (u16*) &gObjectList[objectIndex].orientation[1], 0x0400U, 0x00004000) != 0) { + func_80086FD4(objectIndex); + func_800726CC(objectIndex, 3); + } + break; + case 9: + if (func_80073E18(objectIndex, (u16*) &gObjectList[objectIndex].orientation[1], 0x0400U, 0x00010000) != 0) { + func_80086FD4(objectIndex); + } + break; + case 10: + if (f32_step_towards(gObjectList[objectIndex].offset, 0.0f, 4.0f) != 0) { + func_80086FD4(objectIndex); + } + break; + case 11: + if (func_80073E18(objectIndex, (u16*) &gObjectList[objectIndex].orientation[1], 0x0400U, 0x00010000) != 0) { + func_80086FD4(objectIndex); + func_800726CC(objectIndex, 3); + } + break; + case 13: + if (func_80073E18(objectIndex, (u16*) &gObjectList[objectIndex].orientation[1], 0x0400U, 0x00014000) != 0) { + func_80086FD4(objectIndex); + } + break; + case 14: + if (f32_step_up_towards(&gObjectList[objectIndex].offset[2], 0.0f, 2.0f) != 0) { + func_80086FD4(objectIndex); + } + break; + case 15: + if (func_80073E18(objectIndex, (u16*) &gObjectList[objectIndex].orientation[1], 0x0400U, 0x0000C000) != 0) { + func_80086FD4(objectIndex); + func_800726CC(objectIndex, 3); + } + break; + case 17: + func_8008701C(objectIndex, 1); + break; + case 0: + default: + break; + } +} + +void OThwomp::func_8007F280(s32 objectIndex) { + switch (gObjectList[objectIndex].unk_0AE) { + case 1: + if (func_80073E18(objectIndex, (u16*) &gObjectList[objectIndex].orientation[1], 0x0400U, 0x00010000) != 0) { + gObjectList[objectIndex].unk_01C[0] = (f32) ((f64) xOrientation * -200.0); + func_80086FD4(objectIndex); + } + break; + case 2: + if (f32_step_towards(gObjectList[objectIndex].offset, gObjectList[objectIndex].unk_01C[0], 4.0f) != 0) { + func_80086FD4(objectIndex); + } + break; + case 3: + if (func_80073E18(objectIndex, (u16*) &gObjectList[objectIndex].orientation[1], 0x0400U, 0x00010000) != 0) { + func_800726CC(objectIndex, 3); + func_80086FD4(objectIndex); + } + break; + case 5: + if (func_80073E18(objectIndex, (u16*) &gObjectList[objectIndex].orientation[1], 0x0400U, 0x00004000) != 0) { + func_80086FD4(objectIndex); + } + break; + case 6: + if (f32_step_up_towards(&gObjectList[objectIndex].offset[2], 100.0f, 2.0f) != 0) { + func_80086FD4(objectIndex); + } + break; + case 7: + if (func_80073E18(objectIndex, (u16*) &gObjectList[objectIndex].orientation[1], 0x0400U, 0x0000C000) != 0) { + func_80086FD4(objectIndex); + func_800726CC(objectIndex, 3); + } + break; + case 9: + if (func_80073E18(objectIndex, (u16*) &gObjectList[objectIndex].orientation[1], 0x0400U, 0x00008000) != 0) { + func_80086FD4(objectIndex); + } + break; + case 10: + if (f32_step_towards(gObjectList[objectIndex].offset, 0.0f, 4.0f) != 0) { + func_80086FD4(objectIndex); + } + break; + case 11: + if (func_80073E18(objectIndex, (u16*) &gObjectList[objectIndex].orientation[1], 0x0400U, 0x00008000) != 0) { + func_80086FD4(objectIndex); + func_800726CC(objectIndex, 3); + } + break; + case 13: + if (func_80073E18(objectIndex, (u16*) &gObjectList[objectIndex].orientation[1], 0x0400U, 0x0000C000) != 0) { + func_80086FD4(objectIndex); + } + break; + case 14: + if (f32_step_down_towards(&gObjectList[objectIndex].offset[2], 0.0f, 2.0f) != 0) { + func_80086FD4(objectIndex); + } + break; + case 15: + if (func_80073E18(objectIndex, (u16*) &gObjectList[objectIndex].orientation[1], 0x0400U, 0x00014000) != 0) { + func_80086FD4(objectIndex); + func_800726CC(objectIndex, 3); + } + break; + case 17: + func_8008701C(objectIndex, 1); + break; + case 0: + default: + break; + } +} + +void OThwomp::func_8007F660(s32 objectIndex, s32 arg1, s32 arg2) { + Object* object; + + func_800722A4(objectIndex, 8); + func_80086E70(objectIndex); + object = &gObjectList[objectIndex]; + object->unk_0DD = 1; + object->unk_0D1 = arg1; + object->unk_048 = arg2; +} + +void OThwomp::func_8007F6C4(s32 objectIndex, s32 playerId) { + Player* player; + + player = &gPlayerOne[playerId]; + func_800722A4(objectIndex, 8); + func_80086E70(objectIndex); + gObjectList[objectIndex].unk_0DD = 2; + gObjectList[objectIndex].unk_01C[0] = player->pos[0] - gObjectList[objectIndex].origin_pos[0]; + gObjectList[objectIndex].unk_0D1 = playerId; +} + void OThwomp::func_80080B28(s32 objectIndex, s32 playerId) { f32 temp_f0; Player* temp_s0; @@ -212,7 +617,7 @@ void OThwomp::func_80080B28(s32 objectIndex, s32 playerId) { } else { func_800C9060((u8) playerId, SOUND_ARG_LOAD(0x19, 0x01, 0xA2, 0x4A)); } - func_80080DE4(objectIndex); + OThwomp::func_80080DE4(objectIndex); func_80075304(gObjectList[objectIndex].pos, 3, 3, D_8018D3C4); set_object_flag_status_false(objectIndex, 0x00000200); func_800722A4(objectIndex, 0x00000040); @@ -240,6 +645,16 @@ void OThwomp::func_80080B28(s32 objectIndex, s32 playerId) { } } +Lights1 D_800E4638 = gdSPDefLights1(85, 85, 85, 255, 255, 255, 0, -120, 0); + +Lights1 D_800E4650 = gdSPDefLights1(85, 85, 0, 255, 255, 0, 0, 120, 0); + +Lights1 D_800E4668 = gdSPDefLights1(85, 85, 85, 255, 255, 255, -66, 82, -55); + +Lights1 D_800E4680 = gdSPDefLights1(85, 85, 85, 255, 255, 255, 0, 0, 120); + +Lights1 D_800E4698 = gdSPDefLights1(85, 85, 85, 255, 255, 255, 0, 0, 120); + void OThwomp::Draw(s32 cameraId) { s32 objectIndex = 0; s32 i; @@ -255,7 +670,7 @@ void OThwomp::Draw(s32 cameraId) { func_800722CC(objectIndex, 0x00000110); } - translate_thwomp_lights(objectIndex); + OThwomp::TranslateThwompLights(); objectIndex = indexObjectList1[_idx]; minusone = gObjectList[objectIndex].unk_0DF - 1; @@ -310,7 +725,7 @@ void OThwomp::DrawModel(s32 objectIndex) { func_8004A7AC(objectIndex, 1.75f); rsp_set_matrix_transformation(gObjectList[objectIndex].pos, gObjectList[objectIndex].orientation, gObjectList[objectIndex].sizeScaling); - thwomp_lights(objectIndex); + OThwomp::ThwompLights(objectIndex); gSPDisplayList(gDisplayListHead++, (Gfx*)D_0D007828); gDPSetTextureLUT(gDisplayListHead++, G_TT_RGBA16); gDPLoadTLUT_pal256(gDisplayListHead++, d_course_bowsers_castle_thwomp_tlut); @@ -319,6 +734,54 @@ void OThwomp::DrawModel(s32 objectIndex) { } } +void OThwomp::TranslateThwompLights() { + func_800419F8(); + 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 OThwomp::ThwompLights(s32 objectIndex) { + // Why these don't just use `gSPSetLights1` calls... + switch (gObjectList[objectIndex].type) { // hmm very strange 80165C18 + case 0: + gSPLight(gDisplayListHead++, &D_800E4638.l[0], LIGHT_1); + gSPLight(gDisplayListHead++, &D_800E4638.a, LIGHT_2); + break; + case 1: + gSPLight(gDisplayListHead++, &D_800E4650.l[0], LIGHT_1); + gSPLight(gDisplayListHead++, &D_800E4650.a, LIGHT_2); + break; + case 2: + gSPLight(gDisplayListHead++, &D_800E4668.l[0], LIGHT_1); + gSPLight(gDisplayListHead++, &D_800E4668.a, LIGHT_2); + break; + case 3: + gSPLight(gDisplayListHead++, &D_800E4680.l[0], LIGHT_1); + gSPLight(gDisplayListHead++, &D_800E4680.a, LIGHT_2); + break; + case 4: + gSPLight(gDisplayListHead++, &D_800E4698.l[0], LIGHT_1); + gSPLight(gDisplayListHead++, &D_800E4698.a, LIGHT_2); + break; + default: + break; + } +} + +void OThwomp::func_80080DE4(s32 arg0) { + Player* player; + s32 var_v1; + + player = gPlayerOne; + for (var_v1 = 0; var_v1 < NUM_PLAYERS; var_v1++, player++) { + if (arg0 == player->unk_040) { + player->soundEffects &= ~0x100; + player->unk_040 = -1; + } + } +} + /** Behaviours **/ void OThwomp::StationaryBehaviour(s32 objectIndex) { // func_8007ED6C @@ -343,7 +806,7 @@ void OThwomp::StationaryBehaviour(s32 objectIndex) { // func_8007ED6C } break; } - func_8007E63C(objectIndex); + OThwomp::func_8007E63C(objectIndex); object_calculate_new_pos_offset(objectIndex); gObjectList[objectIndex].direction_angle[1] = gObjectList[objectIndex].orientation[1]; func_80073514(objectIndex); @@ -391,7 +854,7 @@ void OThwomp::MoveAndRotateBehaviour(s32 objectIndex) { // func_8007F5A8 object_next_state(objectIndex); break; } - func_8007E63C(objectIndex); + OThwomp::func_8007E63C(objectIndex); func_8007F544(objectIndex); object_calculate_new_pos_offset(objectIndex); func_80073514(objectIndex); @@ -444,8 +907,8 @@ void OThwomp::MoveFarBehaviour(s32 objectIndex) { // func_8007FFC0 func_80086FD4(objectIndex); break; } - func_8007E63C(objectIndex); - func_8007FF5C(objectIndex); + OThwomp::func_8007E63C(objectIndex); + OThwomp::func_8007FF5C(objectIndex); object_calculate_new_pos_offset(objectIndex); func_80073514(objectIndex); } @@ -478,6 +941,118 @@ void OThwomp::func_8007FA08(s32 objectIndex) { object_next_state(objectIndex); } +void OThwomp::func_8007FF5C(s32 objectIndex) { + switch (gObjectList[objectIndex].unk_0DD) { + case 1: + OThwomp::func_8007FB48(objectIndex); + break; + case 2: + OThwomp::func_8007FEA4(objectIndex); + break; + } +} + +void OThwomp::func_8007FB48(s32 objectIndex) { + s32 var_v0; + UNUSED s32 stackPadding; + Player* player; + + player = &gPlayerOne[gObjectList[objectIndex].unk_0D1]; + switch (gObjectList[objectIndex].unk_0AE) { + case 1: + gObjectList[objectIndex].unk_0B0 = 0x00A0; + gObjectList[objectIndex].offset[0] = 0.0f; + gObjectList[objectIndex].offset[2] = 0.0f; + gObjectList[objectIndex].velocity[2] = 0.0f; + func_80086FD4(objectIndex); + break; + case 2: + gObjectList[objectIndex].velocity[0] = player->unk_094 * xOrientation * 1.25; + if (gObjectList[objectIndex].unk_048 >= gObjectList[objectIndex].unk_0B0) { + if (gObjectList[objectIndex].unk_0B0 == gObjectList[objectIndex].unk_048) { + if (D_8018D400 & 1) { + gObjectList[objectIndex].velocity[2] = 1.5f; + } else { + gObjectList[objectIndex].velocity[2] = -1.5f; + } + } + if (gObjectList[objectIndex].velocity[2] >= 0.0) { + if (gObjectList[objectIndex].offset[2] >= 40.0) { + gObjectList[objectIndex].velocity[2] = -1.5f; + } + } else if ((f64) gObjectList[objectIndex].offset[2] <= -40.0) { + gObjectList[objectIndex].velocity[2] = 1.5f; + } + } + object_add_velocity_offset_xz(objectIndex); + if (gObjectList[objectIndex].unk_0B0 < 0x65) { + gObjectList[objectIndex].orientation[1] = func_800417B4( + gObjectList[objectIndex].orientation[1], (gObjectList[objectIndex].direction_angle[1] + 0x8000)); + if (gObjectList[objectIndex].unk_0B0 == 0x0064) { + gObjectList[objectIndex].textureListIndex = 1; + } + } + var_v0 = 0; + if (gIsMirrorMode != 0) { + if (gObjectList[objectIndex].offset[0] <= -1000.0) { + var_v0 = 1; + } + } else if (gObjectList[objectIndex].offset[0] >= 1000.0) { + var_v0 = 1; + } + gObjectList[objectIndex].unk_0B0--; + if ((gObjectList[objectIndex].unk_0B0 == 0) || (var_v0 != 0)) { + gObjectList[objectIndex].unk_034 = 0.0f; + func_800726CC(objectIndex, 3); + func_80086FD4(objectIndex); + } + break; + case 4: + f32_step_towards(&gObjectList[objectIndex].offset[2], 0.0f, 2.0f); + f32_step_towards(gObjectList[objectIndex].offset, 0.0f, 5.0f); + if ((gObjectList[objectIndex].offset[0] + gObjectList[objectIndex].offset[2]) == 0.0) { + func_80086FD4(objectIndex); + } + break; + case 5: + gObjectList[objectIndex].orientation[1] = + func_800417B4(gObjectList[objectIndex].orientation[1], gObjectList[objectIndex].direction_angle[1]); + if (gObjectList[objectIndex].orientation[1] == gObjectList[objectIndex].direction_angle[1]) { + func_800722CC(objectIndex, 8); + func_80086FD4(objectIndex); + gObjectList[objectIndex].textureListIndex = 0; + } + break; + case 0: + case 3: + default: + break; + } +} + +void OThwomp::func_8007FEA4(s32 objectIndex) { + Object* object; + + object = &gObjectList[objectIndex]; + switch (object->unk_0AE) { + case 1: + if (f32_step_towards(&object->offset[0], object->unk_01C[0], 5.0f) != 0) { + func_800726CC(objectIndex, 3); + func_80086FD4(objectIndex); + break; + } + case 0: + case 2: + break; + case 3: + if (f32_step_towards(&object->offset[0], 0.0f, 5.0f) != 0) { + func_80086FD4(objectIndex); + func_800722CC(objectIndex, 8); + } + break; + } +} + void OThwomp::StationaryFastBehaviour(s32 objectIndex) { // func_800801FC Object* object; @@ -499,7 +1074,7 @@ void OThwomp::StationaryFastBehaviour(s32 objectIndex) { // func_800801FC func_800726CC(objectIndex, 2); break; } - func_8007E63C(objectIndex); + OThwomp::func_8007E63C(objectIndex); object_calculate_new_pos_offset(objectIndex); func_80073514(objectIndex); } @@ -616,8 +1191,8 @@ void OThwomp::SlidingBehaviour(s32 objectIndex) { // func_800808CC break; } if (gObjectList[objectIndex].state >= 2) { - func_8007E63C(objectIndex); - func_8008085C(objectIndex); + OThwomp::func_8007E63C(objectIndex); + OThwomp::func_8008085C(objectIndex); func_80073514(objectIndex); if (gGamestate != 9) { if ((D_8018D40C == 0) && (gObjectList[objectIndex].state == 2)) { @@ -631,6 +1206,60 @@ void OThwomp::SlidingBehaviour(s32 objectIndex) { // func_800808CC } } +void OThwomp::func_8008085C(s32 objectIndex) { + switch (gObjectList[objectIndex].unk_0DD) { + case 1: + OThwomp::func_800806BC(objectIndex); + break; + case 2: + OThwomp::func_8008078C(objectIndex); + break; + } + object_calculate_new_pos_offset(objectIndex); +} + +void OThwomp::func_800806BC(s32 objectIndex) { + switch (gObjectList[objectIndex].unk_0AE) { + case 0: + break; + case 1: + if (f32_step_towards(&gObjectList[objectIndex].offset[2], 250.0f, gObjectList[objectIndex].velocity[2]) != + 0) { + gObjectList[objectIndex].velocity[2] = -gObjectList[objectIndex].velocity[2]; + func_80086FD4(objectIndex); + } + break; + case 2: + if (f32_step_towards(&gObjectList[objectIndex].offset[2], 0.0f, gObjectList[objectIndex].velocity[2]) != + 0) { + gObjectList[objectIndex].velocity[2] = -gObjectList[objectIndex].velocity[2]; + func_8008701C(objectIndex, 1); + } + break; + } +} + +void OThwomp::func_8008078C(s32 objectIndex) { + switch (gObjectList[objectIndex].unk_0AE) { + case 0: + break; + case 1: + if (f32_step_towards(&gObjectList[objectIndex].offset[2], -250.0f, gObjectList[objectIndex].velocity[2]) != + 0) { + gObjectList[objectIndex].velocity[2] = -gObjectList[objectIndex].velocity[2]; + func_80086FD4(objectIndex); + } + break; + case 2: + if (f32_step_towards(&gObjectList[objectIndex].offset[2], 0.0f, gObjectList[objectIndex].velocity[2]) != + 0) { + gObjectList[objectIndex].velocity[2] = -gObjectList[objectIndex].velocity[2]; + func_8008701C(objectIndex, 1); + } + break; + } +} + // SlidingBehaviour void OThwomp::func_80080524(s32 objectIndex) { Object* object; @@ -667,3 +1296,143 @@ void OThwomp::func_80080524(s32 objectIndex) { func_800722A4(objectIndex, 0x00000080); object_next_state(objectIndex); } + +void OThwomp::func_8007E63C(s32 objectIndex) { + switch (gObjectList[objectIndex].state) { /* irregular */ + case 0x32: + if (f32_step_up_towards(&gObjectList[objectIndex].offset[1], gObjectList[objectIndex].unk_01C[1] + 15.0, + 1.5f) != 0) { + set_object_flag_status_true(objectIndex, 0x00000200); + func_800722A4(objectIndex, 1); + func_800722CC(objectIndex, 2); + object_next_state(objectIndex); + } + break; + case 0x33: + if (f32_step_down_towards(&gObjectList[objectIndex].offset[1], 0.0f, 2.0f) != 0) { + if (gObjectList[objectIndex].offset[1] >= 16.0f) { + gObjectList[objectIndex].textureListIndex = 0; + } else if (gObjectList[objectIndex].offset[1] >= 8.0f) { + gObjectList[objectIndex].textureListIndex = 1; + } else { + gObjectList[objectIndex].textureListIndex = 2; + } + func_800722CC(objectIndex, 1); + if (is_obj_flag_status_active(objectIndex, 0x00010000) != 0) { + func_800722A4(objectIndex, 0x00000010); + if (is_obj_flag_status_active(objectIndex, VISIBLE) != 0) { + func_800722A4(objectIndex, 0x00000020); + } + } + if (func_80072320(objectIndex, 2) != 0) { + func_800726CC(objectIndex, 0x00000064); + } else { + object_next_state(objectIndex); + } + } + break; + case 0x34: + func_80072AAC(objectIndex, 3, 6); + break; + case 0x35: + func_80072AAC(objectIndex, 2, 0x00000032); + break; + case 0x36: + if (gObjectList[objectIndex].offset[1] >= 20.0f) { + gObjectList[objectIndex].textureListIndex = 0; + } else if (gObjectList[objectIndex].offset[1] >= 18.0f) { + gObjectList[objectIndex].textureListIndex = 1; + } + if (f32_step_up_towards(&gObjectList[objectIndex].offset[1], gObjectList[objectIndex].unk_01C[1], 0.5f) != + 0) { + set_object_flag_status_false(objectIndex, 0x00000200); + func_8007266C(objectIndex); + } + break; + case 0x64: + func_80072E54(objectIndex, 3, 5, 1, 8, 0); + break; + case 0x65: + set_and_run_timer_object(objectIndex, 0x0000001E); + break; + case 0x66: + if (f32_step_up_towards(&gObjectList[objectIndex].offset[1], 20.0f, 1.5f) != 0) { + object_next_state(objectIndex); + } + break; + case 0x67: + if (f32_step_down_towards(&gObjectList[objectIndex].offset[1], 0.0f, 1.5f) != 0) { + if (is_obj_flag_status_active(objectIndex, 0x00020000) != 0) { + func_800722A4(objectIndex, 0x00000010); + if (is_obj_flag_status_active(objectIndex, VISIBLE) != 0) { + func_800722A4(objectIndex, 0x00000020); + } + } + object_next_state(objectIndex); + } + break; + case 0x68: + if (f32_step_up_towards(&gObjectList[objectIndex].offset[1], 12.0f, 1.5f) != 0) { + object_next_state(objectIndex); + } + break; + case 0x69: + if (f32_step_down_towards(&gObjectList[objectIndex].offset[1], 0.0f, 1.5f) != 0) { + if (is_obj_flag_status_active(objectIndex, 0x00020000) != 0) { + func_800722A4(objectIndex, 0x00000010); + if (is_obj_flag_status_active(objectIndex, VISIBLE) != 0) { + func_800722A4(objectIndex, 0x00000020); + } + } + func_800C98B8(gObjectList[objectIndex].pos, gObjectList[objectIndex].velocity, + SOUND_ARG_LOAD(0x19, 0x01, 0x80, 0x45)); + object_next_state(objectIndex); + } + break; + case 0x6A: + if (func_8007326C(objectIndex, 5, 3, 1, 6, 3) != 0) { + OThwomp::func_80080DE4(objectIndex); + } + break; + case 0x6B: + if (gObjectList[objectIndex].offset[1] >= 22.0f) { + gObjectList[objectIndex].textureListIndex = 0; + } else if (gObjectList[objectIndex].offset[1] >= 20.0f) { + gObjectList[objectIndex].textureListIndex = 1; + } else if (gObjectList[objectIndex].offset[1] >= 18.0f) { + gObjectList[objectIndex].textureListIndex = 2; + } else if (gObjectList[objectIndex].offset[1] >= 16.0f) { + gObjectList[objectIndex].textureListIndex = 3; + } else if (gObjectList[objectIndex].offset[1] >= 14.0f) { + gObjectList[objectIndex].textureListIndex = 4; + } else { + func_800730BC(objectIndex, 3, 5, 1, 6, -1); + } + if (f32_step_up_towards(&gObjectList[objectIndex].offset[1], gObjectList[objectIndex].unk_01C[1], 0.5f) != + 0) { + set_object_timer_state(objectIndex, 0); + object_next_state(objectIndex); + } + break; + case 0x6C: + if (set_and_run_timer_object(objectIndex, 0x00000064) != 0) { + func_800722CC(objectIndex, 2); + set_object_flag_status_false(objectIndex, 0x00000200); + func_8007266C(objectIndex); + } + break; + case 0xC8: + if (set_and_run_timer_object(objectIndex, 0x0000012C) != 0) { + func_80072320(objectIndex, 0x00000080); + func_80072428(objectIndex); + func_800726CC(objectIndex, 1); + } + break; + case 0x12C: + if (func_80073E18(objectIndex, &gObjectList[objectIndex].orientation[1], 0x0400U, 0x00008000) != 0) { + func_800722CC(objectIndex, 4); + func_8007266C(objectIndex); + } + break; + } +} diff --git a/src/engine/objects/OThwomp.h b/src/engine/objects/OThwomp.h index 2d8a2a075..517d2972d 100644 --- a/src/engine/objects/OThwomp.h +++ b/src/engine/objects/OThwomp.h @@ -10,6 +10,8 @@ extern "C" { #include "waypoints.h" #include "common_structs.h" #include "objects.h" +#include "camera.h" +#include "some_data.h" } //! @todo Make shadow size bigger if thwomp is scaled up @@ -43,11 +45,34 @@ public: explicit OThwomp(s32 i, s16 x, s16 z, s16 direction, f32 scale, s16 behaviour, s16 primAlpha, u16 boundingBoxSize); void Tick(); + void SetVisibility(s32 objectIndex); void func_80080B28(s32 objectIndex, s32 playerId); void Draw(s32 playerId); void DrawModel(s32); + void TranslateThwompLights(); + void ThwompLights(s32 objectIndex); + void func_80080DE4(s32 arg0); s32 func_8007F75C(s32 playerId); void func_8007F8D8(); + void SetPlayerCrushedEffect(s32 objectIndex, Player* player); + void func_80080A4C(s32 objectIndex, s32 cameraPlayerId); + void func_8007542C(s32 arg0); + void func_80074FD8(s32 objectIndex); + void AddParticles(s32 arg0); + + s32 func_8007E50C(s32 objectIndex, Player* player, Camera* camera); + s32 func_8007E59C(s32 objectIndex); + + void func_8007F544(s32 objectIndex); + void func_8007EFBC(s32 objectIndex); + void func_8007F280(s32 objectIndex); + + void func_8007F660(s32 objectIndex, s32 arg1, s32 arg2); + void func_80080E8C(s32 objectIndex1, s32 objectIndex2, s32 arg2); + void func_8007F6C4(s32 objectIndex, s32 playerId); + + void func_800810F4(s32 objectIndex); + void func_80081080(s32 objectIndex); void StationaryBehaviour(s32 objectIndex); void func_8007EC30(s32 objectIndex); @@ -57,6 +82,9 @@ public: void MoveFarBehaviour(s32 objectIndex); void func_8007FA08(s32 objectIndex); + void func_8007FF5C(s32 objectIndex); + void func_8007FB48(s32 objectIndex); + void func_8007FEA4(s32 objectIndex); void StationaryFastBehaviour(s32 objectIndex); void func_80080078(s32 objectIndex); @@ -66,12 +94,15 @@ public: void SlidingBehaviour(s32 objectIndex); void func_80080524(s32 objectIndex); + void func_8008085C(s32 objectIndex); + void func_800806BC(s32 objectIndex); + void func_8008078C(s32 objectIndex); + + void func_8007E63C(s32 objectIndex); private: s32 _idx; s16 _faceDirection; //! @todo Write this better. This effects the squish size and the bounding box size. // We should probably return to the programmer the pointer to the actor so they can do thwomp->squishSize = value. u16 _boundingBoxSize; - - }; diff --git a/src/render_objects.c b/src/render_objects.c index e7062e767..a5b828f0f 100644 --- a/src/render_objects.c +++ b/src/render_objects.c @@ -56,16 +56,6 @@ Lights1 D_800E45C0[] = { Lights1 D_800E4620 = gdSPDefLights1(150, 180, 250, 255, 255, 255, 0, 0, 0); -Lights1 D_800E4638 = gdSPDefLights1(85, 85, 85, 255, 255, 255, 0, -120, 0); - -Lights1 D_800E4650 = gdSPDefLights1(85, 85, 0, 255, 255, 0, 0, 120, 0); - -Lights1 D_800E4668 = gdSPDefLights1(85, 85, 85, 255, 255, 255, -66, 82, -55); - -Lights1 D_800E4680 = gdSPDefLights1(85, 85, 85, 255, 255, 255, 0, 0, 120); - -Lights1 D_800E4698 = gdSPDefLights1(85, 85, 85, 255, 255, 255, 0, 0, 120); - Lights1 D_800E46B0 = gdSPDefLights1(85, 85, 85, 255, 255, 255, 0, 0, 120); Lights1 D_800E46C8 = gdSPDefLights1(85, 85, 85, 255, 255, 255, 0, 0, 120); @@ -3757,127 +3747,6 @@ void render_lakitu(s32 cameraId) { } } -void translate_thwomp_lights(UNUSED s32 arg0) { - func_800419F8(); - 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) { - // Why these don't just use `gSPSetLights1` calls... - switch (gObjectList[objectIndex].type) { // hmm very strange 80165C18 - case 0: - gSPLight(gDisplayListHead++, &D_800E4638.l[0], LIGHT_1); - gSPLight(gDisplayListHead++, &D_800E4638.a, LIGHT_2); - break; - case 1: - gSPLight(gDisplayListHead++, &D_800E4650.l[0], LIGHT_1); - gSPLight(gDisplayListHead++, &D_800E4650.a, LIGHT_2); - break; - case 2: - gSPLight(gDisplayListHead++, &D_800E4668.l[0], LIGHT_1); - gSPLight(gDisplayListHead++, &D_800E4668.a, LIGHT_2); - break; - case 3: - gSPLight(gDisplayListHead++, &D_800E4680.l[0], LIGHT_1); - gSPLight(gDisplayListHead++, &D_800E4680.a, LIGHT_2); - break; - case 4: - gSPLight(gDisplayListHead++, &D_800E4698.l[0], LIGHT_1); - gSPLight(gDisplayListHead++, &D_800E4698.a, LIGHT_2); - break; - default: - break; - } -} - -void render_object_thwomps_model(s32 objectIndex) { - if ((gObjectList[objectIndex].state >= 2) && (func_80072354(objectIndex, 0x00000040) != 0)) { - func_8004A7AC(objectIndex, 1.75f); - rsp_set_matrix_transformation(gObjectList[objectIndex].pos, gObjectList[objectIndex].orientation, - gObjectList[objectIndex].sizeScaling); - thwomp_lights(objectIndex); - gSPDisplayList(gDisplayListHead++, D_0D007828); - gDPSetTextureLUT(gDisplayListHead++, G_TT_RGBA16); - gDPLoadTLUT_pal256(gDisplayListHead++, d_course_bowsers_castle_thwomp_tlut); - rsp_load_texture_mask(gObjectList[objectIndex].activeTexture, 0x00000010, 0x00000040, 4); - gSPDisplayList(gDisplayListHead++, gObjectList[objectIndex].model); - } -} - -void render_object_thwomps(s32 cameraId) { - s32 objectIndex = 0; - s32 i; - UNUSED s32 stackPadding0; - s16 minusone, plusone; - Camera* camera; - Object* object; - // Lights1 *D_800E4668l = (Lights1 *) LOAD_ASSET(D_800E4668); - - camera = &camera1[cameraId]; - if (cameraId == PLAYER_ONE) { - for (i = 0; i < gNumActiveThwomps; i++) { - objectIndex = indexObjectList1[i]; - set_object_flag_status_false(objectIndex, 0x00070000); - func_800722CC(objectIndex, 0x00000110); - } - } - - translate_thwomp_lights(objectIndex); - for (i = 0; i < gNumActiveThwomps; i++) { - objectIndex = indexObjectList1[i]; - minusone = gObjectList[objectIndex].unk_0DF - 1; - plusone = gObjectList[objectIndex].unk_0DF + 1; - if (gGamestate != CREDITS_SEQUENCE) { - if ((D_8018CF68[cameraId] >= minusone) && (plusone >= D_8018CF68[cameraId]) && - (is_object_visible_on_camera(objectIndex, camera, 0x8000U) != 0)) { - render_object_thwomps_model(objectIndex); - } - } else { // CREDITS_SEQUENCE - render_object_thwomps_model(objectIndex); - } - } - gSPDisplayList(gDisplayListHead++, D_0D0079C8); - gDPSetCombineMode(gDisplayListHead++, G_CC_MODULATEIA, G_CC_MODULATEIA); - gSPNumLights(gDisplayListHead++, 1); - gSPLight(gDisplayListHead++, &D_800E4668.l[0], LIGHT_1); - gSPLight(gDisplayListHead++, &D_800E4668.a, LIGHT_2); - gSPClearGeometryMode(gDisplayListHead++, G_CULL_BOTH); - gSPSetGeometryMode(gDisplayListHead++, G_SHADE | G_LIGHTING | G_SHADING_SMOOTH); - load_texture_block_rgba16_mirror(d_course_bowsers_castle_thwomp_side, 0x00000020, 0x00000020); - for (i = 0; i < gObjectParticle3_SIZE; i++) { - objectIndex = gObjectParticle3[i]; - if (objectIndex != NULL_OBJECT_ID) { - object = &gObjectList[objectIndex]; - if ((object->state > 0) && (object->unk_0D5 == 3) && (gMatrixHudCount <= MTX_HUD_POOL_SIZE_MAX)) { - rsp_set_matrix_transformation(object->pos, object->orientation, object->sizeScaling); - gSPVertex(gDisplayListHead++, D_0D005C00, 3, 0); - gSPDisplayList(gDisplayListHead++, D_0D006930); - } - } - } - gSPSetGeometryMode(gDisplayListHead++, G_CULL_BACK); - gSPClearGeometryMode(gDisplayListHead++, G_LIGHTING); - gSPTexture(gDisplayListHead++, 0x0001, 0x0001, 0, G_TX_RENDERTILE, G_OFF); - gSPDisplayList(gDisplayListHead++, D_0D007AE0); - load_texture_block_ia8_nomirror(D_8018D490, 0x00000020, 0x00000020); - func_8004B3C8(0); - D_80183E80[0] = 0; - D_80183E80[2] = 0x8000; - for (i = 0; i < gObjectParticle2_SIZE; i++) { - objectIndex = gObjectParticle2[i]; - if (objectIndex != NULL_OBJECT_ID) { - object = &gObjectList[objectIndex]; - if ((object->state >= 2) && (object->unk_0D5 == 2) && (gMatrixHudCount <= MTX_HUD_POOL_SIZE_MAX)) { - func_8004B138(0x000000FF, 0x000000FF, 0x000000FF, (s32) object->primAlpha); - D_80183E80[1] = func_800418AC(object->pos[0], object->pos[2], camera->pos); - func_800431B0(object->pos, D_80183E80, object->sizeScaling, D_0D005AE0); - } - } - } -} - void func_80053D74(s32 objectIndex, UNUSED s32 arg1, s32 vertexIndex) { Object* object; diff --git a/src/update_objects.c b/src/update_objects.c index c2e4b530f..039ebab87 100644 --- a/src/update_objects.c +++ b/src/update_objects.c @@ -1444,28 +1444,6 @@ void func_80074EE8(void) { } } -void func_80074FD8(s32 objectIndex) { - switch (gObjectList[objectIndex].state) { /* irregular */ - case 0: - break; - case 1: - if (func_80087E08(objectIndex, gObjectList[objectIndex].velocity[1], 0.12f, - gObjectList[objectIndex].unk_034, gObjectList[objectIndex].direction_angle[1], - 0x00000064) != 0) { - object_next_state(objectIndex); - } - object_calculate_new_pos_offset(objectIndex); - gObjectList[objectIndex].orientation[0] += D_8016582C[0]; - gObjectList[objectIndex].orientation[1] += D_8016582C[1]; - gObjectList[objectIndex].orientation[2] += D_8016582C[2]; - break; - case 2: - func_80086F60(objectIndex); - func_80072428(objectIndex); - break; - } -} - void func_800750D8(s32 objectIndex, s32 arg1, Vec3f arg2, s32 arg3, s32 arg4) { s32 sp24; s32 temp_v0; @@ -1512,40 +1490,6 @@ void func_80075304(Vec3f arg0, s32 arg1, s32 arg2, s32 arg3) { } } -void func_8007542C(s32 arg0) { - s32 objectIndex; - s32 var_s2; - s32* var_s3; - Object* object; - - D_8016582C[0] += 0x2000; - D_8016582C[1] += 0x1000; - D_8016582C[2] += 0x1800; - for (var_s2 = 0; var_s2 < 0x80; var_s2++) { - switch (arg0) { /* irregular */ - case 1: - var_s3 = gObjectParticle1; - break; - case 2: - var_s3 = gObjectParticle2; - break; - case 3: - var_s3 = gObjectParticle3; - break; - } - objectIndex = var_s3[var_s2]; - if (objectIndex != DELETED_OBJECT_ID) { - object = &gObjectList[objectIndex]; - if (object->state != 0) { - func_80074FD8(objectIndex); - if (object->state == 0) { - delete_object_wrapper(&var_s3[var_s2]); - } - } - } - } -} - void init_train_smoke(s32 objectIndex, Vec3f pos, f32 velocity) { Object* object; UNUSED s32 pad[2]; @@ -5558,1187 +5502,6 @@ void func_8007E4C4(void) { } } -s32 func_8007E50C(s32 objectIndex, Player* player, Camera* camera) { - s32 sp24; - - sp24 = 0; - if ((func_80072354(objectIndex, 4) != 0) && - (is_within_horizontal_distance_of_player(objectIndex, player, 300.0f) != 0) && - (func_8008A0B4(objectIndex, player, camera, 0x4000U) != 0) && - (func_8008A060(objectIndex, camera, 0x1555U) != 0)) { - func_800722A4(objectIndex, 4); - sp24 = 1; - } - return sp24; -} - -s32 func_8007E59C(s32 objectIndex) { - Camera* camera; - Player* player; - s32 temp_v0; - s32 someIndex; - - temp_v0 = 0; - player = gPlayerOne; - camera = camera1; - for (someIndex = 0; someIndex < gPlayerCountSelection1; someIndex++) { - temp_v0 = func_8007E50C(objectIndex, player++, camera++); - if (temp_v0 != 0) { - break; - } - } - return temp_v0; -} - -void func_8007E63C(s32 objectIndex) { - switch (gObjectList[objectIndex].state) { /* irregular */ - case 0x32: - if (f32_step_up_towards(&gObjectList[objectIndex].offset[1], gObjectList[objectIndex].unk_01C[1] + 15.0, - 1.5f) != 0) { - set_object_flag_status_true(objectIndex, 0x00000200); - func_800722A4(objectIndex, 1); - func_800722CC(objectIndex, 2); - object_next_state(objectIndex); - } - break; - case 0x33: - if (f32_step_down_towards(&gObjectList[objectIndex].offset[1], 0.0f, 2.0f) != 0) { - if (gObjectList[objectIndex].offset[1] >= 16.0f) { - gObjectList[objectIndex].textureListIndex = 0; - } else if (gObjectList[objectIndex].offset[1] >= 8.0f) { - gObjectList[objectIndex].textureListIndex = 1; - } else { - gObjectList[objectIndex].textureListIndex = 2; - } - func_800722CC(objectIndex, 1); - if (is_obj_flag_status_active(objectIndex, 0x00010000) != 0) { - func_800722A4(objectIndex, 0x00000010); - if (is_obj_flag_status_active(objectIndex, VISIBLE) != 0) { - func_800722A4(objectIndex, 0x00000020); - } - } - if (func_80072320(objectIndex, 2) != 0) { - func_800726CC(objectIndex, 0x00000064); - } else { - object_next_state(objectIndex); - } - } - break; - case 0x34: - func_80072AAC(objectIndex, 3, 6); - break; - case 0x35: - func_80072AAC(objectIndex, 2, 0x00000032); - break; - case 0x36: - if (gObjectList[objectIndex].offset[1] >= 20.0f) { - gObjectList[objectIndex].textureListIndex = 0; - } else if (gObjectList[objectIndex].offset[1] >= 18.0f) { - gObjectList[objectIndex].textureListIndex = 1; - } - if (f32_step_up_towards(&gObjectList[objectIndex].offset[1], gObjectList[objectIndex].unk_01C[1], 0.5f) != - 0) { - set_object_flag_status_false(objectIndex, 0x00000200); - func_8007266C(objectIndex); - } - break; - case 0x64: - func_80072E54(objectIndex, 3, 5, 1, 8, 0); - break; - case 0x65: - set_and_run_timer_object(objectIndex, 0x0000001E); - break; - case 0x66: - if (f32_step_up_towards(&gObjectList[objectIndex].offset[1], 20.0f, 1.5f) != 0) { - object_next_state(objectIndex); - } - break; - case 0x67: - if (f32_step_down_towards(&gObjectList[objectIndex].offset[1], 0.0f, 1.5f) != 0) { - if (is_obj_flag_status_active(objectIndex, 0x00020000) != 0) { - func_800722A4(objectIndex, 0x00000010); - if (is_obj_flag_status_active(objectIndex, VISIBLE) != 0) { - func_800722A4(objectIndex, 0x00000020); - } - } - object_next_state(objectIndex); - } - break; - case 0x68: - if (f32_step_up_towards(&gObjectList[objectIndex].offset[1], 12.0f, 1.5f) != 0) { - object_next_state(objectIndex); - } - break; - case 0x69: - if (f32_step_down_towards(&gObjectList[objectIndex].offset[1], 0.0f, 1.5f) != 0) { - if (is_obj_flag_status_active(objectIndex, 0x00020000) != 0) { - func_800722A4(objectIndex, 0x00000010); - if (is_obj_flag_status_active(objectIndex, VISIBLE) != 0) { - func_800722A4(objectIndex, 0x00000020); - } - } - func_800C98B8(gObjectList[objectIndex].pos, gObjectList[objectIndex].velocity, - SOUND_ARG_LOAD(0x19, 0x01, 0x80, 0x45)); - object_next_state(objectIndex); - } - break; - case 0x6A: - if (func_8007326C(objectIndex, 5, 3, 1, 6, 3) != 0) { - func_80080DE4(objectIndex); - } - break; - case 0x6B: - if (gObjectList[objectIndex].offset[1] >= 22.0f) { - gObjectList[objectIndex].textureListIndex = 0; - } else if (gObjectList[objectIndex].offset[1] >= 20.0f) { - gObjectList[objectIndex].textureListIndex = 1; - } else if (gObjectList[objectIndex].offset[1] >= 18.0f) { - gObjectList[objectIndex].textureListIndex = 2; - } else if (gObjectList[objectIndex].offset[1] >= 16.0f) { - gObjectList[objectIndex].textureListIndex = 3; - } else if (gObjectList[objectIndex].offset[1] >= 14.0f) { - gObjectList[objectIndex].textureListIndex = 4; - } else { - func_800730BC(objectIndex, 3, 5, 1, 6, -1); - } - if (f32_step_up_towards(&gObjectList[objectIndex].offset[1], gObjectList[objectIndex].unk_01C[1], 0.5f) != - 0) { - set_object_timer_state(objectIndex, 0); - object_next_state(objectIndex); - } - break; - case 0x6C: - if (set_and_run_timer_object(objectIndex, 0x00000064) != 0) { - func_800722CC(objectIndex, 2); - set_object_flag_status_false(objectIndex, 0x00000200); - func_8007266C(objectIndex); - } - break; - case 0xC8: - if (set_and_run_timer_object(objectIndex, 0x0000012C) != 0) { - func_80072320(objectIndex, 0x00000080); - func_80072428(objectIndex); - func_800726CC(objectIndex, 1); - } - break; - case 0x12C: - if (func_80073E18(objectIndex, &gObjectList[objectIndex].orientation[1], 0x0400U, 0x00008000) != 0) { - func_800722CC(objectIndex, 4); - func_8007266C(objectIndex); - } - break; - } -} - -void func_8007EC30(s32 objectIndex) { - Object* object; - - object = &gObjectList[objectIndex]; - object->surfaceHeight = 0.0f; - object->origin_pos[1] = 0.0f; - set_obj_origin_offset(objectIndex, 0.0f, 0.0f, 0.0f); - if (gIsMirrorMode != 0) { - set_obj_direction_angle(objectIndex, 0U, 0x4000U, 0U); - set_obj_orientation(objectIndex, 0U, 0x4000U, 0U); - } else { - set_obj_direction_angle(objectIndex, 0U, 0xC000U, 0U); - set_obj_orientation(objectIndex, 0U, 0xC000U, 0U); - } - init_texture_object(objectIndex, d_course_bowsers_castle_thwomp_tlut, (u8*) d_course_bowsers_castle_thwomp_faces, - 0x10U, (u16) 0x00000040); - object->model = d_course_bowsers_castle_dl_thwomp; - object->boundingBoxSize = 0x000C; - object->sizeScaling = 1.0f; - object->unk_01C[1] = 30.0f; - set_object_flag_status_true(objectIndex, 0x05000220); - object->type = 0; - object->unk_0DF = 6; - func_800724DC(objectIndex); - object_next_state(objectIndex); -} - -void func_8007ED6C(s32 objectIndex) { - UNUSED s32 stackPadding[4]; - switch (gObjectList[objectIndex].state) { - case 0: - break; - case 1: - func_8007EC30(objectIndex); - break; - case 2: - set_and_run_timer_object(objectIndex, 0x0000003C); - break; - case 3: - func_80072568(objectIndex, 0x00000032); - break; - case 4: - if (func_8007E59C(objectIndex) != 0) { - func_800725E8(objectIndex, 0x0000012C, 2); - } else { - func_800726CC(objectIndex, 2); - } - break; - } - func_8007E63C(objectIndex); - object_calculate_new_pos_offset(objectIndex); - gObjectList[objectIndex].direction_angle[1] = gObjectList[objectIndex].orientation[1]; - func_80073514(objectIndex); -} - -void func_8007EE5C(s32 objectIndex) { - Object* object; - - init_texture_object(objectIndex, d_course_bowsers_castle_thwomp_tlut, (u8*) d_course_bowsers_castle_thwomp_faces, - 0x10U, (u16) 0x00000040); - object = &gObjectList[objectIndex]; - object->sizeScaling = 1.0f; - object->model = d_course_bowsers_castle_dl_thwomp; - object->boundingBoxSize = 0x000C; - set_object_flag_status_true(objectIndex, 0x04000220); - object->type = 0; - object->unk_0DF = 6; - func_80086E70(objectIndex); - object->surfaceHeight = 0.0f; - object->origin_pos[1] = 0.0f; - set_obj_origin_offset(objectIndex, 0.0f, 20.0f, 0.0f); - object->unk_01C[1] = 20.0f; - if (gIsMirrorMode != 0) { - set_obj_direction_angle(objectIndex, 0U, 0x4000U, 0U); - set_obj_orientation(objectIndex, 0U, 0x4000U, 0U); - } else { - set_obj_direction_angle(objectIndex, 0U, 0xC000U, 0U); - set_obj_orientation(objectIndex, 0U, 0xC000U, 0U); - } - object->unk_0AE = 1; - if (object->primAlpha == 0) { - object->unk_0DD = 1; - } else { - object->unk_0DD = 2; - } - object_next_state(objectIndex); -} - -void func_8007EFBC(s32 objectIndex) { - switch (gObjectList[objectIndex].unk_0AE) { - case 1: - if (func_80073E18(objectIndex, (u16*) &gObjectList[objectIndex].orientation[1], 0x0800U, 0x00008000) != 0) { - gObjectList[objectIndex].unk_01C[0] = (f32) ((f64) xOrientation * 200.0); - func_80086FD4(objectIndex); - } - break; - case 2: - if (f32_step_towards(gObjectList[objectIndex].offset, gObjectList[objectIndex].unk_01C[0], 4.0f) != 0) { - func_80086FD4(objectIndex); - } - break; - case 3: - if (func_80073E18(objectIndex, (u16*) &gObjectList[objectIndex].orientation[1], 0x0400U, 0x00008000) != 0) { - func_800726CC(objectIndex, 3); - func_80086FD4(objectIndex); - } - break; - case 5: - if (func_80073E18(objectIndex, (u16*) &gObjectList[objectIndex].orientation[1], 0x0400U, 0x0000C000) != 0) { - func_80086FD4(objectIndex); - } - break; - case 6: - if (f32_step_down_towards(&gObjectList[objectIndex].offset[2], -100.0f, 2.0f) != 0) { - func_80086FD4(objectIndex); - } - break; - case 7: - if (func_80073E18(objectIndex, (u16*) &gObjectList[objectIndex].orientation[1], 0x0400U, 0x00004000) != 0) { - func_80086FD4(objectIndex); - func_800726CC(objectIndex, 3); - } - break; - case 9: - if (func_80073E18(objectIndex, (u16*) &gObjectList[objectIndex].orientation[1], 0x0400U, 0x00010000) != 0) { - func_80086FD4(objectIndex); - } - break; - case 10: - if (f32_step_towards(gObjectList[objectIndex].offset, 0.0f, 4.0f) != 0) { - func_80086FD4(objectIndex); - } - break; - case 11: - if (func_80073E18(objectIndex, (u16*) &gObjectList[objectIndex].orientation[1], 0x0400U, 0x00010000) != 0) { - func_80086FD4(objectIndex); - func_800726CC(objectIndex, 3); - } - break; - case 13: - if (func_80073E18(objectIndex, (u16*) &gObjectList[objectIndex].orientation[1], 0x0400U, 0x00014000) != 0) { - func_80086FD4(objectIndex); - } - break; - case 14: - if (f32_step_up_towards(&gObjectList[objectIndex].offset[2], 0.0f, 2.0f) != 0) { - func_80086FD4(objectIndex); - } - break; - case 15: - if (func_80073E18(objectIndex, (u16*) &gObjectList[objectIndex].orientation[1], 0x0400U, 0x0000C000) != 0) { - func_80086FD4(objectIndex); - func_800726CC(objectIndex, 3); - } - break; - case 17: - func_8008701C(objectIndex, 1); - break; - case 0: - default: - break; - } -} - -void func_8007F280(s32 objectIndex) { - switch (gObjectList[objectIndex].unk_0AE) { - case 1: - if (func_80073E18(objectIndex, (u16*) &gObjectList[objectIndex].orientation[1], 0x0400U, 0x00010000) != 0) { - gObjectList[objectIndex].unk_01C[0] = (f32) ((f64) xOrientation * -200.0); - func_80086FD4(objectIndex); - } - break; - case 2: - if (f32_step_towards(gObjectList[objectIndex].offset, gObjectList[objectIndex].unk_01C[0], 4.0f) != 0) { - func_80086FD4(objectIndex); - } - break; - case 3: - if (func_80073E18(objectIndex, (u16*) &gObjectList[objectIndex].orientation[1], 0x0400U, 0x00010000) != 0) { - func_800726CC(objectIndex, 3); - func_80086FD4(objectIndex); - } - break; - case 5: - if (func_80073E18(objectIndex, (u16*) &gObjectList[objectIndex].orientation[1], 0x0400U, 0x00004000) != 0) { - func_80086FD4(objectIndex); - } - break; - case 6: - if (f32_step_up_towards(&gObjectList[objectIndex].offset[2], 100.0f, 2.0f) != 0) { - func_80086FD4(objectIndex); - } - break; - case 7: - if (func_80073E18(objectIndex, (u16*) &gObjectList[objectIndex].orientation[1], 0x0400U, 0x0000C000) != 0) { - func_80086FD4(objectIndex); - func_800726CC(objectIndex, 3); - } - break; - case 9: - if (func_80073E18(objectIndex, (u16*) &gObjectList[objectIndex].orientation[1], 0x0400U, 0x00008000) != 0) { - func_80086FD4(objectIndex); - } - break; - case 10: - if (f32_step_towards(gObjectList[objectIndex].offset, 0.0f, 4.0f) != 0) { - func_80086FD4(objectIndex); - } - break; - case 11: - if (func_80073E18(objectIndex, (u16*) &gObjectList[objectIndex].orientation[1], 0x0400U, 0x00008000) != 0) { - func_80086FD4(objectIndex); - func_800726CC(objectIndex, 3); - } - break; - case 13: - if (func_80073E18(objectIndex, (u16*) &gObjectList[objectIndex].orientation[1], 0x0400U, 0x0000C000) != 0) { - func_80086FD4(objectIndex); - } - break; - case 14: - if (f32_step_down_towards(&gObjectList[objectIndex].offset[2], 0.0f, 2.0f) != 0) { - func_80086FD4(objectIndex); - } - break; - case 15: - if (func_80073E18(objectIndex, (u16*) &gObjectList[objectIndex].orientation[1], 0x0400U, 0x00014000) != 0) { - func_80086FD4(objectIndex); - func_800726CC(objectIndex, 3); - } - break; - case 17: - func_8008701C(objectIndex, 1); - break; - case 0: - default: - break; - } -} - -void func_8007F544(s32 objectIndex) { - switch (gObjectList[objectIndex].unk_0DD) { /* irregular */ - case 1: - func_8007EFBC(objectIndex); - break; - case 2: - func_8007F280(objectIndex); - break; - } -} - -void func_8007F5A8(s32 objectIndex) { - - switch (gObjectList[objectIndex].state) { /* irregular */ - case 0: - break; - case 1: - func_8007EE5C(objectIndex); - break; - case 3: - func_80072568(objectIndex, 0x00000032); - break; - case 4: - func_80086FD4(objectIndex); - object_next_state(objectIndex); - break; - } - func_8007E63C(objectIndex); - func_8007F544(objectIndex); - object_calculate_new_pos_offset(objectIndex); - func_80073514(objectIndex); -} - -void func_8007F660(s32 objectIndex, s32 arg1, s32 arg2) { - Object* object; - - func_800722A4(objectIndex, 8); - func_80086E70(objectIndex); - object = &gObjectList[objectIndex]; - object->unk_0DD = 1; - object->unk_0D1 = arg1; - object->unk_048 = arg2; -} - -void func_8007F6C4(s32 objectIndex, s32 playerId) { - Player* player; - - player = &gPlayerOne[playerId]; - func_800722A4(objectIndex, 8); - func_80086E70(objectIndex); - gObjectList[objectIndex].unk_0DD = 2; - gObjectList[objectIndex].unk_01C[0] = player->pos[0] - gObjectList[objectIndex].origin_pos[0]; - gObjectList[objectIndex].unk_0D1 = playerId; -} - -s32 func_8007F75C(s32 playerId) { - s32 someIndex; - s32 objectIndex; - s32 temp_s7; - s32 var_s6; - s32 waypoint; - - waypoint = gNearestWaypointByPlayerId[playerId]; - var_s6 = 0; - if ((waypoint >= 0xAA) && (waypoint < 0xB5)) { - temp_s7 = random_int(0x0032U) + 0x32; - for (someIndex = 0; someIndex < gNumActiveThwomps; someIndex++) { - objectIndex = indexObjectList1[someIndex]; - if (gObjectList[objectIndex].unk_0D5 == 3) { - var_s6 = 1; - func_8007F660(objectIndex, playerId, temp_s7); - } - } - } else if ((waypoint >= 0xD7) && (waypoint < 0xE2)) { - for (someIndex = 0; someIndex < gNumActiveThwomps; someIndex++) { - objectIndex = indexObjectList1[someIndex]; - if (gObjectList[objectIndex].unk_0D5 == 3) { - var_s6 = 1; - func_8007F6C4(objectIndex, playerId); - } - } - } - return var_s6; -} - -void func_8007F8D8(void) { - Player* player; - s32 objectIndex; - s32 var_s0; - s32 someIndex; - s32 var_s4; - Object* object; - - player = gPlayerOne; - var_s4 = 1; - for (someIndex = 0; someIndex < gNumActiveThwomps; someIndex++) { - objectIndex = indexObjectList1[someIndex]; - object = &gObjectList[objectIndex]; - if (object->unk_0D5 == 3) { - var_s0 = 0; - if ((object->state >= 2) && (func_80072354(objectIndex, 8) != 0)) { - var_s0 = 1; - } - var_s4 *= var_s0; - } - } - if (var_s4 != 0) { - for (var_s0 = 0; var_s0 < 4; var_s0++, player++) { - if ((player->type & PLAYER_EXISTS) && !(player->type & PLAYER_KART_AI)) { - if (func_8007F75C(var_s0) != 0) { - break; - } - } - } - } -} - -void func_8007FA08(s32 objectIndex) { - Object* object; - - init_texture_object(objectIndex, d_course_bowsers_castle_thwomp_tlut, (u8*) d_course_bowsers_castle_thwomp_faces, - 0x10U, (u16) 0x00000040); - object = &gObjectList[objectIndex]; - object->model = d_course_bowsers_castle_dl_thwomp; - object->boundingBoxSize = 0x000C; - object->sizeScaling = 1.0f; - set_object_flag_status_true(objectIndex, 0x04000220); - object->type = 0; - object->surfaceHeight = 0.0f; - object->origin_pos[1] = 0.0f; - set_obj_origin_offset(objectIndex, 0.0f, 0.0f, 0.0f); - set_obj_direction_angle(objectIndex, 0U, 0U, 0U); - if (gIsMirrorMode != 0) { - set_obj_orientation(objectIndex, 0U, 0xC000U, 0U); - } else { - set_obj_orientation(objectIndex, 0U, 0x4000U, 0U); - } - object->velocity[0] = 0.0f; - object->direction_angle[1] = object->orientation[1]; - object->unk_0DD = 1; - object->unk_0DF = 8; - object->offset[1] = 15.0f; - object->unk_01C[1] = 15.0f; - object_next_state(objectIndex); -} - -void func_8007FB48(s32 objectIndex) { - s32 var_v0; - UNUSED s32 stackPadding; - Player* player; - - player = &gPlayerOne[gObjectList[objectIndex].unk_0D1]; - switch (gObjectList[objectIndex].unk_0AE) { - case 1: - gObjectList[objectIndex].unk_0B0 = 0x00A0; - gObjectList[objectIndex].offset[0] = 0.0f; - gObjectList[objectIndex].offset[2] = 0.0f; - gObjectList[objectIndex].velocity[2] = 0.0f; - func_80086FD4(objectIndex); - break; - case 2: - gObjectList[objectIndex].velocity[0] = player->unk_094 * xOrientation * 1.25; - if (gObjectList[objectIndex].unk_048 >= gObjectList[objectIndex].unk_0B0) { - if (gObjectList[objectIndex].unk_0B0 == gObjectList[objectIndex].unk_048) { - if (D_8018D400 & 1) { - gObjectList[objectIndex].velocity[2] = 1.5f; - } else { - gObjectList[objectIndex].velocity[2] = -1.5f; - } - } - if (gObjectList[objectIndex].velocity[2] >= 0.0) { - if (gObjectList[objectIndex].offset[2] >= 40.0) { - gObjectList[objectIndex].velocity[2] = -1.5f; - } - } else if ((f64) gObjectList[objectIndex].offset[2] <= -40.0) { - gObjectList[objectIndex].velocity[2] = 1.5f; - } - } - object_add_velocity_offset_xz(objectIndex); - if (gObjectList[objectIndex].unk_0B0 < 0x65) { - gObjectList[objectIndex].orientation[1] = func_800417B4( - gObjectList[objectIndex].orientation[1], (gObjectList[objectIndex].direction_angle[1] + 0x8000)); - if (gObjectList[objectIndex].unk_0B0 == 0x0064) { - gObjectList[objectIndex].textureListIndex = 1; - } - } - var_v0 = 0; - if (gIsMirrorMode != 0) { - if (gObjectList[objectIndex].offset[0] <= -1000.0) { - var_v0 = 1; - } - } else if (gObjectList[objectIndex].offset[0] >= 1000.0) { - var_v0 = 1; - } - gObjectList[objectIndex].unk_0B0--; - if ((gObjectList[objectIndex].unk_0B0 == 0) || (var_v0 != 0)) { - gObjectList[objectIndex].unk_034 = 0.0f; - func_800726CC(objectIndex, 3); - func_80086FD4(objectIndex); - } - break; - case 4: - f32_step_towards(&gObjectList[objectIndex].offset[2], 0.0f, 2.0f); - f32_step_towards(gObjectList[objectIndex].offset, 0.0f, 5.0f); - if ((gObjectList[objectIndex].offset[0] + gObjectList[objectIndex].offset[2]) == 0.0) { - func_80086FD4(objectIndex); - } - break; - case 5: - gObjectList[objectIndex].orientation[1] = - func_800417B4(gObjectList[objectIndex].orientation[1], gObjectList[objectIndex].direction_angle[1]); - if (gObjectList[objectIndex].orientation[1] == gObjectList[objectIndex].direction_angle[1]) { - func_800722CC(objectIndex, 8); - func_80086FD4(objectIndex); - gObjectList[objectIndex].textureListIndex = 0; - } - break; - case 0: - case 3: - default: - break; - } -} - -void func_8007FEA4(s32 objectIndex) { - Object* object; - - object = &gObjectList[objectIndex]; - switch (object->unk_0AE) { - case 1: - if (f32_step_towards(&object->offset[0], object->unk_01C[0], 5.0f) != 0) { - func_800726CC(objectIndex, 3); - func_80086FD4(objectIndex); - break; - } - case 0: - case 2: - break; - case 3: - if (f32_step_towards(&object->offset[0], 0.0f, 5.0f) != 0) { - func_80086FD4(objectIndex); - func_800722CC(objectIndex, 8); - } - break; - } -} - -void func_8007FF5C(s32 objectIndex) { - switch (gObjectList[objectIndex].unk_0DD) { - case 1: - func_8007FB48(objectIndex); - break; - case 2: - func_8007FEA4(objectIndex); - break; - } -} - -void func_8007FFC0(s32 objectIndex) { - switch (gObjectList[objectIndex].state) { /* irregular */ - case 0: - break; - case 1: - func_8007FA08(objectIndex); - break; - case 3: - func_80072568(objectIndex, 0x00000032); - break; - case 4: - object_next_state(objectIndex); - func_80086FD4(objectIndex); - break; - } - func_8007E63C(objectIndex); - func_8007FF5C(objectIndex); - object_calculate_new_pos_offset(objectIndex); - func_80073514(objectIndex); -} - -void func_80080078(s32 objectIndex) { - Object* object; - - init_texture_object(objectIndex, d_course_bowsers_castle_thwomp_tlut, (u8*) d_course_bowsers_castle_thwomp_faces, - 0x10U, (u16) 0x00000040); - object = &gObjectList[objectIndex]; - object->model = d_course_bowsers_castle_dl_thwomp; - object->boundingBoxSize = 0x000C; - object->sizeScaling = 1.0f; - set_object_flag_status_true(objectIndex, 0x04000220); - object->type = 2; - object->unk_0DF = 8; - set_obj_direction_angle(objectIndex, 0U, 0U, 0U); - object->surfaceHeight = 0.0f; - object->origin_pos[1] = 0.0f; - set_obj_origin_offset(objectIndex, 0.0f, 0.0f, 0.0f); - object->unk_01C[1] = 30.0f; - if (gIsMirrorMode != 0) { - set_obj_orientation(objectIndex, 0U, 0x4000U, 0U); - } else { - set_obj_orientation(objectIndex, 0U, 0xC000U, 0U); - } - switch (object->primAlpha) { /* irregular */ - case 0: - object->timer = 2; - break; - case 1: - object->timer = 0x0000003C; - break; - case 2: - object->timer = 0x00000078; - break; - case 3: - object->timer = 0x000000B4; - break; - } - func_800724DC(objectIndex); - object_next_state(objectIndex); -} - -void func_800801FC(s32 objectIndex) { - Object* object; - - object = &gObjectList[objectIndex]; - switch (object->state) { - case 0: - break; - case 1: - func_80080078(objectIndex); - break; - case 2: - set_and_run_timer_object(objectIndex, object->timer); - break; - case 3: - func_80072568(objectIndex, 0x00000032); - break; - case 4: - object->timer = 0x0000003C; - func_800726CC(objectIndex, 2); - break; - } - func_8007E63C(objectIndex); - object_calculate_new_pos_offset(objectIndex); - func_80073514(objectIndex); -} - -void func_800802C0(s32 objectIndex) { - Object* object; - - object = &gObjectList[objectIndex]; - object->unk_0D8 = 0; - init_texture_object(objectIndex, d_course_bowsers_castle_thwomp_tlut, (u8*) d_course_bowsers_castle_thwomp_faces, - 0x10U, (u16) 0x00000040); - object->model = d_course_bowsers_castle_dl_thwomp; - object->textureListIndex = 0; - object->boundingBoxSize = 0x000C; - object->sizeScaling = 1.5f; - set_object_flag_status_true(objectIndex, 0x05000220); - object->type = 1; - object->unk_0DF = 6; - set_obj_origin_offset(objectIndex, 0.0f, 0.0f, 0.0f); - set_obj_direction_angle(objectIndex, 0U, 0U, 0U); - object->surfaceHeight = 0.0f; - object->origin_pos[1] = 0.0f; - object->offset[1] = 10.0f; - object->unk_01C[1] = 10.0f; - if (gIsMirrorMode != 0) { - set_obj_orientation(objectIndex, 0U, 0x4000U, 0U); - } else { - set_obj_orientation(objectIndex, 0U, 0xC000U, 0U); - } - object->offset[0] = 0.0f; - object->offset[2] = 0.0f; - func_800724DC(objectIndex); - object_next_state(objectIndex); -} - -void func_80080408(s32 objectIndex) { - switch (gObjectList[objectIndex].state) { - case 0: - break; - case 1: - func_800802C0(objectIndex); - break; - case 2: - func_8008A6DC(objectIndex, 100.0f); - if (is_obj_flag_status_active(objectIndex, VISIBLE) != 0) { - func_800C98B8(gObjectList[objectIndex].pos, gObjectList[objectIndex].velocity, - SOUND_ARG_LOAD(0x19, 0x01, 0x80, 0x45)); - object_next_state(objectIndex); - } - break; - case 3: - if (func_800730BC(objectIndex, 3, 5, 1, 6, 6) != 0) { - gObjectList[objectIndex].textureListIndex = 0; - } - break; - case 4: - if (set_and_run_timer_object(objectIndex, 0x0000012C) != 0) { - func_800726CC(objectIndex, 2); - } - break; - } - object_calculate_new_pos_offset(objectIndex); - func_80073514(objectIndex); -} - -void func_80080524(s32 objectIndex) { - Object* object; - - init_texture_object(objectIndex, d_course_bowsers_castle_thwomp_tlut, (u8*) d_course_bowsers_castle_thwomp_faces, - 0x10U, (u16) 0x00000040); - object = &gObjectList[objectIndex]; - object->model = d_course_bowsers_castle_dl_thwomp; - object->boundingBoxSize = 0x000C; - object->textureListIndex = 0; - object->sizeScaling = 1.0f; - set_object_flag_status_true(objectIndex, 0x04000220); - object->type = 0; - object->unk_0DF = 0x0A; - func_80086E70(objectIndex); - set_obj_origin_offset(objectIndex, 0.0f, 0.0f, 0.0f); - object->surfaceHeight = 70.0f; - object->origin_pos[1] = 70.0f; - object->unk_01C[1] = 0.0f; - set_obj_direction_angle(objectIndex, 0U, 0U, 0U); - if ((gIsMirrorMode != 0) || (gGamestate == 9)) { - set_obj_orientation(objectIndex, 0U, 0xC000U, 0U); - } else { - set_obj_orientation(objectIndex, 0U, 0x4000U, 0U); - } - switch (object->primAlpha) { /* irregular */ - case 0: - object->unk_0DD = 2; - object->velocity[2] = -1.0f; - break; - case 1: - object->unk_0DD = 2; - object->velocity[2] = -1.5f; - break; - } - func_800722A4(objectIndex, 0x00000080); - object_next_state(objectIndex); -} - -void func_800806BC(s32 objectIndex) { - switch (gObjectList[objectIndex].unk_0AE) { - case 0: - break; - case 1: - if (f32_step_towards(&gObjectList[objectIndex].offset[2], 250.0f, gObjectList[objectIndex].velocity[2]) != - 0) { - gObjectList[objectIndex].velocity[2] = -gObjectList[objectIndex].velocity[2]; - func_80086FD4(objectIndex); - } - break; - case 2: - if (f32_step_towards(&gObjectList[objectIndex].offset[2], 0.0f, gObjectList[objectIndex].velocity[2]) != - 0) { - gObjectList[objectIndex].velocity[2] = -gObjectList[objectIndex].velocity[2]; - func_8008701C(objectIndex, 1); - } - break; - } -} - -void func_8008078C(s32 objectIndex) { - switch (gObjectList[objectIndex].unk_0AE) { - case 0: - break; - case 1: - if (f32_step_towards(&gObjectList[objectIndex].offset[2], -250.0f, gObjectList[objectIndex].velocity[2]) != - 0) { - gObjectList[objectIndex].velocity[2] = -gObjectList[objectIndex].velocity[2]; - func_80086FD4(objectIndex); - } - break; - case 2: - if (f32_step_towards(&gObjectList[objectIndex].offset[2], 0.0f, gObjectList[objectIndex].velocity[2]) != - 0) { - gObjectList[objectIndex].velocity[2] = -gObjectList[objectIndex].velocity[2]; - func_8008701C(objectIndex, 1); - } - break; - } -} - -void func_8008085C(s32 objectIndex) { - switch (gObjectList[objectIndex].unk_0DD) { - case 1: - func_800806BC(objectIndex); - break; - case 2: - func_8008078C(objectIndex); - break; - } - object_calculate_new_pos_offset(objectIndex); -} - -void func_800808CC(s32 objectIndex) { - switch (gObjectList[objectIndex].state) { /* irregular */ - case 0: - break; - case 1: - func_80080524(objectIndex); - break; - case 2: - func_800730BC(objectIndex, 3, 5, 1, 6, -1); - break; - } - if (gObjectList[objectIndex].state >= 2) { - func_8007E63C(objectIndex); - func_8008085C(objectIndex); - func_80073514(objectIndex); - if (gGamestate != 9) { - if ((D_8018D40C == 0) && (gObjectList[objectIndex].state == 2)) { - func_800C98B8(gObjectList[objectIndex].pos, gObjectList[objectIndex].velocity, - SOUND_ARG_LOAD(0x19, 0x03, 0x60, 0x45)); - } - } else if ((gCutsceneShotTimer < 0xBF) && (((s16) gCutsceneShotTimer % 88) == 0x0000001E)) { - func_800C98B8(gObjectList[objectIndex].pos, gObjectList[objectIndex].velocity, - SOUND_ARG_LOAD(0x19, 0x03, 0x60, 0x45)); - } - } -} - -void func_80080A14(s32 objectIndex, Player* player) { - if (is_within_horizontal_distance_of_player(objectIndex, player, 12.0f) != 0) { - player->tyres[FRONT_LEFT].unk_14 |= 3; - } -} - -void func_80080A4C(s32 objectIndex, s32 cameraPlayerId) { - Camera* camera = &camera1[cameraPlayerId]; - Player* player = &gPlayerOne[cameraPlayerId]; - - if (gScreenModeSelection != SCREEN_MODE_3P_4P_SPLITSCREEN) { - if ((func_80072320(objectIndex, 0x00000010) != 0) && - (is_within_horizontal_distance_of_player(objectIndex, player, 500.0f) != false)) { - func_8001CA10(camera); - func_800C98B8(gObjectList[objectIndex].pos, gObjectList[objectIndex].velocity, - SOUND_ARG_LOAD(0x19, 0x00, 0x80, 0x0F)); - } - } -} - -void func_80080B28(s32 objectIndex, s32 playerId) { - f32 temp_f0; - Player* temp_s0; - - temp_s0 = &gPlayerOne[playerId]; - if (is_obj_flag_status_active(objectIndex, 0x00000200) != 0) { - if (!(temp_s0->soundEffects & 0x100)) { - temp_f0 = func_80088F54(objectIndex, temp_s0); - if ((temp_f0 <= 9.0) && !(temp_s0->effects & 0x04000000) && - (has_collided_horizontally_with_player(objectIndex, temp_s0) != 0)) { - if ((temp_s0->type & 0x8000) && !(temp_s0->type & 0x100)) { - if (!(temp_s0->effects & 0x200)) { - func_80089474(objectIndex, playerId, 1.4f, 1.1f, SOUND_ARG_LOAD(0x19, 0x00, 0xA0, 0x4C)); - } else if (func_80072354(objectIndex, 0x00000040) != 0) { - if (temp_s0->type & 0x1000) { - func_800C98B8(temp_s0->pos, temp_s0->velocity, SOUND_ARG_LOAD(0x19, 0x01, 0xA2, 0x4A)); - } else { - func_800C9060((u8) playerId, SOUND_ARG_LOAD(0x19, 0x01, 0xA2, 0x4A)); - } - func_80080DE4(objectIndex); - func_80075304(gObjectList[objectIndex].pos, 3, 3, D_8018D3C4); - set_object_flag_status_false(objectIndex, 0x00000200); - func_800722A4(objectIndex, 0x00000040); - func_80086F60(objectIndex); - func_800726CC(objectIndex, 0x000000C8); - } - } - } else if ((temp_f0 <= 17.5) && (func_80072320(objectIndex, 1) != 0) && - (is_within_horizontal_distance_of_player(objectIndex, temp_s0, (temp_s0->unk_094 * 0.5) + 7.0) != - 0)) { - if ((temp_s0->type & 0x8000) && !(temp_s0->type & 0x100)) { - if (is_obj_flag_status_active(objectIndex, 0x04000000) != 0) { - func_80072180(); - } - func_800722A4(objectIndex, 2); - temp_s0->unk_040 = (s16) objectIndex; - temp_s0->unk_046 |= 2; - temp_s0->soundEffects |= 0x100; - func_80088FF0(temp_s0); - } - } - } else { - func_80088FF0(temp_s0); - } - } -} - -void func_80080DE4(s32 arg0) { - Player* player; - s32 var_v1; - - player = gPlayerOne; - for (var_v1 = 0; var_v1 < NUM_PLAYERS; var_v1++, player++) { - if (arg0 == player->unk_040) { - player->soundEffects &= ~0x100; - player->unk_040 = -1; - } - } -} - -#ifdef NON_MATCHING -// https://decomp.me/scratch/YMJDJ -// No idea what the problem is -void func_80080E8C(s32 objectIndex1, s32 objectIndex2, s32 arg2) { - u16 anAngle; - f32 thing0; - f32 thing1; - f32* temp_v1; - - init_object(objectIndex1, arg2); - temp_v1 = D_800E594C[arg2]; - gObjectList[objectIndex1].unk_0D5 = 2; - anAngle = gObjectList[objectIndex2].direction_angle[1]; - thing1 = func_800416D8(temp_v1[1], temp_v1[0], anAngle); - thing0 = func_80041724(temp_v1[1], temp_v1[0], anAngle); - gObjectList[objectIndex1].origin_pos[0] = gObjectList[objectIndex2].pos[0] + thing0; - gObjectList[objectIndex1].origin_pos[1] = gObjectList[objectIndex2].surfaceHeight - 9.0; - gObjectList[objectIndex1].origin_pos[2] = gObjectList[objectIndex2].pos[2] + thing1; - anAngle = D_800E597C[arg2] + gObjectList[objectIndex2].direction_angle[1]; - gObjectList[objectIndex1].velocity[0] = sins(anAngle) * 0.6; - gObjectList[objectIndex1].velocity[2] = coss(anAngle) * 0.6; -} -#else -GLOBAL_ASM("asm/non_matchings/update_objects/func_80080E8C.s") -#endif - -void func_80080FEC(s32 arg0) { - s32 objectIndex; - s32 i; - - for (i = 0; i < 6; i++) { - objectIndex = add_unused_obj_index(gObjectParticle2, &gNextFreeObjectParticle2, gObjectParticle2_SIZE); - if (objectIndex == NULL_OBJECT_ID) { - break; - } - func_80080E8C(objectIndex, arg0, i); - } -} - -void func_80081080(s32 objectIndex) { - Object* object; - - object = &gObjectList[objectIndex]; - object->activeTexture = D_8018D490; - object->textureList = D_8018D490; - object->primAlpha = 0x00FF; - object->direction_angle[1] = 0; - object->orientation[0] = 0; - object->orientation[2] = 0; - object->offset[0] = 0.0f; - object->offset[1] = 0.0f; - object->offset[2] = 0.0f; - object->sizeScaling = 0.25f; - object_next_state(objectIndex); -} - -void func_800810F4(s32 objectIndex) { - switch (gObjectList[objectIndex].state) { /* irregular */ - case 0: - break; - case 1: - func_80081080(objectIndex); - break; - case 2: - object_add_velocity_offset_xz(objectIndex); - f32_step_up_towards(&gObjectList[objectIndex].offset[1], 14.0f, 0.5f); - func_8007415C(objectIndex, &gObjectList[objectIndex].sizeScaling, 0.25f, 0.75f, 0.025f, 1, 0); - if (func_80073B00(objectIndex, &gObjectList[objectIndex].primAlpha, 0x000000FF, 0, 4, 0, 0) != 0) { - object_next_state(objectIndex); - } - break; - case 3: - func_80072428(objectIndex); - break; - } - object_calculate_new_pos_offset(objectIndex); -} - -// update twomp I think -void func_80081208(void) { -} - -void func_80081210(void) { - Player* player; - s32 objectIndex; - s32 var_s2_3; - s32 var_s4; - - D_80165834[0] += 0x100; - D_80165834[1] += 0x200; - for (var_s4 = 0; var_s4 < gNumActiveThwomps; var_s4++) { - objectIndex = indexObjectList1[var_s4]; - func_800722CC(objectIndex, 0x00000010); - func_8008A4CC(objectIndex); - } - func_8007F8D8(); - for (var_s4 = 0; var_s4 < gNumActiveThwomps; var_s4++) { - objectIndex = indexObjectList1[var_s4]; - if (gObjectList[objectIndex].state != 0) { - switch (gObjectList[objectIndex].unk_0D5) { - case 1: - func_8007ED6C(objectIndex); - break; - case 2: - func_8007F5A8(objectIndex); - break; - case 3: - func_8007FFC0(objectIndex); - break; - case 4: - func_800801FC(objectIndex); - break; - case 6: - func_80080408(objectIndex); - break; - case 5: - func_800808CC(objectIndex); - break; - } - } - } - player = gPlayerOne; - for (var_s4 = 0; var_s4 < NUM_PLAYERS; var_s4++, player++) { - player->tyres[FRONT_LEFT].unk_14 &= ~3; - player->unk_046 &= ~0x0006; - for (var_s2_3 = 0; var_s2_3 < gNumActiveThwomps; var_s2_3++) { - objectIndex = indexObjectList1[var_s2_3]; - if (!(player->effects & BOO_EFFECT)) { - func_80080B28(objectIndex, var_s4); - } - if (is_obj_flag_status_active(objectIndex, 0x00020000) != 0) { - func_80080A14(objectIndex, player); - } - if (is_obj_flag_status_active(objectIndex, 0x00010000) != 0) { - func_80080A4C(objectIndex, var_s4); - } - } - } - func_8007542C(3); - for (var_s4 = 0; var_s4 < gNumActiveThwomps; var_s4++) { - objectIndex = indexObjectList1[var_s4]; - if (func_80072320(objectIndex, 0x00000020) == 0) { - continue; - } - - func_800722CC(objectIndex, 0x00000020); - func_80080FEC(objectIndex); - } - for (var_s4 = 0; var_s4 < gObjectParticle2_SIZE; var_s4++) { - objectIndex = gObjectParticle2[var_s4]; - if (objectIndex == DELETED_OBJECT_ID) { - continue; - } - if (gObjectList[objectIndex].state == 0) { - continue; - } - func_800810F4(objectIndex); - if (gObjectList[objectIndex].state != 0) { - continue; - } - delete_object_wrapper(&gObjectParticle2[var_s4]); - } -} - void func_8008153C(s32 objectIndex) { UNUSED s32 stackPadding[3]; s32 sp70; diff --git a/src/update_objects.h b/src/update_objects.h index 8e9da1cc5..b375c59e4 100644 --- a/src/update_objects.h +++ b/src/update_objects.h @@ -254,8 +254,6 @@ void func_8007E1F4(s32); void func_8007E358(s32); void func_8007E3EC(s32); void func_8007E4C4(void); -s32 func_8007E50C(s32, Player*, Camera*); -s32 func_8007E59C(s32); void func_8007E63C(s32); void func_8007EC30(s32); void func_8007ED6C(s32); From a4890f9dfcc993f3001d491395294f6836cdc0dc Mon Sep 17 00:00:00 2001 From: MegaMech <7255464+MegaMech@users.noreply.github.com> Date: Sat, 7 Dec 2024 19:38:47 -0700 Subject: [PATCH 08/21] Move penguin code to class --- src/engine/objects/OPenguin.cpp | 190 +++++++++-------- src/engine/objects/OPenguin.h | 5 + src/update_objects.c | 361 -------------------------------- src/update_objects.h | 1 - 4 files changed, 113 insertions(+), 444 deletions(-) diff --git a/src/engine/objects/OPenguin.cpp b/src/engine/objects/OPenguin.cpp index f43a76ffc..944ec38fd 100644 --- a/src/engine/objects/OPenguin.cpp +++ b/src/engine/objects/OPenguin.cpp @@ -144,28 +144,28 @@ void OPenguin::Draw(s32 cameraId) { } } -void OPenguin::Behaviours(s32 objectIndex, s32 arg1) { +void OPenguin::Behaviours(s32 objectIndex, s32 arg1) { // func_800850B0 Object* object; object = &gObjectList[objectIndex]; switch (_bhv) { case 1: // emperor - func_80085080(objectIndex); + OPenguin::func_80085080(objectIndex); break; case 2: - func_8008502C(objectIndex, arg1); + OPenguin::func_8008502C(objectIndex, arg1); break; case 3: - func_80084D2C(objectIndex, 0); + OPenguin::func_80084D2C(objectIndex, 0); break; case 4: - func_80084D2C(objectIndex, 1); + OPenguin::func_80084D2C(objectIndex, 1); break; case 5: - func_80084D2C(objectIndex, 2); + OPenguin::func_80084D2C(objectIndex, 2); break; case 6: - func_80084D2C(objectIndex, 3); + OPenguin::func_80084D2C(objectIndex, 3); break; } if (func_80072320(objectIndex, 0x00000020) != 0) { @@ -189,6 +189,105 @@ void OPenguin::Behaviours(s32 objectIndex, s32 arg1) { } } +void OPenguin::func_80084D2C(s32 objectIndex, s32 arg1) { + f32 sp24; + + switch (gObjectList[objectIndex].unk_0AE) { + case 0: + break; + case 1: + gObjectList[objectIndex].direction_angle[1] = + func_800417B4(gObjectList[objectIndex].direction_angle[1], gObjectList[objectIndex].unk_0C6); + if (gObjectList[objectIndex].direction_angle[1] == gObjectList[objectIndex].unk_0C6) { + gObjectList[objectIndex].unk_09C = 4; + gObjectList[objectIndex].unk_034 = 0.4f; + func_80086FD4(objectIndex); + } + break; + case 2: + f32_step_towards(&gObjectList[objectIndex].unk_034, 0.8f, 0.02f); + if (func_80087060(objectIndex, 0x0000000F) != 0) { + func_800722A4(objectIndex, 1); + func_800722A4(objectIndex, 2); + gObjectList[objectIndex].unk_09C = 1; + gObjectList[objectIndex].unk_0D8 = 1; + gObjectList[objectIndex].textureListIndex = 0; + gObjectList[objectIndex].type = + get_animation_length(d_course_sherbet_land_unk_data11, gObjectList[objectIndex].unk_0D8); + func_800726CC(objectIndex, 3); + func_80086FD4(objectIndex); + if (func_80072354(objectIndex, 0x00000020) != 0) { + func_800722A4(objectIndex, 0x00000080); + } + } + break; + case 3: + switch (arg1) { /* switch 1; irregular */ + case 0: /* switch 1 */ + sp24 = 1.0f; + break; + case 1: /* switch 1 */ + sp24 = 1.5f; + break; + case 2: /* switch 1 */ + sp24 = 2.0f; + break; + case 3: /* switch 1 */ + sp24 = 2.5f; + break; + } + f32_step_towards(&gObjectList[objectIndex].unk_034, sp24, 0.15f); + if ((func_80072354(objectIndex, 2) != 0) && (sp24 == gObjectList[objectIndex].unk_034)) { + func_80086FD4(objectIndex); + } + break; + case 4: + if (func_80087060(objectIndex, 0x0000001E) != 0) { + func_800722CC(objectIndex, 1); + func_80086FD4(objectIndex); + } + break; + case 5: + f32_step_towards(&gObjectList[objectIndex].unk_034, 0.4f, 0.2f); + if (func_80087060(objectIndex, 0x0000000A) != 0) { + func_800722A4(objectIndex, 2); + gObjectList[objectIndex].unk_0D8 = 2; + gObjectList[objectIndex].textureListIndex = 0; + gObjectList[objectIndex].type = + get_animation_length(d_course_sherbet_land_unk_data11, gObjectList[objectIndex].unk_0D8); + func_800726CC(objectIndex, 3); + func_80086FD4(objectIndex); + } + break; + case 6: + if (func_80072354(objectIndex, 2) != 0) { + gObjectList[objectIndex].unk_0D8 = 0; + gObjectList[objectIndex].textureListIndex = 0; + gObjectList[objectIndex].type = + get_animation_length(d_course_sherbet_land_unk_data11, gObjectList[objectIndex].unk_0D8); + gObjectList[objectIndex].unk_0C6 += 0x8000; + func_800726CC(objectIndex, 2); + func_8008701C(objectIndex, 1); + } + break; + } + func_8008781C(objectIndex); + object_calculate_new_pos_offset(objectIndex); +} + +void OPenguin::func_80085080(s32 objectIndex) { + func_8008B78C(objectIndex); + object_calculate_new_pos_offset(objectIndex); + func_800873F4(objectIndex); +} + +void OPenguin::func_8008502C(s32 objectIndex, s32 arg1) { + func_80088038(objectIndex, gObjectList[objectIndex].unk_01C[1], gObjectList[objectIndex].unk_0C6); + object_calculate_new_pos_offset(objectIndex); + func_800873F4(objectIndex); +} + + void OPenguin::EmperorPenguin(s32 objectIndex) { switch (gObjectList[objectIndex].state) { case 0: @@ -280,6 +379,8 @@ void OPenguin::InitOtherPenguin(s32 objectIndex) { object->unk_04C = random_int(0x012CU); set_object_flag_status_true(objectIndex, 0x04000220); + // This code has been significantly refactored from the original func_800845C8 + // Into a switch statement instead of checking for the index of the penguin switch(_bhv) { case Behaviour::CIRCLE: object->unk_01C[1] = Diameter; @@ -301,81 +402,6 @@ void OPenguin::InitOtherPenguin(s32 objectIndex) { 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); diff --git a/src/engine/objects/OPenguin.h b/src/engine/objects/OPenguin.h index 111f629ba..5df5ef9ea 100644 --- a/src/engine/objects/OPenguin.h +++ b/src/engine/objects/OPenguin.h @@ -56,10 +56,15 @@ public: private: void Behaviours(s32 objectIndex, s32 arg1); void EmperorPenguin(s32 objectIndex); + void func_80085080(s32 objectIndex); + void func_8008502C(s32 objectIndex, s32 arg1); + void func_80084D2C(s32 objectIndex, s32 arg1); + void InitEmperorPenguin(s32 objectIndex); void OtherPenguin(s32 objectIndex); void InitOtherPenguin(s32 objectIndex); + s32 _idx; PenguinType _type; Behaviour _bhv; diff --git a/src/update_objects.c b/src/update_objects.c index 039ebab87..f06012939 100644 --- a/src/update_objects.c +++ b/src/update_objects.c @@ -6512,367 +6512,6 @@ void func_800842C8(void) { } } -void func_80084430(s32 objectIndex, UNUSED s32 arg1) { - 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_origin_pos(objectIndex, xOrientation * -383.0, 2.0f, -690.0f); - 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 func_8008453C(s32 objectIndex, s32 arg1) { - switch (gObjectList[objectIndex].state) { /* irregular */ - case 0: - break; - case 1: - if (gPlayerCountSelection1 == 1) { - func_80084430(objectIndex, arg1); - } - break; - case 2: - func_80072E54(objectIndex, 0, gObjectList[objectIndex].type, 1, 0, -1); - break; - } -} - -void func_800845C8(s32 objectIndex, s32 arg1) { - 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); - if ((arg1 > 0) && (arg1 < 9)) { - if ((arg1 == 1) || (arg1 == 2)) { - set_obj_origin_pos(objectIndex, xOrientation * -2960.0, -80.0f, 1521.0f); - object->unk_0C6 = 0x0150; - object->unk_01C[1] = 100.0f; - } else if ((arg1 == 3) || (arg1 == 4)) { - set_obj_origin_pos(objectIndex, xOrientation * -2490.0, -80.0f, 1612.0f); - object->unk_0C6 = 0x0100; - object->unk_01C[1] = 80.0f; - } else if ((arg1 == 5) || (arg1 == 6)) { - set_obj_origin_pos(objectIndex, xOrientation * -2098.0, -80.0f, 1624.0f); - object->unk_0C6 = 0xFF00; - object->unk_01C[1] = 80.0f; - } else if ((arg1 == 7) || (arg1 == 8)) { - set_obj_origin_pos(objectIndex, xOrientation * -2080.0, -80.0f, 1171.0f); - object->unk_0C6 = 0x0150; - object->unk_01C[1] = 80.0f; - } - object->unk_0C4 = (arg1 << 0xF) & 0xFFFF; - object->surfaceHeight = -80.0f; - object->sizeScaling = 0.08f; - object->unk_0DD = 2; - func_800722A4(objectIndex, 8); - } else if ((arg1 > 8) && (arg1 < 15)) { - switch (arg1) { /* irregular */ - case 9: - if (gGamestate != 9) { - set_obj_origin_pos(objectIndex, xOrientation * 146.0, 0.0f, -380.0f); - } else { - set_obj_origin_pos(objectIndex, xOrientation * 380.0, 0.0f, -535.0f); - object->sizeScaling = 0.15f; - } - object->unk_0C6 = 0x9000; - if (gIsMirrorMode != 0) { - object->unk_0C6 -= 0x4000; - } - object->unk_0DD = 3; - break; - case 10: - set_obj_origin_pos(objectIndex, xOrientation * 380.0, 0.0f, -766.0f); - object->unk_0C6 = 0x5000; - if (gIsMirrorMode != 0) { - object->unk_0C6 += 0x8000; - } - object->unk_0DD = 4; - break; - case 11: - set_obj_origin_pos(objectIndex, xOrientation * -2300.0, 0.0f, -210.0f); - object->unk_0C6 = 0xC000; - object->unk_0DD = 6; - if (gIsMirrorMode != 0) { - object->unk_0C6 += 0x8000; - } - break; - case 12: - set_obj_origin_pos(objectIndex, xOrientation * -2500.0, 0.0f, -250.0f); - object->unk_0C6 = 0x4000; - object->unk_0DD = 6; - if (gIsMirrorMode != 0) { - object->unk_0C6 += 0x8000; - } - break; - case 13: - set_obj_origin_pos(objectIndex, xOrientation * -535.0, 0.0f, 875.0f); - object->unk_0C6 = 0x8000; - object->unk_0DD = 6; - if (gIsMirrorMode != 0) { - object->unk_0C6 -= 0x4000; - } - break; - case 14: - set_obj_origin_pos(objectIndex, xOrientation * -250.0, 0.0f, 953.0f); - 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); -} - -void func_80084B7C(s32 objectIndex, s32 arg1) { - Object* object; - - object = &gObjectList[objectIndex]; - switch (object->state) { - case 0: - break; - case 1: - func_800845C8(objectIndex, arg1); - 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 func_80084D2C(s32 objectIndex, s32 arg1) { - f32 sp24; - - switch (gObjectList[objectIndex].unk_0AE) { - case 0: - break; - case 1: - gObjectList[objectIndex].direction_angle[1] = - func_800417B4(gObjectList[objectIndex].direction_angle[1], gObjectList[objectIndex].unk_0C6); - if (gObjectList[objectIndex].direction_angle[1] == gObjectList[objectIndex].unk_0C6) { - gObjectList[objectIndex].unk_09C = 4; - gObjectList[objectIndex].unk_034 = 0.4f; - func_80086FD4(objectIndex); - } - break; - case 2: - f32_step_towards(&gObjectList[objectIndex].unk_034, 0.8f, 0.02f); - if (func_80087060(objectIndex, 0x0000000F) != 0) { - func_800722A4(objectIndex, 1); - func_800722A4(objectIndex, 2); - gObjectList[objectIndex].unk_09C = 1; - gObjectList[objectIndex].unk_0D8 = 1; - gObjectList[objectIndex].textureListIndex = 0; - gObjectList[objectIndex].type = - get_animation_length(d_course_sherbet_land_unk_data11, gObjectList[objectIndex].unk_0D8); - func_800726CC(objectIndex, 3); - func_80086FD4(objectIndex); - if (func_80072354(objectIndex, 0x00000020) != 0) { - func_800722A4(objectIndex, 0x00000080); - } - } - break; - case 3: - switch (arg1) { /* switch 1; irregular */ - case 0: /* switch 1 */ - sp24 = 1.0f; - break; - case 1: /* switch 1 */ - sp24 = 1.5f; - break; - case 2: /* switch 1 */ - sp24 = 2.0f; - break; - case 3: /* switch 1 */ - sp24 = 2.5f; - break; - } - f32_step_towards(&gObjectList[objectIndex].unk_034, sp24, 0.15f); - if ((func_80072354(objectIndex, 2) != 0) && (sp24 == gObjectList[objectIndex].unk_034)) { - func_80086FD4(objectIndex); - } - break; - case 4: - if (func_80087060(objectIndex, 0x0000001E) != 0) { - func_800722CC(objectIndex, 1); - func_80086FD4(objectIndex); - } - break; - case 5: - f32_step_towards(&gObjectList[objectIndex].unk_034, 0.4f, 0.2f); - if (func_80087060(objectIndex, 0x0000000A) != 0) { - func_800722A4(objectIndex, 2); - gObjectList[objectIndex].unk_0D8 = 2; - gObjectList[objectIndex].textureListIndex = 0; - gObjectList[objectIndex].type = - get_animation_length(d_course_sherbet_land_unk_data11, gObjectList[objectIndex].unk_0D8); - func_800726CC(objectIndex, 3); - func_80086FD4(objectIndex); - } - break; - case 6: - if (func_80072354(objectIndex, 2) != 0) { - gObjectList[objectIndex].unk_0D8 = 0; - gObjectList[objectIndex].textureListIndex = 0; - gObjectList[objectIndex].type = - get_animation_length(d_course_sherbet_land_unk_data11, gObjectList[objectIndex].unk_0D8); - gObjectList[objectIndex].unk_0C6 += 0x8000; - func_800726CC(objectIndex, 2); - func_8008701C(objectIndex, 1); - } - break; - } - func_8008781C(objectIndex); - object_calculate_new_pos_offset(objectIndex); -} - -void func_80085024(void) { -} - -void func_8008502C(s32 objectIndex, UNUSED s32 arg1) { - func_80088038(objectIndex, gObjectList[objectIndex].unk_01C[1], gObjectList[objectIndex].unk_0C6); - object_calculate_new_pos_offset(objectIndex); - func_800873F4(objectIndex); -} - -void func_80085080(s32 objectIndex) { - func_8008B78C(objectIndex); - object_calculate_new_pos_offset(objectIndex); - func_800873F4(objectIndex); -} - -void func_800850B0(s32 objectIndex, s32 arg1) { - Object* object; - - object = &gObjectList[objectIndex]; - switch (object->unk_0DD) { - case 1: - 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 update_penguins(void) { - UNUSED s32 var_s2; - s32 objectIndex; - s32 var_s1; - - for (var_s1 = 0; var_s1 < NUM_PENGUINS; var_s1++) { - objectIndex = indexObjectList1[var_s1]; - if (gObjectList[objectIndex].state != 0) { - if (var_s1 == 0) { - func_8008453C(objectIndex, var_s1); - } else { - func_80084B7C(objectIndex, var_s1); - } - func_800850B0(objectIndex, var_s1); - } - 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 init_hot_air_balloon(s32 objectIndex) { gObjectList[objectIndex].sizeScaling = 1.0f; gObjectList[objectIndex].model = d_course_luigi_raceway_dl_F960; diff --git a/src/update_objects.h b/src/update_objects.h index b375c59e4..ddaa5b0c1 100644 --- a/src/update_objects.h +++ b/src/update_objects.h @@ -336,7 +336,6 @@ void func_80084430(s32, s32); void func_8008453C(s32, s32); void func_800845C8(s32, s32); void func_80084B7C(s32, s32); -void func_80084D2C(s32, s32); void func_80085024(void); void func_8008502C(s32, s32); void func_80085080(s32); From 95b8cca50025f7fa10e47ca24ac5f71f9813a2e3 Mon Sep 17 00:00:00 2001 From: MegaMech <7255464+MegaMech@users.noreply.github.com> Date: Wed, 11 Dec 2024 20:58:18 -0700 Subject: [PATCH 09/21] Reimplementing objects --- src/code_80057C60.c | 25 +- src/code_80086E70.c | 112 +-- src/data/some_data.c | 4 - src/data/some_data.h | 1 - src/engine/GameObject.cpp | 20 - src/engine/GameObject.h | 24 - src/engine/World.cpp | 37 +- src/engine/World.h | 19 +- src/engine/courses/BansheeBoardwalk.cpp | 2 +- src/engine/courses/BigDonut.cpp | 2 +- src/engine/courses/BlockFort.cpp | 2 +- src/engine/courses/BowsersCastle.cpp | 2 +- src/engine/courses/ChocoMountain.cpp | 2 +- src/engine/courses/DKJungle.cpp | 2 +- src/engine/courses/DoubleDeck.cpp | 2 +- src/engine/courses/FrappeSnowland.cpp | 2 +- src/engine/courses/KalimariDesert.cpp | 2 +- src/engine/courses/KoopaTroopaBeach.cpp | 34 +- src/engine/courses/LuigiRaceway.cpp | 2 +- src/engine/courses/MarioRaceway.cpp | 2 +- src/engine/courses/MooMooFarm.cpp | 55 +- src/engine/courses/MooMooFarm.h | 3 + src/engine/courses/PodiumCeremony.cpp | 2 +- src/engine/courses/RainbowRoad.cpp | 2 +- src/engine/courses/RoyalRaceway.cpp | 2 +- src/engine/courses/SherbetLand.cpp | 4 +- src/engine/courses/Skyscraper.cpp | 2 +- src/engine/courses/TestCourse.cpp | 9 +- src/engine/courses/ToadsTurnpike.cpp | 2 +- src/engine/courses/WarioStadium.cpp | 2 +- src/engine/courses/YoshiValley.cpp | 2 +- .../objects/{OBombKart.cpp => BombKart.cpp} | 6 +- .../objects/{OBombKart.h => BombKart.h} | 0 src/engine/objects/Crab.cpp | 175 +++++ src/engine/objects/Crab.h | 41 ++ src/engine/objects/GameObject.cpp | 20 + src/engine/objects/GameObject.h | 24 + src/engine/objects/Mole.cpp | 422 ++++++++++++ src/engine/objects/Mole.h | 52 ++ .../objects/{OPenguin.cpp => Penguin.cpp} | 8 +- src/engine/objects/{OPenguin.h => Penguin.h} | 13 - src/engine/objects/Seagull.cpp | 194 ++++++ src/engine/objects/Seagull.h | 44 ++ .../objects/{OThwomp.cpp => Thwomp.cpp} | 32 +- src/engine/objects/{OThwomp.h => Thwomp.h} | 0 src/port/Game.cpp | 30 +- src/port/Game.h | 7 + src/render_objects.c | 139 +--- src/render_objects.h | 1 - src/update_objects.c | 646 +++--------------- src/update_objects.h | 4 +- 51 files changed, 1306 insertions(+), 935 deletions(-) delete mode 100644 src/engine/GameObject.cpp delete mode 100644 src/engine/GameObject.h rename src/engine/objects/{OBombKart.cpp => BombKart.cpp} (99%) rename src/engine/objects/{OBombKart.h => BombKart.h} (100%) create mode 100644 src/engine/objects/Crab.cpp create mode 100644 src/engine/objects/Crab.h create mode 100644 src/engine/objects/GameObject.cpp create mode 100644 src/engine/objects/GameObject.h create mode 100644 src/engine/objects/Mole.cpp create mode 100644 src/engine/objects/Mole.h rename src/engine/objects/{OPenguin.cpp => Penguin.cpp} (98%) rename src/engine/objects/{OPenguin.h => Penguin.h} (70%) create mode 100644 src/engine/objects/Seagull.cpp create mode 100644 src/engine/objects/Seagull.h rename src/engine/objects/{OThwomp.cpp => Thwomp.cpp} (98%) rename src/engine/objects/{OThwomp.h => Thwomp.h} (100%) diff --git a/src/code_80057C60.c b/src/code_80057C60.c index 564a32d9d..ee82cd511 100644 --- a/src/code_80057C60.c +++ b/src/code_80057C60.c @@ -700,10 +700,13 @@ void render_player_snow_effect_four(void) { void render_object_for_player(s32 cameraId) { - CourseManager_RenderCourseObjects(cameraId); - CourseManager_TrainSmokeDraw(cameraId); - CourseManager_DrawThwomps(cameraId); - CourseManager_DrawPenguins(cameraId); + CourseManager_DrawObjects(cameraId); + + // CourseManager_RenderCourseObjects(cameraId); + // CourseManager_TrainSmokeDraw(cameraId); + // CourseManager_DrawThwomps(cameraId); + // CourseManager_DrawPenguins(cameraId); + // CourseManager_DrawSeagulls(cameraId); // switch (gCurrentCourseId) { // case COURSE_MARIO_RACEWAY: @@ -1338,7 +1341,6 @@ void func_80059D00(void) { func_80059820(PLAYER_TWO); func_80078C70(2); } - update_object(); break; case SCREEN_MODE_2P_SPLITSCREEN_VERTICAL: randomize_seed_from_controller(PLAYER_ONE); @@ -1357,7 +1359,6 @@ void func_80059D00(void) { } func_80078C70(2); func_8005D1F4(1); - update_object(); break; case SCREEN_MODE_2P_SPLITSCREEN_HORIZONTAL: randomize_seed_from_controller(PLAYER_ONE); @@ -1376,7 +1377,6 @@ void func_80059D00(void) { } func_80078C70(4); func_8005D1F4(1); - update_object(); break; case SCREEN_MODE_3P_4P_SPLITSCREEN: randomize_seed_from_controller(PLAYER_ONE); @@ -1409,9 +1409,9 @@ void func_80059D00(void) { } func_8005D1F4(3); } - update_object(); break; } + CourseManager_TickObjects(); func_800744CC(); } } @@ -1431,7 +1431,7 @@ void func_8005A070(void) { } else if (gGamestate == CREDITS_SEQUENCE) { func_80059820(PLAYER_ONE); func_80078C70(0); - update_object(); + CourseManager_TickObjects(); } else { func_80059D00(); } @@ -1579,9 +1579,10 @@ void func_8005A71C(void) { void update_object(void) { - CourseManager_UpdateCourseObjects(); - CourseManager_TrainSmokeTick(); - CourseManager_TickPenguins(); + // CourseManager_UpdateCourseObjects(); + // CourseManager_TrainSmokeTick(); + // CourseManager_TickPenguins(); + // CourseManager_TickSeagulls(); // switch (gCurrentCourseId) { // case COURSE_MARIO_RACEWAY: diff --git a/src/code_80086E70.c b/src/code_80086E70.c index 4f3393944..490e8e32c 100644 --- a/src/code_80086E70.c +++ b/src/code_80086E70.c @@ -19,13 +19,13 @@ void func_80086E70(s32 objectIndex) { gObjectList[objectIndex].unk_0AE = 1; // * 0xE0)) = 1; - set_object_flag_status_false(objectIndex, 8); + clear_object_flag(objectIndex, 8); } void func_80086EAC(s32 objectIndex, s32 arg1, s16 arg2) { gObjectList[objectIndex].unk_0DD = arg1; gObjectList[objectIndex].unk_0AE = arg2; - set_object_flag_status_false(objectIndex, 8); + clear_object_flag(objectIndex, 8); } void func_80086EF0(s32 objectIndex) { @@ -42,7 +42,7 @@ void func_80086F60(s32 objectIndex) { gObjectList[objectIndex].unk_0AE = 0; gObjectList[objectIndex].unk_0DD = 0; gObjectList[objectIndex].unk_0DE = 0; - set_object_flag_status_false(objectIndex, 8); + clear_object_flag(objectIndex, 8); } bool func_80086FA4(s32 objectIndex) { @@ -54,12 +54,12 @@ bool func_80086FA4(s32 objectIndex) { } void func_80086FD4(s32 objectIndex) { - set_object_flag_status_false(objectIndex, 8); + clear_object_flag(objectIndex, 8); gObjectList[objectIndex].unk_0AE += 1; } void func_8008701C(s32 objectIndex, s32 arg1) { - set_object_flag_status_false(objectIndex, 8); + clear_object_flag(objectIndex, 8); gObjectList[objectIndex].unk_0AE = arg1; } @@ -68,12 +68,12 @@ s32 func_80087060(s32 objectIndex, s32 arg1) { sp1C = 0; if (is_obj_index_flag_status_inactive(objectIndex, 8) != false) { - set_object_flag_status_true(objectIndex, 8); + set_object_flag(objectIndex, 8); gObjectList[objectIndex].unk_0B0 = arg1; } gObjectList[objectIndex].unk_0B0--; if (gObjectList[objectIndex].unk_0B0 < 0) { - set_object_flag_status_false(objectIndex, 8); + clear_object_flag(objectIndex, 8); sp1C = 1; } return sp1C; @@ -84,12 +84,12 @@ s32 func_80087104(s32 objectIndex, u16 arg1) { sp24 = 0; if (is_obj_index_flag_status_inactive(objectIndex, 8) != false) { - set_object_flag_status_true(objectIndex, 8); + set_object_flag(objectIndex, 8); gObjectList[objectIndex].unk_0B0 = random_int(arg1); } gObjectList[objectIndex].unk_0B0--; if (gObjectList[objectIndex].unk_0B0 < 0) { - set_object_flag_status_false(objectIndex, 8); + clear_object_flag(objectIndex, 8); sp24 = 1; } return sp24; @@ -100,12 +100,12 @@ s32 func_800871AC(s32 objectIndex, s32 arg1) { sp24 = 0; if (is_obj_index_flag_status_inactive(objectIndex, 8) != false) { - set_object_flag_status_true(objectIndex, 8); + set_object_flag(objectIndex, 8); gObjectList[objectIndex].unk_0B0 = (s16) arg1; } gObjectList[objectIndex].unk_0B0--; if (gObjectList[objectIndex].unk_0B0 < 0) { - set_object_flag_status_false(objectIndex, 8); + clear_object_flag(objectIndex, 8); func_80086FD4(objectIndex); sp24 = 1; } @@ -235,13 +235,13 @@ s32 func_8008789C(s32 objectIndex, s32 arg1) { sp24 = 0; if (is_obj_index_flag_status_inactive(objectIndex, 8) != false) { - set_object_flag_status_true(objectIndex, 8); + set_object_flag(objectIndex, 8); func_8008751C(objectIndex); gObjectList[objectIndex].unk_0B0 = arg1; } gObjectList[objectIndex].unk_0B0--; if (gObjectList[objectIndex].unk_0B0 < 0) { - set_object_flag_status_false(objectIndex, 8); + clear_object_flag(objectIndex, 8); sp24 = 1; } else { object_add_velocity_offset_xz(objectIndex); @@ -254,13 +254,13 @@ s32 func_80087954(s32 objectIndex, s32 arg1) { sp24 = 0; if (is_obj_index_flag_status_inactive(objectIndex, 8) != false) { - set_object_flag_status_true(objectIndex, 8); + set_object_flag(objectIndex, 8); func_80087620(objectIndex); gObjectList[objectIndex].unk_0B0 = arg1; } gObjectList[objectIndex].unk_0B0--; if (gObjectList[objectIndex].unk_0B0 < 0) { - set_object_flag_status_false(objectIndex, 8); + clear_object_flag(objectIndex, 8); sp24 = 1; } else { object_add_velocity_offset_xz(objectIndex); @@ -276,7 +276,7 @@ bool func_80087A0C(s32 objectIndex, s16 arg1, s16 arg2, s16 arg3, s16 arg4) { sp2C = false; if (is_obj_index_flag_status_inactive(objectIndex, 8) != false) { - set_object_flag_status_true(objectIndex, 8); + set_object_flag(objectIndex, 8); temp_v0 = arg2 - arg1; temp_a0 = arg4 - arg3; dist = sqrtf((temp_v0 * temp_v0) + (temp_a0 * temp_a0)); @@ -287,7 +287,7 @@ bool func_80087A0C(s32 objectIndex, s16 arg1, s16 arg2, s16 arg3, s16 arg4) { } gObjectList[objectIndex].unk_0B0--; if (gObjectList[objectIndex].unk_0B0 < 0) { - set_object_flag_status_false(objectIndex, 8); + clear_object_flag(objectIndex, 8); sp2C = true; } else { object_add_velocity_offset_xz(objectIndex); @@ -300,12 +300,12 @@ s32 func_80087B84(s32 objectIndex, f32 arg1, f32 arg2) { sp24 = 0; if (is_obj_index_flag_status_inactive(objectIndex, 8) != false) { - set_object_flag_status_true(objectIndex, 8); + set_object_flag(objectIndex, 8); gObjectList[objectIndex].velocity[1] = -arg1; } object_add_velocity_offset_y(objectIndex); if (gObjectList[objectIndex].pos[1] <= arg2) { - set_object_flag_status_false(objectIndex, 8); + clear_object_flag(objectIndex, 8); func_80086FD4(objectIndex); sp24 = 1; } @@ -317,13 +317,13 @@ s32 func_80087C48(s32 objectIndex, f32 arg1, f32 arg2, s32 arg3) { sp24 = 0; if (is_obj_index_flag_status_inactive(objectIndex, 8) != false) { - set_object_flag_status_true(objectIndex, 8); + set_object_flag(objectIndex, 8); gObjectList[objectIndex].velocity[1] = arg1; gObjectList[objectIndex].unk_0B0 = (s16) arg3; } gObjectList[objectIndex].unk_0B0--; if (gObjectList[objectIndex].unk_0B0 < 0) { - set_object_flag_status_false(objectIndex, 8); + clear_object_flag(objectIndex, 8); func_80086FD4(objectIndex); sp24 = 1; } else { @@ -338,13 +338,13 @@ s32 func_80087D24(s32 objectIndex, f32 arg1, f32 arg2, f32 arg3) { sp24 = 0; if (is_obj_index_flag_status_inactive(objectIndex, 8) != 0) { - set_object_flag_status_true(objectIndex, 8); + set_object_flag(objectIndex, 8); gObjectList[objectIndex].velocity[1] = arg1; } gObjectList[objectIndex].velocity[1] -= arg2; object_add_velocity_offset_y(objectIndex); if (gObjectList[objectIndex].offset[1] <= arg3) { - set_object_flag_status_false(objectIndex, 8); + clear_object_flag(objectIndex, 8); gObjectList[objectIndex].offset[1] = arg3; func_80086FD4(objectIndex); sp24 = 1; @@ -358,7 +358,7 @@ bool func_80087E08(s32 objectIndex, f32 arg1, f32 arg2, f32 arg3, s16 arg4, s32 sp2C = false; if (is_obj_index_flag_status_inactive(objectIndex, 8) != 0) { - set_object_flag_status_true(objectIndex, 8); + set_object_flag(objectIndex, 8); gObjectList[objectIndex].offset[2] = 0.0f; gObjectList[objectIndex].offset[1] = 0.0f; gObjectList[objectIndex].offset[0] = 0.0f; @@ -370,7 +370,7 @@ bool func_80087E08(s32 objectIndex, f32 arg1, f32 arg2, f32 arg3, s16 arg4, s32 } gObjectList[objectIndex].unk_0B0--; if (gObjectList[objectIndex].unk_0B0 < 0) { - set_object_flag_status_false(objectIndex, 8); + clear_object_flag(objectIndex, 8); func_80086FD4(objectIndex); sp2C = true; } else { @@ -386,7 +386,7 @@ UNUSED s32 func_80087F14(s32 objectIndex, f32 arg1, f32 arg2, f32 arg3, s16 arg4 sp2C = 0; if (is_obj_index_flag_status_inactive(objectIndex, 8) != 0) { - set_object_flag_status_true(objectIndex, 8); + set_object_flag(objectIndex, 8); gObjectList[objectIndex].offset[2] = 0.0f; gObjectList[objectIndex].offset[1] = 0.0f; gObjectList[objectIndex].offset[0] = 0.0f; @@ -397,7 +397,7 @@ UNUSED s32 func_80087F14(s32 objectIndex, f32 arg1, f32 arg2, f32 arg3, s16 arg4 gObjectList[objectIndex].unk_0B0 = gVBlankTimer; } if (gObjectList[objectIndex].offset[1] <= arg5) { - set_object_flag_status_false(objectIndex, 8); + clear_object_flag(objectIndex, 8); func_80086FD4(objectIndex); sp2C = 1; } else { @@ -526,13 +526,13 @@ s32 func_8008847C(s32 objectIndex) { s32 sp2C; sp2C = 0; - set_object_flag_status_false(objectIndex, 0x00800000); + clear_object_flag(objectIndex, 0x00800000); if (is_obj_flag_status_active(objectIndex, 0x00000400) != 0) { check_bounding_collision(&D_8018C3B0, 10.0f, gObjectList[objectIndex].pos[0], 20.0f, gObjectList[objectIndex].pos[2]); if (D_8018C3B0.unk34 == 1) { sp2C = 1; - set_object_flag_status_true(objectIndex, 0x00800000); + set_object_flag(objectIndex, 0x00800000); } gObjectList[objectIndex].surfaceHeight = calculate_surface_height( gObjectList[objectIndex].pos[0], 0.0f, gObjectList[objectIndex].pos[2], D_8018C3B0.meshIndexZX); @@ -544,13 +544,13 @@ s32 func_80088538(s32 objectIndex) { s32 sp2C; sp2C = 0; - set_object_flag_status_false(objectIndex, 0x00800000); + clear_object_flag(objectIndex, 0x00800000); if (is_obj_flag_status_active(objectIndex, 0x00000400) != 0) { check_bounding_collision(&D_8018C3B0, 10.0f, gObjectList[objectIndex].pos[0], 20.0f, gObjectList[objectIndex].pos[2]); if (D_8018C3B0.unk34 == 1) { sp2C = 1; - set_object_flag_status_true(objectIndex, 0x00800000); + set_object_flag(objectIndex, 0x00800000); } gObjectList[objectIndex].surfaceHeight = calculate_surface_height( gObjectList[objectIndex].pos[0], 0.0f, gObjectList[objectIndex].pos[2], D_8018C3B0.meshIndexZX); @@ -565,13 +565,13 @@ s32 func_8008861C(s32 objectIndex) { s32 sp2C; sp2C = 0; - set_object_flag_status_false(objectIndex, 0x00800000); + clear_object_flag(objectIndex, 0x00800000); if (is_obj_flag_status_active(objectIndex, 0x00000400) != 0) { check_bounding_collision(&D_8018C3B0, 10.0f, gObjectList[objectIndex].pos[0], 20.0f, gObjectList[objectIndex].pos[2]); if (D_8018C3B0.unk34 == 1) { sp2C = 1; - set_object_flag_status_true(objectIndex, 0x00800000); + set_object_flag(objectIndex, 0x00800000); } gObjectList[objectIndex].surfaceHeight = calculate_surface_height( gObjectList[objectIndex].pos[0], 0.0f, gObjectList[objectIndex].pos[2], D_8018C3B0.meshIndexZX); @@ -586,7 +586,7 @@ void func_800886F4(s32 objectIndex) { check_bounding_collision(&D_8018C3B0, 10.0f, gObjectList[objectIndex].pos[0], 20.0f, gObjectList[objectIndex].pos[2]); if (D_8018C3B0.unk34 == 1) { - set_object_flag_status_true(objectIndex, 0x00800000); + set_object_flag(objectIndex, 0x00800000); gObjectList[objectIndex].surfaceHeight = calculate_surface_height( gObjectList[objectIndex].pos[0], 0.0f, gObjectList[objectIndex].pos[2], D_8018C3B0.meshIndexZX); gObjectList[objectIndex].unk_0B8[0] = @@ -594,14 +594,14 @@ void func_800886F4(s32 objectIndex) { gObjectList[objectIndex].unk_0B8[2] = atan2s(D_8018C3B0.orientationVector[0], D_8018C3B0.orientationVector[1]); return; } - set_object_flag_status_false(objectIndex, 0x00800000); + clear_object_flag(objectIndex, 0x00800000); } void func_800887C0(s32 objectIndex) { check_bounding_collision(&D_8018C3B0, 10.0f, gObjectList[objectIndex].pos[0], 20.0f, gObjectList[objectIndex].pos[2]); if (D_8018C3B0.unk34 == 1) { - set_object_flag_status_true(objectIndex, 0x00800000); + set_object_flag(objectIndex, 0x00800000); gObjectList[objectIndex].surfaceHeight = calculate_surface_height( gObjectList[objectIndex].pos[0], 0.0f, gObjectList[objectIndex].pos[2], D_8018C3B0.meshIndexZX); gObjectList[objectIndex].velocity[0] = D_8018C3B0.orientationVector[0]; @@ -609,7 +609,7 @@ void func_800887C0(s32 objectIndex) { gObjectList[objectIndex].velocity[2] = D_8018C3B0.orientationVector[2]; return; } - set_object_flag_status_false(objectIndex, 0x00800000); + clear_object_flag(objectIndex, 0x00800000); } /** @@ -1131,14 +1131,14 @@ void func_80089820(s32 objectIndex, f32 arg1, f32 arg2, u32 arg3) { s32 var_s1; player = gPlayerOne; - set_object_flag_status_false(objectIndex, 0x02000000); + clear_object_flag(objectIndex, 0x02000000); if (is_obj_flag_status_active(objectIndex, 0x00000200) != 0) { for (var_s1 = 0; var_s1 < D_8018D158; var_s1++, player++) { if ((gObjectList[objectIndex].state != 0) && !(player->effects & BOO_EFFECT)) { if ((player->type & PLAYER_EXISTS) && !(player->type & PLAYER_INVISIBLE_OR_BOMB) && (has_collided_horizontally_with_player(objectIndex, player) != 0)) { if (player->effects & STAR_EFFECT) { - set_object_flag_status_true(objectIndex, 0x02000000); + set_object_flag(objectIndex, 0x02000000); } else { if (is_obj_flag_status_active(objectIndex, 0x04000000) != 0) { func_80072180(); @@ -1328,7 +1328,7 @@ void func_8008A1D0(s32 objectIndex, s32 cameraId, s32 arg2, s32 arg3) { Camera* camera; camera = &camera1[cameraId]; - set_object_flag_status_false(objectIndex, 0x00100000 | VISIBLE); + clear_object_flag(objectIndex, 0x00100000 | VISIBLE); temp_v0 = get_horizontal_distance_to_camera(objectIndex, camera); if (CVarGetInteger("gNoCulling", 0) == 1) { temp_v0 = MIN(temp_v0, arg3 * arg3); @@ -1341,9 +1341,9 @@ void func_8008A1D0(s32 objectIndex, s32 cameraId, s32 arg2, s32 arg3) { var_a2 = 0x2AAB; } if ((is_object_visible_on_camera(objectIndex, camera, var_a2) != 0) && ((u32) (arg3 * arg3) >= temp_v0)) { - set_object_flag_status_true(objectIndex, VISIBLE); + set_object_flag(objectIndex, VISIBLE); if (temp_v0 >= (u32) (arg2 * arg2)) { - set_object_flag_status_true(objectIndex, 0x00100000); + set_object_flag(objectIndex, 0x00100000); } } } @@ -1355,7 +1355,7 @@ UNUSED void func_8008A2CC(s32 objectIndex, s32 cameraId, u16 arg2) { u16 var_a2; camera = &camera1[cameraId]; - set_object_flag_status_false(objectIndex, VISIBLE); + clear_object_flag(objectIndex, VISIBLE); if (no_init < 0x2711U) { var_a2 = 0x5555; } else if (no_init < 0x9C41U) { @@ -1364,7 +1364,7 @@ UNUSED void func_8008A2CC(s32 objectIndex, s32 cameraId, u16 arg2) { var_a2 = arg2; } if (is_object_visible_on_camera(objectIndex, camera, var_a2) != 0) { - set_object_flag_status_true(objectIndex, VISIBLE); + set_object_flag(objectIndex, VISIBLE); } } @@ -1374,13 +1374,13 @@ s32 func_8008A364(s32 objectIndex, s32 cameraId, u16 arg2, s32 arg3) { u16 var_a2; camera = &camera1[cameraId]; - set_object_flag_status_false(objectIndex, 0x00020000 | VISIBLE); + clear_object_flag(objectIndex, 0x00020000 | VISIBLE); dist = get_horizontal_distance_to_camera(objectIndex, camera); if (CVarGetInteger("gNoCulling", 0) == 1) { dist = MIN(dist, (arg3 * arg3) - 1); } if (dist < (arg3 * arg3)) { - set_object_flag_status_true(objectIndex, 0x00020000); + set_object_flag(objectIndex, 0x00020000); if (dist < 0x2711U) { var_a2 = 0x5555; } else if (dist < 0x9C41U) { @@ -1389,7 +1389,7 @@ s32 func_8008A364(s32 objectIndex, s32 cameraId, u16 arg2, s32 arg3) { var_a2 = arg2; } if (is_object_visible_on_camera(objectIndex, camera, var_a2) != 0) { - set_object_flag_status_true(objectIndex, VISIBLE); + set_object_flag(objectIndex, VISIBLE); } } return dist; @@ -1397,9 +1397,9 @@ s32 func_8008A364(s32 objectIndex, s32 cameraId, u16 arg2, s32 arg3) { void func_8008A454(s32 objectIndex, s32 cameraId, s32 arg2) { if (get_horizontal_distance_to_camera(objectIndex, &camera1[cameraId]) < (u32) (arg2 * arg2)) { - set_object_flag_status_true(objectIndex, 0x00000020); + set_object_flag(objectIndex, 0x00000020); } else { - set_object_flag_status_false(objectIndex, 0x00000020); + clear_object_flag(objectIndex, 0x00000020); } } @@ -1407,10 +1407,10 @@ UNUSED void func_8008A610(s32 objectIndex) { s32 loopIndex; Camera* camera; - set_object_flag_status_false(objectIndex, VISIBLE); + clear_object_flag(objectIndex, VISIBLE); for (camera = camera1, loopIndex = 0; loopIndex < gPlayerCountSelection1; loopIndex++, camera++) { if ((gObjectList[objectIndex].state != 0) && (is_object_visible_on_camera(objectIndex, camera, 0x2AABU) != 0)) { - set_object_flag_status_true(objectIndex, VISIBLE); + set_object_flag(objectIndex, VISIBLE); } } } @@ -1420,18 +1420,18 @@ void func_8008A6DC(s32 objectIndex, f32 arg1) { s32 loopIndex; Camera* camera; - set_object_flag_status_false(objectIndex, 0x00060000); + clear_object_flag(objectIndex, 0x00060000); for (camera = camera1, loopIndex = 0; loopIndex < gPlayerCountSelection1; loopIndex++, camera++) { if ((gObjectList[objectIndex].state != 0) && (is_within_horizontal_distance_to_camera(objectIndex, camera, arg1) != 0)) { - set_object_flag_status_true(objectIndex, 0x00020000); + set_object_flag(objectIndex, 0x00020000); if (arg1 <= 500.0) { var_a2 = 0x4000; } else { var_a2 = 0x2AAB; } if (is_object_visible_on_camera(objectIndex, camera, var_a2) != 0) { - set_object_flag_status_true(objectIndex, VISIBLE); + set_object_flag(objectIndex, VISIBLE); } } } @@ -1723,7 +1723,7 @@ void func_8008B3E4(s32 objectIndex) { */ object->unk_084[8] = *(((s16*) object->controlPoints) - 1); - set_object_flag_status_true(objectIndex, 8); + set_object_flag(objectIndex, 8); } } @@ -1790,7 +1790,7 @@ void func_8008B6A4(s32 objectIndex) { // Have to do it this way due to the u16 cast object->unk_084[9] = (u16) object->unk_084[9] + 1; if ((u16) object->unk_084[9] == (u16) object->unk_084[8]) { - set_object_flag_status_false(objectIndex, 8); + clear_object_flag(objectIndex, 8); } else { func_8008B44C(objectIndex); } diff --git a/src/data/some_data.c b/src/data/some_data.c index 3b01da911..431e60247 100644 --- a/src/data/some_data.c +++ b/src/data/some_data.c @@ -561,10 +561,6 @@ SplineData D_800E6280 = { 0x0016, { { 0xffce, 0x00aa, 0xfe0c }, 0x0028 }, } }; -// Note the use of the plain SplineData type here. Since these are pointers, we don't care -// about their internal array size -SplineData* D_800E633C[] = { &D_800E6034, &D_800E60F0, &D_800E61B4, &D_800E6280 }; - // Might be Cheep Cheep related? Vec3s D_800E634C[] = { { 0xf37e, 0x0013, 0xfe22 }, diff --git a/src/data/some_data.h b/src/data/some_data.h index dc56a53fd..90b9b13ac 100644 --- a/src/data/some_data.h +++ b/src/data/some_data.h @@ -60,7 +60,6 @@ extern SplineData D_800E6034; extern SplineData D_800E60F0; extern SplineData D_800E61B4; extern SplineData D_800E6280; -extern SplineData* D_800E633C[]; extern Vec3s D_800E634C[]; extern MoleSpawnUnion gMoleSpawns; extern SplineData D_800E641C; diff --git a/src/engine/GameObject.cpp b/src/engine/GameObject.cpp deleted file mode 100644 index fc7c03344..000000000 --- a/src/engine/GameObject.cpp +++ /dev/null @@ -1,20 +0,0 @@ -// #include -// #include "GameObject.h" - -// #include "World.h" - -// extern "C" { -// #include "camera.h" -// } - - -// //GameActor() - -// GameObject::GameObject() {} - -// // Virtual functions to be overridden by derived classes -// void GameObject::Tick() { } -// void GameObject::Draw(Camera* camera) { } -// void GameObject::Collision() {} -// void GameObject::Expire() { } -// void GameObject::Destroy() { } diff --git a/src/engine/GameObject.h b/src/engine/GameObject.h deleted file mode 100644 index b6ac8c559..000000000 --- a/src/engine/GameObject.h +++ /dev/null @@ -1,24 +0,0 @@ -// #pragma once - -// #include - -// extern "C" { -// #include "camera.h" -// #include "objects.h" -// } - -// class GameObject { -// public: -// uint8_t uuid[16]; -// Object o; - -// virtual ~GameObject() = default; - -// explicit GameObject(); - -// virtual void Tick(); -// virtual void Draw(Camera* camera); -// virtual void Collision(); -// virtual void Expire(); -// virtual void Destroy(); -// }; diff --git a/src/engine/World.cpp b/src/engine/World.cpp index ecaad485d..ead375a24 100644 --- a/src/engine/World.cpp +++ b/src/engine/World.cpp @@ -9,11 +9,11 @@ #include "vehicles/Bus.h" #include "vehicles/TankerTruck.h" #include "vehicles/Car.h" -#include "objects/OBombKart.h" -#include "objects/OPenguin.h" +#include "objects/BombKart.h" +#include "objects/Penguin.h" #include "TrainCrossing.h" #include -//#include "objects/GameObject.h" +#include "objects/GameObject.h" extern "C" { #include "camera.h" @@ -49,6 +49,7 @@ static size_t cars; static size_t boats; static size_t thwomps; static size_t penguins; +static size_t seagulls; /** * Note that you can only remove the tender if there are no carriages @@ -113,6 +114,13 @@ std::shared_ptr World::AddPenguin(Vec3f pos, u16 direction, OPenguin:: return penguin; } +std::shared_ptr World::AddSeagull(Vec3f pos) { + auto seagull = std::make_shared(seagulls, pos); + Seagulls.push_back(seagull); + seagulls++; + return seagull; +} + u32 World::GetCupIndex() { return this->CupIndex; } @@ -185,12 +193,6 @@ void World::PreviousCourse() { gWorldInstance.CurrentCourse = Courses[CourseIndex]; } -// Object* World::AddObject(std::unique_ptr object) { -// GameObject* rawPtr = object.get(); -// GameObjects.push_back(std::move(object)); -// return &rawPtr->o; -// } - AActor* World::AddActor(AActor* actor) { Actors.push_back(actor); return Actors.back(); @@ -240,16 +242,21 @@ void RemoveExpiredActors() { // Actors.end()); } +GameObject* World::AddObject(GameObject* object) { + Objects.push_back(object); + return Objects.back(); +} + void World::TickObjects() { - //for (const auto& object : this->GameObjects) { - // object->Tick(); - //} + for (const auto& object : Objects) { + object->Tick(); + } } void World::DrawObjects(Camera *camera) { - //for (const auto& object : this->GameObjects) { - // object->Draw(camera); - //} + for (const auto& object : Objects) { + object->Draw(camera); + } } void World::ExpiredObjects() { diff --git a/src/engine/World.h b/src/engine/World.h index 0df9e7278..2ae4462f4 100644 --- a/src/engine/World.h +++ b/src/engine/World.h @@ -1,16 +1,17 @@ #pragma once #include -//#include "objects/GameObject.h" +#include "objects/GameObject.h" #include "Cup.h" #include "vehicles/Vehicle.h" #include "vehicles/Train.h" #include "vehicles/Car.h" -#include "objects/OBombKart.h" +#include "objects/BombKart.h" #include "vehicles/Train.h" #include "TrainCrossing.h" -#include "objects/OThwomp.h" -#include "objects/OPenguin.h" +#include "objects/Thwomp.h" +#include "objects/Penguin.h" +#include "objects/Seagull.h" #include #include "Actor.h" @@ -20,7 +21,7 @@ extern "C" { #include "engine/Engine.h" }; -//class GameObject; +class GameObject; class Cup; // <-- Forward declaration class Course; class AVehicle; @@ -28,6 +29,7 @@ class ATrain; class ACar; class TrainCrossing; class OThwomp; +class OSeagull; class World { @@ -93,7 +95,7 @@ public: AActor* ConvertActorToAActor(Actor* actor); Actor* ConvertAActorToActor(AActor* actor); -// Object* AddObject(std::unique_ptr object); + GameObject* AddObject(GameObject* object); CProperties* GetCourseProps(); void TickObjects(); @@ -129,7 +131,7 @@ public: size_t CupIndex = 1; std::vector Actors; -// std::vector> GameObjects; + std::vector Objects; /** Actors */ void AddBoat(f32 speed, uint32_t waypoint); @@ -151,6 +153,9 @@ public: std::vector> Penguins; std::shared_ptr AddPenguin(Vec3f pos, u16 direction, OPenguin::PenguinType type, OPenguin::Behaviour behaviour); + std::vector> Seagulls; + std::shared_ptr AddSeagull(Vec3f pos); + TrainCrossing* AddCrossing(Vec3f position, u32 waypointMin, u32 waypointMax, f32 approachRadius, f32 exitRadius); std::vector> Crossings; diff --git a/src/engine/courses/BansheeBoardwalk.cpp b/src/engine/courses/BansheeBoardwalk.cpp index 04ed6caf0..9983ac0b7 100644 --- a/src/engine/courses/BansheeBoardwalk.cpp +++ b/src/engine/courses/BansheeBoardwalk.cpp @@ -6,7 +6,7 @@ #include "BansheeBoardwalk.h" #include "World.h" #include "engine/actors/AFinishline.h" -#include "engine/objects/OBombKart.h" +#include "engine/objects/BombKart.h" #include "assets/banshee_boardwalk_data.h" #include "assets/boo_frames.h" diff --git a/src/engine/courses/BigDonut.cpp b/src/engine/courses/BigDonut.cpp index d4597fe7b..c3abe1add 100644 --- a/src/engine/courses/BigDonut.cpp +++ b/src/engine/courses/BigDonut.cpp @@ -5,7 +5,7 @@ #include "BigDonut.h" #include "World.h" -#include "engine/objects/OBombKart.h" +#include "engine/objects/BombKart.h" #include "assets/big_donut_data.h" extern "C" { diff --git a/src/engine/courses/BlockFort.cpp b/src/engine/courses/BlockFort.cpp index 6178dcc5c..948eaf5e0 100644 --- a/src/engine/courses/BlockFort.cpp +++ b/src/engine/courses/BlockFort.cpp @@ -5,7 +5,7 @@ #include "BlockFort.h" #include "World.h" -#include "engine/objects/OBombKart.h" +#include "engine/objects/BombKart.h" #include "assets/block_fort_data.h" extern "C" { diff --git a/src/engine/courses/BowsersCastle.cpp b/src/engine/courses/BowsersCastle.cpp index 9e9c85d61..d5766b668 100644 --- a/src/engine/courses/BowsersCastle.cpp +++ b/src/engine/courses/BowsersCastle.cpp @@ -6,7 +6,7 @@ #include "BowsersCastle.h" #include "World.h" #include "engine/actors/AFinishline.h" -#include "engine/objects/OBombKart.h" +#include "engine/objects/BombKart.h" #include "bowsers_castle_data.h" extern "C" { diff --git a/src/engine/courses/ChocoMountain.cpp b/src/engine/courses/ChocoMountain.cpp index b497b2431..292d12076 100644 --- a/src/engine/courses/ChocoMountain.cpp +++ b/src/engine/courses/ChocoMountain.cpp @@ -5,7 +5,7 @@ #include "ChocoMountain.h" #include "World.h" -#include "engine/objects/OBombKart.h" +#include "engine/objects/BombKart.h" #include "choco_mountain_data.h" #include "engine/actors/AFinishline.h" diff --git a/src/engine/courses/DKJungle.cpp b/src/engine/courses/DKJungle.cpp index ccf2af4b9..941ccdb22 100644 --- a/src/engine/courses/DKJungle.cpp +++ b/src/engine/courses/DKJungle.cpp @@ -6,7 +6,7 @@ #include "DKJungle.h" #include "World.h" #include "engine/actors/AFinishline.h" -#include "engine/objects/OBombKart.h" +#include "engine/objects/BombKart.h" #include "assets/dks_jungle_parkway_data.h" #include "engine/vehicles/Utils.h" diff --git a/src/engine/courses/DoubleDeck.cpp b/src/engine/courses/DoubleDeck.cpp index 37064a059..d5fe16763 100644 --- a/src/engine/courses/DoubleDeck.cpp +++ b/src/engine/courses/DoubleDeck.cpp @@ -5,7 +5,7 @@ #include "DoubleDeck.h" #include "World.h" -#include "engine/objects/OBombKart.h" +#include "engine/objects/BombKart.h" #include "assets/double_deck_data.h" extern "C" { diff --git a/src/engine/courses/FrappeSnowland.cpp b/src/engine/courses/FrappeSnowland.cpp index 23fa73460..9095a19d0 100644 --- a/src/engine/courses/FrappeSnowland.cpp +++ b/src/engine/courses/FrappeSnowland.cpp @@ -6,7 +6,7 @@ #include "FrappeSnowland.h" #include "World.h" #include "engine/actors/AFinishline.h" -#include "engine/objects/OBombKart.h" +#include "engine/objects/BombKart.h" #include "assets/frappe_snowland_data.h" #include "assets/boo_frames.h" diff --git a/src/engine/courses/KalimariDesert.cpp b/src/engine/courses/KalimariDesert.cpp index 405abbce4..2440e8b01 100644 --- a/src/engine/courses/KalimariDesert.cpp +++ b/src/engine/courses/KalimariDesert.cpp @@ -6,7 +6,7 @@ #include "KalimariDesert.h" #include "World.h" #include "engine/actors/AFinishline.h" -#include "engine/objects/OBombKart.h" +#include "engine/objects/BombKart.h" #include "kalimari_desert_data.h" #include "engine/vehicles/Utils.h" diff --git a/src/engine/courses/KoopaTroopaBeach.cpp b/src/engine/courses/KoopaTroopaBeach.cpp index 7fe30085b..eb4c3c45f 100644 --- a/src/engine/courses/KoopaTroopaBeach.cpp +++ b/src/engine/courses/KoopaTroopaBeach.cpp @@ -6,7 +6,7 @@ #include "KoopaTroopaBeach.h" #include "World.h" #include "engine/actors/AFinishline.h" -#include "engine/objects/OBombKart.h" +#include "engine/objects/BombKart.h" #include "assets/koopa_troopa_beach_data.h" extern "C" { @@ -185,37 +185,45 @@ void KoopaTroopaBeach::InitCourseObjects() { gObjectList[objectId].unk_01C[2] = gCrabSpawns[i].patrolZ; } } - for (i = 0; i < NUM_SEAGULLS; i++) { - objectId = indexObjectList2[i]; - init_object(objectId, 0); - if (i < (NUM_SEAGULLS / 2)) { - gObjectList[objectId].unk_0D5 = 0; - } else { - gObjectList[objectId].unk_0D5 = 1; + + if (gGamestate == CREDITS_SEQUENCE) { + Vec3f pos = {-360.0f, 60.0f, -1300.0f}; + for (size_t i = 0; i < NUM_SEAGULLS; i++) { + gWorldInstance.AddSeagull(pos); + } + } else { // Normal gameplay + Vec3f pos = {-985.0f, 15.0f, 1200.0f}; + for (size_t i = 0; i < 4; i++) { + gWorldInstance.AddSeagull(pos); + } + + Vec3f pos2 = {328.0f, 20.0f, 2541.0f}; + for (size_t i = 0; i < 6; i++) { + gWorldInstance.AddSeagull(pos2); } } } void KoopaTroopaBeach::UpdateCourseObjects() { if (gGamestate != CREDITS_SEQUENCE) { - update_crabs(); + //update_crabs(); } if ((gPlayerCount == 1) || (gPlayerCount == 2) || (gGamestate == CREDITS_SEQUENCE)) { - update_seagulls(); + //update_seagulls(); } } void KoopaTroopaBeach::RenderCourseObjects(s32 cameraId) { if (gGamestate != CREDITS_SEQUENCE) { - render_object_crabs(cameraId); + //render_object_crabs(cameraId); } if (gGamestate != CREDITS_SEQUENCE) { if ((gPlayerCount == 1) || (gPlayerCount == 2)) { - render_object_seagulls(cameraId); + //render_object_seagulls(cameraId); } } else { - render_object_seagulls(cameraId); + //render_object_seagulls(cameraId); } } diff --git a/src/engine/courses/LuigiRaceway.cpp b/src/engine/courses/LuigiRaceway.cpp index 65506cd99..7740ebf49 100644 --- a/src/engine/courses/LuigiRaceway.cpp +++ b/src/engine/courses/LuigiRaceway.cpp @@ -5,7 +5,7 @@ #include "LuigiRaceway.h" #include "World.h" -#include "engine/objects/OBombKart.h" +#include "engine/objects/BombKart.h" #include "assets/luigi_raceway_data.h" #include "engine/actors/AFinishline.h" diff --git a/src/engine/courses/MarioRaceway.cpp b/src/engine/courses/MarioRaceway.cpp index f16caeeaf..05a4cc438 100644 --- a/src/engine/courses/MarioRaceway.cpp +++ b/src/engine/courses/MarioRaceway.cpp @@ -6,7 +6,7 @@ #include "MarioRaceway.h" #include "World.h" #include "engine/actors/AFinishline.h" -#include "engine/objects/OBombKart.h" +#include "engine/objects/BombKart.h" extern "C" { #include "main.h" diff --git a/src/engine/courses/MooMooFarm.cpp b/src/engine/courses/MooMooFarm.cpp index 1c7854c6c..f46f263ee 100644 --- a/src/engine/courses/MooMooFarm.cpp +++ b/src/engine/courses/MooMooFarm.cpp @@ -6,8 +6,9 @@ #include "MooMooFarm.h" #include "World.h" #include "engine/actors/AFinishline.h" -#include "engine/objects/OBombKart.h" +#include "engine/objects/BombKart.h" #include "assets/moo_moo_farm_data.h" +#include "engine/objects/Mole.h" extern "C" { #include "main.h" @@ -223,27 +224,37 @@ void MooMooFarm::InitCourseObjects() { D_8018D1D0 = 6; D_8018D1D8 = 6; } - for (i = 0; i < NUM_GROUP1_MOLES; i++) { + + Vec3f pos = {0, 22, 0}; + for (size_t i = 0; i < NUM_GROUP1_MOLES; i++) { D_8018D198[i] = 0; - find_unused_obj_index(&indexObjectList1[i]); - } - for (i = 0; i < NUM_GROUP2_MOLES; i++) { - D_8018D1A8[i] = 0; - find_unused_obj_index(&indexObjectList1[i]); - } - for (i = 0; i < NUM_GROUP3_MOLES; i++) { - D_8018D1B8[i] = 0; - find_unused_obj_index(&indexObjectList1[i]); - } - for (i = 0; i < NUM_TOTAL_MOLES; i++) { - find_unused_obj_index(&gObjectParticle1[i]); - objectId = gObjectParticle1[i]; - init_object(objectId, 0); - gObjectList[objectId].pos[0] = gMoleSpawns.asVec3sList[i][0] * xOrientation; - gObjectList[objectId].pos[2] = gMoleSpawns.asVec3sList[i][2]; - func_800887C0(objectId); - gObjectList[objectId].sizeScaling = 0.7f; + gWorldInstance.AddObject(new OMole(pos)); + } + + // for (i = 0; i < NUM_GROUP1_MOLES; i++) { + // D_8018D198[i] = 0; + // find_unused_obj_index(&indexObjectList1[i]); + // } + // for (i = 0; i < NUM_GROUP2_MOLES; i++) { + // D_8018D1A8[i] = 0; + // find_unused_obj_index(&indexObjectList1[i]); + // } + // for (i = 0; i < NUM_GROUP3_MOLES; i++) { + // D_8018D1B8[i] = 0; + // find_unused_obj_index(&indexObjectList1[i]); + // } + // for (i = 0; i < NUM_TOTAL_MOLES; i++) { + // find_unused_obj_index(&gObjectParticle1[i]); + // objectId = gObjectParticle1[i]; + // init_object(objectId, 0); + // gObjectList[objectId].pos[0] = gMoleSpawns.asVec3sList[i][0] * xOrientation; + // gObjectList[objectId].pos[2] = gMoleSpawns.asVec3sList[i][2]; + // func_800887C0(objectId); + // gObjectList[objectId].sizeScaling = 0.7f; + // } + + for (i = 0; i < gObjectParticle2_SIZE; i++) { find_unused_obj_index(&gObjectParticle2[i]); } @@ -252,13 +263,13 @@ void MooMooFarm::InitCourseObjects() { void MooMooFarm::UpdateCourseObjects() { if (gGamestate != CREDITS_SEQUENCE) { - update_moles(); + //update_moles(); } } void MooMooFarm::RenderCourseObjects(s32 cameraId) { if (gGamestate != CREDITS_SEQUENCE) { - render_object_moles(cameraId); + //render_object_moles(cameraId); } } diff --git a/src/engine/courses/MooMooFarm.h b/src/engine/courses/MooMooFarm.h index fb27ef725..5815db8c7 100644 --- a/src/engine/courses/MooMooFarm.h +++ b/src/engine/courses/MooMooFarm.h @@ -2,6 +2,7 @@ #include #include "Course.h" +#include "engine/objects/Mole.h" extern "C" { #include "assets/moo_moo_farm_vertices.h" @@ -15,6 +16,8 @@ extern "C" { extern const course_texture moo_moo_farm_textures[]; } +class OMole; + class MooMooFarm : public Course { public: virtual ~MooMooFarm() = default; // Virtual destructor for proper cleanup in derived classes diff --git a/src/engine/courses/PodiumCeremony.cpp b/src/engine/courses/PodiumCeremony.cpp index e2e5a1262..e05b54e51 100644 --- a/src/engine/courses/PodiumCeremony.cpp +++ b/src/engine/courses/PodiumCeremony.cpp @@ -5,7 +5,7 @@ #include "PodiumCeremony.h" #include "World.h" -#include "engine/objects/OBombKart.h" +#include "engine/objects/BombKart.h" #include "assets/royal_raceway_data.h" #include "assets/ceremony_data.h" diff --git a/src/engine/courses/RainbowRoad.cpp b/src/engine/courses/RainbowRoad.cpp index e13b3229b..4cc7e2a51 100644 --- a/src/engine/courses/RainbowRoad.cpp +++ b/src/engine/courses/RainbowRoad.cpp @@ -6,7 +6,7 @@ #include "RainbowRoad.h" #include "World.h" #include "engine/actors/AFinishline.h" -#include "engine/objects/OBombKart.h" +#include "engine/objects/BombKart.h" #include "assets/rainbow_road_data.h" extern "C" { diff --git a/src/engine/courses/RoyalRaceway.cpp b/src/engine/courses/RoyalRaceway.cpp index 8fe5eec32..733d42a92 100644 --- a/src/engine/courses/RoyalRaceway.cpp +++ b/src/engine/courses/RoyalRaceway.cpp @@ -6,7 +6,7 @@ #include "RoyalRaceway.h" #include "World.h" #include "engine/actors/AFinishline.h" -#include "engine/objects/OBombKart.h" +#include "engine/objects/BombKart.h" #include "assets/royal_raceway_data.h" extern "C" { diff --git a/src/engine/courses/SherbetLand.cpp b/src/engine/courses/SherbetLand.cpp index df2be3f2d..fd97ba95e 100644 --- a/src/engine/courses/SherbetLand.cpp +++ b/src/engine/courses/SherbetLand.cpp @@ -6,9 +6,9 @@ #include "SherbetLand.h" #include "World.h" #include "engine/actors/AFinishline.h" -#include "engine/objects/OBombKart.h" +#include "engine/objects/BombKart.h" #include "assets/sherbet_land_data.h" -#include "engine/objects/OPenguin.h" +#include "engine/objects/Penguin.h" extern "C" { #include "main.h" diff --git a/src/engine/courses/Skyscraper.cpp b/src/engine/courses/Skyscraper.cpp index b95c15899..da3cca777 100644 --- a/src/engine/courses/Skyscraper.cpp +++ b/src/engine/courses/Skyscraper.cpp @@ -5,7 +5,7 @@ #include "Skyscraper.h" #include "World.h" -#include "engine/objects/OBombKart.h" +#include "engine/objects/BombKart.h" #include "assets/skyscraper_data.h" extern "C" { diff --git a/src/engine/courses/TestCourse.cpp b/src/engine/courses/TestCourse.cpp index b636600ec..74f7fee13 100644 --- a/src/engine/courses/TestCourse.cpp +++ b/src/engine/courses/TestCourse.cpp @@ -6,7 +6,7 @@ #include "TestCourse.h" #include "World.h" #include "engine/actors/AFinishline.h" -#include "engine/objects/OBombKart.h" +#include "engine/objects/BombKart.h" #include "assets/mario_raceway_data.h" #include "assets/bowsers_castle_data.h" #include "assets/bowsers_castle_displaylists.h" @@ -187,8 +187,13 @@ void TestCourse::SpawnActors() { ACTOR_RAILROAD_CROSSING)); rrxing->crossingTrigger = crossing1; - //Vec3f pos = {-80, 7, -20}; + Vec3f pos = {0, 80, 0}; //gWorldInstance.AddActor(new ACloud(pos)); + + gWorldInstance.AddActor(new OSeagull(0, pos)); + gWorldInstance.AddActor(new OSeagull(1, pos)); + gWorldInstance.AddActor(new OSeagull(2, pos)); + gWorldInstance.AddActor(new OSeagull(3, pos)); } // Likely sets minimap boundaries diff --git a/src/engine/courses/ToadsTurnpike.cpp b/src/engine/courses/ToadsTurnpike.cpp index cbac2d4e5..4acdcd466 100644 --- a/src/engine/courses/ToadsTurnpike.cpp +++ b/src/engine/courses/ToadsTurnpike.cpp @@ -5,7 +5,7 @@ #include "ToadsTurnpike.h" #include "World.h" -#include "engine/objects/OBombKart.h" +#include "engine/objects/BombKart.h" #include "assets/toads_turnpike_data.h" #include "engine/actors/AFinishline.h" diff --git a/src/engine/courses/WarioStadium.cpp b/src/engine/courses/WarioStadium.cpp index 78bdf3079..a71b670f1 100644 --- a/src/engine/courses/WarioStadium.cpp +++ b/src/engine/courses/WarioStadium.cpp @@ -5,7 +5,7 @@ #include "WarioStadium.h" #include "World.h" -#include "engine/objects/OBombKart.h" +#include "engine/objects/BombKart.h" #include "assets/wario_stadium_data.h" #include "engine/actors/AWarioSign.h" #include "engine/actors/AFinishline.h" diff --git a/src/engine/courses/YoshiValley.cpp b/src/engine/courses/YoshiValley.cpp index 1d7bb0d6a..770e5ae1d 100644 --- a/src/engine/courses/YoshiValley.cpp +++ b/src/engine/courses/YoshiValley.cpp @@ -6,7 +6,7 @@ #include "YoshiValley.h" #include "World.h" #include "engine/actors/AFinishline.h" -#include "engine/objects/OBombKart.h" +#include "engine/objects/BombKart.h" #include "assets/yoshi_valley_data.h" #include "assets/boo_frames.h" diff --git a/src/engine/objects/OBombKart.cpp b/src/engine/objects/BombKart.cpp similarity index 99% rename from src/engine/objects/OBombKart.cpp rename to src/engine/objects/BombKart.cpp index e51340b8f..42506f826 100644 --- a/src/engine/objects/OBombKart.cpp +++ b/src/engine/objects/BombKart.cpp @@ -1,5 +1,5 @@ #include -#include "OBombKart.h" +#include "BombKart.h" #include #include "port/Game.h" @@ -358,7 +358,7 @@ void OBombKart::Draw(s32 cameraId) { } else if (gGamestate != ENDING) { Unk_4A = 1; } - set_object_flag_status_false(ObjectIndex, 0x00200000); + clear_object_flag(ObjectIndex, 0x00200000); } // huh??? @@ -369,7 +369,7 @@ void OBombKart::Draw(s32 cameraId) { gObjectList[ObjectIndex].pos[2] = Pos[2]; temp_s4 = func_8008A364(ObjectIndex, cameraId, 0x31C4U, 0x000001F4); if (is_obj_flag_status_active(ObjectIndex, VISIBLE) != 0) { - set_object_flag_status_true(ObjectIndex, 0x00200000); + set_object_flag(ObjectIndex, 0x00200000); D_80183E80[0] = 0; D_80183E80[1] = func_800418AC(Pos[0], Pos[2], camera->pos); D_80183E80[2] = 0x8000; diff --git a/src/engine/objects/OBombKart.h b/src/engine/objects/BombKart.h similarity index 100% rename from src/engine/objects/OBombKart.h rename to src/engine/objects/BombKart.h diff --git a/src/engine/objects/Crab.cpp b/src/engine/objects/Crab.cpp new file mode 100644 index 000000000..cfb84f259 --- /dev/null +++ b/src/engine/objects/Crab.cpp @@ -0,0 +1,175 @@ +#include +#include +#include "Crab.h" +#include + +#include "port/Game.h" + +extern "C" { +#include "macros.h" +#include "main.h" +#include "defines.h" +#include "camera.h" +#include "update_objects.h" +#include "render_objects.h" +#include "actors.h" +#include "code_80057C60.h" +#include "code_80086E70.h" +#include "math_util.h" +#include "math_util_2.h" +#include "code_80005FD0.h" +#include "some_data.h" +#include "ceremony_and_credits.h" +#include "assets/koopa_troopa_beach_data.h" +} + +OCrab::OCrab(s32 i, Vec3f pos) { + s32 objectId; + //for (i = 0; i < NUM_CRABS; i++) { + _idx = i; + objectId = indexObjectList1[i]; + init_object(objectId, 0); + gObjectList[objectId].pos[0] = gObjectList[objectId].origin_pos[0] = + gCrabSpawns[i].startX * xOrientation; + + gObjectList[objectId].unk_01C[0] = gCrabSpawns[i].patrolX * xOrientation; + + gObjectList[objectId].pos[2] = gObjectList[objectId].origin_pos[2] = gCrabSpawns[i].startZ; + gObjectList[objectId].unk_01C[2] = gCrabSpawns[i].patrolZ; +} + +void OCrab::Tick(void) { + s32 objectIndex; + + //for (var_s1 = 0; var_s1 < NUM_CRABS; var_s1++) { + objectIndex = indexObjectList1[_idx]; + if (gObjectList[objectIndex].state != 0) { + OCrab::func_80082B34(objectIndex); + func_8008A6DC(objectIndex, 500.0f); + OCrab::func_80082C30(objectIndex); + OCrab::func_80082E18(objectIndex); + } + //} +} + +void OCrab::Draw(s32 objectIndex, s32 cameraId) { + Camera* camera; + + if (gObjectList[objectIndex].state >= 2) { + Vtx* vtx = (Vtx*) LOAD_ASSET_RAW(common_vtx_hedgehog); + camera = &camera1[cameraId]; + func_8004A6EC(objectIndex, 0.5f); + gObjectList[objectIndex].orientation[1] = + func_800418AC(gObjectList[objectIndex].pos[0], gObjectList[objectIndex].pos[2], camera->pos); + draw_2d_texture_at(gObjectList[objectIndex].pos, gObjectList[objectIndex].orientation, + gObjectList[objectIndex].sizeScaling, (u8*) gObjectList[objectIndex].activeTLUT, + (uint8_t*)gObjectList[objectIndex].activeTexture, vtx, 64, 64, + 64, 32); + } +} + +void OCrab::DrawModel(s32 cameraId) { + s32 someIndex; + s32 test; + + //for (someIndex = 0; someIndex < NUM_CRABS; someIndex++) { + test = indexObjectList1[_idx]; + func_8008A364(test, cameraId, 0x2AABU, 800); + if (is_obj_flag_status_active(test, VISIBLE) != 0) { + Camera *camera; + s32 objectIndex; + + if (gObjectList[objectIndex].state >= 2) { + camera = &camera1[cameraId]; + func_8004A6EC(objectIndex, 0.5f); + gObjectList[objectIndex].orientation[1] = func_800418AC(gObjectList[objectIndex].pos[0], gObjectList[objectIndex].pos[2], camera->pos); + draw_2d_texture_at(gObjectList[objectIndex].pos, gObjectList[objectIndex].orientation, gObjectList[objectIndex].sizeScaling, (u8*) gObjectList[objectIndex].activeTLUT, (u8*)gObjectList[objectIndex].activeTexture, (Vtx*)common_vtx_hedgehog, 0x00000040, 0x00000040, 0x00000040, 0x00000020); + } + } + //} +} + +void OCrab::init_ktb_crab(s32 objectIndex) { + Object* object; + + init_texture_object(objectIndex, (uint8_t*) d_course_koopa_troopa_beach_crab_tlut, + (const char**) d_course_koopa_troopa_beach_crab_frames, 64, (u16) 64); + object = &gObjectList[objectIndex]; + object->sizeScaling = 0.15f; + object->textureListIndex = 0; + object_next_state(objectIndex); + object->boundingBoxSize = 1; + set_object_flag(objectIndex, 0x04000420); + func_80086EAC(objectIndex, 0, 1); + set_obj_origin_offset(objectIndex, 0.0f, 0.0f, 0.0f); + set_obj_orientation(objectIndex, 0U, 0U, 0x8000U); + object->unk_034 = 1.5f; + set_object_flag(objectIndex, 0x00000200); +} + +void OCrab::func_80082B34(s32 objectIndex) { + switch (gObjectList[objectIndex].state) { /* irregular */ + case 0: + break; + case 1: + OCrab::init_ktb_crab(objectIndex); + break; + case 2: + func_80072E54(objectIndex, 0, 3, 1, 2, -1); + break; + case 3: + func_80072E54(objectIndex, 4, 6, 1, 2, -1); + break; + } + if (gObjectList[objectIndex].state >= 2) { + func_80073514(objectIndex); + } +} + +void OCrab::func_80082C30(s32 objectIndex) { + switch (gObjectList[objectIndex].unk_0AE) { + case 1: + if (func_80087A0C(objectIndex, gObjectList[objectIndex].origin_pos[0], gObjectList[objectIndex].unk_01C[0], + gObjectList[objectIndex].origin_pos[2], gObjectList[objectIndex].unk_01C[2]) != 0) { + func_800726CC(objectIndex, 3); + func_80086FD4(objectIndex); + } + break; + case 2: + if (func_80087104(objectIndex, 0x003CU) != 0) { + gObjectList[objectIndex].unk_034 = 0.8f; + func_800726CC(objectIndex, 2); + func_80086FD4(objectIndex); + } + break; + case 3: + if (func_80087954(objectIndex, 0x0000003C) != 0) { + func_80086FD4(objectIndex); + func_800726CC(objectIndex, 3); + } + break; + case 4: + if (func_80087104(objectIndex, 0x003CU) != 0) { + func_800726CC(objectIndex, 2); + func_80086FD4(objectIndex); + } + break; + case 5: + if (func_8008789C(objectIndex, 0x0000003C) != 0) { + func_800726CC(objectIndex, 3); + func_8008701C(objectIndex, 2); + } + break; + } + object_calculate_new_pos_offset(objectIndex); + if (is_obj_flag_status_active(objectIndex, VISIBLE) != 0) { + func_80088538(objectIndex); + gObjectList[objectIndex].pos[1] = (f32) (gObjectList[objectIndex].surfaceHeight + 2.5); + } +} + +void OCrab::func_80082E18(s32 objectIndex) { + if (gObjectList[objectIndex].state >= 2) { + func_80089F24(objectIndex); + } +} diff --git a/src/engine/objects/Crab.h b/src/engine/objects/Crab.h new file mode 100644 index 000000000..697a8bd7b --- /dev/null +++ b/src/engine/objects/Crab.h @@ -0,0 +1,41 @@ +#pragma once + +#include +#include + +extern "C" { +#include "macros.h" +#include "main.h" +#include "vehicles.h" +#include "waypoints.h" +#include "common_structs.h" +#include "objects.h" +#include "course_offsets.h" +#include "some_data.h" +} + + +class OCrab { +public: + enum Behaviour : uint16_t { + }; + +public: + f32 Diameter = 0.0f; // Waddle in a circle around the spawn point at this diameter. + uint16_t MirrorModeAngleOffset; + + explicit OCrab(s32 i, Vec3f pos); + + void Tick(); + void Draw(s32 objectIndex, s32 cameraId); + void DrawModel(s32 cameraId); + + void init_ktb_crab(s32 objectIndex); + void func_80082B34(s32 objectIndex); + void func_80082C30(s32 objectIndex); + void func_80082E18(s32 objectIndex); + +private: + + s32 _idx; +}; diff --git a/src/engine/objects/GameObject.cpp b/src/engine/objects/GameObject.cpp new file mode 100644 index 000000000..c7be32769 --- /dev/null +++ b/src/engine/objects/GameObject.cpp @@ -0,0 +1,20 @@ +#include +#include "GameObject.h" + +#include "World.h" + +extern "C" { + #include "camera.h" +} + + + //GameActor() + +GameObject::GameObject() {} + + // Virtual functions to be overridden by derived classes +void GameObject::Tick() { } +void GameObject::Draw(Camera* camera) { } +void GameObject::Collision() {} +void GameObject::Expire() { } +void GameObject::Destroy() { } diff --git a/src/engine/objects/GameObject.h b/src/engine/objects/GameObject.h new file mode 100644 index 000000000..19d5301cd --- /dev/null +++ b/src/engine/objects/GameObject.h @@ -0,0 +1,24 @@ +#pragma once + +#include + +extern "C" { + #include "camera.h" + #include "objects.h" +} + +class GameObject { +public: + uint8_t uuid[16]; + Object o; + + virtual ~GameObject() = default; + + explicit GameObject(); + + virtual void Tick(); + virtual void Draw(Camera* camera); + virtual void Collision(); + virtual void Expire(); + virtual void Destroy(); +}; diff --git a/src/engine/objects/Mole.cpp b/src/engine/objects/Mole.cpp new file mode 100644 index 000000000..9ef7f40ef --- /dev/null +++ b/src/engine/objects/Mole.cpp @@ -0,0 +1,422 @@ +#include +#include +#include "Mole.h" + +extern "C" { +#include "macros.h" +#include "main.h" +#include "defines.h" +#include "camera.h" +#include "update_objects.h" +#include "render_objects.h" +#include "actors.h" +#include "code_80057C60.h" +#include "code_80086E70.h" +#include "math_util.h" +#include "math_util_2.h" +#include "code_80005FD0.h" +#include "some_data.h" +#include "ceremony_and_credits.h" +#include "assets/moo_moo_farm_data.h" +#include "sounds.h" +#include "external.h" +} + +OMole::OMole(Vec3f pos) { + + find_unused_obj_index(&indexObjectList1[0]); +} + +void OMole::Tick() { + s32 var_s1; + s32 objectIndex; + + for (var_s1 = 0; var_s1 < D_8018D1C8; var_s1++) { + objectIndex = indexObjectList1[var_s1]; + if (gObjectList[objectIndex].state == 0) { + if (func_8008A8B0(8, 9) != 0) { + func_80081FF4(objectIndex, 1); + } + } else { + OMole::func_800821AC(objectIndex, 1); + } + } + + for (var_s1 = 0; var_s1 < D_8018D1D0; var_s1++) { + objectIndex = indexObjectList2[var_s1]; + if (gObjectList[objectIndex].state == 0) { + if (func_8008A8B0(0x0010, 0x0013) != 0) { + OMole::func_80081FF4(objectIndex, 2); + } + } else { + OMole::func_800821AC(objectIndex, 2); + } + } + + for (var_s1 = 0; var_s1 < D_8018D1D8; var_s1++) { + objectIndex = indexObjectList3[var_s1]; + if (gObjectList[objectIndex].state == 0) { + if (func_8008A8B0(0x0011, 0x0014) != 0) { + func_80081FF4(objectIndex, 3); + } + } else { + OMole::func_800821AC(objectIndex, 3); + } + } + + for (var_s1 = 0; var_s1 < gObjectParticle2_SIZE; var_s1++) { + objectIndex = gObjectParticle2[var_s1]; + if (gObjectList[objectIndex].state != 0) { + OMole::func_80081790(objectIndex); + } + } +} + +void OMole::Draw(Camera* camera) { + +} + +void OMole::func_80081790(s32 objectIndex) { + switch (gObjectList[objectIndex].state) { + case 0: + break; /* irregular */ + case 1: + if (func_80087E08(objectIndex, gObjectList[objectIndex].velocity[1], 0.3f, gObjectList[objectIndex].unk_034, + gObjectList[objectIndex].orientation[1], 0x00000032) != 0) { + object_next_state(objectIndex); + } + object_calculate_new_pos_offset(objectIndex); + break; + case 2: + func_80072428(objectIndex); + func_80086F60(objectIndex); + break; + } +} + + + + + +void OMole::func_80081AFC(s32 objectIndex, s32 arg1) { + s8* sp2C; + Object* object; + + object = &gObjectList[objectIndex]; + switch (object->state) { + case 0x1: + OMole::func_80081848(objectIndex); + break; + case 0x2: + if (object->unk_04C == 0) { + func_80086EAC(objectIndex, 2, 1); + object_next_state(objectIndex); + set_object_flag(objectIndex, 0x00000200); + } else { + object->unk_04C--; + } + break; + case 0x3: + if (object->unk_0AE == 0) { + func_80086EAC(objectIndex, 2, 4); + func_8008153C(objectIndex); + object_next_state(objectIndex); + func_800C98B8(object->pos, object->velocity, SOUND_ARG_LOAD(0x19, 0x01, 0x80, 0x07)); + } + break; + case 0x4: + if (func_80072E54(objectIndex, 1, 6, 1, 2, 0) != 0) { + func_800726CC(objectIndex, 0x00000064); + } + break; + case 0xA: + func_80072E54(objectIndex, 1, 6, 1, 0, -1); + if (object->unk_0AE == 0) { + func_800726CC(objectIndex, 0x00000064); + } + break; + case 0x64: + if (object->unk_0AE == 0) { + clear_object_flag(objectIndex, 0x00000200); + func_80072428(objectIndex); + switch (arg1) { /* switch 1; irregular */ + case 1: /* switch 1 */ + sp2C = D_8018D198; + break; + case 2: /* switch 1 */ + sp2C = D_8018D1A8; + break; + case 3: /* switch 1 */ + sp2C = D_8018D1B8; + break; + } + sp2C[object->type] = 0; + } + break; + case 0: + default: + break; + } + if (object->state >= 2) { + func_80073514(objectIndex); + } +} + +void OMole::func_80081D34(s32 objectIndex) { + Player* player; + Camera* var_s4; + s32 var_s2; + s32 var_s5; + Object* object; + + var_s5 = 0; + player = gPlayerOne; + var_s4 = camera1; + for (var_s2 = 0; var_s2 < D_8018D158; var_s2++, player++, var_s4++) { + if ((is_obj_flag_status_active(objectIndex, 0x00000200) != 0) && !(player->effects & 0x80000000) && + (has_collided_with_player(objectIndex, player) != 0)) { + if ((player->type & 0x8000) && !(player->type & 0x100)) { + var_s5 = 1; + object = &gObjectList[objectIndex]; + if (is_obj_flag_status_active(objectIndex, 0x04000000) != 0) { + func_80072180(); + } + if (player->effects & 0x200) { + func_800C9060(var_s2, 0x1900A046U); + } else { + player->soundEffects |= 2; + } + object->direction_angle[1] = var_s4->rot[1]; + object->velocity[1] = (player->unk_094 / 2) + 3.0; + object->unk_034 = player->unk_094 + 1.0; + if (object->velocity[1] >= 5.0) { + object->velocity[1] = 5.0f; + } + if (object->unk_034 >= 4.0) { + object->velocity[1] = 4.0f; + } + } + } + } + if (var_s5 != 0) { + object = &gObjectList[objectIndex]; + clear_object_flag(objectIndex, 0x00000200); + func_80086F60(objectIndex); + set_obj_origin_pos(objectIndex, object->pos[0], object->pos[1], object->pos[2]); + set_obj_origin_offset(objectIndex, 0.0f, 0.0f, 0.0f); + func_80086EAC(objectIndex, 2, 0x000A); + func_800726CC(objectIndex, 0x0000000A); + } +} + + +void OMole::func_80081FF4(s32 objectIndex, s32 arg1) { + UNUSED s32 stackPadding0; + UNUSED s32 stackPadding1; + s32 moleCount; + s16 var_v1; + s16 offset; + s32 var_a0; + s8* var_a2; + + init_object(objectIndex, 0); + gObjectList[objectIndex].unk_04C = random_int(0x001EU) + 5; + switch (arg1) { /* irregular */ + case 1: + var_a2 = D_8018D198; + moleCount = NUM_GROUP1_MOLES; + offset = 0; + break; + case 2: + var_a2 = D_8018D1A8; + moleCount = NUM_GROUP2_MOLES; + offset = 24; + // offset = NUM_GROUP1_MOLES; + break; + case 3: + var_a2 = D_8018D1B8; + moleCount = NUM_GROUP3_MOLES; + offset = 57; + // offset = NUM_GROUP1_MOLES + NUM_GROUP2_MOLES; + break; + } + var_v1 = random_int(moleCount); + for (var_a0 = 0; var_a0 < moleCount; var_a0++) { + if (var_a2[var_v1] != 0) { + var_v1++; + if (var_v1 == moleCount) { + var_v1 = 0; + } + } else { + var_a2[var_v1] = 1; + gObjectList[objectIndex].type = var_v1; + break; + } + } + /* + Ideally `gMoleSpawns` wouldn't be a union at all and its just be a list of Vec3s + Even more ideally each mole group would have its own array for its spawns + gObjectList[objectIndex].origin_pos[0] = gMoleSpawns.asVec3sList[offset + var_v1][0] * xOrientation; + gObjectList[objectIndex].origin_pos[1] = gMoleSpawns.asVec3sList[offset + var_v1][1] - 9.0; + gObjectList[objectIndex].origin_pos[2] = gMoleSpawns.asVec3sList[offset + var_v1][2]; + */ + gObjectList[objectIndex].origin_pos[0] = gMoleSpawns.asFlatList[offset + (var_v1 * 3) + 0] * xOrientation; + gObjectList[objectIndex].origin_pos[1] = gMoleSpawns.asFlatList[offset + (var_v1 * 3) + 1] - 9.0; + gObjectList[objectIndex].origin_pos[2] = gMoleSpawns.asFlatList[offset + (var_v1 * 3) + 2]; +} + +void OMole::func_80081848(s32 objectIndex) { + u8* mole = (u8*) LOAD_ASSET_RAW(d_course_moo_moo_farm_mole_frames); + u8* tlut = (u8*) LOAD_ASSET_RAW(d_course_moo_moo_farm_mole_tlut); + init_texture_object(objectIndex, (u8*)d_course_moo_moo_farm_mole_tlut, (const char**) mole, 0x20U, (u16) 0x00000040); + gObjectList[objectIndex].sizeScaling = 0.15f; + gObjectList[objectIndex].textureListIndex = 0; + set_obj_origin_offset(objectIndex, 0.0f, 0.0f, 0.0f); + set_obj_direction_angle(objectIndex, 0U, 0U, 0U); + set_obj_orientation(objectIndex, 0U, 0U, 0x8000U); + gObjectList[objectIndex].boundingBoxSize = 6; + gObjectList[objectIndex].velocity[1] = 4.0f; + set_object_flag(objectIndex, 0x04000000); + object_next_state(objectIndex); +} + + +void OMole::func_80081924(s32 objectIndex) { + switch (gObjectList[objectIndex].unk_0AE) { + case 1: + if (f32_step_up_towards(&gObjectList[objectIndex].offset[1], 9.0f, 0.7f) != 0) { + func_80086FD4(objectIndex); + } + break; + case 2: + func_800871AC(objectIndex, 0x0000000A); + break; + case 3: + if (f32_step_down_towards(&gObjectList[objectIndex].offset[1], 3.0f, 1.0f) != 0) { + func_80086F60(objectIndex); + } + break; + case 4: + func_80087D24(objectIndex, 3.6f, 0.25f, 0.0f); + break; + case 5: + func_80086F60(objectIndex); + break; + case 10: + gObjectList[objectIndex].orientation[2] += 0x1000; + gObjectList[objectIndex].velocity[1] -= 0.184; + func_8008751C(objectIndex); + object_add_velocity_offset_xyz(objectIndex); + if (gObjectList[objectIndex].pos[1] <= -10.0) { + func_80086F60(objectIndex); + } + break; + case 0: + default: + break; + } +} + + +void OMole::func_80081A88(s32 objectIndex) { + switch (gObjectList[objectIndex].unk_0DD) { /* irregular */ + case 0: + break; + case 1: + func_8008B724(objectIndex); + break; + case 2: + OMole::func_80081924(objectIndex); + break; + } + object_calculate_new_pos_offset(objectIndex); +} + +void OMole::func_800821AC(s32 objectIndex, s32 arg1) { + if (gObjectList[objectIndex].state != 0) { + OMole::func_80081AFC(objectIndex, arg1); + OMole::func_80081A88(objectIndex); + OMole::func_80081D34(objectIndex); + } +} + +void OMole::func_80054E10(s32 objectIndex) { + if (gObjectList[objectIndex].state > 0) { + if (is_obj_flag_status_active(objectIndex, 0x00800000) != 0) { + D_80183E50[0] = gObjectList[objectIndex].pos[0]; + D_80183E50[1] = gObjectList[objectIndex].surfaceHeight + 0.8; + D_80183E50[2] = gObjectList[objectIndex].pos[2]; + D_80183E70[0] = gObjectList[objectIndex].velocity[0]; + D_80183E70[1] = gObjectList[objectIndex].velocity[1]; + D_80183E70[2] = gObjectList[objectIndex].velocity[2]; + func_8004A9B8(gObjectList[objectIndex].sizeScaling); + } + } +} + +// Almost certainly responsible for spawning/handling the moles on Moo Moo farm +void OMole::func_80054EB8() { + s32 someIndex; + + for (someIndex = 0; someIndex < NUM_TOTAL_MOLES; someIndex++) { + func_80054E10(gObjectParticle1[someIndex]); + } +} + +void OMole::func_80054D00(s32 objectIndex, s32 cameraId) { + Camera* camera; + + camera = &camera1[cameraId]; + if (gObjectList[objectIndex].state >= 3) { + func_8008A364(objectIndex, cameraId, 0x2AABU, 0x0000012C); + if (is_obj_flag_status_active(objectIndex, VISIBLE) != 0) { + D_80183E80[0] = (s16) gObjectList[objectIndex].orientation[0]; + D_80183E80[1] = + func_800418AC(gObjectList[objectIndex].pos[0], gObjectList[objectIndex].pos[2], camera->pos); + D_80183E80[2] = (u16) gObjectList[objectIndex].orientation[2]; + func_80048130(gObjectList[objectIndex].pos, (u16*) D_80183E80, gObjectList[objectIndex].sizeScaling, + (u8*) gObjectList[objectIndex].activeTLUT, (u8*)gObjectList[objectIndex].activeTexture, + (Vtx*)LOAD_ASSET_RAW(D_0D0062B0), 0x00000020, 0x00000040, 0x00000020, 0x00000040, 5); + } + } +} + +void OMole::func_80054F04(s32 cameraId) { + s32 var_s2; + s32 objectIndex; + Camera* sp44; + Object* object; + + sp44 = &camera1[cameraId]; + gSPDisplayList(gDisplayListHead++, (Gfx*)D_0D0079C8); + load_texture_block_rgba16_mirror((u8*) LOAD_ASSET_RAW(d_course_moo_moo_farm_mole_dirt), 0x00000010, 0x00000010); + for (var_s2 = 0; var_s2 < gObjectParticle2_SIZE; var_s2++) { + objectIndex = gObjectParticle2[var_s2]; + object = &gObjectList[objectIndex]; + if (object->state > 0) { + func_8008A364(objectIndex, cameraId, 0x2AABU, 0x000000C8); + if ((is_obj_flag_status_active(objectIndex, VISIBLE) != 0) && (gMatrixHudCount <= MTX_HUD_POOL_SIZE_MAX)) { + object->orientation[1] = func_800418AC(object->pos[0], object->pos[2], sp44->pos); + rsp_set_matrix_gObjectList(objectIndex); + gSPDisplayList(gDisplayListHead++, (Gfx*)D_0D006980); + } + } + } + gSPTexture(gDisplayListHead++, 1, 1, 0, G_TX_RENDERTILE, G_OFF); +} + +void OMole::render_object_moles(s32 cameraId) { + s32 i; + + for (i = 0; i < NUM_GROUP1_MOLES; i++) { + OMole::func_80054D00(indexObjectList1[i], cameraId); + } + for (i = 0; i < NUM_GROUP2_MOLES; i++) { + OMole::func_80054D00(indexObjectList2[i], cameraId); + } + for (i = 0; i < NUM_GROUP3_MOLES; i++) { + OMole::func_80054D00(indexObjectList3[i], cameraId); + } + OMole::func_80054EB8(); + OMole::func_80054F04(cameraId); +} \ No newline at end of file diff --git a/src/engine/objects/Mole.h b/src/engine/objects/Mole.h new file mode 100644 index 000000000..d5d605fa5 --- /dev/null +++ b/src/engine/objects/Mole.h @@ -0,0 +1,52 @@ +#pragma once + +#include +#include +#include "GameObject.h" + +extern "C" { +#include "macros.h" +#include "main.h" +#include "vehicles.h" +#include "waypoints.h" +#include "common_structs.h" +#include "objects.h" +#include "course_offsets.h" +#include "some_data.h" +} + + +class OMole : public GameObject { +public: + enum Behaviour : uint16_t { + }; + +public: + explicit OMole(Vec3f pos); + + virtual void Tick() override; + virtual void Draw(Camera*) override; + + void func_80054E10(s32 objectIndex); + void func_80054EB8(); + void func_80054F04(s32 cameraId); + void render_object_moles(s32 cameraId); + void func_80054D00(s32 objectIndex, s32 cameraId); + void func_800821AC(s32 objectIndex, s32 arg1); + void func_80081FF4(s32 objectIndex, s32 arg1); + void func_80081D34(s32 objectIndex); + void func_80081AFC(s32 objectIndex, s32 arg1); + void func_80081A88(s32 objectIndex); + void func_80081924(s32 objectIndex); + void func_80081848(s32 objectIndex); + void func_80081790(s32 objectIndex); + +private: + s32 _idx; + s32 _state; + s32 _timer; + s32 _status; + bool _toggle; + + SplineData *spline; +}; diff --git a/src/engine/objects/OPenguin.cpp b/src/engine/objects/Penguin.cpp similarity index 98% rename from src/engine/objects/OPenguin.cpp rename to src/engine/objects/Penguin.cpp index 944ec38fd..c126174a1 100644 --- a/src/engine/objects/OPenguin.cpp +++ b/src/engine/objects/Penguin.cpp @@ -1,6 +1,6 @@ #include #include -#include "OPenguin.h" +#include "Penguin.h" #include #include "port/Game.h" @@ -98,7 +98,7 @@ void OPenguin::Tick(void) { 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); + clear_object_flag(objectIndex, 0x02000000); } } @@ -315,7 +315,7 @@ void OPenguin::InitEmperorPenguin(s32 objectIndex) { object->unk_0DD = 1; func_80086EF0(objectIndex); object->spline = D_800E672C[0]; - set_object_flag_status_true(objectIndex, 0x04000800); + set_object_flag(objectIndex, 0x04000800); object->type = get_animation_length(d_course_sherbet_land_unk_data11, 0); object_next_state(objectIndex); } @@ -377,7 +377,7 @@ void OPenguin::InitOtherPenguin(s32 objectIndex) { //object->boundingBoxSize = 4; object->unk_09C = 2; object->unk_04C = random_int(0x012CU); - set_object_flag_status_true(objectIndex, 0x04000220); + set_object_flag(objectIndex, 0x04000220); // This code has been significantly refactored from the original func_800845C8 // Into a switch statement instead of checking for the index of the penguin diff --git a/src/engine/objects/OPenguin.h b/src/engine/objects/Penguin.h similarity index 70% rename from src/engine/objects/OPenguin.h rename to src/engine/objects/Penguin.h index 5df5ef9ea..0e9c36f49 100644 --- a/src/engine/objects/OPenguin.h +++ b/src/engine/objects/Penguin.h @@ -13,19 +13,6 @@ extern "C" { #include "course_offsets.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 { diff --git a/src/engine/objects/Seagull.cpp b/src/engine/objects/Seagull.cpp new file mode 100644 index 000000000..4b36bbf31 --- /dev/null +++ b/src/engine/objects/Seagull.cpp @@ -0,0 +1,194 @@ +#include +#include +#include "Seagull.h" +#include "engine/Actor.h" +#include "ObjectReimpl.h" +#include + +#include "port/Game.h" + +extern "C" { +#include "macros.h" +#include "main.h" +#include "defines.h" +#include "camera.h" +#include "update_objects.h" +#include "render_objects.h" +#include "actors.h" +#include "code_80057C60.h" +#include "code_80086E70.h" +#include "math_util.h" +#include "math_util_2.h" +#include "code_80005FD0.h" +#include "some_data.h" +#include "ceremony_and_credits.h" +extern SplineData D_800E6034; +extern SplineData D_800E60F0; +extern SplineData D_800E61B4; +extern SplineData D_800E6280; +} + +SplineData* D_800E633C[] = { &D_800E6034, &D_800E60F0, &D_800E61B4, &D_800E6280 }; + +OSeagull::OSeagull(s32 i, Vec3f pos) { + size_t objectId; + _idx = i; + + s16 randZ; + s16 randX; + s16 randY; + randX = random_int(200) + -100.0; + randY = random_int(20); + randZ = random_int(200) + -100.0; + + SpawnPos[0] = pos[0] + randX; + SpawnPos[1] = pos[1] + randY; + SpawnPos[2] = pos[2] + randZ; + + //for (i = 0; i < NUM_SEAGULLS; i++) { + + + //objectId = indexObjectList2[i]; + //init_object(objectId, 0); + + + //set_obj_origin_pos(objectId, pos[0], pos[1], pos[2]); + //if (i < (NUM_SEAGULLS / 2)) { + //gObjectList[objectId].unk_0D5 = 0; + //} else { + // gObjectList[objectId].unk_0D5 = 1; + //} + //} +} + +bool OSeagull::IsMod() { return true; } + +void OSeagull::Tick() { + Object* object; + UNUSED s32* var_s4; + s32 temp_s0; + + //for (var_s3 = 0; var_s3 < NUM_SEAGULLS; var_s3++) { + //temp_s0 = indexObjectList2[_idx]; + + //object = &gObjectList[temp_s0]; + if (_state == 0) { + return; + } + + OSeagull::func_80082714(temp_s0, _idx); + OSeagull::func_8008275C(temp_s0); + if (_toggle) { + _toggle = false; + if (D_80165A90 != 0) { + D_80165A90 = 0; + D_80183E40[0] = 0.0f; + D_80183E40[1] = 0.0f; + D_80183E40[2] = 0.0f; + if (gGamestate != CREDITS_SEQUENCE) { + func_800C98B8(Pos, D_80183E40, SOUND_ARG_LOAD(0x19, 0x01, 0x70, 0x43)); + } else { + //temp_s0 = indexObjectList2[1]; + //! @todo confirm this is equivallent to indexObjectList2[1]; + if (_idx == 1) { + if (gCutsceneShotTimer <= 150) { + //object = &gObjectList[temp_s0]; + func_800C98B8(Pos, D_80183E40, SOUND_ARG_LOAD(0x19, 0x01, 0x70, 0x43)); + } + } + } + } + } + //} + if (D_80165900 != 0) { + D_80165900 -= 1; + } else { + if (gGamestate != CREDITS_SEQUENCE) { + D_80165900 = 60; + } else { + D_80165900 = 15; + } + if ((D_80165908 != 0) && (D_80165A90 == 0)) { + D_80165A90 = 1; + } + } + D_80165908 = 0; +} + +void OSeagull::Draw(Camera* camera) { // render_object_seagulls + s32 var_s1; + //for (i = 0; i < NUM_SEAGULLS; i++) { + var_s1 = indexObjectList2[_idx]; + //! @todo: Quick hack to let seagull work in actor system. Should be cameraId not camera->playerId + //if (func_8008A364(var_s1, camera->playerId, 0x5555U, 0x000005DC) < 0x9C401 && CVarGetInteger("gNoCulling", 0) == 0) { + D_80165908 = 1; + _toggle = true; + //} + //if (is_obj_flag_status_active(var_s1, VISIBLE) != 0) { + func_800552BC(var_s1); + //} + //} +} + +void OSeagull::func_8008275C(s32 objectIndex) { + UNUSED s32 stackPadding; + switch (gObjectList[objectIndex].unk_0DD) { + case 1: + func_8008B78C(objectIndex); + ObjectImpl::CalculateNewPosOffset(this); + break; + case 2: + func_8008B78C(objectIndex); + vec3f_copy(gObjectList[objectIndex].unk_01C, gObjectList[objectIndex].pos); + func_8000D940(SpawnPos, (s16*) &gObjectList[objectIndex].unk_0C6, + gObjectList[objectIndex].unk_034, 0.0f, 0); + Offset[0] *= 2.0; + Offset[1] *= 2.5; + Offset[2] *= 2.0; + ObjectImpl::CalculateNewPosOffset(this); + gObjectList[objectIndex].direction_angle[1] = + get_angle_between_two_vectors(gObjectList[objectIndex].unk_01C, gObjectList[objectIndex].pos); + break; + } + func_800873F4(objectIndex); +} + +void OSeagull::func_8008241C(s32 objectIndex, s32 arg1) { + UNUSED s16 stackPadding0; + + gObjectList[objectIndex].unk_0D8 = 1; + gObjectList[objectIndex].model = (Gfx*) d_course_koopa_troopa_beach_unk4; + gObjectList[objectIndex].vertex = (Vtx*) d_course_koopa_troopa_beach_unk_data5; + gObjectList[objectIndex].sizeScaling = 0.2f; + gObjectList[objectIndex].unk_0DD = 1; + // if (gGamestate == CREDITS_SEQUENCE) { + // set_obj_origin_pos(objectIndex, randX + -360.0, randY + 60.0, randZ + -1300.0); + // } else if (gObjectList[objectIndex].unk_0D5 != 0) { + // set_obj_origin_pos(objectIndex, (randX + 328.0) * xOrientation, randY + 20.0, randZ + 2541.0); + // } else { + // set_obj_origin_pos(objectIndex, (randX + -985.0) * xOrientation, randY + 15.0, randZ + 1200.0); + // } + set_obj_direction_angle(objectIndex, 0U, 0U, 0U); + gObjectList[objectIndex].unk_034 = 1.0f; + func_80086EF0(objectIndex); + //gObjectList[objectIndex].spline = D_800E633C[arg1 % 4]; + spline = D_800E633C[arg1 % 4]; + //set_object_flag(objectIndex, 0x800); + //object_next_state(objectIndex); + _status |= 0x800; + _timer = 0; + _status &= ~0x2000; + _state++; +} + + +void OSeagull::func_80082714(s32 objectIndex, s32 arg1) { + switch (gObjectList[objectIndex].state) { + case 1: + OSeagull::func_8008241C(objectIndex, arg1); + break; + case 0: + default: + break; + } +} \ No newline at end of file diff --git a/src/engine/objects/Seagull.h b/src/engine/objects/Seagull.h new file mode 100644 index 000000000..798d25f8d --- /dev/null +++ b/src/engine/objects/Seagull.h @@ -0,0 +1,44 @@ +#pragma once + +#include +#include +#include "engine/Actor.h" + +extern "C" { +#include "macros.h" +#include "main.h" +#include "vehicles.h" +#include "waypoints.h" +#include "common_structs.h" +#include "objects.h" +#include "course_offsets.h" +#include "some_data.h" +} + + +class OSeagull : public AActor { +public: + enum Behaviour : uint16_t { + }; + +public: + explicit OSeagull(s32 i, Vec3f pos); + + virtual void Tick() override; + virtual void Draw(Camera*) override; + + void func_8008275C(s32 objectIndex); + void func_8008241C(s32 objectIndex, s32 arg1); + void func_80082714(s32 objectIndex, s32 arg1); + virtual bool IsMod() override; + Vec3f Offset; + Vec3f SpawnPos; +private: + s32 _idx; + s32 _state; + s32 _timer; + s32 _status; + bool _toggle; + + SplineData *spline; +}; diff --git a/src/engine/objects/OThwomp.cpp b/src/engine/objects/Thwomp.cpp similarity index 98% rename from src/engine/objects/OThwomp.cpp rename to src/engine/objects/Thwomp.cpp index 558b00534..87d670cfd 100644 --- a/src/engine/objects/OThwomp.cpp +++ b/src/engine/objects/Thwomp.cpp @@ -1,6 +1,6 @@ #include #include -#include "OThwomp.h" +#include "Thwomp.h" #include #include "port/Game.h" @@ -305,17 +305,17 @@ void OThwomp::SetVisibility(s32 objectIndex) { // func_8008A4CC s32 loopIndex; Camera* camera; - set_object_flag_status_false(objectIndex, 0x00070000); + clear_object_flag(objectIndex, 0x00070000); for (loopIndex = 0, camera = camera1; loopIndex < gPlayerCountSelection1; loopIndex++, camera++) { if (gObjectList[objectIndex].state != 0) { if ((D_8018CF68[loopIndex] >= (gObjectList[objectIndex].unk_0DF - 1)) && ((gObjectList[objectIndex].unk_0DF + 1) >= D_8018CF68[loopIndex])) { - set_object_flag_status_true(objectIndex, 0x00010000); + set_object_flag(objectIndex, 0x00010000); if (D_8018CF68[loopIndex] == gObjectList[objectIndex].unk_0DF) { - set_object_flag_status_true(objectIndex, 0x00020000); + set_object_flag(objectIndex, 0x00020000); } if (is_object_visible_on_camera(objectIndex, camera, 0x2AABU) != 0) { - set_object_flag_status_true(objectIndex, VISIBLE); + set_object_flag(objectIndex, VISIBLE); } } } @@ -619,7 +619,7 @@ void OThwomp::func_80080B28(s32 objectIndex, s32 playerId) { } OThwomp::func_80080DE4(objectIndex); func_80075304(gObjectList[objectIndex].pos, 3, 3, D_8018D3C4); - set_object_flag_status_false(objectIndex, 0x00000200); + clear_object_flag(objectIndex, 0x00000200); func_800722A4(objectIndex, 0x00000040); func_80086F60(objectIndex); func_800726CC(objectIndex, 0x000000C8); @@ -666,7 +666,7 @@ void OThwomp::Draw(s32 cameraId) { camera = &camera1[cameraId]; if (cameraId == PLAYER_ONE) { objectIndex = indexObjectList1[_idx]; - set_object_flag_status_false(objectIndex, 0x00070000); + clear_object_flag(objectIndex, 0x00070000); func_800722CC(objectIndex, 0x00000110); } @@ -831,7 +831,7 @@ void OThwomp::func_8007EC30(s32 objectIndex) { 0x10U, (u16) 0x00000040); object->model = (Gfx*)d_course_bowsers_castle_dl_thwomp; object->unk_01C[1] = 30.0f; - set_object_flag_status_true(objectIndex, 0x05000220); + set_object_flag(objectIndex, 0x05000220); object->type = 0; object->unk_0DF = 6; func_800724DC(objectIndex); @@ -868,7 +868,7 @@ void OThwomp::func_8007EE5C(s32 objectIndex) { 0x10U, (u16) 0x00000040); object = &gObjectList[objectIndex]; object->model = (Gfx*)d_course_bowsers_castle_dl_thwomp; - set_object_flag_status_true(objectIndex, 0x04000220); + set_object_flag(objectIndex, 0x04000220); object->type = 0; object->unk_0DF = 6; func_80086E70(objectIndex); @@ -921,7 +921,7 @@ void OThwomp::func_8007FA08(s32 objectIndex) { 0x10U, (u16) 0x00000040); object = &gObjectList[objectIndex]; object->model = (Gfx*)d_course_bowsers_castle_dl_thwomp; - set_object_flag_status_true(objectIndex, 0x04000220); + set_object_flag(objectIndex, 0x04000220); object->type = 0; object->surfaceHeight = 0.0f; object->origin_pos[1] = 0.0f; @@ -1087,7 +1087,7 @@ void OThwomp::func_80080078(s32 objectIndex) { // func_80080078 0x10U, (u16) 0x00000040); object = &gObjectList[objectIndex]; object->model = (Gfx*)d_course_bowsers_castle_dl_thwomp; - set_object_flag_status_true(objectIndex, 0x04000220); + set_object_flag(objectIndex, 0x04000220); object->type = 2; object->unk_0DF = 8; set_obj_direction_angle(objectIndex, 0U, 0U, 0U); @@ -1159,7 +1159,7 @@ void OThwomp::func_800802C0(s32 objectIndex) { object->model = (Gfx*)d_course_bowsers_castle_dl_thwomp; object->textureListIndex = 0; //object->sizeScaling = 1.5f; - set_object_flag_status_true(objectIndex, 0x05000220); + set_object_flag(objectIndex, 0x05000220); object->type = 1; object->unk_0DF = 6; set_obj_origin_offset(objectIndex, 0.0f, 0.0f, 0.0f); @@ -1269,7 +1269,7 @@ void OThwomp::func_80080524(s32 objectIndex) { object = &gObjectList[objectIndex]; object->model = (Gfx*)d_course_bowsers_castle_dl_thwomp; object->textureListIndex = 0; - set_object_flag_status_true(objectIndex, 0x04000220); + set_object_flag(objectIndex, 0x04000220); object->type = 0; object->unk_0DF = 0x0A; func_80086E70(objectIndex); @@ -1302,7 +1302,7 @@ void OThwomp::func_8007E63C(s32 objectIndex) { case 0x32: if (f32_step_up_towards(&gObjectList[objectIndex].offset[1], gObjectList[objectIndex].unk_01C[1] + 15.0, 1.5f) != 0) { - set_object_flag_status_true(objectIndex, 0x00000200); + set_object_flag(objectIndex, 0x00000200); func_800722A4(objectIndex, 1); func_800722CC(objectIndex, 2); object_next_state(objectIndex); @@ -1345,7 +1345,7 @@ void OThwomp::func_8007E63C(s32 objectIndex) { } if (f32_step_up_towards(&gObjectList[objectIndex].offset[1], gObjectList[objectIndex].unk_01C[1], 0.5f) != 0) { - set_object_flag_status_false(objectIndex, 0x00000200); + clear_object_flag(objectIndex, 0x00000200); func_8007266C(objectIndex); } break; @@ -1417,7 +1417,7 @@ void OThwomp::func_8007E63C(s32 objectIndex) { case 0x6C: if (set_and_run_timer_object(objectIndex, 0x00000064) != 0) { func_800722CC(objectIndex, 2); - set_object_flag_status_false(objectIndex, 0x00000200); + clear_object_flag(objectIndex, 0x00000200); func_8007266C(objectIndex); } break; diff --git a/src/engine/objects/OThwomp.h b/src/engine/objects/Thwomp.h similarity index 100% rename from src/engine/objects/OThwomp.h rename to src/engine/objects/Thwomp.h diff --git a/src/port/Game.cpp b/src/port/Game.cpp index 337321662..300deed9f 100644 --- a/src/port/Game.cpp +++ b/src/port/Game.cpp @@ -32,7 +32,7 @@ #include "engine/courses/PodiumCeremony.h" #include "engine/TrainCrossing.h" -#include "src/engine/objects/OBombKart.h" +#include "src/engine/objects/BombKart.h" #include "Smoke.h" @@ -378,6 +378,18 @@ extern "C" { } } + void CourseManager_TickObjects() { + if (gWorldInstance.CurrentCourse) { + gWorldInstance.TickObjects(); + } + } + + void CourseManager_DrawObjects(Camera* camera) { + if (gWorldInstance.CurrentCourse) { + gWorldInstance.DrawObjects(camera); + } + } + // Helps prevents users from forgetting to add a finishline to their course bool cm_DoesFinishlineExist() { for (AActor* actor : gWorldInstance.Actors) { @@ -522,6 +534,22 @@ extern "C" { } } + void CourseManager_DrawSeagulls(s32 cameraId) { + for (auto& seagull : gWorldInstance.Seagulls) { + if (seagull) { + // seagull->Draw(cameraId); + } + } + } + + void CourseManager_TickSeagulls(void) { + for (auto& seagull : gWorldInstance.Seagulls) { + if (seagull) { + //seagull->Tick(); + } + } + } + void CourseManager_DrawPenguins(s32 cameraId) { for (auto& penguin : gWorldInstance.Penguins) { if (penguin) { diff --git a/src/port/Game.h b/src/port/Game.h index 6e19b1b63..0cf450c34 100644 --- a/src/port/Game.h +++ b/src/port/Game.h @@ -49,6 +49,9 @@ void CourseManager_InitClouds(); void CourseManager_DrawActor(Camera* camera, struct Actor* actor); +void CourseManager_TickObjects(); +void CourseManager_DrawObjects(Camera* camera); + void CourseManager_UpdateClouds(s32 arg0, Camera* camera); void CourseManager_Waypoints(Player* player, int8_t playerId); @@ -100,6 +103,10 @@ void CourseManager_DrawThwomps(s32 cameraId); void CourseManager_TickThwomps(); +void CourseManager_DrawSeagulls(s32 cameraId); + +void CourseManager_TickSeagulls(); + void CourseManager_DrawPenguins(s32 cameraId); void CourseManager_TickPenguins(); diff --git a/src/render_objects.c b/src/render_objects.c index a5b828f0f..a56e91c0d 100644 --- a/src/render_objects.c +++ b/src/render_objects.c @@ -4015,86 +4015,6 @@ void func_80054BE8(s32 cameraId) { } } -void func_80054D00(s32 objectIndex, s32 cameraId) { - Camera* camera; - - camera = &camera1[cameraId]; - if (gObjectList[objectIndex].state >= 3) { - func_8008A364(objectIndex, cameraId, 0x2AABU, 0x0000012C); - if (is_obj_flag_status_active(objectIndex, VISIBLE) != 0) { - D_80183E80[0] = (s16) gObjectList[objectIndex].orientation[0]; - D_80183E80[1] = - func_800418AC(gObjectList[objectIndex].pos[0], gObjectList[objectIndex].pos[2], camera->pos); - D_80183E80[2] = (u16) gObjectList[objectIndex].orientation[2]; - func_80048130(gObjectList[objectIndex].pos, (u16*) D_80183E80, gObjectList[objectIndex].sizeScaling, - (u8*) gObjectList[objectIndex].activeTLUT, gObjectList[objectIndex].activeTexture, - LOAD_ASSET(D_0D0062B0), 0x00000020, 0x00000040, 0x00000020, 0x00000040, 5); - } - } -} - -void func_80054E10(s32 objectIndex) { - if (gObjectList[objectIndex].state > 0) { - if (is_obj_flag_status_active(objectIndex, 0x00800000) != 0) { - D_80183E50[0] = gObjectList[objectIndex].pos[0]; - D_80183E50[1] = gObjectList[objectIndex].surfaceHeight + 0.8; - D_80183E50[2] = gObjectList[objectIndex].pos[2]; - D_80183E70[0] = gObjectList[objectIndex].velocity[0]; - D_80183E70[1] = gObjectList[objectIndex].velocity[1]; - D_80183E70[2] = gObjectList[objectIndex].velocity[2]; - func_8004A9B8(gObjectList[objectIndex].sizeScaling); - } - } -} - -// Almost certainly responsible for spawning/handling the moles on Moo Moo farm -void func_80054EB8(UNUSED s32 unused) { - s32 someIndex; - - for (someIndex = 0; someIndex < NUM_TOTAL_MOLES; someIndex++) { - func_80054E10(gObjectParticle1[someIndex]); - } -} - -void func_80054F04(s32 cameraId) { - s32 var_s2; - s32 objectIndex; - Camera* sp44; - Object* object; - - sp44 = &camera1[cameraId]; - gSPDisplayList(gDisplayListHead++, D_0D0079C8); - load_texture_block_rgba16_mirror((u8*) LOAD_ASSET(d_course_moo_moo_farm_mole_dirt), 0x00000010, 0x00000010); - for (var_s2 = 0; var_s2 < gObjectParticle2_SIZE; var_s2++) { - objectIndex = gObjectParticle2[var_s2]; - object = &gObjectList[objectIndex]; - if (object->state > 0) { - func_8008A364(objectIndex, cameraId, 0x2AABU, 0x000000C8); - if ((is_obj_flag_status_active(objectIndex, VISIBLE) != 0) && (gMatrixHudCount <= MTX_HUD_POOL_SIZE_MAX)) { - object->orientation[1] = func_800418AC(object->pos[0], object->pos[2], sp44->pos); - rsp_set_matrix_gObjectList(objectIndex); - gSPDisplayList(gDisplayListHead++, D_0D006980); - } - } - } - gSPTexture(gDisplayListHead++, 1, 1, 0, G_TX_RENDERTILE, G_OFF); -} - -void render_object_moles(s32 cameraId) { - s32 i; - - for (i = 0; i < NUM_GROUP1_MOLES; i++) { - func_80054D00(indexObjectList1[i], cameraId); - } - for (i = 0; i < NUM_GROUP2_MOLES; i++) { - func_80054D00(indexObjectList2[i], cameraId); - } - for (i = 0; i < NUM_GROUP3_MOLES; i++) { - func_80054D00(indexObjectList3[i], cameraId); - } - func_80054EB8(cameraId); - func_80054F04(cameraId); -} void func_80055164(s32 objectIndex) { if (gObjectList[objectIndex].state >= 2) { @@ -4141,51 +4061,6 @@ void func_800552BC(s32 objectIndex) { } } -void render_object_seagulls(s32 arg0) { - s32 i; - s32 var_s1; - - for (i = 0; i < NUM_SEAGULLS; i++) { - var_s1 = indexObjectList2[i]; - if (func_8008A364(var_s1, arg0, 0x5555U, 0x000005DC) < 0x9C401 && CVarGetInteger("gNoCulling", 0) == 0) { - D_80165908 = 1; - func_800722A4(var_s1, 2); - } - if (is_obj_flag_status_active(var_s1, VISIBLE) != 0) { - func_800552BC(var_s1); - } - } -} - -void draw_crabs(s32 objectIndex, s32 cameraId) { - Camera* camera; - - if (gObjectList[objectIndex].state >= 2) { - Vtx* vtx = (Vtx*) LOAD_ASSET(common_vtx_hedgehog); - camera = &camera1[cameraId]; - func_8004A6EC(objectIndex, 0.5f); - gObjectList[objectIndex].orientation[1] = - func_800418AC(gObjectList[objectIndex].pos[0], gObjectList[objectIndex].pos[2], camera->pos); - draw_2d_texture_at(gObjectList[objectIndex].pos, gObjectList[objectIndex].orientation, - gObjectList[objectIndex].sizeScaling, (u8*) gObjectList[objectIndex].activeTLUT, - gObjectList[objectIndex].activeTexture, vtx, 64, 64, - 64, 32); - } -} - -void render_object_crabs(s32 arg0) { - s32 someIndex; - s32 test; - - for (someIndex = 0; someIndex < NUM_CRABS; someIndex++) { - test = indexObjectList1[someIndex]; - func_8008A364(test, arg0, 0x2AABU, 0x00000320); - if (is_obj_flag_status_active(test, VISIBLE) != 0) { - draw_crabs(test, arg0); - } - } -} - void func_800555BC(s32 objectIndex, s32 cameraId) { Camera* camera; @@ -4212,14 +4087,14 @@ void render_object_hedgehogs(s32 arg0) { something = MIN(something, 0x52211U - 1); } if (is_obj_flag_status_active(test, VISIBLE) != 0) { - set_object_flag_status_true(test, 0x00200000); + set_object_flag(test, 0x00200000); if (something < 0x2711U) { - set_object_flag_status_true(test, 0x00000020); + set_object_flag(test, 0x00000020); } else { - set_object_flag_status_false(test, 0x00000020); + clear_object_flag(test, 0x00000020); } if (something < 0x57E41U) { - set_object_flag_status_true(test, 0x00400000); + set_object_flag(test, 0x00400000); } if (something < 0x52211U) { func_800555BC(test, arg0); @@ -4382,7 +4257,7 @@ void render_object_hot_air_balloon(s32 arg0) { func_80055CCC(objectIndex, arg0); } } else { - set_object_flag_status_false(objectIndex, 0x00100000); + clear_object_flag(objectIndex, 0x00100000); func_80055CCC(objectIndex, arg0); } } @@ -4682,7 +4557,7 @@ void render_bomb_karts(s32 cameraId) { } else if (gGamestate != 5) { gBombKarts[i].unk_4A = 1; } - set_object_flag_status_false(objectIndex, 0x00200000); + clear_object_flag(objectIndex, 0x00200000); } } @@ -4697,7 +4572,7 @@ void render_bomb_karts(s32 cameraId) { gObjectList[objectIndex].pos[2] = var_s1_2->bombPos[2]; temp_s4 = func_8008A364(objectIndex, cameraId, 0x31C4U, 0x000001F4); if (is_obj_flag_status_active(objectIndex, VISIBLE) != 0) { - set_object_flag_status_true(objectIndex, 0x00200000); + set_object_flag(objectIndex, 0x00200000); D_80183E80[0] = 0; D_80183E80[1] = func_800418AC(var_s1_2->bombPos[0], var_s1_2->bombPos[2], camera->pos); D_80183E80[2] = 0x8000; diff --git a/src/render_objects.h b/src/render_objects.h index 9a6ffd1e9..b77d7ce18 100644 --- a/src/render_objects.h +++ b/src/render_objects.h @@ -372,7 +372,6 @@ void func_80055164(s32); void func_80055228(s32); void func_800552BC(s32); void render_object_seagulls(s32); -void draw_crabs(s32, s32); void render_object_crabs(s32); void func_800555BC(s32, s32); void render_object_hedgehogs(s32); diff --git a/src/update_objects.c b/src/update_objects.c index f06012939..e441e2392 100644 --- a/src/update_objects.c +++ b/src/update_objects.c @@ -201,7 +201,7 @@ void func_80072120(s32* arg0, s32 arg1) { s32 i; for (i = 0; i < arg1; i++) { - set_object_flag_status_false(*arg0, 0x00600000); + clear_object_flag(*arg0, 0x00600000); arg0++; } } @@ -215,11 +215,11 @@ void func_80072180(void) { } } -void set_object_flag_status_true(s32 objectIndex, s32 flag) { +void set_object_flag(s32 objectIndex, s32 flag) { gObjectList[objectIndex].status |= flag; } -void set_object_flag_status_false(s32 objectIndex, s32 flag) { +void clear_object_flag(s32 objectIndex, s32 flag) { gObjectList[objectIndex].status &= ~flag; } @@ -302,7 +302,7 @@ void func_80072428(s32 objectIndex) { void object_next_state(s32 objectIndex) { set_object_timer_state(objectIndex, 0); - set_object_flag_status_false(objectIndex, 0x2000); + clear_object_flag(objectIndex, 0x2000); gObjectList[objectIndex].state++; } @@ -322,8 +322,8 @@ s16 func_80072530(s32 objectIndex) { void func_80072568(s32 objectIndex, s32 arg1) { set_object_timer_state(objectIndex, 0); - set_object_flag_status_false(objectIndex, 0x2000); - set_object_flag_status_false(objectIndex, 8); + clear_object_flag(objectIndex, 0x2000); + clear_object_flag(objectIndex, 8); object_next_state(objectIndex); func_800724F8(objectIndex, gObjectList[objectIndex].state); gObjectList[objectIndex].state = arg1; @@ -331,8 +331,8 @@ void func_80072568(s32 objectIndex, s32 arg1) { void func_800725E8(s32 objectIndex, s32 arg1, s32 arg2) { set_object_timer_state(objectIndex, 0); - set_object_flag_status_false(objectIndex, 0x2000); - set_object_flag_status_false(objectIndex, 8); + clear_object_flag(objectIndex, 0x2000); + clear_object_flag(objectIndex, 8); gObjectList[objectIndex].state = arg2; func_800724F8(objectIndex, gObjectList[objectIndex].state); gObjectList[objectIndex].state = arg1; @@ -342,14 +342,14 @@ s16 func_80072530(s32); // extern void func_8007266C(s32 objectIndex) { set_object_timer_state(objectIndex, 0); - set_object_flag_status_false(objectIndex, 0x2000); - set_object_flag_status_false(objectIndex, 8); + clear_object_flag(objectIndex, 0x2000); + clear_object_flag(objectIndex, 8); gObjectList[objectIndex].state = func_80072530(objectIndex); } void func_800726CC(s32 objectIndex, s32 arg1) { set_object_timer_state(objectIndex, 0); - set_object_flag_status_false(objectIndex, 0x2000); + clear_object_flag(objectIndex, 0x2000); gObjectList[objectIndex].state = arg1; } @@ -499,14 +499,14 @@ s32 func_80072B48(s32 objectIndex, s32 arg1) { phi_v1 = 0; if (gObjectList[objectIndex].isTimerActive == 0) { set_object_timer_state(objectIndex, 1); - set_object_flag_status_true(objectIndex, 0x80000); + set_object_flag(objectIndex, 0x80000); gObjectList[objectIndex].textureListIndex = D_8018D140; gObjectList[objectIndex].timer = arg1; } gObjectList[objectIndex].timer--; if (gObjectList[objectIndex].timer < 0) { - set_object_flag_status_false(objectIndex, 0x80000); + clear_object_flag(objectIndex, 0x80000); set_object_timer_state(objectIndex, 0); object_next_state(objectIndex); phi_v1 = 1; @@ -521,16 +521,16 @@ void func_80072C00(s32 objectIndex, s32 arg1, s32 arg2, s32 arg3) { gObjectList[objectIndex].textureListIndex = arg1; gObjectList[objectIndex].unk_0D4 = 1; gObjectList[objectIndex].unk_0CC = arg3; - set_object_flag_status_true(objectIndex, 0x2000); + set_object_flag(objectIndex, 0x2000); } else { gObjectList[objectIndex].timer--; if (gObjectList[objectIndex].timer < 0) { gObjectList[objectIndex].timer = arg2; gObjectList[objectIndex].unk_0D4--; if ((gObjectList[objectIndex].unk_0D4 & 1) != 0) { - set_object_flag_status_false(objectIndex, 0x80000); + clear_object_flag(objectIndex, 0x80000); } else { - set_object_flag_status_true(objectIndex, 0x80000); + set_object_flag(objectIndex, 0x80000); } if (gObjectList[objectIndex].unk_0D4 < 0) { @@ -541,7 +541,7 @@ void func_80072C00(s32 objectIndex, s32 arg1, s32 arg2, s32 arg3) { } if (gObjectList[objectIndex].unk_0CC == 0) { - set_object_flag_status_false(objectIndex, 0x2000); + clear_object_flag(objectIndex, 0x2000); object_next_state(objectIndex); } } @@ -555,7 +555,7 @@ void func_80072D3C(s32 objectIndex, s32 arg1, s32 arg2, s32 arg3, s32 arg4) { gObjectList[objectIndex].textureListIndex = arg1; gObjectList[objectIndex].unk_0D4 = 1; gObjectList[objectIndex].unk_0CC = arg4; - set_object_flag_status_true(objectIndex, 0x2000); + set_object_flag(objectIndex, 0x2000); return; } @@ -576,7 +576,7 @@ void func_80072D3C(s32 objectIndex, s32 arg1, s32 arg2, s32 arg3, s32 arg4) { } if (gObjectList[objectIndex].unk_0CC == 0) { - set_object_flag_status_false(objectIndex, 0x2000); + clear_object_flag(objectIndex, 0x2000); object_next_state(objectIndex); } } @@ -592,7 +592,7 @@ s32 func_80072E54(s32 objectIndex, s32 arg1, s32 arg2, s32 arg3, s32 arg4, s32 a gObjectList[objectIndex].timer = arg4; gObjectList[objectIndex].unk_0CC = arg5; set_object_timer_state(objectIndex, 1); - set_object_flag_status_true(objectIndex, 0x2000); + set_object_flag(objectIndex, 0x2000); } else { gObjectList[objectIndex].timer--; if (gObjectList[objectIndex].timer <= 0) { @@ -605,7 +605,7 @@ s32 func_80072E54(s32 objectIndex, s32 arg1, s32 arg2, s32 arg3, s32 arg4, s32 a } if (gObjectList[objectIndex].unk_0CC == 0) { gObjectList[objectIndex].textureListIndex = arg2; - set_object_flag_status_false(objectIndex, 0x2000); + clear_object_flag(objectIndex, 0x2000); set_object_timer_state(objectIndex, 0); object_next_state(objectIndex); sp24 = 1; @@ -627,7 +627,7 @@ bool func_80072F88(s32 objectIndex, s32 arg1, s32 arg2, s32 arg3, s32 arg4, s32 gObjectList[objectIndex].timer = arg4; gObjectList[objectIndex].unk_0CC = arg5; set_object_timer_state(objectIndex, 1); - set_object_flag_status_true(objectIndex, 0x2000); + set_object_flag(objectIndex, 0x2000); } else { gObjectList[objectIndex].timer--; if (gObjectList[objectIndex].timer <= 0) { @@ -639,7 +639,7 @@ bool func_80072F88(s32 objectIndex, s32 arg1, s32 arg2, s32 arg3, s32 arg4, s32 } if (gObjectList[objectIndex].unk_0CC == 0) { gObjectList[objectIndex].textureListIndex = arg2; - set_object_flag_status_false(objectIndex, 0x2000); + clear_object_flag(objectIndex, 0x2000); set_object_timer_state(objectIndex, 0); object_next_state(objectIndex); sp24 = true; @@ -661,8 +661,8 @@ bool func_800730BC(s32 objectIndex, s32 arg1, s32 arg2, s32 arg3, s32 arg4, s32 gObjectList[objectIndex].timer = arg4; gObjectList[objectIndex].unk_0CC = arg5; set_object_timer_state(objectIndex, 1); - set_object_flag_status_true(objectIndex, 0x2000); - set_object_flag_status_false(objectIndex, 0x4000); + set_object_flag(objectIndex, 0x2000); + clear_object_flag(objectIndex, 0x4000); } else { gObjectList[objectIndex].timer--; if (gObjectList[objectIndex].timer <= 0) { @@ -671,7 +671,7 @@ bool func_800730BC(s32 objectIndex, s32 arg1, s32 arg2, s32 arg3, s32 arg4, s32 gObjectList[objectIndex].textureListIndex += arg3; if (gObjectList[objectIndex].textureListIndex >= arg2) { gObjectList[objectIndex].textureListIndex = arg2; - set_object_flag_status_true(objectIndex, 0x4000); + set_object_flag(objectIndex, 0x4000); } } else { gObjectList[objectIndex].textureListIndex -= arg3; @@ -682,14 +682,14 @@ bool func_800730BC(s32 objectIndex, s32 arg1, s32 arg2, s32 arg3, s32 arg4, s32 } if (gObjectList[objectIndex].unk_0CC == 0) { - set_object_flag_status_false(objectIndex, 0x80); - set_object_flag_status_false(objectIndex, 0x2000); + clear_object_flag(objectIndex, 0x80); + clear_object_flag(objectIndex, 0x2000); set_object_timer_state(objectIndex, 0); object_next_state(objectIndex); sp24 = true; } else { - set_object_flag_status_false(objectIndex, 0x4000); - set_object_flag_status_true(objectIndex, 0x80); + clear_object_flag(objectIndex, 0x4000); + set_object_flag(objectIndex, 0x80); } } } @@ -707,8 +707,8 @@ s32 func_8007326C(s32 objectIndex, s32 arg1, s32 arg2, s32 arg3, s32 arg4, s32 a gObjectList[objectIndex].timer = arg4; gObjectList[objectIndex].unk_0CC = arg5; set_object_timer_state(objectIndex, 1); - set_object_flag_status_true(objectIndex, 0x2000); - set_object_flag_status_false(objectIndex, 0x4000); + set_object_flag(objectIndex, 0x2000); + clear_object_flag(objectIndex, 0x4000); } else { gObjectList[objectIndex].timer--; if (gObjectList[objectIndex].timer <= 0) { @@ -717,7 +717,7 @@ s32 func_8007326C(s32 objectIndex, s32 arg1, s32 arg2, s32 arg3, s32 arg4, s32 a gObjectList[objectIndex].textureListIndex -= arg3; if (arg2 >= gObjectList[objectIndex].textureListIndex) { gObjectList[objectIndex].textureListIndex = arg2; - set_object_flag_status_true(objectIndex, 0x4000); + set_object_flag(objectIndex, 0x4000); } } else { gObjectList[objectIndex].textureListIndex += arg3; @@ -727,12 +727,12 @@ s32 func_8007326C(s32 objectIndex, s32 arg1, s32 arg2, s32 arg3, s32 arg4, s32 a gObjectList[objectIndex].unk_0CC--; } if (gObjectList[objectIndex].unk_0CC == 0) { - set_object_flag_status_false(objectIndex, 0x2000); + clear_object_flag(objectIndex, 0x2000); set_object_timer_state(objectIndex, 0); object_next_state(objectIndex); sp24 = 1; } else { - set_object_flag_status_false(objectIndex, 0x4000); + clear_object_flag(objectIndex, 0x4000); } } } @@ -811,26 +811,26 @@ void func_80073600(s32 objectIndex) { set_object_timer_state(objectIndex, 0); gObjectList[objectIndex].unk_0D6 = 0; gObjectList[objectIndex].unk_04C = -1; - set_object_flag_status_false(objectIndex, 0x8000); + clear_object_flag(objectIndex, 0x8000); } void func_80073654(s32 objectIndex) { - set_object_flag_status_false(objectIndex, 0x8000); + clear_object_flag(objectIndex, 0x8000); ++gObjectList[objectIndex].unk_0D6; } UNUSED void func_8007369C(s32 objectIndex, s32 arg1) { - set_object_flag_status_false(objectIndex, 0x8000); + clear_object_flag(objectIndex, 0x8000); gObjectList[objectIndex].unk_0D6 = arg1; } void func_800736E0(s32 objectIndex) { - set_object_flag_status_false(objectIndex, 0x8000); + clear_object_flag(objectIndex, 0x8000); gObjectList[objectIndex].unk_0D6 = 1; } void func_80073720(s32 objectIndex) { - set_object_flag_status_false(objectIndex, 0x8000); + clear_object_flag(objectIndex, 0x8000); gObjectList[objectIndex].unk_0D6 = 0; } @@ -840,11 +840,11 @@ bool func_8007375C(s32 objectIndex, s32 arg1) { sp24 = false; if (is_obj_index_flag_status_inactive(objectIndex, 0x00008000) != 0) { gObjectList[objectIndex].unk_04C = arg1; - set_object_flag_status_true(objectIndex, 0x00008000); + set_object_flag(objectIndex, 0x00008000); } gObjectList[objectIndex].unk_04C--; if (gObjectList[objectIndex].unk_04C < 0) { - set_object_flag_status_false(objectIndex, 0x00008000); + clear_object_flag(objectIndex, 0x00008000); func_80073654(objectIndex); sp24 = true; } @@ -2513,7 +2513,7 @@ void func_80077E20(s32 objectIndex) { object->textureHeight = 0x10; object->textureWidth = object->textureHeight; object->sizeScaling = 0.15f; - set_object_flag_status_true(objectIndex, 0x00000010); + set_object_flag(objectIndex, 0x00000010); func_80086EF0(objectIndex); object->primAlpha = 0x00FF; object->unk_0D5 = 0; @@ -2527,10 +2527,10 @@ void func_80077EB8(s32 objectIndex, u16 arg1, Camera* camera) { temp_v0 = camera->rot[1] - arg1; if ((temp_v0 >= D_8018D210) || (D_8018D208 >= temp_v0)) { gObjectList[objectIndex].offset[0] = D_8018D218 + (D_8018D1E8 * (f32) temp_v0); - set_object_flag_status_true(objectIndex, 0x00000010); + set_object_flag(objectIndex, 0x00000010); return; } - set_object_flag_status_false(objectIndex, 0x00000010); + clear_object_flag(objectIndex, 0x00000010); } void func_80077F64(s32 objectIndex, Camera* camera) { @@ -2727,15 +2727,15 @@ void func_800788F8(s32 objectIndex, u16 rot, Camera* camera) { temp_v0 = camera->rot[1] + rot; if ((temp_v0 >= D_8018D210) && (D_8018D208 >= temp_v0)) { gObjectList[objectIndex].unk_09C = (D_8018D218 + (D_8018D1E8 * temp_v0)); - set_object_flag_status_true(objectIndex, 0x00000010); + set_object_flag(objectIndex, 0x00000010); return; } if (CVarGetInteger("gNoCulling", 0) == 1) { gObjectList[objectIndex].unk_09C = (D_8018D218 + (D_8018D1E8 * temp_v0)); - set_object_flag_status_true(objectIndex, 0x00000010); + set_object_flag(objectIndex, 0x00000010); return; } - set_object_flag_status_false(objectIndex, 0x00000010); + clear_object_flag(objectIndex, 0x00000010); } void update_clouds(s32 arg0, Camera* arg1, CloudData* cloudList) { @@ -2979,7 +2979,7 @@ void init_obj_lakitu_red_flag_countdown(s32 objectIndex, s32 playerId) { Vtx* vtx = (Vtx*) LOAD_ASSET(common_vtx_lakitu); gObjectList[objectIndex].vertex = vtx; gObjectList[objectIndex].sizeScaling = 0.15f; - set_object_flag_status_false(objectIndex, 0x00000010); + clear_object_flag(objectIndex, 0x00000010); object_next_state(objectIndex); gObjectList[objectIndex].unk_048 = D_8018D180; } @@ -2999,7 +2999,7 @@ void update_object_lakitu_countdown(s32 objectIndex, s32 arg1) { } break; case 3: - set_object_flag_status_true(objectIndex, 0x00000010); + set_object_flag(objectIndex, 0x00000010); func_80086F10(objectIndex, 1, &D_800E67B8); // set a spline object_next_state(objectIndex); break; @@ -3094,7 +3094,7 @@ void init_obj_lakitu_red_flag(s32 objectIndex, s32 playerIndex) { object->pos[0] = 5000.0f; object->sizeScaling = 0.15f; func_80086F10(objectIndex, 2, &D_800E6834); - set_object_flag_status_false(objectIndex, 0x00000010); + clear_object_flag(objectIndex, 0x00000010); object_next_state(objectIndex); } @@ -3106,7 +3106,7 @@ void update_object_lakitu_red_flag(s32 objectIndex, s32 playerIndex) { init_obj_lakitu_red_flag(objectIndex, playerIndex); break; case 2: - set_object_flag_status_true(objectIndex, 0x00000010); + set_object_flag(objectIndex, 0x00000010); object_next_state(objectIndex); break; case 3: @@ -3169,7 +3169,7 @@ void init_obj_lakitu_red_flag_fishing(s32 objectIndex, s32 arg1) { gObjectList[objectIndex].vertex = vtx; gObjectList[objectIndex].sizeScaling = 0.15f; func_80086E70(objectIndex); - set_object_flag_status_false(objectIndex, 0x00000010); + clear_object_flag(objectIndex, 0x00000010); func_80073720(objectIndex); object_next_state(objectIndex); func_800C8F80((u8) arg1, 0x0100FA28); @@ -3211,7 +3211,7 @@ void update_object_lakitu_fishing(s32 objectIndex, s32 playerId) { init_obj_lakitu_red_flag_fishing(objectIndex, playerId); break; case 2: /* switch 1 */ - set_object_flag_status_true(objectIndex, 0x00000010); + set_object_flag(objectIndex, 0x00000010); func_800736E0(objectIndex); object_next_state(objectIndex); break; @@ -3265,7 +3265,7 @@ void update_object_lakitu_fishing2(s32 objectIndex, s32 playerId) { init_obj_lakitu_red_flag_fishing(objectIndex, playerId); break; case 2: /* switch 1 */ - set_object_flag_status_true(objectIndex, 0x00000010); + set_object_flag(objectIndex, 0x00000010); func_800736E0(objectIndex); player->unk_0CA |= 0x80; object_next_state(objectIndex); @@ -3356,7 +3356,7 @@ void func_8007A060(s32 objectIndex, s32 playerIndex) { object->pos[1] = 5000.0f; object->pos[0] = 5000.0f; object->sizeScaling = 0.15f; - set_object_flag_status_false(objectIndex, 0x00000010); + clear_object_flag(objectIndex, 0x00000010); func_80086F10(objectIndex, 5, &D_800E694C); object_next_state(objectIndex); } @@ -3369,7 +3369,7 @@ void update_object_lakitu_second_lap(s32 objectIndex, s32 playerIndex) { func_8007A060(objectIndex, playerIndex); break; case 2: - set_object_flag_status_true(objectIndex, 0x00000010); + set_object_flag(objectIndex, 0x00000010); object_next_state(objectIndex); break; case 3: @@ -3415,7 +3415,7 @@ void func_8007A228(s32 objectIndex, s32 playerIndex) { object->pos[1] = 5000.0f; object->pos[0] = 5000.0f; object->sizeScaling = 0.15f; - set_object_flag_status_false(objectIndex, 0x00000010); + clear_object_flag(objectIndex, 0x00000010); func_80086F10(objectIndex, 5, &D_800E694C); object_next_state(objectIndex); } @@ -3428,7 +3428,7 @@ void update_object_lakitu_final_lap(s32 objectIndex, s32 playerIndex) { func_8007A228(objectIndex, playerIndex); break; case 2: - set_object_flag_status_true(objectIndex, 0x00000010); + set_object_flag(objectIndex, 0x00000010); object_next_state(objectIndex); break; case 3: @@ -3472,7 +3472,7 @@ void func_8007A3F0(s32 objectIndex, s32 arg1) { gObjectList[objectIndex].pos[1] = var; gObjectList[objectIndex].pos[0] = var; gObjectList[objectIndex].sizeScaling = 0.15f; - set_object_flag_status_false(objectIndex, 0x00000010); + clear_object_flag(objectIndex, 0x00000010); func_80086F10(objectIndex, 6, &D_800E69B0); gObjectList[objectIndex].unk_0D6 = 0; object_next_state(objectIndex); @@ -3489,7 +3489,7 @@ void update_object_lakitu_reverse(s32 objectIndex, s32 playerId) { func_8007A3F0(objectIndex, playerId); break; case 2: - set_object_flag_status_true(objectIndex, 0x00000010); + set_object_flag(objectIndex, 0x00000010); gObjectList[objectIndex].unk_0D6 = 1; object_next_state(objectIndex); break; @@ -4504,7 +4504,7 @@ void func_8007BBBC(s32 objectIndex) { switch (object->state) { /* irregular */ case 1: func_800735BC(objectIndex, d_course_banshee_boardwalk_dl_cheep_cheep, 2.0f); - set_object_flag_status_true(objectIndex, 0x00000010); + set_object_flag(objectIndex, 0x00000010); object->unk_0D5 = 0; break; case 2: @@ -4576,7 +4576,7 @@ void func_8007BEC8(s32 objectIndex) { break; case 2: if (set_and_run_timer_object(objectIndex, 0x0000003C) != 0) { - set_object_flag_status_true(objectIndex, 0x00000010); + set_object_flag(objectIndex, 0x00000010); func_80086E70(objectIndex); } break; @@ -4656,7 +4656,7 @@ void func_8007BFB0(s32 objectIndex) { case 7: object->sizeScaling = (f32) ((f64) object->sizeScaling - 0.05); if ((f64) object->sizeScaling <= 0.01) { - set_object_flag_status_false(objectIndex, 0x00000010); + clear_object_flag(objectIndex, 0x00000010); object->sizeScaling = 0.000001f; func_80086FD4(objectIndex); } @@ -4707,10 +4707,10 @@ void func_8007C360(s32 objectIndex, Camera* camera) { u16 temp = ((u16) (gObjectList[objectIndex].direction_angle[1] - rot + 0x8000) * 0x24) / 0x10000; if (temp < 0x13) { - set_object_flag_status_false(objectIndex, 0x80); + clear_object_flag(objectIndex, 0x80); gObjectList[objectIndex].textureListIndex = temp; } else { - set_object_flag_status_true(objectIndex, 0x80); + set_object_flag(objectIndex, 0x80); gObjectList[objectIndex].textureListIndex = 0x24 - temp; } } @@ -4735,10 +4735,10 @@ void func_8007C4A4(s32 objectIndex) { var_t9 = gObjectList[objectIndex].direction_angle[1] * 0x24 / 0x10000; if (var_t9 < 0x13) { - set_object_flag_status_false(objectIndex, 0x80); + clear_object_flag(objectIndex, 0x80); gObjectList[objectIndex].textureListIndex = var_t9; } else { - set_object_flag_status_true(objectIndex, 0x80); + set_object_flag(objectIndex, 0x80); gObjectList[objectIndex].textureListIndex = 0x24 - var_t9; } } @@ -4758,7 +4758,7 @@ void func_8007C5B4(s32 objectIndex) { object->pos[0] = 0.0f; object->pos[1] = 0.0f; object->pos[2] = 0.0f; - set_object_flag_status_true(objectIndex, 0x00000020); + set_object_flag(objectIndex, 0x00000020); object_next_state(objectIndex); object->primAlpha = 0; func_80073844(objectIndex); @@ -4766,7 +4766,7 @@ void func_8007C5B4(s32 objectIndex) { object->unk_034 = 1.0f; func_80073FD4(objectIndex); func_80086EF0(objectIndex); - set_object_flag_status_true(objectIndex, 0x00000800); + set_object_flag(objectIndex, 0x00000800); object->orientation[0] = 0; object->orientation[2] = 0x8000; } @@ -5114,7 +5114,7 @@ void func_8007D6A8(s32 objectIndex, s32 arg1) { object->unk_0D5 = 0x0D; func_8007D360(objectIndex, arg1); object->sizeScaling = 0.1f; - set_object_flag_status_true(objectIndex, 0x00000200); + set_object_flag(objectIndex, 0x00000200); object->boundingBoxSize = 3; } @@ -5542,521 +5542,33 @@ void func_8008153C(s32 objectIndex) { } } -void func_80081790(s32 objectIndex) { - switch (gObjectList[objectIndex].state) { - case 0: - break; /* irregular */ - case 1: - if (func_80087E08(objectIndex, gObjectList[objectIndex].velocity[1], 0.3f, gObjectList[objectIndex].unk_034, - gObjectList[objectIndex].orientation[1], 0x00000032) != 0) { - object_next_state(objectIndex); - } - object_calculate_new_pos_offset(objectIndex); - break; - case 2: - func_80072428(objectIndex); - func_80086F60(objectIndex); - break; - } -} -void func_80081848(s32 objectIndex) { - u8* mole = (u8*) LOAD_ASSET(d_course_moo_moo_farm_mole_frames); - u8* tlut = (u8*) LOAD_ASSET(d_course_moo_moo_farm_mole_tlut); - init_texture_object(objectIndex, d_course_moo_moo_farm_mole_tlut, (u8*) mole, 0x20U, (u16) 0x00000040); - gObjectList[objectIndex].sizeScaling = 0.15f; - gObjectList[objectIndex].textureListIndex = 0; - set_obj_origin_offset(objectIndex, 0.0f, 0.0f, 0.0f); - set_obj_direction_angle(objectIndex, 0U, 0U, 0U); - set_obj_orientation(objectIndex, 0U, 0U, 0x8000U); - gObjectList[objectIndex].boundingBoxSize = 6; - gObjectList[objectIndex].velocity[1] = 4.0f; - set_object_flag_status_true(objectIndex, 0x04000000); - object_next_state(objectIndex); -} -void func_80081924(s32 objectIndex) { - switch (gObjectList[objectIndex].unk_0AE) { - case 1: - if (f32_step_up_towards(&gObjectList[objectIndex].offset[1], 9.0f, 0.7f) != 0) { - func_80086FD4(objectIndex); - } - break; - case 2: - func_800871AC(objectIndex, 0x0000000A); - break; - case 3: - if (f32_step_down_towards(&gObjectList[objectIndex].offset[1], 3.0f, 1.0f) != 0) { - func_80086F60(objectIndex); - } - break; - case 4: - func_80087D24(objectIndex, 3.6f, 0.25f, 0.0f); - break; - case 5: - func_80086F60(objectIndex); - break; - case 10: - gObjectList[objectIndex].orientation[2] += 0x1000; - gObjectList[objectIndex].velocity[1] -= 0.184; - func_8008751C(objectIndex); - object_add_velocity_offset_xyz(objectIndex); - if (gObjectList[objectIndex].pos[1] <= -10.0) { - func_80086F60(objectIndex); - } - break; - case 0: - default: - break; - } -} -void func_80081A88(s32 objectIndex) { - switch (gObjectList[objectIndex].unk_0DD) { /* irregular */ - case 0: - break; - case 1: - func_8008B724(objectIndex); - break; - case 2: - func_80081924(objectIndex); - break; - } - object_calculate_new_pos_offset(objectIndex); -} -void func_80081AFC(s32 objectIndex, s32 arg1) { - s8* sp2C; - Object* object; - object = &gObjectList[objectIndex]; - switch (object->state) { /* irregular */ - case 0x1: - func_80081848(objectIndex); - break; - case 0x2: - if (object->unk_04C == 0) { - func_80086EAC(objectIndex, 2, 1); - object_next_state(objectIndex); - set_object_flag_status_true(objectIndex, 0x00000200); - } else { - object->unk_04C--; - } - break; - case 0x3: - if (object->unk_0AE == 0) { - func_80086EAC(objectIndex, 2, 4); - func_8008153C(objectIndex); - object_next_state(objectIndex); - func_800C98B8(object->pos, object->velocity, SOUND_ARG_LOAD(0x19, 0x01, 0x80, 0x07)); - } - break; - case 0x4: - if (func_80072E54(objectIndex, 1, 6, 1, 2, 0) != 0) { - func_800726CC(objectIndex, 0x00000064); - } - break; - case 0xA: - func_80072E54(objectIndex, 1, 6, 1, 0, -1); - if (object->unk_0AE == 0) { - func_800726CC(objectIndex, 0x00000064); - } - break; - case 0x64: - if (object->unk_0AE == 0) { - set_object_flag_status_false(objectIndex, 0x00000200); - func_80072428(objectIndex); - switch (arg1) { /* switch 1; irregular */ - case 1: /* switch 1 */ - sp2C = D_8018D198; - break; - case 2: /* switch 1 */ - sp2C = D_8018D1A8; - break; - case 3: /* switch 1 */ - sp2C = D_8018D1B8; - break; - } - sp2C[object->type] = 0; - } - break; - case 0: - default: - break; - } - if (object->state >= 2) { - func_80073514(objectIndex); - } -} -void func_80081D34(s32 objectIndex) { - Player* player; - Camera* var_s4; - s32 var_s2; - s32 var_s5; - Object* object; - var_s5 = 0; - player = gPlayerOne; - var_s4 = camera1; - for (var_s2 = 0; var_s2 < D_8018D158; var_s2++, player++, var_s4++) { - if ((is_obj_flag_status_active(objectIndex, 0x00000200) != 0) && !(player->effects & 0x80000000) && - (has_collided_with_player(objectIndex, player) != 0)) { - if ((player->type & 0x8000) && !(player->type & 0x100)) { - var_s5 = 1; - object = &gObjectList[objectIndex]; - if (is_obj_flag_status_active(objectIndex, 0x04000000) != 0) { - func_80072180(); - } - if (player->effects & 0x200) { - func_800C9060(var_s2, 0x1900A046U); - } else { - player->soundEffects |= 2; - } - object->direction_angle[1] = var_s4->rot[1]; - object->velocity[1] = (player->unk_094 / 2) + 3.0; - object->unk_034 = player->unk_094 + 1.0; - if (object->velocity[1] >= 5.0) { - object->velocity[1] = 5.0f; - } - if (object->unk_034 >= 4.0) { - object->velocity[1] = 4.0f; - } - } - } - } - if (var_s5 != 0) { - object = &gObjectList[objectIndex]; - set_object_flag_status_false(objectIndex, 0x00000200); - func_80086F60(objectIndex); - set_obj_origin_pos(objectIndex, object->pos[0], object->pos[1], object->pos[2]); - set_obj_origin_offset(objectIndex, 0.0f, 0.0f, 0.0f); - func_80086EAC(objectIndex, 2, 0x000A); - func_800726CC(objectIndex, 0x0000000A); - } -} -void func_80081FF4(s32 objectIndex, s32 arg1) { - UNUSED s32 stackPadding0; - UNUSED s32 stackPadding1; - s32 moleCount; - s16 var_v1; - s16 offset; - s32 var_a0; - s8* var_a2; - init_object(objectIndex, 0); - gObjectList[objectIndex].unk_04C = random_int(0x001EU) + 5; - switch (arg1) { /* irregular */ - case 1: - var_a2 = D_8018D198; - moleCount = NUM_GROUP1_MOLES; - offset = 0; - break; - case 2: - var_a2 = D_8018D1A8; - moleCount = NUM_GROUP2_MOLES; - offset = 24; - // offset = NUM_GROUP1_MOLES; - break; - case 3: - var_a2 = D_8018D1B8; - moleCount = NUM_GROUP3_MOLES; - offset = 57; - // offset = NUM_GROUP1_MOLES + NUM_GROUP2_MOLES; - break; - } - var_v1 = random_int(moleCount); - for (var_a0 = 0; var_a0 < moleCount; var_a0++) { - if (var_a2[var_v1] != 0) { - var_v1++; - if (var_v1 == moleCount) { - var_v1 = 0; - } - } else { - var_a2[var_v1] = 1; - gObjectList[objectIndex].type = var_v1; - break; - } - } - /* - Ideally `gMoleSpawns` wouldn't be a union at all and its just be a list of Vec3s - Even more ideally each mole group would have its own array for its spawns - gObjectList[objectIndex].origin_pos[0] = gMoleSpawns.asVec3sList[offset + var_v1][0] * xOrientation; - gObjectList[objectIndex].origin_pos[1] = gMoleSpawns.asVec3sList[offset + var_v1][1] - 9.0; - gObjectList[objectIndex].origin_pos[2] = gMoleSpawns.asVec3sList[offset + var_v1][2]; - */ - gObjectList[objectIndex].origin_pos[0] = gMoleSpawns.asFlatList[offset + (var_v1 * 3) + 0] * xOrientation; - gObjectList[objectIndex].origin_pos[1] = gMoleSpawns.asFlatList[offset + (var_v1 * 3) + 1] - 9.0; - gObjectList[objectIndex].origin_pos[2] = gMoleSpawns.asFlatList[offset + (var_v1 * 3) + 2]; -} -void func_800821AC(s32 objectIndex, s32 arg1) { - if (gObjectList[objectIndex].state != 0) { - func_80081AFC(objectIndex, arg1); - func_80081A88(objectIndex); - func_80081D34(objectIndex); - } -} -void update_moles(void) { - s32 var_s1; - s32 objectIndex; - UNUSED s32 stackPadding; - for (var_s1 = 0; var_s1 < D_8018D1C8; var_s1++) { - objectIndex = indexObjectList1[var_s1]; - if (gObjectList[objectIndex].state == 0) { - if (func_8008A8B0(8, 9) != 0) { - func_80081FF4(objectIndex, 1); - } - } else { - func_800821AC(objectIndex, 1); - } - } - for (var_s1 = 0; var_s1 < D_8018D1D0; var_s1++) { - objectIndex = indexObjectList2[var_s1]; - if (gObjectList[objectIndex].state == 0) { - if (func_8008A8B0(0x0010, 0x0013) != 0) { - func_80081FF4(objectIndex, 2); - } - } else { - func_800821AC(objectIndex, 2); - } - } - for (var_s1 = 0; var_s1 < D_8018D1D8; var_s1++) { - objectIndex = indexObjectList3[var_s1]; - if (gObjectList[objectIndex].state == 0) { - if (func_8008A8B0(0x0011, 0x0014) != 0) { - func_80081FF4(objectIndex, 3); - } - } else { - func_800821AC(objectIndex, 3); - } - } - for (var_s1 = 0; var_s1 < gObjectParticle2_SIZE; var_s1++) { - objectIndex = gObjectParticle2[var_s1]; - if (gObjectList[objectIndex].state != 0) { - func_80081790(objectIndex); - } - } -} -void func_8008241C(s32 objectIndex, s32 arg1) { - UNUSED s16 stackPadding0; - s16 temp_f4; - s16 sp22; - s16 sp20; - gObjectList[objectIndex].unk_0D8 = 1; - gObjectList[objectIndex].model = (Gfx*) d_course_koopa_troopa_beach_unk4; - gObjectList[objectIndex].vertex = (Vtx*) d_course_koopa_troopa_beach_unk_data5; - gObjectList[objectIndex].sizeScaling = 0.2f; - gObjectList[objectIndex].unk_0DD = 1; - sp22 = random_int(0x00C8) + -100.0; - sp20 = random_int(0x0014); - temp_f4 = random_int(0x00C8) + -100.0; - if (gGamestate == 9) { - set_obj_origin_pos(objectIndex, sp22 + -360.0, sp20 + 60.0, temp_f4 + -1300.0); - } else if (gObjectList[objectIndex].unk_0D5 != 0) { - set_obj_origin_pos(objectIndex, (sp22 + 328.0) * xOrientation, sp20 + 20.0, temp_f4 + 2541.0); - } else { - set_obj_origin_pos(objectIndex, (sp22 + -985.0) * xOrientation, sp20 + 15.0, temp_f4 + 1200.0); - } - set_obj_direction_angle(objectIndex, 0U, 0U, 0U); - gObjectList[objectIndex].unk_034 = 1.0f; - func_80086EF0(objectIndex); - gObjectList[objectIndex].spline = D_800E633C[arg1 % 4]; - set_object_flag_status_true(objectIndex, 0x00000800); - object_next_state(objectIndex); -} -void func_80082714(s32 objectIndex, s32 arg1) { - switch (gObjectList[objectIndex].state) { - case 1: - func_8008241C(objectIndex, arg1); - break; - case 0: - default: - break; - } -} -void func_8008275C(s32 objectIndex) { - UNUSED s32 stackPadding; - switch (gObjectList[objectIndex].unk_0DD) { /* irregular */ - case 1: - func_8008B78C(objectIndex); - object_calculate_new_pos_offset(objectIndex); - break; - case 2: - func_8008B78C(objectIndex); - vec3f_copy(gObjectList[objectIndex].unk_01C, gObjectList[objectIndex].pos); - func_8000D940(gObjectList[objectIndex].origin_pos, (s16*) &gObjectList[objectIndex].unk_0C6, - gObjectList[objectIndex].unk_034, 0.0f, 0); - gObjectList[objectIndex].offset[0] *= 2.0; - gObjectList[objectIndex].offset[1] *= 2.5; - gObjectList[objectIndex].offset[2] *= 2.0; - object_calculate_new_pos_offset(objectIndex); - gObjectList[objectIndex].direction_angle[1] = - get_angle_between_two_vectors(gObjectList[objectIndex].unk_01C, gObjectList[objectIndex].pos); - break; - } - func_800873F4(objectIndex); -} -void update_seagulls(void) { - Object* object; - UNUSED s32* var_s4; - s32 temp_s0; - s32 var_s3; - for (var_s3 = 0; var_s3 < NUM_SEAGULLS; var_s3++) { - temp_s0 = indexObjectList2[var_s3]; - object = &gObjectList[temp_s0]; - if (object->state == 0) { - continue; - } - func_80082714(temp_s0, var_s3); - func_8008275C(temp_s0); - if (func_80072320(temp_s0, 2) != 0) { - func_800722CC(temp_s0, 2); - if (D_80165A90 != 0) { - D_80165A90 = 0; - D_80183E40[0] = 0.0f; - D_80183E40[1] = 0.0f; - D_80183E40[2] = 0.0f; - if (gGamestate != CREDITS_SEQUENCE) { - func_800C98B8(object->pos, D_80183E40, SOUND_ARG_LOAD(0x19, 0x01, 0x70, 0x43)); - } else { - temp_s0 = indexObjectList2[1]; - if (gCutsceneShotTimer < 0x97) { - object = &gObjectList[temp_s0]; - func_800C98B8(object->pos, D_80183E40, SOUND_ARG_LOAD(0x19, 0x01, 0x70, 0x43)); - } - } - } - } - } - if (D_80165900 != 0) { - D_80165900 -= 1; - } else { - if (gGamestate != 9) { - D_80165900 = 0x003C; - } else { - D_80165900 = 0x000F; - } - if ((D_80165908 != 0) && (D_80165A90 == 0)) { - D_80165A90 = 1; - } - } - D_80165908 = 0; -} -void init_ktb_crab(s32 objectIndex) { - Object* object; - init_texture_object(objectIndex, d_course_koopa_troopa_beach_crab_tlut, - (u8*) d_course_koopa_troopa_beach_crab_frames, 64, (u16) 64); - object = &gObjectList[objectIndex]; - object->sizeScaling = 0.15f; - object->textureListIndex = 0; - object_next_state(objectIndex); - object->boundingBoxSize = 1; - set_object_flag_status_true(objectIndex, 0x04000420); - func_80086EAC(objectIndex, 0, 1); - set_obj_origin_offset(objectIndex, 0.0f, 0.0f, 0.0f); - set_obj_orientation(objectIndex, 0U, 0U, 0x8000U); - object->unk_034 = 1.5f; - set_object_flag_status_true(objectIndex, 0x00000200); -} -void func_80082B34(s32 objectIndex, UNUSED s32 unused) { - switch (gObjectList[objectIndex].state) { /* irregular */ - case 0: - break; - case 1: - init_ktb_crab(objectIndex); - break; - case 2: - func_80072E54(objectIndex, 0, 3, 1, 2, -1); - break; - case 3: - func_80072E54(objectIndex, 4, 6, 1, 2, -1); - break; - } - if (gObjectList[objectIndex].state >= 2) { - func_80073514(objectIndex); - } -} -void func_80082C30(s32 objectIndex) { - switch (gObjectList[objectIndex].unk_0AE) { - case 1: - if (func_80087A0C(objectIndex, gObjectList[objectIndex].origin_pos[0], gObjectList[objectIndex].unk_01C[0], - gObjectList[objectIndex].origin_pos[2], gObjectList[objectIndex].unk_01C[2]) != 0) { - func_800726CC(objectIndex, 3); - func_80086FD4(objectIndex); - } - break; - case 2: - if (func_80087104(objectIndex, 0x003CU) != 0) { - gObjectList[objectIndex].unk_034 = 0.8f; - func_800726CC(objectIndex, 2); - func_80086FD4(objectIndex); - } - break; - case 3: - if (func_80087954(objectIndex, 0x0000003C) != 0) { - func_80086FD4(objectIndex); - func_800726CC(objectIndex, 3); - } - break; - case 4: - if (func_80087104(objectIndex, 0x003CU) != 0) { - func_800726CC(objectIndex, 2); - func_80086FD4(objectIndex); - } - break; - case 5: - if (func_8008789C(objectIndex, 0x0000003C) != 0) { - func_800726CC(objectIndex, 3); - func_8008701C(objectIndex, 2); - } - break; - } - object_calculate_new_pos_offset(objectIndex); - if (is_obj_flag_status_active(objectIndex, VISIBLE) != 0) { - func_80088538(objectIndex); - gObjectList[objectIndex].pos[1] = (f32) (gObjectList[objectIndex].surfaceHeight + 2.5); - } -} - -void func_80082E18(s32 objectIndex) { - if (gObjectList[objectIndex].state >= 2) { - func_80089F24(objectIndex); - } -} - -void update_crabs(void) { - s32 objectIndex; - s32 var_s1; - - for (var_s1 = 0; var_s1 < NUM_CRABS; var_s1++) { - objectIndex = indexObjectList1[var_s1]; - if (gObjectList[objectIndex].state != 0) { - func_80082B34(objectIndex, var_s1); - func_8008A6DC(objectIndex, 500.0f); - func_80082C30(objectIndex); - func_80082E18(objectIndex); - } - } -} #ifdef NON_MATCHING // https://decomp.me/scratch/PYAg4 @@ -6124,7 +5636,7 @@ void func_8008311C(s32 objectIndex, s32 arg1) { set_obj_orientation(objectIndex, 0U, 0U, 0x8000U); object->unk_034 = ((arg1 % 6) * 0.1) + 0.5; func_80086E70(objectIndex); - set_object_flag_status_true(objectIndex, 0x04000600); + set_object_flag(objectIndex, 0x04000600); object->boundingBoxSize = 2; } @@ -6274,7 +5786,7 @@ void func_80083868(s32 objectIndex) { object->primAlpha = random_int(0x2000U) - 0x1000; func_80086E70(objectIndex); object->unk_034 = 1.5f; - set_object_flag_status_true(objectIndex, 0x00000200); + set_object_flag(objectIndex, 0x00000200); } void func_80083948(s32 objectIndex) { @@ -6338,7 +5850,7 @@ void func_80083B0C(s32 objectIndex) { gObjectList[objectIndex].orientation[2] = 0x8000; gObjectList[objectIndex].boundingBoxSize = 2; gObjectList[objectIndex].unk_034 = 1.5f; - set_object_flag_status_true(objectIndex, 0x04000210); + set_object_flag(objectIndex, 0x04000210); } void func_80083BE4(s32 objectIndex) { @@ -6365,7 +5877,7 @@ void func_80083C04(s32 objectIndex) { break; case 11: if (set_and_run_timer_object(objectIndex, 0x0000000A) != 0) { - set_object_flag_status_true(objectIndex, 0x00000010); + set_object_flag(objectIndex, 0x00000010); object->sizeScaling = 0.001f; } break; @@ -6376,7 +5888,7 @@ void func_80083C04(s32 objectIndex) { break; case 13: func_800726CC(objectIndex, 2); - set_object_flag_status_false(objectIndex, 0x00001000); + clear_object_flag(objectIndex, 0x00001000); break; } if (object->state >= 2) { @@ -6418,8 +5930,8 @@ void update_snowmen(void) { if (is_obj_index_flag_status_inactive(var_s4, 0x00001000) != 0) { object = &gObjectList[var_s4]; if ((func_8008A8B0(object->unk_0D5 - 1, object->unk_0D5 + 1) != 0) && (func_80089B50(var_s4) != 0)) { - set_object_flag_status_true(var_s4, 0x00001000); - set_object_flag_status_false(var_s4, 0x00000010); + set_object_flag(var_s4, 0x00001000); + clear_object_flag(var_s4, 0x00000010); func_800726CC(var_s4, 0x0000000A); func_8008701C(var_s3, 0x0000000A); func_800836F0(object->pos); @@ -6618,7 +6130,7 @@ void func_80085878(s32 objectIndex, s32 arg1) { object->vertex = (Vtx*) d_rainbow_road_unk3; object->sizeScaling = 0.03f; object->boundingBoxSize = 0x000A; - set_object_flag_status_true(objectIndex, 0x04000200); + set_object_flag(objectIndex, 0x04000200); object->unk_084[8] = (arg1 * 0x12C) + 0x1F4; set_obj_origin_pos(objectIndex, 0.0f, -15.0f, 0.0f); temp_v0 = &D_80164490[(u16) object->unk_084[8]]; diff --git a/src/update_objects.h b/src/update_objects.h index ddaa5b0c1..3e7d184b5 100644 --- a/src/update_objects.h +++ b/src/update_objects.h @@ -17,8 +17,8 @@ s32 add_unused_obj_index(s32*, s32*, s32); void delete_object_wrapper(s32*); void func_80072120(s32*, s32); void func_80072180(void); -void set_object_flag_status_true(s32, s32); -void set_object_flag_status_false(s32, s32); +void set_object_flag(s32, s32); +void clear_object_flag(s32, s32); void func_80072214(s32, s32); bool is_obj_flag_status_active(s32, s32); s32 is_obj_index_flag_status_inactive(s32, s32); From 517a59fbf49a4d2bb59aefb10f2acfcdd17ff75e Mon Sep 17 00:00:00 2001 From: MegaMech Date: Fri, 13 Dec 2024 15:18:39 -0700 Subject: [PATCH 10/21] Impl trophy --- CMakeLists.txt | 3 + include/defines.h | 8 +- src/engine/World.cpp | 20 +- src/engine/World.h | 12 +- src/engine/objects/Trophy.cpp | 335 ++++++++++++++++++++++++++++++++++ src/engine/objects/Trophy.h | 55 ++++++ 6 files changed, 417 insertions(+), 16 deletions(-) create mode 100644 src/engine/objects/Trophy.cpp create mode 100644 src/engine/objects/Trophy.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 3cc7f64b9..d2f8f1d6b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -97,6 +97,7 @@ include_directories( ${CMAKE_CURRENT_SOURCE_DIR}/src/engine ${CMAKE_CURRENT_SOURCE_DIR}/src/engine/courses ${CMAKE_CURRENT_SOURCE_DIR}/src/engine/objects + ${CMAKE_CURRENT_SOURCE_DIR}/src/engine/particles ${CMAKE_CURRENT_SOURCE_DIR}/src/enhancements ${CMAKE_CURRENT_SOURCE_DIR}/src/enhancements/freecam ) @@ -144,6 +145,8 @@ file(GLOB_RECURSE ALL_FILES RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} "src/engine/courses/*.h" "src/engine/objects/*.cpp" "src/engine/objects/*.h" + "src/engine/particles/*.cpp" + "src/engine/particles/*.h" "src/enhancements/*.c" "src/enhancements/*.h" "src/enhancements/freecam/*.c" diff --git a/include/defines.h b/include/defines.h index 11394a6c2..e4ee8c41c 100644 --- a/include/defines.h +++ b/include/defines.h @@ -351,6 +351,11 @@ enum DIRECTION { #define BALLOON_STATUS_PRESENT 1 #define BALLOON_STATUS_DEPARTING 2 +/** + * Number of podiums in podium ceremony + */ +#define NUM_PODIUMS 3 + /** * @brief Max representable time, 100 minutes measured in centiseconds */ @@ -397,7 +402,6 @@ enum DIRECTION { #define COLOR_LAVA GPACK_RGB888(0x34, 0x00, 0x00) #define COLOR_BLACK GPACK_RGB888(0, 0, 0) -#endif // DEFINES_H /** * @@ -410,3 +414,5 @@ enum DIRECTION { #define FACING_Y_AXIS 0x4000 #define FACING_X_AXIS 0x8000 #define FACING_Z_AXIS 0x2000 + +#endif // DEFINES_H \ No newline at end of file diff --git a/src/engine/World.cpp b/src/engine/World.cpp index ead375a24..429b402a0 100644 --- a/src/engine/World.cpp +++ b/src/engine/World.cpp @@ -13,7 +13,7 @@ #include "objects/Penguin.h" #include "TrainCrossing.h" #include -#include "objects/GameObject.h" +#include "objects/Object.h" extern "C" { #include "camera.h" @@ -242,7 +242,7 @@ void RemoveExpiredActors() { // Actors.end()); } -GameObject* World::AddObject(GameObject* object) { +OObject* World::AddObject(OObject* object) { Objects.push_back(object); return Objects.back(); } @@ -253,17 +253,17 @@ void World::TickObjects() { } } -void World::DrawObjects(Camera *camera) { +void World::DrawObjects(s32 cameraId) { for (const auto& object : Objects) { - object->Draw(camera); + object->Draw(cameraId); } } void World::ExpiredObjects() { - //this->GameObjects.erase( - // std::remove_if(this->GameObjects.begin(), this->GameObjects.end(), - // [](const std::unique_ptr& object) { return object->uuid == 0; }), // Example condition - // this->GameObjects.end()); + //this->Objects.erase( + // std::remove_if(this->Objects.begin(), this->Objects.end(), + // [](const std::unique_ptr& object) { return object->uuid == 0; }), // Example condition + // this->Objects.end()); } void World::DestroyObjects() { @@ -271,9 +271,9 @@ void World::DestroyObjects() { } Object* World::GetObjectByIndex(size_t index) { - //if (index < this->GameObjects.size()) { + //if (index < this->Objects.size()) { // Assuming GameActor::a is accessible, use reinterpret_cast if needed - // return reinterpret_cast(&this->GameObjects[index]->o); + // return reinterpret_cast(&this->Objects[index]->o); //} return nullptr; // Or handle the error as needed } diff --git a/src/engine/World.h b/src/engine/World.h index 2ae4462f4..3b48284e8 100644 --- a/src/engine/World.h +++ b/src/engine/World.h @@ -1,7 +1,7 @@ #pragma once #include -#include "objects/GameObject.h" +#include "objects/Object.h" #include "Cup.h" #include "vehicles/Vehicle.h" #include "vehicles/Train.h" @@ -14,6 +14,7 @@ #include "objects/Seagull.h" #include #include "Actor.h" +#include "particles/ParticleEmitter.h" extern "C" { #include "camera.h" @@ -21,7 +22,7 @@ extern "C" { #include "engine/Engine.h" }; -class GameObject; +class OObject; class Cup; // <-- Forward declaration class Course; class AVehicle; @@ -95,11 +96,11 @@ public: AActor* ConvertActorToAActor(Actor* actor); Actor* ConvertAActorToActor(AActor* actor); - GameObject* AddObject(GameObject* object); + OObject* AddObject(OObject* object); CProperties* GetCourseProps(); void TickObjects(); - void DrawObjects(Camera *camera); + void DrawObjects(s32 cameraId); void ExpiredObjects(); void DestroyObjects(); Object *GetObjectByIndex(size_t); @@ -131,7 +132,8 @@ public: size_t CupIndex = 1; std::vector Actors; - std::vector Objects; + std::vector Objects; + std::vector Emitters; /** Actors */ void AddBoat(f32 speed, uint32_t waypoint); diff --git a/src/engine/objects/Trophy.cpp b/src/engine/objects/Trophy.cpp new file mode 100644 index 000000000..464a2277c --- /dev/null +++ b/src/engine/objects/Trophy.cpp @@ -0,0 +1,335 @@ +#include "Trophy.h" +#include "assets/common_data.h" +#include "assets/data_segment2.h" +extern "C" { +#include "main.h" +#include "defines.h" +#include "update_objects.h" +#include "code_80057C60.h" +#include "assets/ceremony_data.h" +#include "podium_ceremony_actors.h" +#include "math_util.h" +#include "math_util_2.h" +#include "data/some_data.h" +#include "engine/Matrix.h" +#include "render_objects.h" +#include "code_80086E70.h" +#include "code_80091750.h" +} + +OTrophy::OTrophy(const FVector& pos, TrophyType trophy, Behaviour bhv) { + s32 objectIndex = indexObjectList1[3]; + _trophy = trophy; + _spawnPos = pos; + _spawnPos.y += 16.0f; // Adjust the height so the trophy sits on the surface when positioned to 0,0,0 + _bhv = bhv; + + init_object(objectIndex, 0); + + switch (trophy) { + case TrophyType::GOLD: + gObjectList[objectIndex].model = (Gfx*)gold_trophy_dl10; + break; + case TrophyType::SILVER: + gObjectList[objectIndex].model = (Gfx*)gold_trophy_dl12; + break; + case TrophyType::BRONZE: + gObjectList[objectIndex].model = (Gfx*)gold_trophy_dl14; + break; + case TrophyType::GOLD_150: + gObjectList[objectIndex].model = (Gfx*)gold_trophy_dl11; + break; + case TrophyType::SILVER_150: + gObjectList[objectIndex].model = (Gfx*)gold_trophy_dl13; + break; + case TrophyType::BRONZE_150: + gObjectList[objectIndex].model = (Gfx*)gold_trophy_dl15; + break; + } + + if (OTrophy::Behaviour::PODIUM_CEREMONY) { + _toggleVisibility = &D_801658CE; + } else { + int8_t toggle = 1; + _toggleVisibility = &toggle; + } + + // Set defaults for modded behaviours + if (_bhv != OTrophy::Behaviour::PODIUM_CEREMONY) { + gObjectList[objectIndex].sizeScaling = 0.025f; + gObjectList[objectIndex].unk_084[1] = 0x0200; + object_next_state(objectIndex); + func_80086E70(objectIndex); + } + + switch(_bhv) { + case OTrophy::Behaviour::GO_FISH: + gObjectList[objectIndex].sizeScaling = 0.010f; + break; + } + + Object *object = &gObjectList[objectIndex]; + object->origin_pos[0] = _spawnPos.x; + object->origin_pos[1] = _spawnPos.y; + object->origin_pos[2] = _spawnPos.z; + object->pos[0] = _spawnPos.x; + object->pos[1] = _spawnPos.y; + object->pos[2] = _spawnPos.z; +} + +void OTrophy::Tick() { // func_80086D80 + s32 objectIndex = indexObjectList1[3]; + s32 var_s0; + + // if ((D_801658CE != 0) && (D_801658DC == 0)) { + // temp_s2 = indexObjectList1[3]; + // init_object(temp_s2, 0); + // D_801658DC = 1; + // } + + switch(_bhv) { + case OTrophy::Behaviour::PODIUM_CEREMONY: + if (gObjectList[objectIndex].state != 0) { + OTrophy::func_80086C14(objectIndex); + OTrophy::func_80086940(objectIndex); + if (D_801658F4 != 0) { + if (D_8016559C == 0) { + OTrophy::func_80086C6C(objectIndex); + } + } else { + for (var_s0 = 0; var_s0 < 2; var_s0++) { + OTrophy::func_80086C6C(objectIndex); + } + } + } + break; + + case OTrophy::Behaviour::STATIONARY: + if (gObjectList[objectIndex].state != 0) { + gObjectList[objectIndex].sizeScaling = 0.025f; + set_obj_origin_pos(objectIndex, _spawnPos.x, + _spawnPos.y + 16.0, _spawnPos.z); + set_obj_origin_offset(objectIndex, 0.0f, 0.0f, 0.0f); + set_obj_direction_angle(objectIndex, 0U, 0U, 0U); + gObjectList[objectIndex].unk_084[1] = 0x0200; + object_next_state(objectIndex); + func_80086E70(objectIndex); + OTrophy::func_80086940(objectIndex); + } + break; + case OTrophy::Behaviour::ROTATE: + if (gObjectList[objectIndex].state != 0) { + + gObjectList[objectIndex].direction_angle[0] += 0x400; + gObjectList[objectIndex].direction_angle[1] -= 0x200; + } + break; + case OTrophy::Behaviour::ROTATE2: + if (gObjectList[objectIndex].state != 0) { + + gObjectList[objectIndex].direction_angle[0] += 0x400; + gObjectList[objectIndex].direction_angle[1] = 0xE800; + gObjectList[objectIndex].direction_angle[2] = 0xDA00; + } + break; + case OTrophy::Behaviour::GO_FISH: + if (gObjectList[objectIndex].state != 0) { + + // Get the player's yaw + Player *player = &gPlayers[0]; + float yaw = (player->rotation[1] + 0x4000) * (M_PI / 32768.0f); // Convert degrees to radians + + // Calculate forward direction based on yaw (same as before) + float lookAtX = player->pos[0] + cos(yaw); + float lookAtZ = player->pos[2] + sin(yaw); + + float forwardX = lookAtX - player->pos[0]; + float forwardY = 0; // Optional: Ignore height changes + float forwardZ = lookAtZ - player->pos[2]; + + // Normalize the forward vector + float length = sqrtf(forwardX * forwardX + forwardZ * forwardZ); + if (length != 0) { + forwardX /= length; + forwardZ /= length; + } + + float distance = 30.0f; + + // Calculate the object's position in front of the player (same as before) + gObjectList[objectIndex].pos[0] = player->pos[0] + forwardX * distance; + gObjectList[objectIndex].pos[1] = player->pos[1] + 8.0f; // Optional height offset + gObjectList[objectIndex].pos[2] = player->pos[2] + forwardZ * distance; + + // Apply more sensitive random movement based on player velocity to simulate floating behavior + float velocityFactor = 0.1f; // Increased factor for more sensitivity + gObjectList[objectIndex].pos[0] += player->velocity[0] * velocityFactor; + gObjectList[objectIndex].pos[1] += player->velocity[1] * velocityFactor; // Optional: Add vertical movement + gObjectList[objectIndex].pos[2] += player->velocity[2] * velocityFactor; + + // Increase oscillation for more dynamic movement (sine wave effect) + float oscillationSpeed = 4.0f; // Increased speed for quicker oscillations + float oscillationAmplitude = 0.4f; // Increased amplitude for more noticeable movement + gObjectList[objectIndex].pos[1] += oscillationAmplitude * sinf(oscillationSpeed * gGlobalTimer); // Vertical oscillation based on time + + // Now use smooth interpolation (lerp) to gradually move the trophy towards its target position + float lerpFactor = 0.25f; // Increased to make the trophy follow the player more quickly + + gObjectList[objectIndex].pos[0] = _oldPos[0] + lerpFactor * (gObjectList[objectIndex].pos[0] - _oldPos[0]); + gObjectList[objectIndex].pos[1] = _oldPos[1] + lerpFactor * (gObjectList[objectIndex].pos[1] - _oldPos[1]); + gObjectList[objectIndex].pos[2] = _oldPos[2] + lerpFactor * (gObjectList[objectIndex].pos[2] - _oldPos[2]); + + // Save the current position for the next frame + _oldPos[0] = gObjectList[objectIndex].pos[0]; + _oldPos[1] = gObjectList[objectIndex].pos[1]; + _oldPos[2] = gObjectList[objectIndex].pos[2]; + + + gObjectList[objectIndex].direction_angle[0] += 0x400; + gObjectList[objectIndex].direction_angle[1] -= 0x200; + } + break; + } +} + +void OTrophy::Draw(s32 cameraId) { + s32 listIndex = indexObjectList1[3]; + Mat4 someMatrix1; + Mat4 someMatrix2; + Object* object; + + if (_toggleVisibility) { + object = &gObjectList[listIndex]; + if (object->state >= 2) { + gSPMatrix(gDisplayListHead++, VIRTUAL_TO_PHYSICAL(&gGfxPool->mtxPersp[0]), + G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_PROJECTION); + gSPMatrix(gDisplayListHead++, VIRTUAL_TO_PHYSICAL(&gGfxPool->mtxLookAt[0]), + G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + mtxf_set_matrix_transformation(someMatrix1, object->pos, object->direction_angle, object->sizeScaling); + //convert_to_fixed_point_matrix(&gGfxPool->mtxHud[gMatrixHudCount], someMatrix1); + //gSPMatrix(gDisplayListHead++, VIRTUAL_TO_PHYSICAL(&gGfxPool->mtxHud[gMatrixHudCount++]), + // G_MTX_NOPUSH | G_MTX_MUL | G_MTX_MODELVIEW); + + AddHudMatrix(someMatrix1, G_MTX_NOPUSH | G_MTX_MUL | G_MTX_MODELVIEW); + + gSPDisplayList(gDisplayListHead++, (Gfx*)D_0D0077A0); + gSPDisplayList(gDisplayListHead++, object->model); + gSPMatrix(gDisplayListHead++, VIRTUAL_TO_PHYSICAL(&gGfxPool->mtxLookAt[0]), + G_MTX_NOPUSH | G_MTX_MUL | G_MTX_PROJECTION); + mtxf_identity(someMatrix2); + render_set_position(someMatrix2, 0); + } + + switch (_bhv) { + case GO_FISH: + size_t numTrophies = 0; + func_80057A50(40, 0, (char*) "Trophies Collected: ", (s16) numTrophies); + break; + } + + } +} + +void OTrophy::func_80086700(s32 objectIndex) { + gObjectList[objectIndex].sizeScaling = 0.005f; + set_obj_origin_pos(objectIndex, gObjectList[indexObjectList2[0]].pos[0], + gObjectList[indexObjectList2[0]].pos[1] + 16.0, gObjectList[indexObjectList2[0]].pos[2]); + set_obj_origin_offset(objectIndex, 0.0f, 0.0f, 0.0f); + set_obj_direction_angle(objectIndex, 0U, 0U, 0U); + gObjectList[objectIndex].unk_084[1] = 0x0200; + object_next_state(objectIndex); + func_80086E70(objectIndex); +} + +void OTrophy::func_80086940(s32 objectIndex) { + Object* object; + + object = &gObjectList[objectIndex]; + switch (object->unk_0AE) { + case 0: + break; + case 1: + func_80086FD4(objectIndex); + break; + case 2: + f32_step_towards(&object->sizeScaling, 0.025f, 0.001f); + func_80087C48(objectIndex, 6.0f, 0.1f, 0x000000C8); + if ((f64) object->velocity[1] <= 0.0) { + func_8008701C(objectIndex, 3); + } + break; + case 3: + func_800871AC(objectIndex, 0x00000064); + break; + case 4: + D_801658D6 = 1; + object->velocity[1] = -0.4f; + func_80086FD4(objectIndex); + // object->origin_pos[1] = 90.0f; + object->offset[1] = 60.0f; + // switch (D_802874D8.unk1D) { + // case 1: + // object->origin_pos[0] -= 3.0; + // object->origin_pos[2] += 15.0; + // break; + // case 2: + // object->origin_pos[0] -= 2.0; + // object->origin_pos[2] -= 15.0; + // break; + // } + break; + case 5: + if ((f64) object->offset[1] <= 8.0) { + f32_step_towards(&object->velocity[1], -0.1f, -0.01f); + } + object_add_velocity_offset_y(objectIndex); + if ((f64) object->offset[1] <= 0.0) { + func_80086FD4(objectIndex); + } + break; + case 6: + if (func_800871AC(objectIndex, 0x00000041) != 0) { + D_801658F4 = 1; + } + break; + case 7: + if (func_800871AC(objectIndex, 0x00000064) != 0) { + func_8009265C(); + func_80086F60(objectIndex); + } + break; + } + if (D_801658D6 != 0) { + object->direction_angle[0] += 0x400; + object->direction_angle[1] = 0xE800; + object->direction_angle[2] = 0xDA00; + } else { + object->direction_angle[0] += 0x400; + object->direction_angle[1] -= 0x200; + } + object_calculate_new_pos_offset(objectIndex); +} + +void OTrophy::func_80086C14(s32 objectIndex) { + switch (gObjectList[objectIndex].state) { /* irregular */ + case 1: + OTrophy::func_80086700(objectIndex); + break; + case 0: + case 2: + break; + } +} + +void OTrophy::func_80086C6C(s32 objectIndex) { + Vec3f sp24; + + sp24[0] = (gObjectList[objectIndex].pos[0] - 5.0f) + random_int(0x000AU); + sp24[2] = (gObjectList[objectIndex].pos[2] - 5.0f) + random_int(0x000AU); + if (D_801658F4 != 0) { + sp24[1] = gObjectList[objectIndex].pos[1] + 14.0; + } else { + sp24[1] = gObjectList[objectIndex].pos[1] - 2.0; + } + func_800773D8(sp24, (s32) D_801658F4); +} diff --git a/src/engine/objects/Trophy.h b/src/engine/objects/Trophy.h new file mode 100644 index 000000000..76834d77e --- /dev/null +++ b/src/engine/objects/Trophy.h @@ -0,0 +1,55 @@ +#pragma once + +#include +#include +#include "Object.h" + +extern "C" { +#include "macros.h" +#include "main.h" +#include "vehicles.h" +#include "waypoints.h" +#include "common_structs.h" +#include "objects.h" +#include "course_offsets.h" +#include "some_data.h" +} + + +class OTrophy : public OObject { +public: + enum TrophyType { + BRONZE, + SILVER, + GOLD, + BRONZE_150, + SILVER_150, + GOLD_150, + }; + + enum Behaviour { + PODIUM_CEREMONY, + STATIONARY, + ROTATE, // A dual-axis opposing rotation + ROTATE2, // A single-axis rotation + GO_FISH, + }; + + explicit OTrophy(const FVector& pos, TrophyType trophy, Behaviour bhv); + + virtual void Tick() override; + virtual void Draw(s32 cameraId) override; + void func_80086700(s32 objectIndex); + void func_80086940(s32 objectIndex); + void func_80086C14(s32 objectIndex); + void func_80086C6C(s32 objectIndex); + +private: + + s32 _idx; + TrophyType _trophy; + FVector _spawnPos; + Behaviour _bhv; + int8_t *_toggleVisibility; + Vec3f _oldPos; +}; From 7f22f75db7fa7a1b2149bc953d2a159c52bc5e8b Mon Sep 17 00:00:00 2001 From: MegaMech Date: Fri, 13 Dec 2024 15:19:39 -0700 Subject: [PATCH 11/21] Trophy, Object impl, and cleanup --- src/engine/Actor.cpp | 4 +--- src/engine/courses/TestCourse.cpp | 11 ++++++---- src/engine/objects/GameObject.cpp | 20 ------------------- src/engine/objects/Object.cpp | 20 +++++++++++++++++++ src/engine/objects/{GameObject.h => Object.h} | 8 ++++---- src/engine/objects/Thwomp.h | 2 +- src/engine/objects/Trophy.h | 11 ++++++++++ src/port/Game.cpp | 4 ++-- src/port/Game.h | 2 +- 9 files changed, 47 insertions(+), 35 deletions(-) delete mode 100644 src/engine/objects/GameObject.cpp create mode 100644 src/engine/objects/Object.cpp rename src/engine/objects/{GameObject.h => Object.h} (68%) diff --git a/src/engine/Actor.cpp b/src/engine/Actor.cpp index b6b2520d0..8bd472b08 100644 --- a/src/engine/Actor.cpp +++ b/src/engine/Actor.cpp @@ -2,11 +2,9 @@ #include "Actor.h" - //GameActor() - AActor::AActor() {} - // Virtual functions to be overridden by derived classes +// Virtual functions to be overridden by derived classes void AActor::Tick() { } void AActor::Draw(Camera *camera) { } void AActor::Collision(Player* player, AActor* actor) {} diff --git a/src/engine/courses/TestCourse.cpp b/src/engine/courses/TestCourse.cpp index 74f7fee13..2750c727f 100644 --- a/src/engine/courses/TestCourse.cpp +++ b/src/engine/courses/TestCourse.cpp @@ -13,6 +13,7 @@ #include "engine/actors/ATree.h" #include "engine/actors/ACloud.h" #include "engine/vehicles/Train.h" +#include "engine/objects/Trophy.h" extern "C" { #include "main.h" @@ -190,10 +191,12 @@ void TestCourse::SpawnActors() { Vec3f pos = {0, 80, 0}; //gWorldInstance.AddActor(new ACloud(pos)); - gWorldInstance.AddActor(new OSeagull(0, pos)); - gWorldInstance.AddActor(new OSeagull(1, pos)); - gWorldInstance.AddActor(new OSeagull(2, pos)); - gWorldInstance.AddActor(new OSeagull(3, pos)); + // gWorldInstance.AddActor(new OSeagull(0, pos)); + // gWorldInstance.AddActor(new OSeagull(1, pos)); + // gWorldInstance.AddActor(new OSeagull(2, pos)); + // gWorldInstance.AddActor(new OSeagull(3, pos)); + + gWorldInstance.AddObject(new OTrophy(FVector(0,0,0), OTrophy::TrophyType::GOLD, OTrophy::Behaviour::GO_FISH)); } // Likely sets minimap boundaries diff --git a/src/engine/objects/GameObject.cpp b/src/engine/objects/GameObject.cpp deleted file mode 100644 index c7be32769..000000000 --- a/src/engine/objects/GameObject.cpp +++ /dev/null @@ -1,20 +0,0 @@ -#include -#include "GameObject.h" - -#include "World.h" - -extern "C" { - #include "camera.h" -} - - - //GameActor() - -GameObject::GameObject() {} - - // Virtual functions to be overridden by derived classes -void GameObject::Tick() { } -void GameObject::Draw(Camera* camera) { } -void GameObject::Collision() {} -void GameObject::Expire() { } -void GameObject::Destroy() { } diff --git a/src/engine/objects/Object.cpp b/src/engine/objects/Object.cpp new file mode 100644 index 000000000..74143a923 --- /dev/null +++ b/src/engine/objects/Object.cpp @@ -0,0 +1,20 @@ +#include +#include "Object.h" + +#include "World.h" + +extern "C" { + #include "camera.h" +} + + + //GameActor() + +OObject::OObject() {} + + // Virtual functions to be overridden by derived classes +void OObject::Tick() { } +void OObject::Draw(s32 cameraId) { } +void OObject::Collision() {} +void OObject::Expire() { } +void OObject::Destroy() { } diff --git a/src/engine/objects/GameObject.h b/src/engine/objects/Object.h similarity index 68% rename from src/engine/objects/GameObject.h rename to src/engine/objects/Object.h index 19d5301cd..c41cfae6d 100644 --- a/src/engine/objects/GameObject.h +++ b/src/engine/objects/Object.h @@ -7,17 +7,17 @@ extern "C" { #include "objects.h" } -class GameObject { +class OObject { public: uint8_t uuid[16]; Object o; - virtual ~GameObject() = default; + virtual ~OObject() = default; - explicit GameObject(); + explicit OObject(); virtual void Tick(); - virtual void Draw(Camera* camera); + virtual void Draw(s32 cameraId); virtual void Collision(); virtual void Expire(); virtual void Destroy(); diff --git a/src/engine/objects/Thwomp.h b/src/engine/objects/Thwomp.h index 517d2972d..f64318e4d 100644 --- a/src/engine/objects/Thwomp.h +++ b/src/engine/objects/Thwomp.h @@ -18,7 +18,7 @@ extern "C" { //! @todo make adjustable properties for squishSize and boundingBoxSize /** - * Thwomp GameObject + * Thwomp OObject * * The game automatically places the actor on the ground so you do not need to provide a Y coordinate value. * diff --git a/src/engine/objects/Trophy.h b/src/engine/objects/Trophy.h index 76834d77e..d73e04929 100644 --- a/src/engine/objects/Trophy.h +++ b/src/engine/objects/Trophy.h @@ -15,6 +15,17 @@ extern "C" { #include "some_data.h" } +//! @todo move this like World.h or something +struct FVector { + float x, y, z; + + FVector& operator=(const FVector& other) { + x = other.x; + y = other.y; + z = other.z; + return *this; + } +}; class OTrophy : public OObject { public: diff --git a/src/port/Game.cpp b/src/port/Game.cpp index 300deed9f..d6cf9643c 100644 --- a/src/port/Game.cpp +++ b/src/port/Game.cpp @@ -384,9 +384,9 @@ extern "C" { } } - void CourseManager_DrawObjects(Camera* camera) { + void CourseManager_DrawObjects(s32 cameraId) { if (gWorldInstance.CurrentCourse) { - gWorldInstance.DrawObjects(camera); + gWorldInstance.DrawObjects(cameraId); } } diff --git a/src/port/Game.h b/src/port/Game.h index 0cf450c34..008d86ef7 100644 --- a/src/port/Game.h +++ b/src/port/Game.h @@ -50,7 +50,7 @@ void CourseManager_InitClouds(); void CourseManager_DrawActor(Camera* camera, struct Actor* actor); void CourseManager_TickObjects(); -void CourseManager_DrawObjects(Camera* camera); +void CourseManager_DrawObjects(s32 cameraId); void CourseManager_UpdateClouds(s32 arg0, Camera* camera); From 60014ec46695fb964a685d6a17d5fc63e02ab7b8 Mon Sep 17 00:00:00 2001 From: MegaMech Date: Mon, 16 Dec 2024 16:42:17 -0700 Subject: [PATCH 12/21] More changes --- src/code_80057C60.c | 14 +- src/engine/World.h | 47 +++ src/engine/courses/BansheeBoardwalk.cpp | 8 +- src/engine/courses/PodiumCeremony.cpp | 41 ++ src/engine/courses/TestCourse.cpp | 7 +- src/engine/objects/CheepCheep.cpp | 244 ++++++++++++ src/engine/objects/CheepCheep.h | 48 +++ src/engine/objects/Mole.cpp | 2 +- src/engine/objects/Mole.h | 6 +- src/engine/objects/Podium.cpp | 140 +++++++ src/engine/objects/Podium.h | 38 ++ src/engine/objects/Seagull.cpp | 5 +- src/engine/objects/Trophy.cpp | 1 - src/engine/objects/Trophy.h | 13 +- src/engine/particles/ParticleEmitter.cpp | 13 + src/engine/particles/ParticleEmitter.h | 23 ++ src/engine/particles/StarEmitter.cpp | 31 ++ src/engine/particles/StarEmitter.h | 42 ++ src/render_objects.c | 87 ----- src/render_objects.h | 3 +- src/update_objects.c | 470 ++--------------------- 21 files changed, 725 insertions(+), 558 deletions(-) create mode 100644 src/engine/objects/CheepCheep.cpp create mode 100644 src/engine/objects/CheepCheep.h create mode 100644 src/engine/objects/Podium.cpp create mode 100644 src/engine/objects/Podium.h create mode 100644 src/engine/particles/ParticleEmitter.cpp create mode 100644 src/engine/particles/ParticleEmitter.h create mode 100644 src/engine/particles/StarEmitter.cpp create mode 100644 src/engine/particles/StarEmitter.h diff --git a/src/code_80057C60.c b/src/code_80057C60.c index ee82cd511..cab096140 100644 --- a/src/code_80057C60.c +++ b/src/code_80057C60.c @@ -561,10 +561,10 @@ void render_object_p1(void) { CourseManager_DrawBombKarts(PLAYER_ONE); //render_bomb_karts_wrap(PLAYER_ONE); if (gGamestate == ENDING) { - func_80055F48(PLAYER_ONE); - func_80056160(PLAYER_ONE); - func_8005217C(PLAYER_ONE); - func_80054BE8(PLAYER_ONE); + //func_80055F48(PLAYER_ONE); + //func_80056160(PLAYER_ONE); + //func_8005217C(PLAYER_ONE); + //func_80054BE8(PLAYER_ONE); return; } if (!gDemoMode) { @@ -1424,9 +1424,9 @@ void func_8005A070(void) { if (gIsGamePaused == false) { func_8005C728(); if (gGamestate == ENDING) { - func_80086604(); - func_80086D80(); - update_cheep_cheep(1); + //func_80086604(); + //func_80086D80(); + //update_cheep_cheep(1); func_80077640(); } else if (gGamestate == CREDITS_SEQUENCE) { func_80059820(PLAYER_ONE); diff --git a/src/engine/World.h b/src/engine/World.h index 3b48284e8..a90ff7441 100644 --- a/src/engine/World.h +++ b/src/engine/World.h @@ -22,6 +22,53 @@ extern "C" { #include "engine/Engine.h" }; +struct FVector { + float x, y, z; + + FVector& operator=(const FVector& other) { + x = other.x; + y = other.y; + z = other.z; + return *this; + } +}; + +/** + * For selecting a section of a course path + * Usage: IPathSpan(point1, point2) --> IPathSpan(40, 65) + */ +struct IPathSpan { + int Start, End; + + // Default Constructor + IPathSpan() : Start(0), End(0) {} + + // Parameterized Constructor + IPathSpan(int InStart, int InEnd) + : Start(InStart), End(InEnd) {} + + // Copy Assignment Operator + IPathSpan& operator=(const IPathSpan& Other) { + if (this != &Other) { // Avoid self-assignment + Start = Other.Start; + End = Other.End; + } + return *this; + } + + // Equality Operator + bool operator==(const IPathSpan& Other) const { + return Start == Other.Start && End == Other.End; + } + + // Inequality Operator + bool operator!=(const IPathSpan& Other) const { + return !(*this == Other); + } +}; + + + class OObject; class Cup; // <-- Forward declaration class Course; diff --git a/src/engine/courses/BansheeBoardwalk.cpp b/src/engine/courses/BansheeBoardwalk.cpp index 9983ac0b7..80549ac90 100644 --- a/src/engine/courses/BansheeBoardwalk.cpp +++ b/src/engine/courses/BansheeBoardwalk.cpp @@ -7,6 +7,7 @@ #include "World.h" #include "engine/actors/AFinishline.h" #include "engine/objects/BombKart.h" +#include "engine/objects/CheepCheep.h" #include "assets/banshee_boardwalk_data.h" #include "assets/boo_frames.h" @@ -150,6 +151,9 @@ void BansheeBoardwalk::SpawnActors() { gWorldInstance.AddActor(new AFinishline()); spawn_all_item_boxes((struct ActorSpawnData*)LOAD_ASSET_RAW(d_course_banshee_boardwalk_item_box_spawns)); + + + gWorldInstance.AddObject(new OCheepCheep(FVector(xOrientation * -1650.0, -200.0f, -1650.0f), OCheepCheep::CheepType::RACE, IPathSpan(160, 170))); } void BansheeBoardwalk::SpawnVehicles() { @@ -199,7 +203,7 @@ void BansheeBoardwalk::UpdateCourseObjects() { update_bat(); } wrapper_update_boos(); - update_cheep_cheep(0); + //update_cheep_cheep(0); } } @@ -207,7 +211,7 @@ void BansheeBoardwalk::RenderCourseObjects(s32 cameraId) { if (gGamestate != CREDITS_SEQUENCE) { render_object_trash_bin(cameraId); render_object_bat(cameraId); - func_8005217C(cameraId); + //func_8005217C(cameraId); // render cheep cheep render_object_boos(cameraId); } } diff --git a/src/engine/courses/PodiumCeremony.cpp b/src/engine/courses/PodiumCeremony.cpp index e05b54e51..6f04bd291 100644 --- a/src/engine/courses/PodiumCeremony.cpp +++ b/src/engine/courses/PodiumCeremony.cpp @@ -8,6 +8,9 @@ #include "engine/objects/BombKart.h" #include "assets/royal_raceway_data.h" #include "assets/ceremony_data.h" +#include "engine/objects/Trophy.h" +#include "engine/objects/Podium.h" +#include "engine/objects/CheepCheep.h" extern "C" { #include "main.h" @@ -30,6 +33,7 @@ extern "C" { #include "collision.h" #include "memory.h" #include "courses/staff_ghost_data.h" + #include "podium_ceremony_actors.h" extern const char *royal_raceway_dls[]; } @@ -160,6 +164,43 @@ void PodiumCeremony::SpawnActors() { spawn_foliage((struct ActorSpawnData*)LOAD_ASSET_RAW(d_course_royal_raceway_tree_spawn)); spawn_all_item_boxes((struct ActorSpawnData*)LOAD_ASSET_RAW(d_course_royal_raceway_item_box_spawns)); spawn_piranha_plants((struct ActorSpawnData*)LOAD_ASSET_RAW(d_course_royal_raceway_piranha_plant_spawn)); + + gWorldInstance.AddObject(new OCheepCheep(FVector((f32)0xf37e, (f32)0x0013, (f32)0xfe22), OCheepCheep::CheepType::PODIUM_CEREMONY, IPathSpan(0, 0))); + gWorldInstance.AddObject(new OPodium(FVector((f32)0xf37e, (f32)0x0013, (f32)0xfe22))); + + FVector pos = {0,0,0}; + pos.y = 90.0f; + OTrophy::TrophyType type = OTrophy::TrophyType::BRONZE; + switch(D_802874D8.unk1D) { + case 0: // Bronze + if (gCCSelection == CC_150) { + OTrophy::TrophyType::BRONZE_150; + } else { + OTrophy::TrophyType::BRONZE; + } + break; + case 1: // Silver + pos.x -= 3.0; + pos.z += 15.0; + + if (gCCSelection == CC_150) { + OTrophy::TrophyType::SILVER_150; + } else { + OTrophy::TrophyType::SILVER; + } + break; + case 2: // Gold + pos.x -= 2.0; + pos.z -= 15.0; + if (gCCSelection == CC_150) { + OTrophy::TrophyType::GOLD_150; + } else { + OTrophy::TrophyType::GOLD; + } + break; + } + + gWorldInstance.AddObject(new OTrophy(pos, type, OTrophy::Behaviour::PODIUM_CEREMONY)); } void PodiumCeremony::SpawnVehicles() { diff --git a/src/engine/courses/TestCourse.cpp b/src/engine/courses/TestCourse.cpp index 2750c727f..465f97012 100644 --- a/src/engine/courses/TestCourse.cpp +++ b/src/engine/courses/TestCourse.cpp @@ -14,6 +14,7 @@ #include "engine/actors/ACloud.h" #include "engine/vehicles/Train.h" #include "engine/objects/Trophy.h" +#include "engine/objects/CheepCheep.h" extern "C" { #include "main.h" @@ -189,14 +190,14 @@ void TestCourse::SpawnActors() { rrxing->crossingTrigger = crossing1; Vec3f pos = {0, 80, 0}; - //gWorldInstance.AddActor(new ACloud(pos)); + // gWorldInstance.AddActor(new ACloud(pos)); // gWorldInstance.AddActor(new OSeagull(0, pos)); // gWorldInstance.AddActor(new OSeagull(1, pos)); // gWorldInstance.AddActor(new OSeagull(2, pos)); // gWorldInstance.AddActor(new OSeagull(3, pos)); - - gWorldInstance.AddObject(new OTrophy(FVector(0,0,0), OTrophy::TrophyType::GOLD, OTrophy::Behaviour::GO_FISH)); + gWorldInstance.AddObject(new OCheepCheep(FVector(0, 40, 0), OCheepCheep::CheepType::RACE, IPathSpan(0, 10))); + //gWorldInstance.AddObject(new OTrophy(FVector(0,0,0), OTrophy::TrophyType::GOLD, OTrophy::Behaviour::GO_FISH)); } // Likely sets minimap boundaries diff --git a/src/engine/objects/CheepCheep.cpp b/src/engine/objects/CheepCheep.cpp new file mode 100644 index 000000000..e81ba7c24 --- /dev/null +++ b/src/engine/objects/CheepCheep.cpp @@ -0,0 +1,244 @@ +#include "CheepCheep.h" + +#include "assets/banshee_boardwalk_data.h" +#include "assets/common_data.h" + +extern "C" { +#include "math_util.h" +#include "math_util_2.h" +#include "render_objects.h" +#include "update_objects.h" +#include "code_800029B0.h" +#include "code_80086E70.h" +#include "waypoints.h" +#include "code_80057C60.h" +#include "some_data.h" +extern Vec3s D_800E634C[]; +extern Lights1 D_800E45C0[]; +} + +OCheepCheep::OCheepCheep(const FVector& pos, CheepType type, IPathSpan span) { + _type = type; + _spawnPos = pos; + _span = span; +} + +void OCheepCheep::Tick() { // update_cheep_cheep + s32 objectIndex; + switch (_type) { + case CheepType::RACE: + UNUSED s32 pad; + + OCheepCheep::func_8007BD04(0); + objectIndex = indexObjectList2[0]; + OCheepCheep::func_8007BBBC(objectIndex); + object_calculate_new_pos_offset(objectIndex); + break; + case CheepType::PODIUM_CEREMONY: + objectIndex = indexObjectList2[0]; + if (D_801658BC == 1) { + D_801658BC = 0; + init_object(objectIndex, 0); + } + if (gObjectList[objectIndex].state != 0) { + OCheepCheep::func_8007BEC8(objectIndex); + OCheepCheep::func_8007BFB0(objectIndex); + } + break; + } +} + +void OCheepCheep::Draw(s32 cameraId) { // func_8005217C + Lights1* D_800E45C0l = (Lights1*) (D_800E45C0); + Object* object; + s32 temp_a3; + + temp_a3 = indexObjectList2[0]; + object = &gObjectList[temp_a3]; + if (object->state >= 2) { + if (is_obj_flag_status_active(temp_a3, 0x10) != 0) { + rsp_set_matrix_transformation(object->pos, object->direction_angle, object->sizeScaling); + func_800520C0(temp_a3); + + gSPDisplayList(gDisplayListHead++, (Gfx*)D_0D007828); + gSPLight(gDisplayListHead++, &D_800E45C0l[0].l[0], LIGHT_1); + gSPLight(gDisplayListHead++, &D_800E45C0l[0].a, LIGHT_2); + gSPDisplayList(gDisplayListHead++, (Gfx*)d_course_banshee_boardwalk_dl_7B38); + gSPLight(gDisplayListHead++, &D_800E45C0l[1].l[0], LIGHT_1); + gSPLight(gDisplayListHead++, &D_800E45C0l[1].a, LIGHT_2); + gSPDisplayList(gDisplayListHead++, (Gfx*)d_course_banshee_boardwalk_dl_7978); + gSPLight(gDisplayListHead++, &D_800E45C0l[2].l[0], LIGHT_1); + gSPLight(gDisplayListHead++, &D_800E45C0l[2].a, LIGHT_2); + gSPDisplayList(gDisplayListHead++, (Gfx*)d_course_banshee_boardwalk_dl_78C0); + gSPLight(gDisplayListHead++, &D_800E45C0l[3].l[0], LIGHT_1); + gSPLight(gDisplayListHead++, &D_800E45C0l[3].a, LIGHT_2); + gSPDisplayList(gDisplayListHead++, (Gfx*)d_course_banshee_boardwalk_dl_7650); + } + } +} + +void OCheepCheep::func_8007BBBC(s32 objectIndex) { + f32 var_f14; + Object* object; + + object = &gObjectList[objectIndex]; + switch (object->state) { + case 1: + func_800735BC(objectIndex, (Gfx*)d_course_banshee_boardwalk_dl_cheep_cheep, 2.0f); + set_object_flag(objectIndex, 0x00000010); + object->unk_0D5 = 0; + break; + case 2: + if (gIsMirrorMode != 0) { + func_80087E08(objectIndex, 18.0f, 0.7f, 25.0f, (s16) -0x00005800, 0x0000012C); + } else { + func_80087E08(objectIndex, 18.0f, 0.7f, 25.0f, (s16) 0x00005800, 0x0000012C); + } + if (object->velocity[2] < 0.0f) { + var_f14 = -object->velocity[2]; + } else { + var_f14 = object->velocity[2]; + } + object->direction_angle[0] = func_80041658(object->velocity[1], var_f14); + set_and_run_timer_object(objectIndex, 0x00000046); + break; + case 3: + func_80072428(objectIndex); + break; + case 0: + break; + } +} + +void OCheepCheep::func_8007BD04(s32 playerId) { + s32 objectIndex; + + objectIndex = indexObjectList2[0]; + if (gObjectList[objectIndex].state == 0) { + if (((s32) gNearestWaypointByPlayerId[playerId] >= _span.Start) && + ((s32) gNearestWaypointByPlayerId[playerId] <= _span.End)) { + set_obj_origin_pos(objectIndex, xOrientation * _spawnPos.x, _spawnPos.y, _spawnPos.z); + init_object(objectIndex, 1); + } + } +} + +void OCheepCheep::init_var_cheep_cheep(s32 objectIndex) { + Object* object; + + object = &gObjectList[objectIndex]; + object->unk_0D5 = 1; + object->status = 0; + object->model = (Gfx*)d_course_banshee_boardwalk_dl_cheep_cheep; + object->sizeScaling = 0.2f; + object_next_state(objectIndex); + set_obj_origin_pos(objectIndex, D_800E634C[0][0], D_800E634C[0][1] + 55.0, D_800E634C[0][2]); + set_obj_origin_offset(objectIndex, 0.0f, 30.0f, 0.0f); + set_obj_direction_angle(objectIndex, 0U, 0x3800U, 0U); +} + +void OCheepCheep::func_8007BEC8(s32 objectIndex) { + Object* object; + + object = &gObjectList[objectIndex]; + switch (object->state) { + case 1: + OCheepCheep::init_var_cheep_cheep(objectIndex); + break; + case 2: + if (set_and_run_timer_object(objectIndex, 0x0000003C) != 0) { + set_object_flag(objectIndex, 0x00000010); + func_80086E70(objectIndex); + } + break; + case 3: + if (object->unk_0AE == 0) { + object_next_state(objectIndex); + } + break; + case 4: + if (set_and_run_timer_object(objectIndex, 0x0000000A) != 0) { + func_8008701C(objectIndex, 2); + } + break; + case 5: + if (object->unk_0AE == 0) { + func_80072428(objectIndex); + } + break; + case 0: + default: + break; + } +} + +void OCheepCheep::func_8007BFB0(s32 objectIndex) { + Object* object; + + object = &gObjectList[objectIndex]; + switch (object->unk_0AE) { + case 0: + break; + case 1: + object->velocity[1] = -0.2f; + if ((f64) object->offset[1] <= 0.0) { + object->offset[1] = 0.0f; + object->velocity[1] = 0.0f; + func_80086F60(objectIndex); + } + break; + case 2: + if (func_800871AC(objectIndex, 0x00000014) != 0) { + object->unk_084[7] = 0x0040; + } + break; + case 3: + object->sizeScaling = (f32) ((f64) object->sizeScaling - 0.0015); + if ((s32) object->direction_angle[0] >= 0xA01) { + object->unk_084[7] -= 4; + } + if (u16_step_up_towards(object->direction_angle, 0x0C00U, (u16) object->unk_084[7]) != 0) { + func_80086FD4(objectIndex); + } + break; + case 4: + object->sizeScaling = (f32) ((f64) object->sizeScaling - 0.0015); + object->unk_034 = 0.001f; + func_80086FD4(objectIndex); + object->unk_084[7] = 0; + break; + case 5: + if (object->unk_034 <= 0.004) { + object->unk_034 += 0.0002; + } + object->sizeScaling += object->unk_034; + s16_step_up_towards(&object->unk_084[7], 0x0100, 0x0010); + object->direction_angle[0] -= object->unk_084[7]; + if (func_80087060(objectIndex, 0x00000035) != 0) { + func_80086FD4(objectIndex); + } + break; + case 6: + if (func_80087060(objectIndex, 0x0000000F) != 0) { + func_80086FD4(objectIndex); + D_801658CE = 1; + } + break; + case 7: + object->sizeScaling = (f32) ((f64) object->sizeScaling - 0.05); + if ((f64) object->sizeScaling <= 0.01) { + clear_object_flag(objectIndex, 0x00000010); + object->sizeScaling = 0.000001f; + func_80086FD4(objectIndex); + } + break; + case 8: + func_80086F60(objectIndex); + break; + } + if (object->unk_0AE < 0xA) { + func_80074344(objectIndex, &object->sizeScaling, 0.2f, 0.21f, 0.001f, 0, -1); + } + object_add_velocity_offset_y(objectIndex); + object_calculate_new_pos_offset(objectIndex); +} diff --git a/src/engine/objects/CheepCheep.h b/src/engine/objects/CheepCheep.h new file mode 100644 index 000000000..32e9a5aeb --- /dev/null +++ b/src/engine/objects/CheepCheep.h @@ -0,0 +1,48 @@ +#pragma once + +#include +#include +#include "Object.h" + +#include "World.h" + +extern "C" { +#include "macros.h" +#include "main.h" +#include "common_structs.h" +#include "objects.h" +#include "course_offsets.h" +#include "some_data.h" +} + + +class OCheepCheep : public OObject { +public: + enum CheepType { + RACE, + PODIUM_CEREMONY + }; + + enum Behaviour : uint16_t { + }; + +public: + + explicit OCheepCheep(const FVector& pos, CheepType type, IPathSpan span); + + virtual void Tick() override; + virtual void Draw(s32 cameraId) override; + void func_8007BBBC(s32 objectIndex); + void func_8007BD04(s32 playerId); + void init_var_cheep_cheep(s32 objectIndex); + void func_8007BEC8(s32 objectIndex); + void func_8007BFB0(s32 objectIndex); + +private: + + s32 _idx; + CheepType _type; + FVector _spawnPos; + IPathSpan _span; + +}; diff --git a/src/engine/objects/Mole.cpp b/src/engine/objects/Mole.cpp index 9ef7f40ef..78b186e77 100644 --- a/src/engine/objects/Mole.cpp +++ b/src/engine/objects/Mole.cpp @@ -72,7 +72,7 @@ void OMole::Tick() { } } -void OMole::Draw(Camera* camera) { +void OMole::Draw(s32 cameraId) { } diff --git a/src/engine/objects/Mole.h b/src/engine/objects/Mole.h index d5d605fa5..7ff95c58c 100644 --- a/src/engine/objects/Mole.h +++ b/src/engine/objects/Mole.h @@ -2,7 +2,7 @@ #include #include -#include "GameObject.h" +#include "Object.h" extern "C" { #include "macros.h" @@ -16,7 +16,7 @@ extern "C" { } -class OMole : public GameObject { +class OMole : public OObject { public: enum Behaviour : uint16_t { }; @@ -25,7 +25,7 @@ public: explicit OMole(Vec3f pos); virtual void Tick() override; - virtual void Draw(Camera*) override; + virtual void Draw(s32 cameraId) override; void func_80054E10(s32 objectIndex); void func_80054EB8(); diff --git a/src/engine/objects/Podium.cpp b/src/engine/objects/Podium.cpp new file mode 100644 index 000000000..426a65b60 --- /dev/null +++ b/src/engine/objects/Podium.cpp @@ -0,0 +1,140 @@ +#include "Podium.h" +#include "assets/ceremony_data.h" + +extern "C" { +#include "main.h" +#include "defines.h" +#include "update_objects.h" +#include "render_objects.h" +#include "code_80057C60.h" +#include "podium_ceremony_actors.h" +#include "math_util.h" +#include "math_util_2.h" +#include "assets/common_data.h" +#include "some_data.h" +#include "code_80091440.h" +#include "code_80086E70.h" +#include "code_80086E70.h" +extern Vec3s D_800E634C[]; +} + +// Might be Cheep Cheep related? +// Vec3s D_800E634C[] = { +// { 0xf37e, 0x0013, 0xfe22 }, +// { 0xf37b, 0x0013, 0xfe31 }, +// { 0xf380, 0x0013, 0xfe14 }, +// }; + +OPodium::OPodium(const FVector& pos) { + + for (size_t i = 0; i < NUM_PODIUMS; i++) { + s32 objectIndex = indexObjectList1[i]; + init_object(objectIndex, 0); + set_obj_origin_pos(objectIndex, pos.x - 1.5, pos.y, pos.z); + } +} + +void OPodium::Tick() { // func_80086604 + s32 objectIndex; + // if ((D_8016347C != 0) && (D_802874D8.unk1D < 3)) { + // if (D_801658C6 == 0) { + // for (size_t i = 0; i < 3; i++) { + // objectIndex = indexObjectList1[i]; + // init_object(objectIndex, 0); + // } + // D_801658C6 = 1; + // } + // } + for (size_t i = 0; i != NUM_PODIUMS; i++) { + objectIndex = indexObjectList1[i]; + if (gObjectList[objectIndex].state != 0) { + OPodium::func_80086528(objectIndex, i); + OPodium::func_80086424(objectIndex); + } + } +} + +void OPodium::Draw(s32 cameraId) { // func_80055F48 + for (size_t i = 0; i < NUM_PODIUMS; i++) { + Object* object; + + object = &gObjectList[i]; + if (object->state >= 2) { + func_80043220(object->pos, object->direction_angle, object->sizeScaling, object->model); + rsp_set_matrix_transformation(object->pos, object->direction_angle, object->sizeScaling); + gSPDisplayList(gDisplayListHead++, (Gfx*)D_0D0077A0); + gSPDisplayList(gDisplayListHead++, object->model); + } + } +} + +void OPodium::func_8008629C(s32 objectIndex, s32 arg1) { + switch (arg1) { /* irregular */ + case 0: + gObjectList[objectIndex].model = (Gfx*)podium_dl3; + gObjectList[objectIndex].unk_04C = 0x00000038; + break; + case 1: + gObjectList[objectIndex].model = (Gfx*)podium2_dl3; + gObjectList[objectIndex].unk_04C = 0x0000002B; + break; + case 2: + gObjectList[objectIndex].model = (Gfx*)podium3_dl3; + gObjectList[objectIndex].unk_04C = 0x0000001E; + break; + default: + break; + } + gObjectList[objectIndex].sizeScaling = 1.0f; + //set_obj_origin_pos(objectIndex, D_800E634C[0][0] - 1.5, D_800E634C[0][1], D_800E634C[0][2]); + set_obj_origin_offset(objectIndex, 0.0f, -10.0f, 0.0f); + set_obj_direction_angle(objectIndex, 0U, 0xF8E4U, 0U); + gObjectList[objectIndex].unk_048 = 0; + object_next_state(objectIndex); +} + +void OPodium::func_80086424(s32 objectIndex) { + switch (gObjectList[objectIndex].unk_0AE) { + case 0: + break; + case 1: + gObjectList[objectIndex].velocity[1] = 0.75f; + func_80086FD4(objectIndex); + break; + case 2: + if (gObjectList[objectIndex].offset[1] >= -2.0) { + gObjectList[objectIndex].velocity[1] -= 0.1; + } + object_add_velocity_offset_y(objectIndex); + if (gObjectList[objectIndex].offset[1] >= 0.0) { + gObjectList[objectIndex].offset[1] = 0.0f; + gObjectList[objectIndex].velocity[1] = 0.0f; + func_80086F60(objectIndex); + } + break; + } + object_calculate_new_pos_offset(objectIndex); +} + +void OPodium::func_80086528(s32 objectIndex, s32 arg1) { + switch (gObjectList[objectIndex].state) { /* irregular */ + case 1: + func_8008629C(objectIndex, arg1); + break; + case 2: + if (set_and_run_timer_object(objectIndex, gObjectList[objectIndex].unk_04C) != 0) { + func_80091440(arg1); + func_80086E70(objectIndex); + object_next_state(objectIndex); + } + break; + case 0: + break; + case 3: + if (gObjectList[objectIndex].unk_0AE == 0) { + gObjectList[objectIndex].unk_048 = 1; + object_next_state(objectIndex); + } + break; + } +} diff --git a/src/engine/objects/Podium.h b/src/engine/objects/Podium.h new file mode 100644 index 000000000..2b3a1033a --- /dev/null +++ b/src/engine/objects/Podium.h @@ -0,0 +1,38 @@ +#pragma once + +#include +#include + +#include "World.h" + +extern "C" { +#include "macros.h" +#include "main.h" +#include "vehicles.h" +#include "waypoints.h" +#include "common_structs.h" +#include "objects.h" +#include "course_offsets.h" +#include "some_data.h" +} + + +class OPodium : public OObject { +public: + enum Behaviour : uint16_t { + }; + +public: + + explicit OPodium(const FVector& pos); + + virtual void Tick() override; + virtual void Draw(s32 cameraId) override; + void func_8008629C(s32 objectIndex, s32 arg1); + void func_80086424(s32 objectIndex); + void func_80086528(s32 objectIndex, s32 arg1); + +private: + + s32 _idx; +}; diff --git a/src/engine/objects/Seagull.cpp b/src/engine/objects/Seagull.cpp index 4b36bbf31..b641ab5b4 100644 --- a/src/engine/objects/Seagull.cpp +++ b/src/engine/objects/Seagull.cpp @@ -2,7 +2,6 @@ #include #include "Seagull.h" #include "engine/Actor.h" -#include "ObjectReimpl.h" #include #include "port/Game.h" @@ -135,7 +134,7 @@ void OSeagull::func_8008275C(s32 objectIndex) { switch (gObjectList[objectIndex].unk_0DD) { case 1: func_8008B78C(objectIndex); - ObjectImpl::CalculateNewPosOffset(this); + object_calculate_new_pos_offset(objectIndex); break; case 2: func_8008B78C(objectIndex); @@ -145,7 +144,7 @@ void OSeagull::func_8008275C(s32 objectIndex) { Offset[0] *= 2.0; Offset[1] *= 2.5; Offset[2] *= 2.0; - ObjectImpl::CalculateNewPosOffset(this); + object_calculate_new_pos_offset(objectIndex); gObjectList[objectIndex].direction_angle[1] = get_angle_between_two_vectors(gObjectList[objectIndex].unk_01C, gObjectList[objectIndex].pos); break; diff --git a/src/engine/objects/Trophy.cpp b/src/engine/objects/Trophy.cpp index 464a2277c..5ac54f5ec 100644 --- a/src/engine/objects/Trophy.cpp +++ b/src/engine/objects/Trophy.cpp @@ -226,7 +226,6 @@ void OTrophy::Draw(s32 cameraId) { func_80057A50(40, 0, (char*) "Trophies Collected: ", (s16) numTrophies); break; } - } } diff --git a/src/engine/objects/Trophy.h b/src/engine/objects/Trophy.h index d73e04929..d413faf12 100644 --- a/src/engine/objects/Trophy.h +++ b/src/engine/objects/Trophy.h @@ -3,6 +3,7 @@ #include #include #include "Object.h" +#include "World.h" extern "C" { #include "macros.h" @@ -15,18 +16,6 @@ extern "C" { #include "some_data.h" } -//! @todo move this like World.h or something -struct FVector { - float x, y, z; - - FVector& operator=(const FVector& other) { - x = other.x; - y = other.y; - z = other.z; - return *this; - } -}; - class OTrophy : public OObject { public: enum TrophyType { diff --git a/src/engine/particles/ParticleEmitter.cpp b/src/engine/particles/ParticleEmitter.cpp new file mode 100644 index 000000000..5154abf56 --- /dev/null +++ b/src/engine/particles/ParticleEmitter.cpp @@ -0,0 +1,13 @@ +#include + +#include "ParticleEmitter.h" + + + +ParticleEmitter::ParticleEmitter() {} + + // Virtual functions to be overridden by derived classes +void ParticleEmitter::Tick() { } +void ParticleEmitter::Draw(s32 cameraId) { } + +bool ParticleEmitter::IsMod() { return false; } diff --git a/src/engine/particles/ParticleEmitter.h b/src/engine/particles/ParticleEmitter.h new file mode 100644 index 000000000..1a71164d1 --- /dev/null +++ b/src/engine/particles/ParticleEmitter.h @@ -0,0 +1,23 @@ +#pragma once + +#include + +extern "C" { +#include "macros.h" +#include "main.h" +#include "camera.h" +#include "common_structs.h" + + +class ParticleEmitter { +public: + virtual ~ParticleEmitter() = default; // Virtual destructor for proper cleanup in derived classes + + explicit ParticleEmitter(); + + virtual void Tick(); + virtual void Draw(s32 cameraId); + virtual bool IsMod(); +}; + +} \ No newline at end of file diff --git a/src/engine/particles/StarEmitter.cpp b/src/engine/particles/StarEmitter.cpp new file mode 100644 index 000000000..b717f177d --- /dev/null +++ b/src/engine/particles/StarEmitter.cpp @@ -0,0 +1,31 @@ + + +#include "StarEmitter.h" + +extern "C" { +#include "render_objects.h" +#include "common_data.h" +#include "code_80057C60.h" +} + +void StarEmitter::Tick() { + +} + +void StarEmitter::Draw(s32 cameraId) { // func_80054BE8 + s32 var_s0; + s32 temp_a0; + Camera* camera; + + camera = &camera1[cameraId]; + gSPDisplayList(gDisplayListHead++, (Gfx*)D_0D007AE0); + load_texture_block_ia8_nomirror(D_8018D488, 0x00000020, 0x00000020); + func_8004B35C(0x000000FF, 0x000000FF, 0, 0x000000FF); + D_80183E80[0] = 0; + for (var_s0 = 0; var_s0 < gObjectParticle3_SIZE; var_s0++) { + temp_a0 = gObjectParticle3[var_s0]; + if ((temp_a0 != -1) && (gObjectList[temp_a0].state >= 2)) { + func_80054AFC(temp_a0, camera->pos); + } + } +} diff --git a/src/engine/particles/StarEmitter.h b/src/engine/particles/StarEmitter.h new file mode 100644 index 000000000..20841598c --- /dev/null +++ b/src/engine/particles/StarEmitter.h @@ -0,0 +1,42 @@ +#pragma once + +#include +#include +#include "ParticleEmitter.h" + +extern "C" { +#include "macros.h" +#include "main.h" +#include "vehicles.h" +#include "waypoints.h" +#include "common_structs.h" +#include "objects.h" +#include "course_offsets.h" +#include "some_data.h" +} + +/** + * Used in the podium ceremony when the trophy appears + */ +class StarEmitter : public ParticleEmitter { +public: + enum Behaviour : uint16_t { + }; + +public: + f32 Diameter = 0.0f; // Waddle in a circle around the spawn point at this diameter. + uint16_t MirrorModeAngleOffset; + + explicit StarEmitter(Vec3f pos); + + virtual void Tick() override; + virtual void Draw(s32 cameraId) override; + void func_80086700(s32 objectIndex); + void func_80086940(s32 objectIndex); + void func_80086C14(s32 objectIndex); + void func_80086C6C(s32 objectIndex); + +private: + + s32 _idx; +}; diff --git a/src/render_objects.c b/src/render_objects.c index a56e91c0d..8c9a8d0e3 100644 --- a/src/render_objects.c +++ b/src/render_objects.c @@ -3411,35 +3411,6 @@ void func_800520C0(s32 arg0) { } } -void func_8005217C(UNUSED s32 arg0) { - Lights1* D_800E45C0l = LOAD_ASSET(D_800E45C0); - Object* object; - s32 temp_a3; - - temp_a3 = indexObjectList2[0]; - object = &gObjectList[temp_a3]; - if (object->state >= 2) { - if (is_obj_flag_status_active(temp_a3, 0x00000010) != 0) { - rsp_set_matrix_transformation(object->pos, object->direction_angle, object->sizeScaling); - func_800520C0(temp_a3); - - gSPDisplayList(gDisplayListHead++, D_0D007828); - gSPLight(gDisplayListHead++, &D_800E45C0l[0].l[0], LIGHT_1); - gSPLight(gDisplayListHead++, &D_800E45C0l[0].a, LIGHT_2); - gSPDisplayList(gDisplayListHead++, d_course_banshee_boardwalk_dl_7B38); - gSPLight(gDisplayListHead++, &D_800E45C0l[1].l[0], LIGHT_1); - gSPLight(gDisplayListHead++, &D_800E45C0l[1].a, LIGHT_2); - gSPDisplayList(gDisplayListHead++, d_course_banshee_boardwalk_dl_7978); - gSPLight(gDisplayListHead++, &D_800E45C0l[2].l[0], LIGHT_1); - gSPLight(gDisplayListHead++, &D_800E45C0l[2].a, LIGHT_2); - gSPDisplayList(gDisplayListHead++, d_course_banshee_boardwalk_dl_78C0); - gSPLight(gDisplayListHead++, &D_800E45C0l[3].l[0], LIGHT_1); - gSPLight(gDisplayListHead++, &D_800E45C0l[3].a, LIGHT_2); - gSPDisplayList(gDisplayListHead++, d_course_banshee_boardwalk_dl_7650); - } - } -} - void func_800523B8(s32 objectIndex, s32 arg1, u32 arg2) { UNUSED s32 pad[2]; Object* object; @@ -3997,25 +3968,6 @@ void func_80054AFC(s32 objectIndex, Vec3f arg1) { gSPDisplayList(gDisplayListHead++, common_rectangle_display); } -void func_80054BE8(s32 cameraId) { - s32 var_s0; - s32 temp_a0; - Camera* camera; - - camera = &camera1[cameraId]; - gSPDisplayList(gDisplayListHead++, D_0D007AE0); - load_texture_block_ia8_nomirror(D_8018D488, 0x00000020, 0x00000020); - func_8004B35C(0x000000FF, 0x000000FF, 0, 0x000000FF); - D_80183E80[0] = 0; - for (var_s0 = 0; var_s0 < gObjectParticle3_SIZE; var_s0++) { - temp_a0 = gObjectParticle3[var_s0]; - if ((temp_a0 != -1) && (gObjectList[temp_a0].state >= 2)) { - func_80054AFC(temp_a0, camera->pos); - } - } -} - - void func_80055164(s32 objectIndex) { if (gObjectList[objectIndex].state >= 2) { gSPDisplayList(gDisplayListHead++, D_0D0077A0); @@ -4271,45 +4223,6 @@ void func_80055EF4(s32 objectIndex, UNUSED s32 arg1) { } } -void func_80055F48(s32 arg0) { - s32 someIndex; - - for (someIndex = 0; someIndex < 3; someIndex++) { - func_80055EF4(indexObjectList1[someIndex], arg0); - } -} - -void func_80055FA0(s32 objectIndex, UNUSED s32 arg1) { - Mat4 someMatrix1; - Mat4 someMatrix2; - Object* object; - - object = &gObjectList[objectIndex]; - if (object->state >= 2) { - gSPMatrix(gDisplayListHead++, VIRTUAL_TO_PHYSICAL(&gGfxPool->mtxPersp[0]), - G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_PROJECTION); - gSPMatrix(gDisplayListHead++, VIRTUAL_TO_PHYSICAL(&gGfxPool->mtxLookAt[0]), - G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); - mtxf_set_matrix_transformation(someMatrix1, object->pos, object->direction_angle, object->sizeScaling); - //convert_to_fixed_point_matrix(&gGfxPool->mtxHud[gMatrixHudCount], someMatrix1); - //gSPMatrix(gDisplayListHead++, VIRTUAL_TO_PHYSICAL(&gGfxPool->mtxHud[gMatrixHudCount++]), - // G_MTX_NOPUSH | G_MTX_MUL | G_MTX_MODELVIEW); - - AddHudMatrix(someMatrix1, G_MTX_NOPUSH | G_MTX_MUL | G_MTX_MODELVIEW); - - gSPDisplayList(gDisplayListHead++, D_0D0077A0); - gSPDisplayList(gDisplayListHead++, object->model); - gSPMatrix(gDisplayListHead++, VIRTUAL_TO_PHYSICAL(&gGfxPool->mtxLookAt[0]), - G_MTX_NOPUSH | G_MTX_MUL | G_MTX_PROJECTION); - mtxf_identity(someMatrix2); - render_set_position(someMatrix2, 0); - } -} - -void func_80056160(s32 arg0) { - func_80055FA0(indexObjectList1[3], arg0); -} - void render_object_neon(s32 cameraId) { Camera* camera; s32 var_s2; diff --git a/src/render_objects.h b/src/render_objects.h index b77d7ce18..8559ce6ca 100644 --- a/src/render_objects.h +++ b/src/render_objects.h @@ -330,7 +330,6 @@ void func_80051F9C(void); void func_80052044(void); void func_80052080(void); void func_800520C0(s32); -void func_8005217C(s32); void func_800523B8(s32, s32, u32); void render_object_boos(s32); void render_object_bat(s32); @@ -361,7 +360,6 @@ void render_object_bowser_flame(s32); void func_8005477C(s32, u8, Vec3f); void render_object_smoke_particles(s32); void func_80054AFC(s32, Vec3f); -void func_80054BE8(s32); void func_80054D00(s32, s32); void func_80054E10(s32); void func_80054EB8(s32); @@ -430,6 +428,7 @@ void func_80057B14(s32, s32, char*, u32); void func_80057B80(s32, s32, char*, u32); void func_80057BEC(s32, s32, char*, u32); +extern Lights1 D_800E45C0[]; extern Lights1 D_800E4668; extern f32 D_801637C4; diff --git a/src/update_objects.c b/src/update_objects.c index e441e2392..fe25980cd 100644 --- a/src/update_objects.c +++ b/src/update_objects.c @@ -2289,6 +2289,18 @@ void func_80077428(s32 arg0) { func_80086E70(arg0); } + + + + + + + + + + + + void func_80077450(s32 objectIndex) { UNUSED s16 stackPadding0; s16 sp3C; @@ -2357,6 +2369,20 @@ void func_80077640(void) { } } + + + + + + + + + + + + + + void init_object_leaf_particle(s32 objectIndex, Vec3f arg1, s32 num) { UNUSED s32 stackPadding1; UNUSED u16 stackPadding0; @@ -4496,206 +4522,27 @@ void func_8007BB9C(s32 arg0) { func_8007B34C(arg0); } -void func_8007BBBC(s32 objectIndex) { - f32 var_f14; - Object* object; - object = &gObjectList[objectIndex]; - switch (object->state) { /* irregular */ - case 1: - func_800735BC(objectIndex, d_course_banshee_boardwalk_dl_cheep_cheep, 2.0f); - set_object_flag(objectIndex, 0x00000010); - object->unk_0D5 = 0; - break; - case 2: - if (gIsMirrorMode != 0) { - func_80087E08(objectIndex, 18.0f, 0.7f, 25.0f, (s16) -0x00005800, 0x0000012C); - } else { - func_80087E08(objectIndex, 18.0f, 0.7f, 25.0f, (s16) 0x00005800, 0x0000012C); - } - if (object->velocity[2] < 0.0f) { - var_f14 = -object->velocity[2]; - } else { - var_f14 = object->velocity[2]; - } - object->direction_angle[0] = func_80041658(object->velocity[1], var_f14); - set_and_run_timer_object(objectIndex, 0x00000046); - break; - case 3: - func_80072428(objectIndex); - break; - case 0: - break; - } -} -void func_8007BD04(s32 playerId) { - s32 objectIndex; - objectIndex = indexObjectList2[0]; - if (gObjectList[objectIndex].state == 0) { - if (((s32) gNearestWaypointByPlayerId[playerId] >= 0xA0) && - ((s32) gNearestWaypointByPlayerId[playerId] < 0xAB)) { - set_obj_origin_pos(objectIndex, xOrientation * -1650.0, -200.0f, -1650.0f); - init_object(objectIndex, 1); - } - } -} -void update_cheep_cheep_race(void) { - UNUSED s32 pad; - s32 objectIndex; - func_8007BD04(0); - objectIndex = indexObjectList2[0]; - func_8007BBBC(objectIndex); - object_calculate_new_pos_offset(objectIndex); -} -void init_var_cheep_cheep(s32 objectIndex) { - Object* object; - object = &gObjectList[objectIndex]; - object->unk_0D5 = 1; - object->status = 0; - object->model = d_course_banshee_boardwalk_dl_cheep_cheep; - object->sizeScaling = 0.2f; - object_next_state(objectIndex); - set_obj_origin_pos(objectIndex, D_800E634C[0][0], D_800E634C[0][1] + 55.0, D_800E634C[0][2]); - set_obj_origin_offset(objectIndex, 0.0f, 30.0f, 0.0f); - set_obj_direction_angle(objectIndex, 0U, 0x3800U, 0U); -} -void func_8007BEC8(s32 objectIndex) { - Object* object; - object = &gObjectList[objectIndex]; - switch (object->state) { - case 1: - init_var_cheep_cheep(objectIndex); - break; - case 2: - if (set_and_run_timer_object(objectIndex, 0x0000003C) != 0) { - set_object_flag(objectIndex, 0x00000010); - func_80086E70(objectIndex); - } - break; - case 3: - if (object->unk_0AE == 0) { - object_next_state(objectIndex); - } - break; - case 4: - if (set_and_run_timer_object(objectIndex, 0x0000000A) != 0) { - func_8008701C(objectIndex, 2); - } - break; - case 5: - if (object->unk_0AE == 0) { - func_80072428(objectIndex); - } - break; - case 0: - default: - break; - } -} -void func_8007BFB0(s32 objectIndex) { - Object* object; - object = &gObjectList[objectIndex]; - switch (object->unk_0AE) { - case 0: - break; - case 1: - object->velocity[1] = -0.2f; - if ((f64) object->offset[1] <= 0.0) { - object->offset[1] = 0.0f; - object->velocity[1] = 0.0f; - func_80086F60(objectIndex); - } - break; - case 2: - if (func_800871AC(objectIndex, 0x00000014) != 0) { - object->unk_084[7] = 0x0040; - } - break; - case 3: - object->sizeScaling = (f32) ((f64) object->sizeScaling - 0.0015); - if ((s32) object->direction_angle[0] >= 0xA01) { - object->unk_084[7] -= 4; - } - if (u16_step_up_towards(object->direction_angle, 0x0C00U, (u16) object->unk_084[7]) != 0) { - func_80086FD4(objectIndex); - } - break; - case 4: - object->sizeScaling = (f32) ((f64) object->sizeScaling - 0.0015); - object->unk_034 = 0.001f; - func_80086FD4(objectIndex); - object->unk_084[7] = 0; - break; - case 5: - if (object->unk_034 <= 0.004) { - object->unk_034 += 0.0002; - } - object->sizeScaling += object->unk_034; - s16_step_up_towards(&object->unk_084[7], 0x0100, 0x0010); - object->direction_angle[0] -= object->unk_084[7]; - if (func_80087060(objectIndex, 0x00000035) != 0) { - func_80086FD4(objectIndex); - } - break; - case 6: - if (func_80087060(objectIndex, 0x0000000F) != 0) { - func_80086FD4(objectIndex); - D_801658CE = 1; - } - break; - case 7: - object->sizeScaling = (f32) ((f64) object->sizeScaling - 0.05); - if ((f64) object->sizeScaling <= 0.01) { - clear_object_flag(objectIndex, 0x00000010); - object->sizeScaling = 0.000001f; - func_80086FD4(objectIndex); - } - break; - case 8: - func_80086F60(objectIndex); - break; - } - if (object->unk_0AE < 0xA) { - func_80074344(objectIndex, &object->sizeScaling, 0.2f, 0.21f, 0.001f, 0, -1); - } - object_add_velocity_offset_y(objectIndex); - object_calculate_new_pos_offset(objectIndex); -} -void update_cheep_cheep_ending(void) { - s32 objectIndex; - objectIndex = indexObjectList2[0]; - if (D_801658BC == 1) { - D_801658BC = 0; - init_object(objectIndex, 0); - } - if (gObjectList[objectIndex].state != 0) { - func_8007BEC8(objectIndex); - func_8007BFB0(objectIndex); - } -} -void update_cheep_cheep(s32 arg0) { - switch (arg0) { - case 0: - update_cheep_cheep_race(); - break; - case 1: - update_cheep_cheep_ending(); - break; - } -} + + + + + + + void wrapper_update_boos(void) { update_boos(); @@ -6366,254 +6213,3 @@ void update_neon(void) { } } } - -void func_8008629C(s32 objectIndex, s32 arg1) { - switch (arg1) { /* irregular */ - case 0: - gObjectList[objectIndex].model = podium_dl3; - gObjectList[objectIndex].unk_04C = 0x00000038; - break; - case 1: - gObjectList[objectIndex].model = podium2_dl3; - gObjectList[objectIndex].unk_04C = 0x0000002B; - break; - case 2: - gObjectList[objectIndex].model = podium3_dl3; - gObjectList[objectIndex].unk_04C = 0x0000001E; - break; - default: - break; - } - gObjectList[objectIndex].sizeScaling = 1.0f; - set_obj_origin_pos(objectIndex, D_800E634C[0][0] - 1.5, D_800E634C[0][1], D_800E634C[0][2]); - set_obj_origin_offset(objectIndex, 0.0f, -10.0f, 0.0f); - set_obj_direction_angle(objectIndex, 0U, 0xF8E4U, 0U); - gObjectList[objectIndex].unk_048 = 0; - object_next_state(objectIndex); -} - -void func_80086424(s32 objectIndex) { - switch (gObjectList[objectIndex].unk_0AE) { - case 0: - break; - case 1: - gObjectList[objectIndex].velocity[1] = 0.75f; - func_80086FD4(objectIndex); - break; - case 2: - if (gObjectList[objectIndex].offset[1] >= -2.0) { - gObjectList[objectIndex].velocity[1] -= 0.1; - } - object_add_velocity_offset_y(objectIndex); - if (gObjectList[objectIndex].offset[1] >= 0.0) { - gObjectList[objectIndex].offset[1] = 0.0f; - gObjectList[objectIndex].velocity[1] = 0.0f; - func_80086F60(objectIndex); - } - break; - } - object_calculate_new_pos_offset(objectIndex); -} - -void func_80086528(s32 objectIndex, s32 arg1) { - switch (gObjectList[objectIndex].state) { /* irregular */ - case 1: - func_8008629C(objectIndex, arg1); - break; - case 2: - if (set_and_run_timer_object(objectIndex, gObjectList[objectIndex].unk_04C) != 0) { - func_80091440(arg1); - func_80086E70(objectIndex); - object_next_state(objectIndex); - } - break; - case 0: - break; - case 3: - if (gObjectList[objectIndex].unk_0AE == 0) { - gObjectList[objectIndex].unk_048 = 1; - object_next_state(objectIndex); - } - break; - } -} - -void func_80086604(void) { - s32 objectIndex; - s32 var_s1; - - if ((D_8016347C != 0) && (D_802874D8.unk1D < 3)) { - if (D_801658C6 == 0) { - for (var_s1 = 0; var_s1 < 3; var_s1++) { - objectIndex = indexObjectList1[var_s1]; - init_object(objectIndex, 0); - } - D_801658C6 = 1; - } - } - for (var_s1 = 0; var_s1 != 3; var_s1++) { - objectIndex = indexObjectList1[var_s1]; - if (gObjectList[objectIndex].state != 0) { - func_80086528(objectIndex, var_s1); - func_80086424(objectIndex); - } - } -} - -void func_80086700(s32 objectIndex) { - if (gCCSelection < CC_150) { - switch (D_802874D8.unk1D) { /* switch 1; irregular */ - case 0: /* switch 1 */ - gObjectList[objectIndex].model = gold_trophy_dl10; - break; - case 1: /* switch 1 */ - gObjectList[objectIndex].model = gold_trophy_dl12; - break; - case 2: /* switch 1 */ - gObjectList[objectIndex].model = gold_trophy_dl14; - break; - default: /* switch 1 */ - break; - } - } else { - switch (D_802874D8.unk1D) { /* irregular */ - case 0: - gObjectList[objectIndex].model = gold_trophy_dl11; - break; - case 1: - gObjectList[objectIndex].model = gold_trophy_dl13; - break; - case 2: - gObjectList[objectIndex].model = gold_trophy_dl15; - break; - default: - break; - } - } - gObjectList[objectIndex].sizeScaling = 0.005f; - set_obj_origin_pos(objectIndex, gObjectList[indexObjectList2[0]].pos[0], - gObjectList[indexObjectList2[0]].pos[1] + 16.0, gObjectList[indexObjectList2[0]].pos[2]); - set_obj_origin_offset(objectIndex, 0.0f, 0.0f, 0.0f); - set_obj_direction_angle(objectIndex, 0U, 0U, 0U); - gObjectList[objectIndex].unk_084[1] = 0x0200; - object_next_state(objectIndex); - func_80086E70(objectIndex); -} - -void func_80086940(s32 objectIndex) { - Object* object; - - object = &gObjectList[objectIndex]; - switch (object->unk_0AE) { - case 0: - break; - case 1: - func_80086FD4(objectIndex); - break; - case 2: - f32_step_towards(&object->sizeScaling, 0.025f, 0.001f); - func_80087C48(objectIndex, 6.0f, 0.1f, 0x000000C8); - if ((f64) object->velocity[1] <= 0.0) { - func_8008701C(objectIndex, 3); - } - break; - case 3: - func_800871AC(objectIndex, 0x00000064); - break; - case 4: - D_801658D6 = 1; - object->velocity[1] = -0.4f; - func_80086FD4(objectIndex); - object->origin_pos[1] = 90.0f; - object->offset[1] = 60.0f; - switch (D_802874D8.unk1D) { /* switch 1; irregular */ - case 1: /* switch 1 */ - object->origin_pos[0] -= 3.0; - object->origin_pos[2] += 15.0; - break; - case 2: /* switch 1 */ - object->origin_pos[0] -= 2.0; - object->origin_pos[2] -= 15.0; - break; - } - break; - case 5: - if ((f64) object->offset[1] <= 8.0) { - f32_step_towards(&object->velocity[1], -0.1f, -0.01f); - } - object_add_velocity_offset_y(objectIndex); - if ((f64) object->offset[1] <= 0.0) { - func_80086FD4(objectIndex); - } - break; - case 6: - if (func_800871AC(objectIndex, 0x00000041) != 0) { - D_801658F4 = 1; - } - break; - case 7: - if (func_800871AC(objectIndex, 0x00000064) != 0) { - func_8009265C(); - func_80086F60(objectIndex); - } - break; - } - if (D_801658D6 != 0) { - object->direction_angle[0] += 0x400; - object->direction_angle[1] = 0xE800; - object->direction_angle[2] = 0xDA00; - } else { - object->direction_angle[0] += 0x400; - object->direction_angle[1] -= 0x200; - } - object_calculate_new_pos_offset(objectIndex); -} - -void func_80086C14(s32 objectIndex) { - switch (gObjectList[objectIndex].state) { /* irregular */ - case 1: - func_80086700(objectIndex); - break; - case 0: - case 2: - break; - } -} - -void func_80086C6C(s32 objectIndex) { - Vec3f sp24; - - sp24[0] = (gObjectList[objectIndex].pos[0] - 5.0f) + random_int(0x000AU); - sp24[2] = (gObjectList[objectIndex].pos[2] - 5.0f) + random_int(0x000AU); - if (D_801658F4 != 0) { - sp24[1] = gObjectList[objectIndex].pos[1] + 14.0; - } else { - sp24[1] = gObjectList[objectIndex].pos[1] - 2.0; - } - func_800773D8(sp24, (s32) D_801658F4); -} - -void func_80086D80(void) { - s32 temp_s2; - s32 var_s0; - - if ((D_801658CE != 0) && (D_801658DC == 0)) { - temp_s2 = indexObjectList1[3]; - init_object(temp_s2, 0); - D_801658DC = 1; - } - temp_s2 = indexObjectList1[3]; - if (gObjectList[temp_s2].state != 0) { - func_80086C14(temp_s2); - func_80086940(temp_s2); - if (D_801658F4 != 0) { - if (D_8016559C == 0) { - func_80086C6C(temp_s2); - } - } else { - for (var_s0 = 0; var_s0 < 2; var_s0++) { - func_80086C6C(temp_s2); - } - } - } -} From 135b51ea719c6107663d9f54cc3e8cb7404dbda3 Mon Sep 17 00:00:00 2001 From: MegaMech <7255464+MegaMech@users.noreply.github.com> Date: Tue, 17 Dec 2024 17:12:12 -0700 Subject: [PATCH 13/21] Impl snowmen and trashbin --- src/code_80086E70.c | 8 +- src/code_80086E70.h | 2 +- src/engine/World.h | 11 + src/engine/courses/BansheeBoardwalk.cpp | 11 +- src/engine/courses/FrappeSnowland.cpp | 44 ++-- src/engine/courses/TestCourse.cpp | 9 +- src/engine/objects/Mole.cpp | 6 +- src/engine/objects/Snowman.cpp | 300 ++++++++++++++++++++++++ src/engine/objects/Snowman.h | 52 ++++ src/engine/objects/TrashBin.cpp | 125 ++++++++++ src/engine/objects/TrashBin.h | 34 +++ src/render_objects.c | 78 ------ src/update_objects.c | 299 ++++------------------- src/update_objects.h | 2 - 14 files changed, 619 insertions(+), 362 deletions(-) create mode 100644 src/engine/objects/Snowman.cpp create mode 100644 src/engine/objects/Snowman.h create mode 100644 src/engine/objects/TrashBin.cpp create mode 100644 src/engine/objects/TrashBin.h diff --git a/src/code_80086E70.c b/src/code_80086E70.c index 490e8e32c..c6e166157 100644 --- a/src/code_80086E70.c +++ b/src/code_80086E70.c @@ -1457,10 +1457,16 @@ s32 func_8008A890(Camera* camera) { return get_track_section_id(camera->collision.meshIndexZX); } -s32 func_8008A8B0(s16 arg0, s16 arg1) { +/** + * This function is used to avoid hefty collision checks if players are not near the actor + */ +s32 are_players_in_course_section(s16 arg0, s16 arg1) { s32 var_v1; s16* var_v0; s32 i; + + return 1; //! @todo This is the easiest solution otherwise actors would not collide on custom courses. + var_v1 = 0; for (i = 0; i < gPlayerCountSelection1; i++) { var_v0 = &D_8018CF68[i]; diff --git a/src/code_80086E70.h b/src/code_80086E70.h index 8d9a6ffdc..7ed425169 100644 --- a/src/code_80086E70.h +++ b/src/code_80086E70.h @@ -106,7 +106,7 @@ void func_8008A830(s32); void func_8008A850(s32); s32 func_8008A870(Player*); s32 func_8008A890(Camera*); -s32 func_8008A8B0(s16, s16); +s32 are_players_in_course_section(s16, s16); void func_8008A920(s32); void func_8008A9B8(s32); void func_8008AA3C(s32); diff --git a/src/engine/World.h b/src/engine/World.h index a90ff7441..2abb06fe0 100644 --- a/src/engine/World.h +++ b/src/engine/World.h @@ -33,6 +33,17 @@ struct FVector { } }; +struct FRotation { + float pitch, yaw, roll; + + FRotation& operator=(const FRotation& other) { + pitch = other.pitch; + yaw = other.yaw; + roll = other.roll; + return *this; + } +}; + /** * For selecting a section of a course path * Usage: IPathSpan(point1, point2) --> IPathSpan(40, 65) diff --git a/src/engine/courses/BansheeBoardwalk.cpp b/src/engine/courses/BansheeBoardwalk.cpp index 80549ac90..92551f058 100644 --- a/src/engine/courses/BansheeBoardwalk.cpp +++ b/src/engine/courses/BansheeBoardwalk.cpp @@ -8,6 +8,7 @@ #include "engine/actors/AFinishline.h" #include "engine/objects/BombKart.h" #include "engine/objects/CheepCheep.h" +#include "engine/objects/TrashBin.h" #include "assets/banshee_boardwalk_data.h" #include "assets/boo_frames.h" @@ -154,6 +155,12 @@ void BansheeBoardwalk::SpawnActors() { gWorldInstance.AddObject(new OCheepCheep(FVector(xOrientation * -1650.0, -200.0f, -1650.0f), OCheepCheep::CheepType::RACE, IPathSpan(160, 170))); + + if (gIsMirrorMode) { + gWorldInstance.AddObject(new OTrashBin(FVector(1765.0f, 45.0f, 195.0f), FRotation(0, 180.0f, 0), 1.0f)); + } else { + gWorldInstance.AddObject(new OTrashBin(FVector(-1765.0f, 45.0f, 70.0f), FRotation(0, 0, 0), 1.0f)); + } } void BansheeBoardwalk::SpawnVehicles() { @@ -197,21 +204,17 @@ void BansheeBoardwalk::InitCourseObjects() { void BansheeBoardwalk::UpdateCourseObjects() { if (gGamestate != CREDITS_SEQUENCE) { - update_trash_bin(); func_8007E4C4(); if (gModeSelection != TIME_TRIALS) { update_bat(); } wrapper_update_boos(); - //update_cheep_cheep(0); } } void BansheeBoardwalk::RenderCourseObjects(s32 cameraId) { if (gGamestate != CREDITS_SEQUENCE) { - render_object_trash_bin(cameraId); render_object_bat(cameraId); - //func_8005217C(cameraId); // render cheep cheep render_object_boos(cameraId); } } diff --git a/src/engine/courses/FrappeSnowland.cpp b/src/engine/courses/FrappeSnowland.cpp index 9095a19d0..3481e1e2b 100644 --- a/src/engine/courses/FrappeSnowland.cpp +++ b/src/engine/courses/FrappeSnowland.cpp @@ -7,6 +7,7 @@ #include "World.h" #include "engine/actors/AFinishline.h" #include "engine/objects/BombKart.h" +#include "engine/objects/Snowman.h" #include "assets/frappe_snowland_data.h" #include "assets/boo_frames.h" @@ -131,6 +132,28 @@ void FrappeSnowland::SpawnActors() { spawn_foliage((struct ActorSpawnData*)LOAD_ASSET_RAW(d_course_frappe_snowland_tree_spawns)); spawn_all_item_boxes((struct ActorSpawnData*)LOAD_ASSET_RAW(d_course_frappe_snowland_item_box_spawns)); + + if (gGamestate != CREDITS_SEQUENCE) { + gWorldInstance.AddObject(new OSnowman(FVector(697, 0, -1684))); + gWorldInstance.AddObject(new OSnowman(FVector(82, 0, -2245))); + gWorldInstance.AddObject(new OSnowman(FVector(27, 5, -2067))); + gWorldInstance.AddObject(new OSnowman(FVector(-656, 0, -1735))); + gWorldInstance.AddObject(new OSnowman(FVector(-1497, 0, -83))); + gWorldInstance.AddObject(new OSnowman(FVector(-1643, 0, -25))); + gWorldInstance.AddObject(new OSnowman(FVector(-1547, 0, -20))); + gWorldInstance.AddObject(new OSnowman(FVector(-1445, 0, -10))); + gWorldInstance.AddObject(new OSnowman(FVector(-1502, 0, 61))); + gWorldInstance.AddObject(new OSnowman(FVector(-1429, 0, 79))); + gWorldInstance.AddObject(new OSnowman(FVector(-1586, 0, 71))); + gWorldInstance.AddObject(new OSnowman(FVector(-1471, 0, 157))); + gWorldInstance.AddObject(new OSnowman(FVector(-1539, 0, 175))); + gWorldInstance.AddObject(new OSnowman(FVector(-1484, 0, 303))); + gWorldInstance.AddObject(new OSnowman(FVector(-1442, 0, 358))); + gWorldInstance.AddObject(new OSnowman(FVector(-1510, 0, 426))); + gWorldInstance.AddObject(new OSnowman(FVector(-665, 0, 830))); + gWorldInstance.AddObject(new OSnowman(FVector(-701, 3, 853))); + gWorldInstance.AddObject(new OSnowman(FVector(-602, 0, 929))); + } } void FrappeSnowland::SpawnVehicles() { @@ -184,34 +207,13 @@ void FrappeSnowland::InitCourseObjects() { for (i = 0; i < NUM_SNOWFLAKES; i++) { find_unused_obj_index(&gObjectParticle1[i]); } - if (gGamestate != CREDITS_SEQUENCE) { - for (i = 0; i < NUM_SNOWMEN; i++) { - objectId = indexObjectList2[i]; - init_object(objectId, 0); - gObjectList[objectId].origin_pos[0] = gSnowmanSpawns[i].pos[0] * xOrientation; - gObjectList[objectId].origin_pos[1] = gSnowmanSpawns[i].pos[1] + 5.0 + 3.0; - gObjectList[objectId].origin_pos[2] = gSnowmanSpawns[i].pos[2]; - objectId = indexObjectList1[i]; - init_object(objectId, 0); - gObjectList[objectId].origin_pos[0] = gSnowmanSpawns[i].pos[0] * xOrientation; - gObjectList[objectId].origin_pos[1] = gSnowmanSpawns[i].pos[1] + 3.0; - gObjectList[objectId].origin_pos[2] = gSnowmanSpawns[i].pos[2]; - gObjectList[objectId].unk_0D5 = gSnowmanSpawns[i].unk_6; - } - } } void FrappeSnowland::UpdateCourseObjects() { - if (gGamestate != CREDITS_SEQUENCE) { - update_snowmen(); - } update_snowflakes(); } void FrappeSnowland::RenderCourseObjects(s32 cameraId) { - if (gGamestate != CREDITS_SEQUENCE) { - render_object_snowmans(cameraId); - } } void FrappeSnowland::SomeSounds() { diff --git a/src/engine/courses/TestCourse.cpp b/src/engine/courses/TestCourse.cpp index 465f97012..ce8d8ca62 100644 --- a/src/engine/courses/TestCourse.cpp +++ b/src/engine/courses/TestCourse.cpp @@ -6,6 +6,7 @@ #include "TestCourse.h" #include "World.h" #include "engine/actors/AFinishline.h" +#include "engine/objects/Object.h" #include "engine/objects/BombKart.h" #include "assets/mario_raceway_data.h" #include "assets/bowsers_castle_data.h" @@ -15,6 +16,8 @@ #include "engine/vehicles/Train.h" #include "engine/objects/Trophy.h" #include "engine/objects/CheepCheep.h" +#include "engine/objects/Snowman.h" +#include "engine/objects/TrashBin.h" extern "C" { #include "main.h" @@ -196,8 +199,10 @@ void TestCourse::SpawnActors() { // gWorldInstance.AddActor(new OSeagull(1, pos)); // gWorldInstance.AddActor(new OSeagull(2, pos)); // gWorldInstance.AddActor(new OSeagull(3, pos)); - gWorldInstance.AddObject(new OCheepCheep(FVector(0, 40, 0), OCheepCheep::CheepType::RACE, IPathSpan(0, 10))); - //gWorldInstance.AddObject(new OTrophy(FVector(0,0,0), OTrophy::TrophyType::GOLD, OTrophy::Behaviour::GO_FISH)); + // gWorldInstance.AddObject(new OCheepCheep(FVector(0, 40, 0), OCheepCheep::CheepType::RACE, IPathSpan(0, 10))); + // gWorldInstance.AddObject(new OTrophy(FVector(0,0,0), OTrophy::TrophyType::GOLD, OTrophy::Behaviour::GO_FISH)); + gWorldInstance.AddObject(new OSnowman(FVector(0, 0, 0))); + gWorldInstance.AddObject(new OTrashBin(FVector(0.0f, 0.0f, 0.0f), FRotation(0, 90, 0), 1.0f)); } // Likely sets minimap boundaries diff --git a/src/engine/objects/Mole.cpp b/src/engine/objects/Mole.cpp index 78b186e77..7cc21e118 100644 --- a/src/engine/objects/Mole.cpp +++ b/src/engine/objects/Mole.cpp @@ -34,7 +34,7 @@ void OMole::Tick() { for (var_s1 = 0; var_s1 < D_8018D1C8; var_s1++) { objectIndex = indexObjectList1[var_s1]; if (gObjectList[objectIndex].state == 0) { - if (func_8008A8B0(8, 9) != 0) { + if (are_players_in_course_section(8, 9) != 0) { func_80081FF4(objectIndex, 1); } } else { @@ -45,7 +45,7 @@ void OMole::Tick() { for (var_s1 = 0; var_s1 < D_8018D1D0; var_s1++) { objectIndex = indexObjectList2[var_s1]; if (gObjectList[objectIndex].state == 0) { - if (func_8008A8B0(0x0010, 0x0013) != 0) { + if (are_players_in_course_section(0x0010, 0x0013) != 0) { OMole::func_80081FF4(objectIndex, 2); } } else { @@ -56,7 +56,7 @@ void OMole::Tick() { for (var_s1 = 0; var_s1 < D_8018D1D8; var_s1++) { objectIndex = indexObjectList3[var_s1]; if (gObjectList[objectIndex].state == 0) { - if (func_8008A8B0(0x0011, 0x0014) != 0) { + if (are_players_in_course_section(0x0011, 0x0014) != 0) { func_80081FF4(objectIndex, 3); } } else { diff --git a/src/engine/objects/Snowman.cpp b/src/engine/objects/Snowman.cpp new file mode 100644 index 000000000..93286845f --- /dev/null +++ b/src/engine/objects/Snowman.cpp @@ -0,0 +1,300 @@ +#include "Snowman.h" +#include "World.h" + +extern "C" { +#include "render_objects.h" +#include "update_objects.h" +#include "assets/frappe_snowland_data.h" +#include "assets/common_data.h" +#include "math_util.h" +#include "math_util_2.h" +#include "code_80086E70.h" +#include "code_80057C60.h" +} + +static const char* sSnowmanHeadList[] = { d_course_frappe_snowland_snowman_head }; + +size_t OSnowman::_count = 0; + +OSnowman::OSnowman(const FVector& pos) { + _pos = pos; + _idx = _count; + + s32 objectId = indexObjectList2[_idx]; + init_object(objectId, 0); + gObjectList[objectId].origin_pos[0] = pos.x * xOrientation; + gObjectList[objectId].origin_pos[1] = pos.y + 5.0 + 3.0; + gObjectList[objectId].origin_pos[2] = pos.z; + gObjectList[objectId].pos[0] = pos.x * xOrientation; + gObjectList[objectId].pos[1] = pos.y + 5.0 + 3.0; + gObjectList[objectId].pos[2] = pos.z; + + objectId = indexObjectList1[_idx]; + init_object(objectId, 0); + gObjectList[objectId].origin_pos[0] = pos.x * xOrientation; + gObjectList[objectId].origin_pos[1] = pos.y + 3.0; + gObjectList[objectId].origin_pos[2] = pos.z; + gObjectList[objectId].unk_0D5 = 0; // Section Id no longer used. + + gObjectList[objectId].pos[0] = pos.x * xOrientation; + gObjectList[objectId].pos[1] = pos.y + 3.0; + gObjectList[objectId].pos[2] = pos.z; + + _count++; +} + +void OSnowman::Tick() { + s32 var_s0; + s32 var_s3; + s32 var_s4; + s32 objectIndex; + Object* object; + + //! @todo quick hack to add the snow particles on hit. Need to separate into its own class + if (_idx == 0) { + for (var_s0 = 0; var_s0 < gObjectParticle2_SIZE; var_s0++) { + objectIndex = gObjectParticle2[var_s0]; + + if (objectIndex == DELETED_OBJECT_ID) { + continue; + } + + if (gObjectList[objectIndex].state == 0) { + continue; + } + func_8008379C(objectIndex); + if (gObjectList[objectIndex].state != 0) { + continue; + } + delete_object_wrapper(&gObjectParticle2[var_s0]); + if (var_s0) {} // ?? + } + } + + //for (var_s0 = 0; var_s0 < NUM_SNOWMEN; var_s0++) { + var_s4 = indexObjectList1[_idx]; + var_s3 = indexObjectList2[_idx]; + OSnowman::func_80083A94(var_s3); // snowman head + OSnowman::func_80083C04(var_s4); // snowman body + if (is_obj_index_flag_status_inactive(var_s4, 0x00001000) != 0) { + object = &gObjectList[var_s4]; + if ((are_players_in_course_section(object->unk_0D5 - 1, object->unk_0D5 + 1) != 0) && (func_80089B50(var_s4) != 0)) { + set_object_flag(var_s4, 0x00001000); + clear_object_flag(var_s4, 0x00000010); + func_800726CC(var_s4, 0x0000000A); + func_8008701C(var_s3, 0x0000000A); + OSnowman::func_800836F0(object->pos); + } + } else if (func_80072320(var_s4, 2) != 0) { + func_800722CC(var_s4, 2); + func_8008701C(var_s3, 0x00000014); + } + //} +} + +void OSnowman::Draw(s32 cameraId) { + OSnowman::DrawHead(cameraId); + OSnowman::DrawBody(cameraId); +} + +void OSnowman::func_800836F0(Vec3f pos) { + s32 objectIndex; + s32 i; + + for (i = 0; i < D_8018D3BC; i++) { + objectIndex = add_unused_obj_index(&gObjectParticle2[0], &gNextFreeObjectParticle2, gObjectParticle2_SIZE); + if (objectIndex == NULL_OBJECT_ID) { + break; + } + func_80083538(objectIndex, pos, i, D_8018D3BC); + } +} + +void OSnowman::DrawHead(s32 cameraId) { + s32 objectIndex; + Camera* camera = &camera1[cameraId]; + objectIndex = indexObjectList1[_idx]; + if (gObjectList[objectIndex].state >= 2) { + func_8008A364(objectIndex, cameraId, 0x2AABU, 0x00000258); + if (is_obj_flag_status_active(objectIndex, VISIBLE) != 0) { + D_80183E80[0] = (s16) gObjectList[objectIndex].orientation[0]; + D_80183E80[1] = + func_800418AC(gObjectList[objectIndex].pos[0], gObjectList[objectIndex].pos[2], camera->pos); + D_80183E80[2] = (u16) gObjectList[objectIndex].orientation[2]; + if (is_obj_flag_status_active(objectIndex, 0x00000010) != 0) { + draw_2d_texture_at(gObjectList[objectIndex].pos, (u16*) D_80183E80, + gObjectList[objectIndex].sizeScaling, (u8*) gObjectList[objectIndex].activeTLUT, + (u8*)gObjectList[objectIndex].activeTexture, gObjectList[objectIndex].vertex, + 0x00000040, 0x00000040, 0x00000040, 0x00000020); + } + objectIndex = indexObjectList2[_idx]; + D_80183E80[0] = (s16) gObjectList[objectIndex].orientation[0]; + D_80183E80[2] = (u16) gObjectList[objectIndex].orientation[2]; + draw_2d_texture_at(gObjectList[objectIndex].pos, (u16*) D_80183E80, + gObjectList[objectIndex].sizeScaling, (u8*) gObjectList[objectIndex].activeTLUT, + (u8*)gObjectList[objectIndex].activeTexture, gObjectList[objectIndex].vertex, 0x00000040, + 0x00000040, 0x00000040, 0x00000020); + } + } +} + +void OSnowman::DrawBody(s32 cameraId) { + UNUSED s32 stackPadding[2]; + Camera* sp44; + s32 someIndex; + s32 objectIndex; + Object* object; + + sp44 = &camera1[cameraId]; + load_texture_and_tlut((u8*)d_course_frappe_snowland_snow_tlut, (u8*)d_course_frappe_snowland_snow, 0x00000020, 0x00000020); + + //! @todo quick hack to add the snow particles on hit. Need to separate into its own class + if (_idx == 0) { + for (someIndex = 0; someIndex < gObjectParticle2_SIZE; someIndex++) { + objectIndex = gObjectParticle2[someIndex]; + if (objectIndex != NULL_OBJECT_ID) { + object = &gObjectList[objectIndex]; + if (object->state > 0) { + func_8008A364(objectIndex, cameraId, 0x2AABU, 0x000001F4); + if (is_obj_flag_status_active(objectIndex, VISIBLE) != 0) { + object->orientation[1] = func_800418AC(object->pos[0], object->pos[2], sp44->pos); + rsp_set_matrix_gObjectList(objectIndex); + gSPDisplayList(gDisplayListHead++, (Gfx*)D_0D0069E0); + } + } + } + } + } + gSPTexture(gDisplayListHead++, 1, 1, 0, G_TX_RENDERTILE, G_OFF); +} + +void OSnowman::func_80083C04(s32 objectIndex) { + Object* object; + + object = &gObjectList[objectIndex]; + switch (object->state) { + case 0: + break; + case 1: + OSnowman::func_80083B0C(objectIndex); + break; + case 2: + set_and_run_timer_object(objectIndex, 0x00000096); + break; + case 10: + if (set_and_run_timer_object(objectIndex, 0x0000012C) != 0) { + func_800722A4(objectIndex, 2); + } + break; + case 11: + if (set_and_run_timer_object(objectIndex, 0x0000000A) != 0) { + set_object_flag(objectIndex, 0x00000010); + object->sizeScaling = 0.001f; + } + break; + case 12: + if (func_80074118(objectIndex, &object->sizeScaling, 0.001f, 0.1f, 0.0025f, 0, 0) != 0) { + object_next_state(objectIndex); + } + break; + case 13: + func_800726CC(objectIndex, 2); + clear_object_flag(objectIndex, 0x00001000); + break; + } + if (object->state >= 2) { + func_80073514(objectIndex); + } + OSnowman::func_80083BE4(objectIndex); +} + +void OSnowman::func_80083BE4(s32 objectIndex) { + object_calculate_new_pos_offset(objectIndex); +} + +void OSnowman::func_80083868(s32 objectIndex) { + Object* object; + Vtx* vtx = (Vtx*) LOAD_ASSET_RAW(D_0D0061B0); + init_texture_object(objectIndex, (u8*)d_course_frappe_snowland_snowman_tlut, (const char**)sSnowmanHeadList, 0x40U, (u16) 0x00000040); + object = &gObjectList[objectIndex]; + object->vertex = vtx; + object->sizeScaling = 0.1f; + object->textureListIndex = 0; + object_next_state(objectIndex); + set_obj_origin_offset(objectIndex, 0.0f, 0.0f, 0.0f); + object->orientation[0] = 0; + object->orientation[1] = 0; + object->orientation[2] = 0x8000; + object->primAlpha = random_int(0x2000U) - 0x1000; + func_80086E70(objectIndex); + object->unk_034 = 1.5f; + set_object_flag(objectIndex, 0x00000200); +} + +void OSnowman::func_80083948(s32 objectIndex) { + switch (gObjectList[objectIndex].unk_0AE) { + case 1: + func_80086FD4(objectIndex); + break; + case 2: + func_800871AC(objectIndex, 0x00000014); + break; + case 3: + func_8008701C(objectIndex, 1); + break; + case 10: + func_80087C48(objectIndex, 10.0f, 0.5f, 0x0000000A); + break; + case 11: + func_80087D24(objectIndex, 0.0f, 0.2f, -7.0f); + break; + case 20: + if (f32_step_up_towards(&gObjectList[objectIndex].offset[1], 0.0f, 0.2f) != 0) { + func_80073800(objectIndex, 0); + func_8008701C(objectIndex, 1); + } + break; + case 0: + default: + break; + } + object_calculate_new_pos_offset(objectIndex); + OSnowman::func_80073D0C(objectIndex, &gObjectList[objectIndex].primAlpha, -0x00001000, 0x00001000, 0x00000400, 1, -1); + gObjectList[objectIndex].orientation[2] = gObjectList[objectIndex].primAlpha + 0x8000; +} + +bool OSnowman::func_80073D0C(s32 objectIndex, s16* arg1, s32 arg2, s32 arg3, s32 arg4, s32 arg5, s32 arg6) { + return func_80073B78(0, objectIndex, arg1, arg2, arg3, arg4, arg5, arg6); +} + +void OSnowman::func_80083A94(s32 objectIndex) { + switch (gObjectList[objectIndex].state) { + case 0: + break; + case 1: + OSnowman::func_80083868(objectIndex); + break; + } + if (gObjectList[objectIndex].state >= 2) { + func_80073514(objectIndex); + } + OSnowman::func_80083948(objectIndex); +} + +static const char* sSnowmanBodyList[] = { d_course_frappe_snowland_snowman_body }; + +void OSnowman::func_80083B0C(s32 objectIndex) { + Vtx* vtx = (Vtx*) LOAD_ASSET_RAW(common_vtx_hedgehog); + init_texture_object(objectIndex, (u8*)d_course_frappe_snowland_snowman_tlut, (const char**)sSnowmanBodyList, 0x40U, (u16) 0x00000040); + gObjectList[objectIndex].vertex = vtx; + gObjectList[objectIndex].sizeScaling = 0.1f; + gObjectList[objectIndex].textureListIndex = 0; + object_next_state(objectIndex); + set_obj_origin_offset(objectIndex, 0.0f, 0.0f, 0.0f); + gObjectList[objectIndex].orientation[0] = 0; + gObjectList[objectIndex].orientation[1] = 0; + gObjectList[objectIndex].orientation[2] = 0x8000; + gObjectList[objectIndex].boundingBoxSize = 2; + gObjectList[objectIndex].unk_034 = 1.5f; + set_object_flag(objectIndex, 0x04000210); +} \ No newline at end of file diff --git a/src/engine/objects/Snowman.h b/src/engine/objects/Snowman.h new file mode 100644 index 000000000..cd2c09244 --- /dev/null +++ b/src/engine/objects/Snowman.h @@ -0,0 +1,52 @@ +#pragma once + +#include +#include +#include "Object.h" + +#include "World.h" + +extern "C" { +#include "macros.h" +#include "main.h" +#include "vehicles.h" +#include "waypoints.h" +#include "common_structs.h" +#include "objects.h" +#include "camera.h" +#include "some_data.h" +} + +class OSnowman : public OObject { +public: + explicit OSnowman(const FVector& pos); + + ~OSnowman() { + _count--; + } + + static size_t GetCount() { + return _count; + } + + virtual void Tick() override; + virtual void Draw(s32 cameraId) override; + + void DrawHead(s32); + void DrawBody(s32); + + void func_80083868(s32); + void func_80083948(s32); + void func_80083A94(s32); + void func_80083B0C(s32); + void func_80083C04(s32); + void func_80083BE4(s32); + void func_800836F0(Vec3f); + bool func_80073D0C(s32 objectIndex, s16* arg1, s32 arg2, s32 arg3, s32 arg4, s32 arg5, s32 arg6); + + +private: + FVector _pos; + static size_t _count; + size_t _idx; +}; diff --git a/src/engine/objects/TrashBin.cpp b/src/engine/objects/TrashBin.cpp new file mode 100644 index 000000000..8a090be5d --- /dev/null +++ b/src/engine/objects/TrashBin.cpp @@ -0,0 +1,125 @@ +#include "TrashBin.h" +#include "World.h" + +extern "C" { +#include "code_800029B0.h" +#include "render_objects.h" +#include "update_objects.h" +#include "assets/banshee_boardwalk_data.h" +#include "assets/common_data.h" +#include "math_util.h" +#include "math_util_2.h" +#include "code_80086E70.h" +#include "code_80057C60.h" +#include "audio/external.h" +} + +#define DEGREES_FLOAT_TO_SHORT(Degrees) ((s16)((Degrees) * (0x8000 / 180.0f))) + +OTrashBin::OTrashBin(const FVector& pos, const FRotation& rotation, f32 scale) { + _pos = pos; + _rot = rotation; + _scale = scale; + + // if (gIsMirrorMode != 0) { + // gObjectList[objectIndex].pos[0] = 1765.0f; + // gObjectList[objectIndex].pos[2] = 195.0f; + // gObjectList[objectIndex].orientation[1] = (s16) rotation.y; + // } else { + // gObjectList[objectIndex].pos[0] = -1765.0f; + // gObjectList[objectIndex].pos[2] = 70.0f; + // } + +} + +void OTrashBin::Tick() { + s32 objectIndex = indexObjectList1[1]; + OTrashBin::func_8007E00C(objectIndex); + if (gModeSelection != TIME_TRIALS) { + func_8007DDC0(objectIndex); + } +} + +void OTrashBin::Draw(s32 cameraId) { + s32 objectIndex; + Object* object; + + objectIndex = indexObjectList1[1]; + func_8008A364(objectIndex, cameraId, 0x5555U, 0x00000320); + if (is_obj_flag_status_active(objectIndex, VISIBLE) != 0) { + object = &gObjectList[objectIndex]; + if (object->state >= 2) { + func_80043220(object->pos, object->orientation, object->sizeScaling, object->model); + } + } +} + +void OTrashBin::init_bb_trash_bin(s32 objectIndex) { + gObjectList[objectIndex].sizeScaling = _scale; + gObjectList[objectIndex].model = (Gfx*)d_course_banshee_boardwalk_dl_trash_bin; + gObjectList[objectIndex].unk_04C = 0; + gObjectList[objectIndex].unk_084[7] = 0; + set_obj_orientation(objectIndex, 0U, 0U, 0U); + gObjectList[objectIndex].orientation[0] = DEGREES_FLOAT_TO_SHORT(_rot.pitch); + gObjectList[objectIndex].orientation[1] = DEGREES_FLOAT_TO_SHORT(_rot.yaw); + gObjectList[objectIndex].orientation[2] = DEGREES_FLOAT_TO_SHORT(_rot.roll); + gObjectList[objectIndex].pos[0] = _pos.x; + gObjectList[objectIndex].pos[1] = _pos.y; + gObjectList[objectIndex].pos[2] = _pos.z; + set_obj_velocity(objectIndex, 0.0f, 0.0f, 0.0f); + gObjectList[objectIndex].type = 0; + object_next_state(objectIndex); +} + +#undef DEGREES_FLOAT_TO_SHORT + +void OTrashBin::func_8007E00C(s32 objectIndex) { + switch (gObjectList[objectIndex].state) { + case 1: + init_bb_trash_bin(objectIndex); + break; + case 3: + D_8018CFB0 = 1; + object_next_state(objectIndex); + break; + case 4: + set_and_run_timer_object(objectIndex, 0x000000D2); + if (D_80165594 == 0) { + if (gCCSelection < CC_150) { + func_8007D714(1); + func_8007D714(1); + } else { + func_8007D714(1); + func_8007D714(1); + func_8007D714(1); + func_8007D714(1); + } + } + func_80073CB0(objectIndex, &gObjectList[objectIndex].primAlpha, -0x00002000, 0, 0x00000400, 0, -1); + gObjectList[objectIndex].orientation[2] = gObjectList[objectIndex].primAlpha; + if (gObjectList[objectIndex].unk_084[7] == 0) { + func_800C98B8(gObjectList[objectIndex].pos, gObjectList[objectIndex].velocity, + SOUND_ARG_LOAD(0x19, 0x01, 0x90, 0x4E)); + gObjectList[objectIndex].unk_084[7] = 0x0014; + } else { + gObjectList[objectIndex].unk_084[7]--; + } + break; + case 5: + gObjectList[objectIndex].orientation[2] = func_800417B4(gObjectList[objectIndex].orientation[2], 0U); + if (gObjectList[objectIndex].orientation[2] == 0) { + object_next_state(objectIndex); + } + break; + case 6: + gObjectList[objectIndex].orientation[2] = 0; + gObjectList[objectIndex].unk_084[7] = 0; + object_next_state(objectIndex); + D_8018CFB0 = 0; + break; + case 0: + case 2: + default: + break; + } +} diff --git a/src/engine/objects/TrashBin.h b/src/engine/objects/TrashBin.h new file mode 100644 index 000000000..328cb4778 --- /dev/null +++ b/src/engine/objects/TrashBin.h @@ -0,0 +1,34 @@ +#pragma once + +#include +#include +#include "Object.h" + +#include "World.h" + +extern "C" { +#include "macros.h" +#include "main.h" +#include "vehicles.h" +#include "waypoints.h" +#include "common_structs.h" +#include "objects.h" +#include "camera.h" +#include "some_data.h" +} + +class OTrashBin : public OObject { +public: + explicit OTrashBin(const FVector& pos, const FRotation& rotation, f32 scale); + + virtual void Tick() override; + virtual void Draw(s32 cameraId) override; + void func_8007E00C(s32 objectIndex); + void init_bb_trash_bin(s32); + +private: + FVector _pos; + FRotation _rot; + float _scale; + size_t _idx; +}; diff --git a/src/render_objects.c b/src/render_objects.c index 8c9a8d0e3..926602a37 100644 --- a/src/render_objects.c +++ b/src/render_objects.c @@ -3488,20 +3488,6 @@ void render_object_bat(s32 cameraId) { gSPTexture(gDisplayListHead++, 0x0001, 0x0001, 0, G_TX_RENDERTILE, G_OFF); } -void render_object_trash_bin(s32 cameraId) { - s32 objectIndex; - Object* object; - - objectIndex = indexObjectList1[1]; - func_8008A364(objectIndex, cameraId, 0x5555U, 0x00000320); - if (is_obj_flag_status_active(objectIndex, VISIBLE) != 0) { - object = &gObjectList[objectIndex]; - if (object->state >= 2) { - func_80043220(object->pos, object->orientation, object->sizeScaling, object->model); - } - } -} - void func_8005285C(s32 arg0) { Player* temp_v0; @@ -3613,70 +3599,6 @@ void func_80052E30(UNUSED s32 arg0) { } } -void render_object_snowmans_list_2(s32 cameraId) { - UNUSED s32 stackPadding[2]; - Camera* sp44; - s32 someIndex; - s32 objectIndex; - Object* object; - - sp44 = &camera1[cameraId]; - load_texture_and_tlut(d_course_frappe_snowland_snow_tlut, d_course_frappe_snowland_snow, 0x00000020, 0x00000020); - for (someIndex = 0; someIndex < gObjectParticle2_SIZE; someIndex++) { - objectIndex = gObjectParticle2[someIndex]; - if (objectIndex != NULL_OBJECT_ID) { - object = &gObjectList[objectIndex]; - if (object->state > 0) { - func_8008A364(objectIndex, cameraId, 0x2AABU, 0x000001F4); - if (is_obj_flag_status_active(objectIndex, VISIBLE) != 0) { - object->orientation[1] = func_800418AC(object->pos[0], object->pos[2], sp44->pos); - rsp_set_matrix_gObjectList(objectIndex); - gSPDisplayList(gDisplayListHead++, D_0D0069E0); - } - } - } - } - gSPTexture(gDisplayListHead++, 1, 1, 0, G_TX_RENDERTILE, G_OFF); -} - -void render_object_snowmans_list_1(s32 cameraId) { - s32 var_s4; - s32 objectIndex; - Camera* camera; - - camera = &camera1[cameraId]; - for (var_s4 = 0; var_s4 < NUM_SNOWMEN; var_s4++) { - objectIndex = indexObjectList1[var_s4]; - if (gObjectList[objectIndex].state >= 2) { - func_8008A364(objectIndex, cameraId, 0x2AABU, 0x00000258); - if (is_obj_flag_status_active(objectIndex, VISIBLE) != 0) { - D_80183E80[0] = (s16) gObjectList[objectIndex].orientation[0]; - D_80183E80[1] = - func_800418AC(gObjectList[objectIndex].pos[0], gObjectList[objectIndex].pos[2], camera->pos); - D_80183E80[2] = (u16) gObjectList[objectIndex].orientation[2]; - if (is_obj_flag_status_active(objectIndex, 0x00000010) != 0) { - draw_2d_texture_at(gObjectList[objectIndex].pos, (u16*) D_80183E80, - gObjectList[objectIndex].sizeScaling, (u8*) gObjectList[objectIndex].activeTLUT, - gObjectList[objectIndex].activeTexture, gObjectList[objectIndex].vertex, - 0x00000040, 0x00000040, 0x00000040, 0x00000020); - } - objectIndex = indexObjectList2[var_s4]; - D_80183E80[0] = (s16) gObjectList[objectIndex].orientation[0]; - D_80183E80[2] = (u16) gObjectList[objectIndex].orientation[2]; - draw_2d_texture_at(gObjectList[objectIndex].pos, (u16*) D_80183E80, - gObjectList[objectIndex].sizeScaling, (u8*) gObjectList[objectIndex].activeTLUT, - gObjectList[objectIndex].activeTexture, gObjectList[objectIndex].vertex, 0x00000040, - 0x00000040, 0x00000040, 0x00000020); - } - } - } -} - -void render_object_snowmans(s32 arg0) { - render_object_snowmans_list_1(arg0); - render_object_snowmans_list_2(arg0); -} - void render_lakitu(s32 cameraId) { UNUSED s32 stackPadding; Camera* camera; diff --git a/src/update_objects.c b/src/update_objects.c index fe25980cd..c3a9b5129 100644 --- a/src/update_objects.c +++ b/src/update_objects.c @@ -1004,10 +1004,6 @@ bool func_80073CB0(s32 objectIndex, s16* arg1, s32 arg2, s32 arg3, s32 arg4, s32 return func_80073B78(1, objectIndex, arg1, arg2, arg3, arg4, arg5, arg6); } -bool func_80073D0C(s32 objectIndex, s16* arg1, s32 arg2, s32 arg3, s32 arg4, s32 arg5, s32 arg6) { - return func_80073B78(0, objectIndex, arg1, arg2, arg3, arg4, arg5, arg6); -} - UNUSED void func_80073D68(s32 objectIndex, s16* arg1, s16 arg2, s32 arg3) { *arg1 = *arg1 + arg3; if (*arg1 >= arg2) { @@ -1803,7 +1799,7 @@ void func_8007601C(s32 objectIndex) { } } - if (func_8008A8B0(9, 0xB) == 0) { + if (are_players_in_course_section(9, 0xB) == 0) { gObjectList[objectIndex].type = 2; } } @@ -1965,7 +1961,7 @@ void func_8007661C(void) { gObjectList[objectIndex].unk_048 = 0x0000003C; } } - if (func_8008A8B0(4, 5) == 0) { + if (are_players_in_course_section(4, 5) == 0) { gObjectList[objectIndex].type = 2; } } @@ -5173,89 +5169,58 @@ void func_8007DDC0(s32 objectIndex) { object->unk_048 = 0x0000012C; } } - if (func_8008A8B0(0x000F, 0x0012) == 0) { + if (are_players_in_course_section(0x000F, 0x0012) == 0) { object->type = 2; } } -void init_bb_trash_bin(s32 objectIndex) { - gObjectList[objectIndex].sizeScaling = 1.0f; - gObjectList[objectIndex].model = d_course_banshee_boardwalk_dl_trash_bin; - gObjectList[objectIndex].unk_04C = 0; - gObjectList[objectIndex].unk_084[7] = 0; - set_obj_orientation(objectIndex, 0U, 0U, 0U); - if (gIsMirrorMode != 0) { - gObjectList[objectIndex].pos[0] = 1765.0f; - gObjectList[objectIndex].pos[2] = 195.0f; - gObjectList[objectIndex].orientation[1] = 0x8000; - } else { - gObjectList[objectIndex].pos[0] = -1765.0f; - gObjectList[objectIndex].pos[2] = 70.0f; - } - gObjectList[objectIndex].pos[1] = 45.0f; - set_obj_velocity(objectIndex, 0.0f, 0.0f, 0.0f); - gObjectList[objectIndex].type = 0; - object_next_state(objectIndex); -} -void func_8007E00C(s32 objectIndex) { - switch (gObjectList[objectIndex].state) { - case 1: - init_bb_trash_bin(objectIndex); - break; - case 3: - D_8018CFB0 = 1; - object_next_state(objectIndex); - break; - case 4: - set_and_run_timer_object(objectIndex, 0x000000D2); - if (D_80165594 == 0) { - if (gCCSelection < CC_150) { - func_8007D714(1); - func_8007D714(1); - } else { - func_8007D714(1); - func_8007D714(1); - func_8007D714(1); - func_8007D714(1); - } - } - func_80073CB0(objectIndex, &gObjectList[objectIndex].primAlpha, -0x00002000, 0, 0x00000400, 0, -1); - gObjectList[objectIndex].orientation[2] = gObjectList[objectIndex].primAlpha; - if (gObjectList[objectIndex].unk_084[7] == 0) { - func_800C98B8(gObjectList[objectIndex].pos, gObjectList[objectIndex].velocity, - SOUND_ARG_LOAD(0x19, 0x01, 0x90, 0x4E)); - gObjectList[objectIndex].unk_084[7] = 0x0014; - } else { - gObjectList[objectIndex].unk_084[7]--; - } - break; - case 5: - gObjectList[objectIndex].orientation[2] = func_800417B4(gObjectList[objectIndex].orientation[2], 0U); - if (gObjectList[objectIndex].orientation[2] == 0) { - object_next_state(objectIndex); - } - break; - case 6: - gObjectList[objectIndex].orientation[2] = 0; - gObjectList[objectIndex].unk_084[7] = 0; - object_next_state(objectIndex); - D_8018CFB0 = 0; - break; - case 0: - case 2: - default: - break; - } -} -void update_trash_bin(void) { - s32 objectIndex = indexObjectList1[1]; - func_8007E00C(objectIndex); - if (gModeSelection != TIME_TRIALS) { - func_8007DDC0(objectIndex); - } -} + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + void func_8007E1F4(s32 objectIndex) { f32 sp2C; @@ -5293,7 +5258,7 @@ void func_8007E1F4(s32 objectIndex) { object->unk_048 = 0x0000012C; } } - if (func_8008A8B0(0x000F, 0x0013) == 0) { + if (are_players_in_course_section(0x000F, 0x0013) == 0) { object->type = 2; } } @@ -5582,19 +5547,6 @@ void func_80083538(s32 objectIndex, Vec3f arg1, s32 arg2, s32 arg3) { object->primAlpha = random_int(0x4000U) + 0x1000; } -void func_800836F0(Vec3f arg0) { - s32 objectIndex; - s32 i; - - for (i = 0; i < D_8018D3BC; i++) { - objectIndex = add_unused_obj_index(&gObjectParticle2[0], &gNextFreeObjectParticle2, gObjectParticle2_SIZE); - if (objectIndex == NULL_OBJECT_ID) { - break; - } - func_80083538(objectIndex, arg0, i, D_8018D3BC); - } -} - void func_8008379C(s32 objectIndex) { switch (gObjectList[objectIndex].state) { case 0: @@ -5636,159 +5588,6 @@ void func_80083868(s32 objectIndex) { set_object_flag(objectIndex, 0x00000200); } -void func_80083948(s32 objectIndex) { - switch (gObjectList[objectIndex].unk_0AE) { - case 1: - func_80086FD4(objectIndex); - break; - case 2: - func_800871AC(objectIndex, 0x00000014); - break; - case 3: - func_8008701C(objectIndex, 1); - break; - case 10: - func_80087C48(objectIndex, 10.0f, 0.5f, 0x0000000A); - break; - case 11: - func_80087D24(objectIndex, 0.0f, 0.2f, -7.0f); - break; - case 20: - if (f32_step_up_towards(&gObjectList[objectIndex].offset[1], 0.0f, 0.2f) != 0) { - func_80073800(objectIndex, 0); - func_8008701C(objectIndex, 1); - } - break; - case 0: - default: - break; - } - object_calculate_new_pos_offset(objectIndex); - func_80073D0C(objectIndex, &gObjectList[objectIndex].primAlpha, -0x00001000, 0x00001000, 0x00000400, 1, -1); - gObjectList[objectIndex].orientation[2] = gObjectList[objectIndex].primAlpha + 0x8000; -} - -void func_80083A94(s32 objectIndex) { - switch (gObjectList[objectIndex].state) { - case 0: - break; - case 1: - func_80083868(objectIndex); - break; - } - if (gObjectList[objectIndex].state >= 2) { - func_80073514(objectIndex); - } - func_80083948(objectIndex); -} - -static const char* sSnowmanBodyList[] = { d_course_frappe_snowland_snowman_body }; - -void func_80083B0C(s32 objectIndex) { - Vtx* vtx = (Vtx*) LOAD_ASSET(common_vtx_hedgehog); - init_texture_object(objectIndex, d_course_frappe_snowland_snowman_tlut, sSnowmanBodyList, 0x40U, (u16) 0x00000040); - gObjectList[objectIndex].vertex = vtx; - gObjectList[objectIndex].sizeScaling = 0.1f; - gObjectList[objectIndex].textureListIndex = 0; - object_next_state(objectIndex); - set_obj_origin_offset(objectIndex, 0.0f, 0.0f, 0.0f); - gObjectList[objectIndex].orientation[0] = 0; - gObjectList[objectIndex].orientation[1] = 0; - gObjectList[objectIndex].orientation[2] = 0x8000; - gObjectList[objectIndex].boundingBoxSize = 2; - gObjectList[objectIndex].unk_034 = 1.5f; - set_object_flag(objectIndex, 0x04000210); -} - -void func_80083BE4(s32 objectIndex) { - object_calculate_new_pos_offset(objectIndex); -} - -void func_80083C04(s32 objectIndex) { - Object* object; - - object = &gObjectList[objectIndex]; - switch (object->state) { - case 0: - break; - case 1: - func_80083B0C(objectIndex); - break; - case 2: - set_and_run_timer_object(objectIndex, 0x00000096); - break; - case 10: - if (set_and_run_timer_object(objectIndex, 0x0000012C) != 0) { - func_800722A4(objectIndex, 2); - } - break; - case 11: - if (set_and_run_timer_object(objectIndex, 0x0000000A) != 0) { - set_object_flag(objectIndex, 0x00000010); - object->sizeScaling = 0.001f; - } - break; - case 12: - if (func_80074118(objectIndex, &object->sizeScaling, 0.001f, 0.1f, 0.0025f, 0, 0) != 0) { - object_next_state(objectIndex); - } - break; - case 13: - func_800726CC(objectIndex, 2); - clear_object_flag(objectIndex, 0x00001000); - break; - } - if (object->state >= 2) { - func_80073514(objectIndex); - } - func_80083BE4(objectIndex); -} - -void update_snowmen(void) { - s32 var_s0; - s32 var_s3; - s32 var_s4; - s32 objectIndex; - Object* object; - - for (var_s0 = 0; var_s0 < gObjectParticle2_SIZE; var_s0++) { - objectIndex = gObjectParticle2[var_s0]; - - if (objectIndex == DELETED_OBJECT_ID) { - continue; - } - - if (gObjectList[objectIndex].state == 0) { - continue; - } - func_8008379C(objectIndex); - if (gObjectList[objectIndex].state != 0) { - continue; - } - delete_object_wrapper(&gObjectParticle2[var_s0]); - if (var_s0) {} // ?? - } - - for (var_s0 = 0; var_s0 < NUM_SNOWMEN; var_s0++) { - var_s4 = indexObjectList1[var_s0]; - var_s3 = indexObjectList2[var_s0]; - func_80083A94(var_s3); // snowman head - func_80083C04(var_s4); // snowman body - if (is_obj_index_flag_status_inactive(var_s4, 0x00001000) != 0) { - object = &gObjectList[var_s4]; - if ((func_8008A8B0(object->unk_0D5 - 1, object->unk_0D5 + 1) != 0) && (func_80089B50(var_s4) != 0)) { - set_object_flag(var_s4, 0x00001000); - clear_object_flag(var_s4, 0x00000010); - func_800726CC(var_s4, 0x0000000A); - func_8008701C(var_s3, 0x0000000A); - func_800836F0(object->pos); - } - } else if (func_80072320(var_s4, 2) != 0) { - func_800722CC(var_s4, 2); - func_8008701C(var_s3, 0x00000014); - } - } -} void func_80083F18(s32 objectIndex) { switch (gObjectList[objectIndex].state) { diff --git a/src/update_objects.h b/src/update_objects.h index 3e7d184b5..bbaf92d9f 100644 --- a/src/update_objects.h +++ b/src/update_objects.h @@ -85,7 +85,6 @@ s32 func_80073B00(s32, s16*, s32, s32, s32, s32, s32); s32 func_80073B34(s32, s16*, s32, s32, s32, s32, s32); bool func_80073B78(s32, s32, s16*, s32, s32, s32, s32, s32); bool func_80073CB0(s32, s16*, s32, s32, s32, s32, s32); -bool func_80073D0C(s32, s16*, s32, s32, s32, s32, s32); void func_80073D68(s32, s16*, s16, s32); void func_80073DC0(s32, s16*, s16, s32); bool func_80073E18(s32, u16*, u16, s32); @@ -319,7 +318,6 @@ void func_800833D0(s32, s32); void func_80083474(s32); void update_hedgehogs(void); void func_80083538(s32, Vec3f, s32, s32); -void func_800836F0(Vec3f); void func_8008379C(s32); void func_80083868(s32); void func_80083948(s32); From 830922541296d049cd5c0689c1f610586f56bc75 Mon Sep 17 00:00:00 2001 From: MegaMech Date: Sat, 28 Dec 2024 00:25:41 -0700 Subject: [PATCH 14/21] Reimpl Lakitu --- include/mk64.h | 2 +- src/code_800029B0.c | 2 +- src/code_80057C60.c | 56 +- src/engine/Engine.h | 1 + src/engine/GarbageCollector.cpp | 31 ++ src/engine/GarbageCollector.h | 11 + src/engine/World.cpp | 29 +- src/engine/World.h | 9 +- src/engine/courses/Course.cpp | 1 + src/engine/courses/Course.h | 3 +- src/engine/courses/SherbetLand.cpp | 3 + src/engine/objects/Lakitu.cpp | 856 +++++++++++++++++++++++++++++ src/engine/objects/Lakitu.h | 82 +++ src/engine/objects/Object.cpp | 7 +- src/main.c | 3 + src/render_objects.c | 58 +- src/render_objects.h | 1 - src/update_objects.c | 799 --------------------------- src/update_objects.h | 1 - 19 files changed, 1047 insertions(+), 908 deletions(-) create mode 100644 src/engine/GarbageCollector.cpp create mode 100644 src/engine/GarbageCollector.h create mode 100644 src/engine/objects/Lakitu.cpp create mode 100644 src/engine/objects/Lakitu.h diff --git a/include/mk64.h b/include/mk64.h index a3068f13b..86eb1ff9a 100644 --- a/include/mk64.h +++ b/include/mk64.h @@ -104,7 +104,7 @@ enum SURFACE_TYPE { /* 0x10 */ ROPE_BRIDGE, // Bowser's Castle bridge 2, DK Jungle bridge /* 0x11 */ WOOD_BRIDGE, // Frappe Snowland bridge, Bowser's Castle bridge 1,3, Yoshi Valley bridge 2 /* 0xFC */ BOOST_RAMP_WOOD = 0xFC, // DK Jungle - /* 0xFD */ OUT_OF_BOUNDS, // DK Jungle river island + /* 0xFD */ OUT_OF_BOUNDS, // DK Jungle river island oob / out of bounds /* 0xFE */ BOOST_RAMP_ASPHALT, // Royal Raceway /* 0xFF */ RAMP // Koopa Troopa beach }; diff --git a/src/code_800029B0.c b/src/code_800029B0.c index d6a806430..14f82137b 100644 --- a/src/code_800029B0.c +++ b/src/code_800029B0.c @@ -322,7 +322,7 @@ void credits_spawn_actors(void) { // Stupid hack to sync segment 3 memory allocations with hard-coded address in data. gNextFreeMemoryAddress += 0x9000; destroy_all_actors(); - m_ClearActors(); + CM_CleanWorld(); CourseManager_CreditsSpawnActors(); diff --git a/src/code_80057C60.c b/src/code_80057C60.c index cab096140..549b2bc95 100644 --- a/src/code_80057C60.c +++ b/src/code_80057C60.c @@ -567,9 +567,6 @@ void render_object_p1(void) { //func_80054BE8(PLAYER_ONE); return; } - if (!gDemoMode) { - render_lakitu(PLAYER_ONE); - } render_object_for_player(PLAYER_ONE); } @@ -582,9 +579,6 @@ void render_object_p2(void) { G_MTX_NOPUSH | G_MTX_MUL | G_MTX_PROJECTION); CourseManager_DrawBombKarts(PLAYER_TWO); //render_bomb_karts_wrap(PLAYER_TWO); - if (!gDemoMode) { - render_lakitu(PLAYER_TWO); - } render_object_for_player(PLAYER_TWO); } @@ -596,9 +590,6 @@ void render_object_p3(void) { G_MTX_NOPUSH | G_MTX_MUL | G_MTX_PROJECTION); CourseManager_DrawBombKarts(PLAYER_THREE); //render_bomb_karts_wrap(PLAYER_THREE); - if (!gDemoMode) { - render_lakitu(PLAYER_THREE); - } render_object_for_player(PLAYER_THREE); } @@ -612,7 +603,7 @@ void render_object_p4(void) { CourseManager_DrawBombKarts(PLAYER_FOUR); //render_bomb_karts_wrap(PLAYER_FOUR); if ((!gDemoMode) && (gPlayerCountSelection1 == 4)) { - render_lakitu(PLAYER_FOUR); + //render_lakitu(PLAYER_FOUR); } render_object_for_player(PLAYER_FOUR); } @@ -805,7 +796,7 @@ void render_object_for_player(s32 cameraId) { } } -void render_snowing_effect(s32 arg0) { +void render_snowing_effect(s32 playerId) { if (GetCourse() == GetFrappeSnowland()) { if (gGamestate != 9) { if ((D_8015F894 == 0) && (gPlayerCountSelection1 == 1)) { @@ -814,8 +805,9 @@ void render_snowing_effect(s32 arg0) { } else { render_object_snowflakes_particles(); } - } else if (GetCourse() == GetSherbetLand()) { - render_ice_block(arg0); + } + if (CourseManager_GetProps()->LakituTowType == 1) { + render_ice_block(playerId); } } @@ -1253,7 +1245,7 @@ void func_8005995C(void) { void func_80059A88(s32 playerId) { func_80059820(playerId); if (!gDemoMode) { - update_object_lakitu(playerId); + //update_object_lakitu(playerId); // Moved to CourseManager_TickObjects60fps func_8007BB9C(playerId); } } @@ -1270,7 +1262,7 @@ void func_80059AC8(void) { } switch (gScreenModeSelection) { case SCREEN_MODE_1P: - if (gGamestate != 9) { + if (gGamestate != CREDITS_SEQUENCE) { func_80059A88(PLAYER_ONE); if (gModeSelection == TIME_TRIALS) { func_8005995C(); @@ -1294,6 +1286,9 @@ void func_80059AC8(void) { func_80059A88(PLAYER_FOUR); break; } + + CourseManager_TickObjects60fps(); + CourseManager_TickThwomps(); // func_8005A71C(); } @@ -1328,7 +1323,7 @@ void func_80059D00(void) { func_80059820(PLAYER_ONE); func_8005B914(); if (!gDemoMode) { - func_8007AA44(0); + //func_8007AA44(0); } func_80078C70(0); if (playerHUD[PLAYER_ONE].raceCompleteBool == 0) { @@ -1348,14 +1343,14 @@ void func_80059D00(void) { func_80059820(PLAYER_ONE); func_8005D0FC(PLAYER_ONE); if (!gDemoMode) { - func_8007AA44(0); + //func_8007AA44(0); } func_80078C70(1); func_8005D1F4(0); func_80059820(PLAYER_TWO); func_8005D0FC(PLAYER_TWO); if (!gDemoMode) { - func_8007AA44(1); + //func_8007AA44(1); } func_80078C70(2); func_8005D1F4(1); @@ -1366,14 +1361,14 @@ void func_80059D00(void) { func_80059820(PLAYER_ONE); func_8005D0FC(PLAYER_ONE); if (!gDemoMode) { - func_8007AA44(0); + //func_8007AA44(0); } func_80078C70(3); func_8005D1F4(0); func_80059820(PLAYER_TWO); func_8005D0FC(PLAYER_TWO); if (!gDemoMode) { - func_8007AA44(1); + //func_8007AA44(1); } func_80078C70(4); func_8005D1F4(1); @@ -1386,31 +1381,32 @@ void func_80059D00(void) { func_80059820(PLAYER_ONE); func_8005D0FC(PLAYER_ONE); if (!gDemoMode) { - func_8007AA44(0); + //func_8007AA44(0); } func_8005D1F4(0); func_80059820(PLAYER_TWO); func_8005D0FC(PLAYER_TWO); if (!gDemoMode) { - func_8007AA44(1); + //func_8007AA44(1); } func_8005D1F4(1); func_80059820(PLAYER_THREE); func_8005D0FC(PLAYER_THREE); if (!gDemoMode) { - func_8007AA44(2); + //func_8007AA44(2); } func_8005D1F4(2); if (gPlayerCountSelection1 == 4) { func_80059820(PLAYER_FOUR); func_8005D0FC(PLAYER_FOUR); if ((!gDemoMode) && (gPlayerCountSelection1 == 4)) { - func_8007AA44(3); + //func_8007AA44(3); } func_8005D1F4(3); } break; } + update_object(); CourseManager_TickObjects(); func_800744CC(); } @@ -1579,7 +1575,7 @@ void func_8005A71C(void) { void update_object(void) { - // CourseManager_UpdateCourseObjects(); + CourseManager_UpdateCourseObjects(); // CourseManager_TrainSmokeTick(); // CourseManager_TickPenguins(); // CourseManager_TickSeagulls(); @@ -1721,7 +1717,7 @@ void func_8005AAF0(void) { void func_8005AB20(void) { if ((gModeSelection == GRAND_PRIX) && (gPlayerCountSelection1 == 1)) { - func_8005AA6C(0x14); + func_8005AA6C(20); } } @@ -2396,7 +2392,7 @@ void func_8005B914(void) { } else if (D_8018D1CC < 0xC8) { func_8005B7A0(); } - if ((D_8018D1CC != 0) && (D_8018D1CC >= 0x14) && (D_8018D1CC < 0x1E)) { + if ((D_8018D1CC != 0) && (D_8018D1CC >= 20) && (D_8018D1CC < 0x1E)) { for (i = 0; i < 4; i++) { f32_step_towards(&D_8018D028[i], D_8018D0C8[i], D_8018D078[i]); if (D_8018D028[i] == D_8018D0C8[i]) { @@ -2604,7 +2600,7 @@ void func_8005CB60(s32 playerId, s32 lapCount) { case 0: /* switch 1 */ break; case 1: /* switch 1 */ - func_80079084(playerId); + CM_ActivateSecondLapLakitu(playerId); // func_80079084(playerId); func_800C9060(playerId, SOUND_ARG_LOAD(0x19, 0x00, 0xF0, 0x15)); if ((GetCourse() == GetLuigiRaceway()) && (D_80165898 == 0) && (gModeSelection != (s32) TIME_TRIALS)) { @@ -2612,7 +2608,7 @@ void func_8005CB60(s32 playerId, s32 lapCount) { } break; case 2: /* switch 1 */ - func_800790B4(playerId); + CM_ActivateFinalLapLakitu(playerId); // func_800790B4(playerId); break; case 3: /* switch 1 */ if ((D_8018D114 == 0) || (D_8018D114 == 1)) { @@ -2637,7 +2633,7 @@ void func_8005CB60(s32 playerId, s32 lapCount) { playerHUD[playerId].totalTimeX = 0x0320; D_8016587C = (s32) 1; if (D_8018D20C == 0) { - func_80079054(playerId); + CM_ActivateFinishLakitu(playerId); // func_80079054(playerId); D_8018D20C = 1; if (gPlayerCount == (s8) 1) { D_8018D1CC = 0x00000064; diff --git a/src/engine/Engine.h b/src/engine/Engine.h index c25afa79c..45fa3a61d 100644 --- a/src/engine/Engine.h +++ b/src/engine/Engine.h @@ -27,6 +27,7 @@ typedef struct { const char* CourseLength; const char* AIBehaviour; const char* MinimapTexture; + s32 LakituTowType; s16 D_800E5548[2]; float AIMaximumSeparation; float AIMinimumSeparation; diff --git a/src/engine/GarbageCollector.cpp b/src/engine/GarbageCollector.cpp new file mode 100644 index 000000000..926620fe1 --- /dev/null +++ b/src/engine/GarbageCollector.cpp @@ -0,0 +1,31 @@ +#include "GarbageCollector.h" +#include "World.h" + +void RunGarbageCollector() { + //CleanActors(); + CleanObjects(); +} + +void CleanActors() { + // for (auto actor = gWorldInstance.Actors.begin(); actor != gWorldInstance.Actors.end();) { + // OObject* act = *actor; // Get a mutable copy + // if (act->PendingDestroy) { + // delete act; + // actor = gWorldInstance.Objects.erase(actor); // Remove from container + // continue; + // } + // actor++; + // } +} + +void CleanObjects() { + for (auto object = gWorldInstance.Objects.begin(); object != gWorldInstance.Objects.end();) { + OObject* obj = *object; // Get a mutable copy + if (obj->PendingDestroy) { + delete obj; + object = gWorldInstance.Objects.erase(object); // Remove from container + continue; + } + object++; + } +} \ No newline at end of file diff --git a/src/engine/GarbageCollector.h b/src/engine/GarbageCollector.h new file mode 100644 index 000000000..337d90e4a --- /dev/null +++ b/src/engine/GarbageCollector.h @@ -0,0 +1,11 @@ +#pragma once + +#include +#include +#include "Object.h" +#include "World.h" + + +void RunGarbageCollector(); +void CleanActors(); +void CleanObjects(); diff --git a/src/engine/World.cpp b/src/engine/World.cpp index 429b402a0..b14c45219 100644 --- a/src/engine/World.cpp +++ b/src/engine/World.cpp @@ -235,13 +235,6 @@ void World::TickActors() { } } -void RemoveExpiredActors() { - // Actors.erase( - // std::remove_if(Actors.begin(), Actors.end(), - // [](const std::unique_ptr& actor) { return actor->uuid == 0; }), - // Actors.end()); -} - OObject* World::AddObject(OObject* object) { Objects.push_back(object); return Objects.back(); @@ -249,27 +242,25 @@ OObject* World::AddObject(OObject* object) { void World::TickObjects() { for (const auto& object : Objects) { - object->Tick(); + object->Tick(); } } +// Some objects such as lakitu are ticked in process_game_tick. +// This is a fallback to support those objects. Probably don't use this. +void World::TickObjects60fps() { + for (const auto& object : Objects) { + object->Tick60fps(); + } +} + + void World::DrawObjects(s32 cameraId) { for (const auto& object : Objects) { object->Draw(cameraId); } } -void World::ExpiredObjects() { - //this->Objects.erase( - // std::remove_if(this->Objects.begin(), this->Objects.end(), - // [](const std::unique_ptr& object) { return object->uuid == 0; }), // Example condition - // this->Objects.end()); -} - -void World::DestroyObjects() { - -} - Object* World::GetObjectByIndex(size_t index) { //if (index < this->Objects.size()) { // Assuming GameActor::a is accessible, use reinterpret_cast if needed diff --git a/src/engine/World.h b/src/engine/World.h index 2abb06fe0..403a708c2 100644 --- a/src/engine/World.h +++ b/src/engine/World.h @@ -12,7 +12,9 @@ #include "objects/Thwomp.h" #include "objects/Penguin.h" #include "objects/Seagull.h" +#include "objects/Lakitu.h" #include +#include #include "Actor.h" #include "particles/ParticleEmitter.h" @@ -89,6 +91,7 @@ class ACar; class TrainCrossing; class OThwomp; class OSeagull; +class OLakitu; class World { @@ -150,7 +153,6 @@ public: AActor* GetActor(size_t index); void TickActors(); - void RemoveExpiredActors(); AActor* ConvertActorToAActor(Actor* actor); Actor* ConvertAActorToActor(AActor* actor); @@ -158,9 +160,8 @@ public: CProperties* GetCourseProps(); void TickObjects(); + void TickObjects60fps(); void DrawObjects(s32 cameraId); - void ExpiredObjects(); - void DestroyObjects(); Object *GetObjectByIndex(size_t); void AddCup(Cup*); @@ -193,6 +194,8 @@ public: std::vector Objects; std::vector Emitters; + std::unordered_map Lakitus; + /** Actors */ void AddBoat(f32 speed, uint32_t waypoint); void AddTrain(ATrain::TenderStatus tender, size_t numCarriages, f32 speed, uint32_t waypoint); diff --git a/src/engine/courses/Course.cpp b/src/engine/courses/Course.cpp index e5c9a0498..7d8fb3bff 100644 --- a/src/engine/courses/Course.cpp +++ b/src/engine/courses/Course.cpp @@ -28,6 +28,7 @@ Course::Course() { // Props.CourseLength = "567m"; // Props.Cup = FLOWER_CUP; // Props.CupIndex = 3; + Props.LakituTowType = (s32)OLakitu::LakituTowType::NORMAL; Props.AIBehaviour = D_0D008F28; Props.AIMaximumSeparation = 50.0f; Props.AIMinimumSeparation = 0.3f; diff --git a/src/engine/courses/Course.h b/src/engine/courses/Course.h index 72dd52639..381ba0340 100644 --- a/src/engine/courses/Course.h +++ b/src/engine/courses/Course.h @@ -6,7 +6,7 @@ // C-compatible function declaration #ifdef __cplusplus -//#include "World.h" +#include "engine/objects/Lakitu.h" extern "C" { #endif @@ -56,6 +56,7 @@ public: const char* CourseLength; const char* AIBehaviour; const char* MinimapTexture; + s32 LakituTowType; s16 D_800E5548[2]; float AIMaximumSeparation; float AIMinimumSeparation; diff --git a/src/engine/courses/SherbetLand.cpp b/src/engine/courses/SherbetLand.cpp index fd97ba95e..e14b2c7e0 100644 --- a/src/engine/courses/SherbetLand.cpp +++ b/src/engine/courses/SherbetLand.cpp @@ -55,6 +55,9 @@ SherbetLand::SherbetLand() { Props.Name = "sherbet land"; Props.DebugName = "sherbet"; Props.CourseLength = "756m"; + + Props.LakituTowType = (s32)OLakitu::LakituTowType::ICE; + Props.AIBehaviour = D_0D009280; Props.AIMaximumSeparation = 50.0f; Props.AIMinimumSeparation = 0.3f; diff --git a/src/engine/objects/Lakitu.cpp b/src/engine/objects/Lakitu.cpp new file mode 100644 index 000000000..1c8547bc8 --- /dev/null +++ b/src/engine/objects/Lakitu.cpp @@ -0,0 +1,856 @@ +#include +#include +#include "Lakitu.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" +#include "race_logic.h" +#include "effects.h" +#include "memory.h" +extern s8 gPlayerCount; +} + +OLakitu::OLakitu(s32 playerId, LakituType type) { + _playerId = playerId; + + init_object(gIndexLakituList[playerId], (s32)type); +} + +void OLakitu::Activate(LakituType type) { + init_object(gIndexLakituList[_playerId], (s32)type); +} + +void OLakitu::Tick() { + OLakitu::func_8007AA44(_playerId); +} + +void OLakitu::Tick60fps() { // update_object_lakitu + s32 playerId = _playerId; + s32 objectIndex = gIndexLakituList[playerId]; + + switch (gObjectList[objectIndex].unk_0D8) { + case 0: + break; + case 1: + OLakitu::update_object_lakitu_starter(objectIndex, playerId); + func_8008BFFC(objectIndex); + break; + case 2: + OLakitu::update_object_lakitu_checkered_flag(objectIndex, playerId); + func_8008BFFC(objectIndex); + break; + case 3: + OLakitu::update_object_lakitu_fishing(objectIndex, playerId); + break; + case 4: + OLakitu::update_object_lakitu_second_lap(objectIndex, playerId); + func_8008BFFC(objectIndex); + break; + case 5: + OLakitu::update_object_lakitu_final_lap(objectIndex, playerId); + func_8008BFFC(objectIndex); + break; + case 6: + OLakitu::update_object_lakitu_reverse(objectIndex, playerId); + func_8008BFFC(objectIndex); + break; + case 7: + OLakitu::update_object_lakitu_fishing2(objectIndex, playerId); + break; + } +} + +void OLakitu::Draw(s32 cameraId) { + UNUSED s32 stackPadding; + Camera* camera; + f32 var_f0; + f32 var_f2; + s32 objectIndex; + Object* object; + + objectIndex = gIndexLakituList[cameraId]; + camera = &camera1[cameraId]; + if (is_obj_flag_status_active(objectIndex, 0x00000010) != 0) { + object = &gObjectList[objectIndex]; + object->orientation[0] = 0; + object->orientation[1] = func_800418AC(object->pos[0], object->pos[2], camera->pos); + object->orientation[2] = 0x8000; + if (func_80072354(objectIndex, 2) != 0) { + draw_2d_texture_at(object->pos, object->orientation, object->sizeScaling, (u8*) object->activeTLUT, + (u8*)object->activeTexture, object->vertex, (s32) object->textureWidth, + (s32) object->textureHeight, (s32) object->textureWidth, + (s32) object->textureHeight / 2); + } else { + func_800485C4(object->pos, object->orientation, object->sizeScaling, (s32) object->primAlpha, + (u8*) object->activeTLUT, (u8*)object->activeTexture, object->vertex, (s32) object->textureWidth, + (s32) object->textureHeight, (s32) object->textureWidth, (s32) object->textureHeight / 2); + } + if (gScreenModeSelection == SCREEN_MODE_1P) { + var_f0 = object->pos[0] - camera->pos[0]; + var_f2 = object->pos[2] - camera->pos[2]; + if (var_f0 < 0.0f) { + var_f0 = -var_f0; + } + if (var_f2 < 0.0f) { + var_f2 = -var_f2; + } + if ((var_f0 + var_f2) <= 200.0) { + func_8004A630(&D_8018C0B0[cameraId], object->pos, 0.35f); + } + } + } +} + +void OLakitu::func_80079114(s32 objectIndex, s32 playerId, s32 arg2) { + s32 a; + if (gObjectList[objectIndex].state >= 2) { + if ((u8) gObjectList[objectIndex].unk_0D8 == 1) { + if (playerId == 0) { + func_80074894(objectIndex, gLakituTexturePtr); + return; + } + a = gIndexLakituList[0]; + gObjectList[objectIndex].activeTLUT = gObjectList[a].activeTLUT; + gObjectList[objectIndex].activeTexture = gObjectList[a].activeTexture; + if (0) {} + return; + } + switch (arg2) { + case 0: + func_800748F4(objectIndex, gLakituTexturePtr); + break; + case 1: + func_800748C4(objectIndex, gLakituTexturePtr); + break; + case 2: + func_80074894(objectIndex, gLakituTexturePtr); + break; + } + } +} + +void OLakitu::func_800791F0(s32 objectIndex, s32 playerId) { + Player* player = &gPlayerOne[playerId]; + + if ((gObjectList[objectIndex].unk_0D8 != 3) && (gObjectList[objectIndex].unk_0D8 != 7)) { + func_800722CC(objectIndex, 1); + if (CourseManager_GetProps()->LakituTowType == LakituTowType::ICE) { + player->unk_0CA &= 0xFFEF; + } + } + + if (CourseManager_GetProps()->LakituTowType == LakituTowType::ICE) { + func_800722CC(objectIndex, 0x00000010); + player->unk_0CA &= 0xFFDF; + } + func_800C9018(playerId, SOUND_ARG_LOAD(0x01, 0x00, 0xFA, 0x28)); +} + +static const char* sLakituTextures[] = { + gTextureLakituNoLights1, gTextureLakituNoLights2, gTextureLakituNoLights3, gTextureLakituNoLights4, + gTextureLakituNoLights5, gTextureLakituNoLights6, gTextureLakituNoLights7, gTextureLakituNoLights8, + gTextureLakituRedLights01, gTextureLakituRedLights02, gTextureLakituRedLights03, gTextureLakituRedLights04, + gTextureLakituRedLights05, gTextureLakituRedLights06, gTextureLakituRedLights07, gTextureLakituRedLights08, + gTextureLakituRedLights09, gTextureLakituRedLights10, gTextureLakituRedLights11, gTextureLakituRedLights12, + gTextureLakituRedLights13, gTextureLakituRedLights14, gTextureLakituRedLights15, gTextureLakituRedLights16, + gTextureLakituBlueLight1, gTextureLakituBlueLight2, gTextureLakituBlueLight3, gTextureLakituBlueLight4, + gTextureLakituBlueLight5, gTextureLakituBlueLight6, gTextureLakituBlueLight7, gTextureLakituBlueLight8, +}; + +void OLakitu::init_obj_lakitu_starter_and_checkered_flag(s32 objectIndex, s32 playerId) { + if (playerId == 0) { + D_801656F0 = 0; + D_8018D168 = 0; + } + + // u8 *tlut = (u8 *) LOAD_ASSET_RAW(common_tlut_lakitu_countdown); + // u8 *lights = (u8 *) LOAD_ASSET_RAW(gTextureLakituNoLights1); + + init_texture_object( + objectIndex, + (u8*) load_lakitu_tlut_x64(common_tlut_lakitu_countdown, ARRAY_COUNT(common_tlut_lakitu_countdown)), + sLakituTextures, 56, (u16) 72); + Vtx* vtx = (Vtx*) LOAD_ASSET_RAW(common_vtx_lakitu); + gObjectList[objectIndex].vertex = vtx; + gObjectList[objectIndex].sizeScaling = 0.15f; + clear_object_flag(objectIndex, 0x00000010); + object_next_state(objectIndex); + gObjectList[objectIndex].unk_048 = D_8018D180; +} + +void OLakitu::update_object_lakitu_starter(s32 objectIndex, s32 arg1) { + UNUSED s32 pad; + switch (gObjectList[objectIndex].state) { + case 0: + break; + case 1: + OLakitu::init_obj_lakitu_starter_and_checkered_flag(objectIndex, arg1); + break; + case 2: + set_and_run_timer_object(objectIndex, gObjectList[objectIndex].unk_048); + if ((gObjectList[objectIndex].timer == 0x00000055) && (gPlayerCount == 3) && (arg1 == 0)) { + D_8018D168 = 1; + } + break; + case 3: + set_object_flag(objectIndex, 0x00000010); + func_80086F10(objectIndex, 1, &D_800E67B8); // set a spline + object_next_state(objectIndex); + break; + case 4: + if ((set_and_run_timer_object(objectIndex, 0x0000001E) != false) && (gPlayerCount != 3) && (arg1 == 0)) { + D_8018D168 = 1; + } + break; + case 5: + set_and_run_timer_object(objectIndex, 0x0000001E); + break; + case 6: + func_80072E54(objectIndex, 1, 7, 1, 2, 0); + break; + case 7: + if (set_and_run_timer_object(objectIndex, 0x00000014) != 0) { + gObjectList[objectIndex].tlutList += 0x200; + if (arg1 == 0) { + play_sound2(SOUND_ACTION_COUNTDOWN_LIGHT); + } + } + break; + case 8: + func_80072E54(objectIndex, 8, 0x0000000F, 1, 6, 0); + break; + case 9: + if ((set_and_run_timer_object(objectIndex, 8) != 0) && (arg1 == 0)) { + play_sound2(SOUND_ACTION_COUNTDOWN_LIGHT); + } + break; + case 10: + if ((func_80072E54(objectIndex, 0x00000010, 0x00000017, 1, 6, 0) != 0) && (arg1 == 0)) { + D_801656F0 = 1; + } + break; + case 11: + if (set_and_run_timer_object(objectIndex, 8) != 0) { + gObjectList[objectIndex].tlutList += 0x200; + if (arg1 == 0) { + play_sound2(SOUND_ACTION_GREEN_LIGHT); + } + } + break; + case 12: + func_80072E54(objectIndex, 0x00000018, 0x0000001B, 1, 6, 0); + break; + case 13: + if (arg1 == 0) { + OLakitu::func_800729EC(objectIndex); + D_8018D160 = 1; + break; + } + object_next_state(objectIndex); + break; + case 14: + set_and_run_timer_object(objectIndex, 0x00000078); + break; + case 15: + func_80072428(objectIndex); + break; + } +} + +void OLakitu::func_800729EC(s32 objectIndex) { + u32 temp_v1 = 1; + s32 i; + + start_race(); + object_next_state(objectIndex); + D_8018D2BC = 1; + D_8018D2A4 = 1; + + if (GetCourse() != GetYoshiValley()) { + for (i = 0; i < gPlayerCount; i++) { + playerHUD[i].unk_81 = temp_v1; + } + } + func_8005AB20(); +} + +static const char* sLakituCheckeredList[] = { + gTextureLakituCheckeredFlag01, gTextureLakituCheckeredFlag02, gTextureLakituCheckeredFlag03, + gTextureLakituCheckeredFlag04, gTextureLakituCheckeredFlag05, gTextureLakituCheckeredFlag06, + gTextureLakituCheckeredFlag07, gTextureLakituCheckeredFlag08, gTextureLakituCheckeredFlag09, + gTextureLakituCheckeredFlag10, gTextureLakituCheckeredFlag11, gTextureLakituCheckeredFlag12, + gTextureLakituCheckeredFlag13, gTextureLakituCheckeredFlag14, gTextureLakituCheckeredFlag15, + gTextureLakituCheckeredFlag16, gTextureLakituCheckeredFlag17, gTextureLakituCheckeredFlag18, + gTextureLakituCheckeredFlag19, gTextureLakituCheckeredFlag20, gTextureLakituCheckeredFlag21, + gTextureLakituCheckeredFlag22, gTextureLakituCheckeredFlag23, gTextureLakituCheckeredFlag24, + gTextureLakituCheckeredFlag25, gTextureLakituCheckeredFlag26, gTextureLakituCheckeredFlag27, + gTextureLakituCheckeredFlag28, gTextureLakituCheckeredFlag29, gTextureLakituCheckeredFlag30, + gTextureLakituCheckeredFlag31, gTextureLakituCheckeredFlag32 +}; + +void OLakitu::init_obj_lakitu_checkered_flag(s32 objectIndex, s32 playerIndex) { + Object* object; + + OLakitu::func_800791F0(objectIndex, playerIndex); + + u8* tex = (u8*) LOAD_ASSET_RAW(common_tlut_lakitu_checkered_flag); + Vtx* vtx = (Vtx*) LOAD_ASSET_RAW(common_vtx_also_lakitu); + + init_texture_object(objectIndex, (u8*) tex, sLakituCheckeredList, 0x48U, (u16) 0x00000038); + object = &gObjectList[objectIndex]; + object->activeTexture = *gObjectList[objectIndex].textureList; + object->vertex = vtx; + object->pos[2] = 5000.0f; + object->pos[1] = 5000.0f; + object->pos[0] = 5000.0f; + object->sizeScaling = 0.15f; + func_80086F10(objectIndex, 2, &D_800E6834); + clear_object_flag(objectIndex, 0x00000010); + object_next_state(objectIndex); +} + +void OLakitu::update_object_lakitu_checkered_flag(s32 objectIndex, s32 playerIndex) { + switch (gObjectList[objectIndex].state) { + case 0: + break; + case 1: + OLakitu::init_obj_lakitu_checkered_flag(objectIndex, playerIndex); + break; + case 2: + set_object_flag(objectIndex, 0x00000010); + object_next_state(objectIndex); + break; + case 3: + func_80072E54(objectIndex, 0, 0x0000001F, 1, 2, -1); + break; + case 4: + func_80072428(objectIndex); + break; + } +} + +void OLakitu::func_800797AC(s32 playerId) { + s32 objectIndex; + Player* player; + + objectIndex = gIndexLakituList[playerId]; + player = &gPlayerOne[playerId]; + //if ((GetCourse() == GetSherbetLand()) && (player->unk_0CA & 1)) { + if ((CourseManager_GetProps()->LakituTowType == LakituTowType::ICE) && (player->unk_0CA & 1)) { + init_object(objectIndex, 7); + player->unk_0CA |= 0x10; + } else { + init_object(objectIndex, 3); + } + func_800722A4(objectIndex, 1); +} + +void OLakitu::func_80079860(s32 playerId) { + s32 objectIndex; + Player* player; + + objectIndex = gIndexLakituList[playerId]; + player = &gPlayerOne[playerId]; + if ((func_80072354(objectIndex, 1) != 0) && + (((func_802ABDF4(player->collision.meshIndexZX) != 0) && (player->collision.surfaceDistance[2] <= 3.0f)) || + (player->unk_0CA & 1) || ((player->surfaceType == OUT_OF_BOUNDS) && !(player->effects & 8)))) { + func_80090778(player); + OLakitu::func_800797AC(playerId); + } +} + +void OLakitu::func_8007993C(s32 objectIndex, Player* player) { + if (player->unk_0CA & 4) { + func_800722A4(objectIndex, 2); + gObjectList[objectIndex].primAlpha = player->unk_0C6; + return; + } + func_800722CC(objectIndex, 2); +} + +static const char* sLakituFishingTextures[] = { gTextureLakituFishing1, gTextureLakituFishing2, gTextureLakituFishing3, + gTextureLakituFishing4 }; + +void OLakitu::init_obj_lakitu_red_flag_fishing(s32 objectIndex, s32 arg1) { + + u8* tlut = (u8*) LOAD_ASSET_RAW(common_tlut_lakitu_fishing); + Vtx* vtx = (Vtx*) LOAD_ASSET_RAW(D_0D005F30); + + OLakitu::func_800791F0(objectIndex, arg1); + init_texture_object(objectIndex, tlut, sLakituFishingTextures, 0x38U, (u16) 0x00000048); + gObjectList[objectIndex].vertex = vtx; + gObjectList[objectIndex].sizeScaling = 0.15f; + func_80086E70(objectIndex); + clear_object_flag(objectIndex, 0x00000010); + func_80073720(objectIndex); + object_next_state(objectIndex); + func_800C8F80((u8) arg1, 0x0100FA28); +} + +void OLakitu::func_80079A5C(s32 objectIndex, UNUSED Player* player) { + switch (gObjectList[objectIndex].unk_0AE) { + case 0: + break; + case 1: + gObjectList[objectIndex].origin_pos[2] = 0.0f; + gObjectList[objectIndex].origin_pos[1] = 0.0f; + gObjectList[objectIndex].origin_pos[0] = 0.0f; + gObjectList[objectIndex].offset[2] = 0.0f; + gObjectList[objectIndex].offset[0] = 0.0f; + gObjectList[objectIndex].offset[1] = 80.0f; + func_80086FD4(objectIndex); + break; + case 2: + if (f32_step_down_towards(&gObjectList[objectIndex].offset[1], 5.0f, 1.0f) != 0) { + func_80086F60(objectIndex); + } + break; + case 3: + if (f32_step_up_towards(&gObjectList[objectIndex].offset[1], 100.0f, 1.0f) != 0) { + func_80086F60(objectIndex); + } + break; + } +} + +void OLakitu::update_object_lakitu_fishing(s32 objectIndex, s32 playerId) { + Player* player = &gPlayerOne[playerId]; + + switch (gObjectList[objectIndex].state) { /* switch 1; irregular */ + case 0: /* switch 1 */ + break; + case 1: /* switch 1 */ + OLakitu::init_obj_lakitu_red_flag_fishing(objectIndex, playerId); + break; + case 2: /* switch 1 */ + set_object_flag(objectIndex, 0x00000010); + func_800736E0(objectIndex); + object_next_state(objectIndex); + break; + case 3: /* switch 1 */ + func_800730BC(objectIndex, 0, 3, 1, 2, -1); + break; + } + switch (gObjectList[objectIndex].unk_0D6) { + case 0: + break; + case 1: + if (func_80086FA4(objectIndex) != 0) { + func_80073654(objectIndex); + } + break; + case 2: + func_80090868(player); + func_80073654(objectIndex); + break; + case 3: + if (!(player->unk_0CA & 2)) { + func_80086EAC(objectIndex, 0, 3); + func_80073654(objectIndex); + } + break; + case 4: + if (func_80086FA4(objectIndex) != 0) { + func_80073654(objectIndex); + } + break; + case 5: + func_800722CC(objectIndex, 1); + func_800C9018((u8) playerId, SOUND_ARG_LOAD(0x01, 0x00, 0xFA, 0x28)); + func_80072428(objectIndex); + func_80073720(objectIndex); + break; + } + if (gObjectList[objectIndex].state >= 2) { + OLakitu::func_8007993C(objectIndex, player); + } + OLakitu::func_80079A5C(objectIndex, player); +} + +void OLakitu::update_object_lakitu_fishing2(s32 objectIndex, s32 playerId) { + Player* player = &gPlayerOne[playerId]; + + switch (gObjectList[objectIndex].state) { /* switch 1; irregular */ + case 0: /* switch 1 */ + break; + case 1: /* switch 1 */ + OLakitu::init_obj_lakitu_red_flag_fishing(objectIndex, playerId); + break; + case 2: /* switch 1 */ + set_object_flag(objectIndex, 0x00000010); + func_800736E0(objectIndex); + player->unk_0CA |= 0x80; + object_next_state(objectIndex); + break; + case 3: /* switch 1 */ + func_800730BC(objectIndex, 0, 3, 1, 2, -1); + break; + } + switch (gObjectList[objectIndex].unk_0D6) { + case 1: + if (func_80086FA4(objectIndex) != 0) { + func_800C9060((u8) playerId, 0x1900A055U); + func_80073654(objectIndex); + } + break; + case 2: + func_80090868(player); + func_800722A4(objectIndex, 4); + func_80073654(objectIndex); + break; + case 3: + if ((player->surfaceType == ICE) && !(player->unk_0CA & 1) && + ((f64) player->collision.surfaceDistance[2] <= 30.0)) { + func_800722A4(objectIndex, 8); + } + if (!(player->unk_0CA & 2)) { + func_80086EAC(objectIndex, 0, 3); + func_80073654(objectIndex); + } + break; + case 4: + func_8007375C(objectIndex, 0x0000001E); + break; + case 5: + player->unk_0CA &= 0xFF7F; + func_800722A4(objectIndex, 0x00000010); + func_800722A4(objectIndex, 0x00000020); + func_800722CC(objectIndex, 4); + func_800722CC(objectIndex, 8); + func_80073654(objectIndex); + func_800C9060((u8) playerId, 0x1900A056U); + break; + case 6: + if (func_8007375C(objectIndex, 0x000000A0) != 0) { + func_800722CC(objectIndex, 0x00000010); + player->unk_0CA &= 0xFFEF; + player->unk_0CA |= 0x20; + } + break; + case 7: + func_8007375C(objectIndex, 0x0000003C); + break; + case 8: + func_80073720(objectIndex); + func_80072428(objectIndex); + player->unk_0CA &= 0xFFDF; + func_800722CC(objectIndex, 1); + func_800C9018((u8) playerId, SOUND_ARG_LOAD(0x01, 0x00, 0xFA, 0x28)); + break; + } + + if (gObjectList[objectIndex].state >= 2) { + OLakitu::func_8007993C(objectIndex, player); + } + OLakitu::func_80079A5C(objectIndex, player); +} + +static const char* sLakituSecondLapTextures[] = { + gTextureLakituSecondLap01, gTextureLakituSecondLap02, gTextureLakituSecondLap03, gTextureLakituSecondLap04, + gTextureLakituSecondLap05, gTextureLakituSecondLap06, gTextureLakituSecondLap07, gTextureLakituSecondLap08, + gTextureLakituSecondLap09, gTextureLakituSecondLap10, gTextureLakituSecondLap11, gTextureLakituSecondLap12, + gTextureLakituSecondLap13, gTextureLakituSecondLap14, gTextureLakituSecondLap15, gTextureLakituSecondLap16 +}; + +void OLakitu::func_8007A060(s32 objectIndex, s32 playerIndex) { + Object* object; + + OLakitu::func_800791F0(objectIndex, playerIndex); + + u8* tlut = (u8*) LOAD_ASSET_RAW(common_tlut_lakitu_second_lap); + Vtx* vtx = (Vtx*) LOAD_ASSET_RAW(common_vtx_also_lakitu); + + init_texture_object(objectIndex, tlut, sLakituSecondLapTextures, 0x48U, (u16) 0x00000038); + object = &gObjectList[objectIndex]; + object->activeTexture = *gObjectList[objectIndex].textureList; + object->vertex = vtx; + object->pos[2] = 5000.0f; + object->pos[1] = 5000.0f; + object->pos[0] = 5000.0f; + object->sizeScaling = 0.15f; + clear_object_flag(objectIndex, 0x00000010); + func_80086F10(objectIndex, 5, &D_800E694C); + object_next_state(objectIndex); +} + +void OLakitu::update_object_lakitu_second_lap(s32 objectIndex, s32 playerIndex) { + switch (gObjectList[objectIndex].state) { + case 0: + break; + case 1: + OLakitu::func_8007A060(objectIndex, playerIndex); + break; + case 2: + set_object_flag(objectIndex, 0x00000010); + object_next_state(objectIndex); + break; + case 3: + set_and_run_timer_object(objectIndex, 0x00000014); + break; + case 4: + func_80072E54(objectIndex, 0, 0x0000000F, 1, 2, 1); + break; + case 5: + set_and_run_timer_object(objectIndex, 0x0000003C); + break; + case 6: + func_80072F88(objectIndex, 0x0000000F, 0, 1, 2, 1); + break; + case 7: + if (gObjectList[objectIndex].unk_0AE == 0) { + func_80072428(objectIndex); + } + break; + } +} + +static const char* sLakituFinalLapTextures[] = { + gTextureLakituFinalLap01, gTextureLakituFinalLap02, gTextureLakituFinalLap03, gTextureLakituFinalLap04, + gTextureLakituFinalLap05, gTextureLakituFinalLap06, gTextureLakituFinalLap07, gTextureLakituFinalLap08, + gTextureLakituFinalLap09, gTextureLakituFinalLap10, gTextureLakituFinalLap11, gTextureLakituFinalLap12, + gTextureLakituFinalLap13, gTextureLakituFinalLap14, gTextureLakituFinalLap15, gTextureLakituFinalLap16, +}; + +void OLakitu::func_8007A228(s32 objectIndex, s32 playerIndex) { + Object* object; + + OLakitu::func_800791F0(objectIndex, playerIndex); + + u8* tlut = (u8*) LOAD_ASSET_RAW(common_tlut_lakitu_final_lap); + Vtx* vtx = (Vtx*) LOAD_ASSET_RAW(common_vtx_also_lakitu); + + init_texture_object(objectIndex, tlut, sLakituFinalLapTextures, 0x48U, (u16) 0x00000038); + object = &gObjectList[objectIndex]; + object->activeTexture = *gObjectList[objectIndex].textureList; + object->vertex = vtx; + object->pos[2] = 5000.0f; + object->pos[1] = 5000.0f; + object->pos[0] = 5000.0f; + object->sizeScaling = 0.15f; + clear_object_flag(objectIndex, 0x00000010); + func_80086F10(objectIndex, 5, &D_800E694C); + object_next_state(objectIndex); +} + +void OLakitu::update_object_lakitu_final_lap(s32 objectIndex, s32 playerIndex) { + switch (gObjectList[objectIndex].state) { + case 0: + break; + case 1: + OLakitu::func_8007A228(objectIndex, playerIndex); + break; + case 2: + set_object_flag(objectIndex, 0x00000010); + object_next_state(objectIndex); + break; + case 3: + set_and_run_timer_object(objectIndex, 0x00000014); + break; + case 4: + func_80072E54(objectIndex, 0, 0x0000000F, 1, 2, 1); + break; + case 5: + set_and_run_timer_object(objectIndex, 0x0000003C); + break; + case 6: + func_80072F88(objectIndex, 0x0000000F, 0, 1, 2, 1); + break; + case 7: + if (gObjectList[objectIndex].unk_0AE == 0) { + func_80072428(objectIndex); + } + break; + } +} + +static const char* sLakituReverseTextures[] = { + gTextureLakituReverse01, gTextureLakituReverse02, gTextureLakituReverse03, gTextureLakituReverse04, + gTextureLakituReverse05, gTextureLakituReverse06, gTextureLakituReverse07, gTextureLakituReverse08, + gTextureLakituReverse09, gTextureLakituReverse10, gTextureLakituReverse11, gTextureLakituReverse12, + gTextureLakituReverse13, gTextureLakituReverse14, gTextureLakituReverse15, gTextureLakituReverse16 +}; + +void OLakitu::func_8007A3F0(s32 objectIndex, s32 arg1) { + f32 var = 5000.0f; + OLakitu::func_800791F0(objectIndex, arg1); + + u8* tlut = (u8*) LOAD_ASSET_RAW(common_tlut_lakitu_reverse); + Vtx* vtx = (Vtx*) LOAD_ASSET_RAW(common_vtx_also_lakitu); + + init_texture_object(objectIndex, tlut, sLakituReverseTextures, 72, (u16) 56); + gObjectList[objectIndex].activeTexture = *gObjectList[objectIndex].textureList; + gObjectList[objectIndex].vertex = vtx; + gObjectList[objectIndex].pos[2] = var; + gObjectList[objectIndex].pos[1] = var; + gObjectList[objectIndex].pos[0] = var; + gObjectList[objectIndex].sizeScaling = 0.15f; + clear_object_flag(objectIndex, 0x00000010); + func_80086F10(objectIndex, 6, &D_800E69B0); + gObjectList[objectIndex].unk_0D6 = 0; + object_next_state(objectIndex); + func_800C8F80((u8) arg1, 0x0100FA28); +} + +void OLakitu::update_object_lakitu_reverse(s32 objectIndex, s32 playerId) { + Player* sp2C = &gPlayerOne[playerId]; + + switch (gObjectList[objectIndex].state) { + case 0: + break; + case 1: + OLakitu::func_8007A3F0(objectIndex, playerId); + break; + case 2: + set_object_flag(objectIndex, 0x00000010); + gObjectList[objectIndex].unk_0D6 = 1; + object_next_state(objectIndex); + break; + case 3: + func_800730BC(objectIndex, 0, 0x0000000F, 1, 2, -1); + break; + case 4: + func_80072428(objectIndex); + break; + } + switch (gObjectList[objectIndex].unk_0D6) { + case 1: + if ((gObjectList[objectIndex].state >= 3) && (!(sp2C->effects & 0x400000))) { + func_80086F10(objectIndex, 6, &D_800E69F4); + gObjectList[objectIndex].unk_0D6 = 2; + gObjectList[objectIndex].unk_04C = 0x00000050; + func_800C9018((u8) playerId, SOUND_ARG_LOAD(0x01, 0x00, 0xFA, 0x28)); + return; + } + return; + case 2: + gObjectList[objectIndex].unk_04C--; + if (gObjectList[objectIndex].unk_04C == 0) { + object_next_state(objectIndex); + gObjectList[objectIndex].unk_0D6 = 0; + } + break; + } +} + +void OLakitu::func_8007A66C(s32 objectIndex) { + Player* player = &gPlayers[_playerId]; + Camera* camera = &cameras[_playerId]; + u16 rot = 0x8000 - camera->rot[1]; + + gObjectList[objectIndex].pos[0] = + (player->pos[0] + + (coss(rot) * (gObjectList[objectIndex].origin_pos[0] + gObjectList[objectIndex].offset[0]))) - + (sins(rot) * (gObjectList[objectIndex].origin_pos[2] + gObjectList[objectIndex].offset[2])); + gObjectList[objectIndex].pos[1] = + player->unk_074 + gObjectList[objectIndex].origin_pos[1] + gObjectList[objectIndex].offset[1]; + gObjectList[objectIndex].pos[2] = + (player->pos[2] + + (sins(rot) * (gObjectList[objectIndex].origin_pos[0] + gObjectList[objectIndex].offset[0]))) + + (coss(rot) * (gObjectList[objectIndex].origin_pos[2] + gObjectList[objectIndex].offset[2])); +} + +void OLakitu::func_8007A778(s32 objectIndex) { + Player* player = &gPlayers[_playerId]; + Camera* camera = &cameras[_playerId]; + u16 rot = 0x8000 - camera->rot[1]; + + gObjectList[objectIndex].pos[0] = + (player->pos[0] + + (coss(rot) * (gObjectList[objectIndex].origin_pos[0] + gObjectList[objectIndex].offset[0]))) - + (sins(rot) * (gObjectList[objectIndex].origin_pos[2] + gObjectList[objectIndex].offset[2])); + gObjectList[objectIndex].pos[1] = + player->pos[1] + gObjectList[objectIndex].origin_pos[1] + gObjectList[objectIndex].offset[1]; + gObjectList[objectIndex].pos[2] = + (player->pos[2] + + (sins(rot) * (gObjectList[objectIndex].origin_pos[0] + gObjectList[objectIndex].offset[0]))) + + (coss(rot) * (gObjectList[objectIndex].origin_pos[2] + gObjectList[objectIndex].offset[2])); +} + +void OLakitu::func_8007A88C(s32 playerId) { + s32 objectIndex; + Player* player; + + objectIndex = gIndexLakituList[playerId]; + player = &gPlayerOne[playerId]; + + if ((gObjectList[objectIndex].state == 0) && (player->effects & 0x400000)) { + //func_800790E4(playerId); + init_object(gIndexLakituList[playerId], 6); + } +} + +void OLakitu::func_8007A910(s32 arg0) { + if (D_801657B4 == 0) { + OLakitu::func_8007A88C(arg0); + } + func_80079860(arg0); +} + +// animate lakitu? +void OLakitu::func_8007AA44(s32 playerId) { + s32 objectIndex; + + OLakitu::func_8007A910(playerId); + objectIndex = gIndexLakituList[playerId]; + gLakituTexturePtr = (const char**)&gLakituTextureBuffer[playerId]; + switch (gObjectList[objectIndex].unk_0D8) { + case 1: + OLakitu::func_80079114(objectIndex, playerId, 2); + OLakitu::func_8007A66C(objectIndex); + break; + case 2: + OLakitu::func_80079114(objectIndex, playerId, 0); + OLakitu::func_8007A66C(objectIndex); + break; + case 3: + OLakitu::func_80079114(objectIndex, playerId, 0); + OLakitu::func_8007A778(objectIndex); + break; + case 4: + OLakitu::func_80079114(objectIndex, playerId, 0); + OLakitu::func_8007A66C(objectIndex); + break; + case 5: + OLakitu::func_80079114(objectIndex, playerId, 0); + OLakitu::func_8007A66C(objectIndex); + break; + case 6: + OLakitu::func_80079114(objectIndex, playerId, 0); + OLakitu::func_8007A66C(objectIndex); + break; + case 7: + OLakitu::func_80079114(objectIndex, playerId, 0); + OLakitu::func_8007A778(objectIndex); + break; + case 0: + default: + break; + } +} + diff --git a/src/engine/objects/Lakitu.h b/src/engine/objects/Lakitu.h new file mode 100644 index 000000000..1944733ee --- /dev/null +++ b/src/engine/objects/Lakitu.h @@ -0,0 +1,82 @@ +#pragma once + +#include +#include +#include "Object.h" +#include "World.h" + +extern "C" { +#include "macros.h" +#include "main.h" +#include "vehicles.h" +#include "waypoints.h" +#include "common_structs.h" +#include "objects.h" +#include "course_offsets.h" +} + +/** + * Note that you only want 1 lakitu spawned in per human player + * Otherwise Lakitu will animate faster than normal. + */ +class OLakitu : public OObject { +public: + enum LakituType : uint32_t { + STARTER = 1, + FINISH, // Checkered flag + TOW, // Picks up an out of bounds player + SECOND_LAP, + FINAL_LAP, + REVERSE, + TOW_ICE_CUBE, // Picks up an out of bounds player in sherbet land as an ice-cube + }; + + enum LakituTowType : uint16_t { + NORMAL, + ICE, // Used in sherbet land to put an ice-cube on the player + }; + +public: + explicit OLakitu(s32 playerId, LakituType type); + + void Activate(LakituType type); // Triggers Lakitu into a behaviour + + virtual void Tick() override; + virtual void Tick60fps() override; + virtual void Draw(s32 playerId) override; + + void func_80078F64(); + void func_80079054(s32 playerId); + void func_80079084(s32 playerId); + void func_800790B4(s32 playerId); + void func_800790E4(s32 playerId); + void func_80079114(s32 objectIndex, s32 playerId, s32 arg2); + void func_800791F0(s32 objectIndex, s32 playerId); + void init_obj_lakitu_starter_and_checkered_flag(s32 objectIndex, s32 playerId); + void update_object_lakitu_starter(s32 objectIndex, s32 arg1); + void func_800729EC(s32 objectIndex); + void init_obj_lakitu_checkered_flag(s32 objectIndex, s32 playerIndex); + void update_object_lakitu_checkered_flag(s32 objectIndex, s32 playerIndex); + void func_800797AC(s32 playerId); + void func_80079860(s32 playerId); + void func_8007993C(s32 objectIndex, Player* player); + void init_obj_lakitu_red_flag_fishing(s32 objectIndex, s32 arg1); + void func_80079A5C(s32 objectIndex, UNUSED Player* player); + void update_object_lakitu_fishing(s32 objectIndex, s32 playerId); + void update_object_lakitu_fishing2(s32 objectIndex, s32 playerId); + void func_8007A060(s32 objectIndex, s32 playerIndex); + void update_object_lakitu_second_lap(s32 objectIndex, s32 playerIndex); + void func_8007A228(s32 objectIndex, s32 playerIndex); + void update_object_lakitu_final_lap(s32 objectIndex, s32 playerIndex); + void func_8007A3F0(s32 objectIndex, s32 arg1); + void update_object_lakitu_reverse(s32 objectIndex, s32 playerId); + void func_8007A66C(s32 objectIndex); + void func_8007A778(s32 objectIndex); + void func_8007A88C(s32 playerId); + void func_8007A910(s32 arg0); + void func_8007AA44(s32 playerId); // animate lakitu + +private: + LakituType _type; + s32 _playerId; +}; diff --git a/src/engine/objects/Object.cpp b/src/engine/objects/Object.cpp index 74143a923..eab390aa1 100644 --- a/src/engine/objects/Object.cpp +++ b/src/engine/objects/Object.cpp @@ -13,8 +13,11 @@ extern "C" { OObject::OObject() {} // Virtual functions to be overridden by derived classes -void OObject::Tick() { } +void OObject::Tick() { } +void OObject::Tick60fps() {} void OObject::Draw(s32 cameraId) { } void OObject::Collision() {} void OObject::Expire() { } -void OObject::Destroy() { } +void OObject::Destroy() { + PendingDestroy = true; +} diff --git a/src/main.c b/src/main.c index 5b3a02a79..b932c7a12 100644 --- a/src/main.c +++ b/src/main.c @@ -897,6 +897,9 @@ void race_logic_loop(void) { FB_WriteFramebufferSliceToCPU(&gDisplayListHead, gPortFramebuffers[sRenderingFramebuffer], true); gDPFullSync(gDisplayListHead++); gSPEndDisplayList(gDisplayListHead++); + + // End of frame cleanup of actors, objects, etc. + CM_RunGarbageCollector(); } /** diff --git a/src/render_objects.c b/src/render_objects.c index 926602a37..ac53334fa 100644 --- a/src/render_objects.c +++ b/src/render_objects.c @@ -3501,7 +3501,7 @@ void func_8005285C(s32 arg0) { func_80043500(D_80183E40, D_80183E80, 0.02f, d_course_sherbet_land_dl_ice_block); } -void func_800528EC(s32 arg0) { +void func_800528EC(s32 playerId) { s32 var_s3; s32 objectIndex; Object* object; @@ -3517,7 +3517,7 @@ void func_800528EC(s32 arg0) { gDPSetCombineMode(gDisplayListHead++, G_CC_MODULATEIA, G_CC_MODULATEIA); gSPClearGeometryMode(gDisplayListHead++, G_CULL_BOTH); gSPSetGeometryMode(gDisplayListHead++, G_SHADE | G_LIGHTING | G_SHADING_SMOOTH); - load_texture_block_ia16_nomirror(d_course_sherbet_land_ice, 0x00000020, 0x00000020); + load_texture_block_ia16_nomirror(d_course_sherbet_land_ice, 32, 32); if (gPlayerCountSelection1 < 3) { for (var_s3 = 0; var_s3 < gObjectParticle2_SIZE; var_s3++) { objectIndex = gObjectParticle2[var_s3]; @@ -3535,7 +3535,7 @@ void func_800528EC(s32 arg0) { objectIndex = gObjectParticle2[var_s3]; if (objectIndex != NULL_OBJECT_ID) { object = &gObjectList[objectIndex]; - if ((object->state > 0) && (arg0 == object->unk_084[7]) && (gMatrixHudCount <= MTX_HUD_POOL_SIZE_MAX)) { + if ((object->state > 0) && (playerId == object->unk_084[7]) && (gMatrixHudCount <= MTX_HUD_POOL_SIZE_MAX)) { rsp_set_matrix_transformation(object->pos, D_80183E80, object->sizeScaling); gSPVertex(gDisplayListHead++, D_0D005BD0, 3, 0); gSPDisplayList(gDisplayListHead++, D_0D006930); @@ -3548,8 +3548,7 @@ void func_800528EC(s32 arg0) { gSPTexture(gDisplayListHead++, 0x0001, 0x0001, 0, G_TX_RENDERTILE, G_OFF); } -void render_ice_block(s32 arg0) { - s32 playerId; +void render_ice_block(s32 playerId) { s32 objectIndex; // Lights1 D_800E4620l = *(Lights1 *) LOAD_ASSET(D_800E4620); D_800E4620.l[0].l.dir[0] = D_80165840[0]; @@ -3557,15 +3556,15 @@ void render_ice_block(s32 arg0) { D_800E4620.l[0].l.dir[2] = D_80165840[2]; gSPLight(gDisplayListHead++, &D_800E4620.l[0], LIGHT_1); gSPLight(gDisplayListHead++, &D_800E4620.a, LIGHT_2); - for (playerId = 0; playerId < gPlayerCountSelection1; playerId++) { - objectIndex = gIndexLakituList[playerId]; + for (size_t i = 0; i < gPlayerCountSelection1; i++) { + objectIndex = gIndexLakituList[i]; if (objectIndex) {} if (func_80072320(objectIndex, 4) != false) { - func_8005285C(playerId); + func_8005285C(i); } func_80072320(objectIndex, 0x00000010); } - func_800528EC(arg0); + func_800528EC(playerId); } void func_80052D70(s32 playerId) { @@ -3599,47 +3598,6 @@ void func_80052E30(UNUSED s32 arg0) { } } -void render_lakitu(s32 cameraId) { - UNUSED s32 stackPadding; - Camera* camera; - f32 var_f0; - f32 var_f2; - s32 objectIndex; - Object* object; - - objectIndex = gIndexLakituList[cameraId]; - camera = &camera1[cameraId]; - if (is_obj_flag_status_active(objectIndex, 0x00000010) != 0) { - object = &gObjectList[objectIndex]; - object->orientation[0] = 0; - object->orientation[1] = func_800418AC(object->pos[0], object->pos[2], camera->pos); - object->orientation[2] = 0x8000; - if (func_80072354(objectIndex, 2) != 0) { - draw_2d_texture_at(object->pos, object->orientation, object->sizeScaling, (u8*) object->activeTLUT, - object->activeTexture, object->vertex, (s32) object->textureWidth, - (s32) object->textureHeight, (s32) object->textureWidth, - (s32) object->textureHeight / 2); - } else { - func_800485C4(object->pos, object->orientation, object->sizeScaling, (s32) object->primAlpha, - (u8*) object->activeTLUT, object->activeTexture, object->vertex, (s32) object->textureWidth, - (s32) object->textureHeight, (s32) object->textureWidth, (s32) object->textureHeight / 2); - } - if (gScreenModeSelection == SCREEN_MODE_1P) { - var_f0 = object->pos[0] - D_8018CF14->pos[0]; - var_f2 = object->pos[2] - D_8018CF14->pos[2]; - if (var_f0 < 0.0f) { - var_f0 = -var_f0; - } - if (var_f2 < 0.0f) { - var_f2 = -var_f2; - } - if ((var_f0 + var_f2) <= 200.0) { - func_8004A630(&D_8018C0B0[cameraId], object->pos, 0.35f); - } - } - } -} - void func_80053D74(s32 objectIndex, UNUSED s32 arg1, s32 vertexIndex) { Object* object; diff --git a/src/render_objects.h b/src/render_objects.h index 8559ce6ca..ec95a0832 100644 --- a/src/render_objects.h +++ b/src/render_objects.h @@ -343,7 +343,6 @@ void render_object_snowmans_list_2(s32); void render_object_snowmans_list_1(s32); void render_object_snowmans(s32); -void render_lakitu(s32); void translate_thwomp_lights(s32); void thwomp_lights(s32); void render_object_thwomps_model(s32); diff --git a/src/update_objects.c b/src/update_objects.c index c3a9b5129..ba56a65a5 100644 --- a/src/update_objects.c +++ b/src/update_objects.c @@ -450,23 +450,6 @@ void set_type_object(s32 objectIndex, s32 arg1) { gObjectList[objectIndex].type = arg1; } -void func_800729EC(s32 objectIndex) { - u32 temp_v1 = 1; - s32 i; - - start_race(); - object_next_state(objectIndex); - D_8018D2BC = 1; - D_8018D2A4 = 1; - - if (GetCourse() != GetYoshiValley()) { - for (i = 0; i < gPlayerCount; i++) { - playerHUD[i].unk_81 = temp_v1; - } - } - func_8005AB20(); -} - UNUSED void func_80072A78(s32 objectIndex, s32 arg1) { gObjectList[objectIndex].textureListIndex = arg1; object_next_state(objectIndex); @@ -2890,788 +2873,6 @@ void func_80078C70(s32 arg0) { } } -void func_80078F64(void) { - switch (gScreenModeSelection) { /* irregular */ - case SCREEN_MODE_1P: - init_object(gIndexLakituList[0], 1); - break; - case SCREEN_MODE_2P_SPLITSCREEN_VERTICAL: - init_object(gIndexLakituList[0], 1); - init_object(gIndexLakituList[1], 1); - break; - case SCREEN_MODE_2P_SPLITSCREEN_HORIZONTAL: - init_object(gIndexLakituList[0], 1); - init_object(gIndexLakituList[1], 1); - break; - case SCREEN_MODE_3P_4P_SPLITSCREEN: - init_object(gIndexLakituList[0], 1); - init_object(gIndexLakituList[1], 1); - init_object(gIndexLakituList[2], 1); - init_object(gIndexLakituList[3], 1); - break; - } -} - -void func_80079054(s32 playerId) { - init_object(gIndexLakituList[playerId], 2); -} - -void func_80079084(s32 playerId) { - init_object(gIndexLakituList[playerId], 4); -} - -void func_800790B4(s32 playerId) { - init_object(gIndexLakituList[playerId], 5); -} - -void func_800790E4(s32 playerId) { - init_object(gIndexLakituList[playerId], 6); -} - -void func_80079114(s32 objectIndex, s32 playerId, s32 arg2) { - s32 a; - if (gObjectList[objectIndex].state >= 2) { - if ((u8) gObjectList[objectIndex].unk_0D8 == 1) { - if (playerId == 0) { - func_80074894(objectIndex, gLakituTexturePtr); - return; - } - a = gIndexLakituList[0]; - gObjectList[objectIndex].activeTLUT = gObjectList[a].activeTLUT; - gObjectList[objectIndex].activeTexture = gObjectList[a].activeTexture; - if (0) {} - return; - } - switch (arg2) { - case 0: - func_800748F4(objectIndex, gLakituTexturePtr); - break; - case 1: - func_800748C4(objectIndex, gLakituTexturePtr); - break; - case 2: - func_80074894(objectIndex, gLakituTexturePtr); - break; - } - } -} - -void func_800791F0(s32 objectIndex, s32 playerId) { - Player* player = &gPlayerOne[playerId]; - - if ((gObjectList[objectIndex].unk_0D8 != 3) && (gObjectList[objectIndex].unk_0D8 != 7)) { - func_800722CC(objectIndex, 1); - if (GetCourse() == GetSherbetLand()) { - player->unk_0CA &= 0xFFEF; - } - } else { - // ????? - } - if (GetCourse() == GetSherbetLand()) { - func_800722CC(objectIndex, 0x00000010); - player->unk_0CA &= 0xFFDF; - } - func_800C9018(playerId, SOUND_ARG_LOAD(0x01, 0x00, 0xFA, 0x28)); -} - -static const char* sLakituTextures[] = { - gTextureLakituNoLights1, gTextureLakituNoLights2, gTextureLakituNoLights3, gTextureLakituNoLights4, - gTextureLakituNoLights5, gTextureLakituNoLights6, gTextureLakituNoLights7, gTextureLakituNoLights8, - gTextureLakituRedLights01, gTextureLakituRedLights02, gTextureLakituRedLights03, gTextureLakituRedLights04, - gTextureLakituRedLights05, gTextureLakituRedLights06, gTextureLakituRedLights07, gTextureLakituRedLights08, - gTextureLakituRedLights09, gTextureLakituRedLights10, gTextureLakituRedLights11, gTextureLakituRedLights12, - gTextureLakituRedLights13, gTextureLakituRedLights14, gTextureLakituRedLights15, gTextureLakituRedLights16, - gTextureLakituBlueLight1, gTextureLakituBlueLight2, gTextureLakituBlueLight3, gTextureLakituBlueLight4, - gTextureLakituBlueLight5, gTextureLakituBlueLight6, gTextureLakituBlueLight7, gTextureLakituBlueLight8, -}; - -void init_obj_lakitu_red_flag_countdown(s32 objectIndex, s32 playerId) { - if (playerId == 0) { - D_801656F0 = 0; - D_8018D168 = 0; - } - - // u8 *tlut = (u8 *) LOAD_ASSET(common_tlut_lakitu_countdown); - // u8 *lights = (u8 *) LOAD_ASSET(gTextureLakituNoLights1); - - init_texture_object( - objectIndex, - (u8*) load_lakitu_tlut_x64(common_tlut_lakitu_countdown, ARRAY_COUNT(common_tlut_lakitu_countdown)), - sLakituTextures, 56, (u16) 72); - Vtx* vtx = (Vtx*) LOAD_ASSET(common_vtx_lakitu); - gObjectList[objectIndex].vertex = vtx; - gObjectList[objectIndex].sizeScaling = 0.15f; - clear_object_flag(objectIndex, 0x00000010); - object_next_state(objectIndex); - gObjectList[objectIndex].unk_048 = D_8018D180; -} - -void update_object_lakitu_countdown(s32 objectIndex, s32 arg1) { - UNUSED s32 pad; - switch (gObjectList[objectIndex].state) { - case 0: - break; - case 1: - init_obj_lakitu_red_flag_countdown(objectIndex, arg1); - break; - case 2: - set_and_run_timer_object(objectIndex, gObjectList[objectIndex].unk_048); - if ((gObjectList[objectIndex].timer == 0x00000055) && (gPlayerCount == 3) && (arg1 == 0)) { - D_8018D168 = 1; - } - break; - case 3: - set_object_flag(objectIndex, 0x00000010); - func_80086F10(objectIndex, 1, &D_800E67B8); // set a spline - object_next_state(objectIndex); - break; - case 4: - if ((set_and_run_timer_object(objectIndex, 0x0000001E) != false) && (gPlayerCount != 3) && (arg1 == 0)) { - D_8018D168 = 1; - } - break; - case 5: - set_and_run_timer_object(objectIndex, 0x0000001E); - break; - case 6: - func_80072E54(objectIndex, 1, 7, 1, 2, 0); - break; - case 7: - if (set_and_run_timer_object(objectIndex, 0x00000014) != 0) { - gObjectList[objectIndex].tlutList += 0x200; - if (arg1 == 0) { - play_sound2(SOUND_ACTION_COUNTDOWN_LIGHT); - } - } - break; - case 8: - func_80072E54(objectIndex, 8, 0x0000000F, 1, 6, 0); - break; - case 9: - if ((set_and_run_timer_object(objectIndex, 8) != 0) && (arg1 == 0)) { - play_sound2(SOUND_ACTION_COUNTDOWN_LIGHT); - } - break; - case 10: - if ((func_80072E54(objectIndex, 0x00000010, 0x00000017, 1, 6, 0) != 0) && (arg1 == 0)) { - D_801656F0 = 1; - } - break; - case 11: - if (set_and_run_timer_object(objectIndex, 8) != 0) { - gObjectList[objectIndex].tlutList += 0x200; - if (arg1 == 0) { - play_sound2(SOUND_ACTION_GREEN_LIGHT); - } - } - break; - case 12: - func_80072E54(objectIndex, 0x00000018, 0x0000001B, 1, 6, 0); - break; - case 13: - if (arg1 == 0) { - func_800729EC(objectIndex); - D_8018D160 = 1; - break; - } - object_next_state(objectIndex); - break; - case 14: - set_and_run_timer_object(objectIndex, 0x00000078); - break; - case 15: - func_80072428(objectIndex); - break; - } -} - -static const char* sLakituCheckeredList[] = { - gTextureLakituCheckeredFlag01, gTextureLakituCheckeredFlag02, gTextureLakituCheckeredFlag03, - gTextureLakituCheckeredFlag04, gTextureLakituCheckeredFlag05, gTextureLakituCheckeredFlag06, - gTextureLakituCheckeredFlag07, gTextureLakituCheckeredFlag08, gTextureLakituCheckeredFlag09, - gTextureLakituCheckeredFlag10, gTextureLakituCheckeredFlag11, gTextureLakituCheckeredFlag12, - gTextureLakituCheckeredFlag13, gTextureLakituCheckeredFlag14, gTextureLakituCheckeredFlag15, - gTextureLakituCheckeredFlag16, gTextureLakituCheckeredFlag17, gTextureLakituCheckeredFlag18, - gTextureLakituCheckeredFlag19, gTextureLakituCheckeredFlag20, gTextureLakituCheckeredFlag21, - gTextureLakituCheckeredFlag22, gTextureLakituCheckeredFlag23, gTextureLakituCheckeredFlag24, - gTextureLakituCheckeredFlag25, gTextureLakituCheckeredFlag26, gTextureLakituCheckeredFlag27, - gTextureLakituCheckeredFlag28, gTextureLakituCheckeredFlag29, gTextureLakituCheckeredFlag30, - gTextureLakituCheckeredFlag31, gTextureLakituCheckeredFlag32 -}; - -void init_obj_lakitu_red_flag(s32 objectIndex, s32 playerIndex) { - Object* object; - - func_800791F0(objectIndex, playerIndex); - - u8* tex = (u8*) LOAD_ASSET(common_tlut_lakitu_checkered_flag); - Vtx* vtx = (Vtx*) LOAD_ASSET(common_vtx_also_lakitu); - - init_texture_object(objectIndex, (u8*) tex, sLakituCheckeredList, 0x48U, (u16) 0x00000038); - object = &gObjectList[objectIndex]; - object->activeTexture = *gObjectList[objectIndex].textureList; - object->vertex = vtx; - object->pos[2] = 5000.0f; - object->pos[1] = 5000.0f; - object->pos[0] = 5000.0f; - object->sizeScaling = 0.15f; - func_80086F10(objectIndex, 2, &D_800E6834); - clear_object_flag(objectIndex, 0x00000010); - object_next_state(objectIndex); -} - -void update_object_lakitu_red_flag(s32 objectIndex, s32 playerIndex) { - switch (gObjectList[objectIndex].state) { - case 0: - break; - case 1: - init_obj_lakitu_red_flag(objectIndex, playerIndex); - break; - case 2: - set_object_flag(objectIndex, 0x00000010); - object_next_state(objectIndex); - break; - case 3: - func_80072E54(objectIndex, 0, 0x0000001F, 1, 2, -1); - break; - case 4: - func_80072428(objectIndex); - break; - } -} - -void func_800797AC(s32 playerId) { - s32 objectIndex; - Player* player; - - objectIndex = gIndexLakituList[playerId]; - player = &gPlayerOne[playerId]; - if ((GetCourse() == GetSherbetLand()) && (player->unk_0CA & 1)) { - init_object(objectIndex, 7); - player->unk_0CA |= 0x10; - } else { - init_object(objectIndex, 3); - } - func_800722A4(objectIndex, 1); -} - -void func_80079860(s32 playerId) { - s32 objectIndex; - Player* player; - - objectIndex = gIndexLakituList[playerId]; - player = &gPlayerOne[playerId]; - if ((func_80072354(objectIndex, 1) != 0) && - (((func_802ABDF4(player->collision.meshIndexZX) != 0) && (player->collision.surfaceDistance[2] <= 3.0f)) || - (player->unk_0CA & 1) || ((player->surfaceType == OUT_OF_BOUNDS) && !(player->effects & 8)))) { - func_80090778(player); - func_800797AC(playerId); - } -} - -void func_8007993C(s32 objectIndex, Player* player) { - if (player->unk_0CA & 4) { - func_800722A4(objectIndex, 2); - gObjectList[objectIndex].primAlpha = player->unk_0C6; - return; - } - func_800722CC(objectIndex, 2); -} - -static const char* sLakituFishingTextures[] = { gTextureLakituFishing1, gTextureLakituFishing2, gTextureLakituFishing3, - gTextureLakituFishing4 }; - -void init_obj_lakitu_red_flag_fishing(s32 objectIndex, s32 arg1) { - - u8* tlut = (u8*) LOAD_ASSET(common_tlut_lakitu_fishing); - Vtx* vtx = (Vtx*) LOAD_ASSET(D_0D005F30); - - func_800791F0(objectIndex, arg1); - init_texture_object(objectIndex, tlut, sLakituFishingTextures, 0x38U, (u16) 0x00000048); - gObjectList[objectIndex].vertex = vtx; - gObjectList[objectIndex].sizeScaling = 0.15f; - func_80086E70(objectIndex); - clear_object_flag(objectIndex, 0x00000010); - func_80073720(objectIndex); - object_next_state(objectIndex); - func_800C8F80((u8) arg1, 0x0100FA28); -} - -void func_80079A5C(s32 objectIndex, UNUSED Player* player) { - switch (gObjectList[objectIndex].unk_0AE) { - case 0: - break; - case 1: - gObjectList[objectIndex].origin_pos[2] = 0.0f; - gObjectList[objectIndex].origin_pos[1] = 0.0f; - gObjectList[objectIndex].origin_pos[0] = 0.0f; - gObjectList[objectIndex].offset[2] = 0.0f; - gObjectList[objectIndex].offset[0] = 0.0f; - gObjectList[objectIndex].offset[1] = 80.0f; - func_80086FD4(objectIndex); - break; - case 2: - if (f32_step_down_towards(&gObjectList[objectIndex].offset[1], 5.0f, 1.0f) != 0) { - func_80086F60(objectIndex); - } - break; - case 3: - if (f32_step_up_towards(&gObjectList[objectIndex].offset[1], 100.0f, 1.0f) != 0) { - func_80086F60(objectIndex); - } - break; - } -} - -void update_object_lakitu_fishing(s32 objectIndex, s32 playerId) { - Player* player = &gPlayerOne[playerId]; - - switch (gObjectList[objectIndex].state) { /* switch 1; irregular */ - case 0: /* switch 1 */ - break; - case 1: /* switch 1 */ - init_obj_lakitu_red_flag_fishing(objectIndex, playerId); - break; - case 2: /* switch 1 */ - set_object_flag(objectIndex, 0x00000010); - func_800736E0(objectIndex); - object_next_state(objectIndex); - break; - case 3: /* switch 1 */ - func_800730BC(objectIndex, 0, 3, 1, 2, -1); - break; - } - switch (gObjectList[objectIndex].unk_0D6) { - case 0: - break; - case 1: - if (func_80086FA4(objectIndex) != 0) { - func_80073654(objectIndex); - } - break; - case 2: - func_80090868(player); - func_80073654(objectIndex); - break; - case 3: - if (!(player->unk_0CA & 2)) { - func_80086EAC(objectIndex, 0, 3); - func_80073654(objectIndex); - } - break; - case 4: - if (func_80086FA4(objectIndex) != 0) { - func_80073654(objectIndex); - } - break; - case 5: - func_800722CC(objectIndex, 1); - func_800C9018((u8) playerId, SOUND_ARG_LOAD(0x01, 0x00, 0xFA, 0x28)); - func_80072428(objectIndex); - func_80073720(objectIndex); - break; - } - if (gObjectList[objectIndex].state >= 2) { - func_8007993C(objectIndex, player); - } - func_80079A5C(objectIndex, player); -} - -void update_object_lakitu_fishing2(s32 objectIndex, s32 playerId) { - Player* player = &gPlayerOne[playerId]; - - switch (gObjectList[objectIndex].state) { /* switch 1; irregular */ - case 0: /* switch 1 */ - break; - case 1: /* switch 1 */ - init_obj_lakitu_red_flag_fishing(objectIndex, playerId); - break; - case 2: /* switch 1 */ - set_object_flag(objectIndex, 0x00000010); - func_800736E0(objectIndex); - player->unk_0CA |= 0x80; - object_next_state(objectIndex); - break; - case 3: /* switch 1 */ - func_800730BC(objectIndex, 0, 3, 1, 2, -1); - break; - } - switch (gObjectList[objectIndex].unk_0D6) { - case 1: - if (func_80086FA4(objectIndex) != 0) { - func_800C9060((u8) playerId, 0x1900A055U); - func_80073654(objectIndex); - } - break; - case 2: - func_80090868(player); - func_800722A4(objectIndex, 4); - func_80073654(objectIndex); - break; - case 3: - if ((player->surfaceType == ICE) && !(player->unk_0CA & 1) && - ((f64) player->collision.surfaceDistance[2] <= 30.0)) { - func_800722A4(objectIndex, 8); - } - if (!(player->unk_0CA & 2)) { - func_80086EAC(objectIndex, 0, 3); - func_80073654(objectIndex); - } - break; - case 4: - func_8007375C(objectIndex, 0x0000001E); - break; - case 5: - player->unk_0CA &= 0xFF7F; - func_800722A4(objectIndex, 0x00000010); - func_800722A4(objectIndex, 0x00000020); - func_800722CC(objectIndex, 4); - func_800722CC(objectIndex, 8); - func_80073654(objectIndex); - func_800C9060((u8) playerId, 0x1900A056U); - break; - case 6: - if (func_8007375C(objectIndex, 0x000000A0) != 0) { - func_800722CC(objectIndex, 0x00000010); - player->unk_0CA &= 0xFFEF; - player->unk_0CA |= 0x20; - } - break; - case 7: - func_8007375C(objectIndex, 0x0000003C); - break; - case 8: - func_80073720(objectIndex); - func_80072428(objectIndex); - player->unk_0CA &= 0xFFDF; - func_800722CC(objectIndex, 1); - func_800C9018((u8) playerId, SOUND_ARG_LOAD(0x01, 0x00, 0xFA, 0x28)); - break; - } - - if (gObjectList[objectIndex].state >= 2) { - func_8007993C(objectIndex, player); - } - func_80079A5C(objectIndex, player); -} - -static const char* sLakituSecondLapTextures[] = { - gTextureLakituSecondLap01, gTextureLakituSecondLap02, gTextureLakituSecondLap03, gTextureLakituSecondLap04, - gTextureLakituSecondLap05, gTextureLakituSecondLap06, gTextureLakituSecondLap07, gTextureLakituSecondLap08, - gTextureLakituSecondLap09, gTextureLakituSecondLap10, gTextureLakituSecondLap11, gTextureLakituSecondLap12, - gTextureLakituSecondLap13, gTextureLakituSecondLap14, gTextureLakituSecondLap15, gTextureLakituSecondLap16 -}; - -void func_8007A060(s32 objectIndex, s32 playerIndex) { - Object* object; - - func_800791F0(objectIndex, playerIndex); - - u8* tlut = (u8*) LOAD_ASSET(common_tlut_lakitu_second_lap); - Vtx* vtx = (Vtx*) LOAD_ASSET(common_vtx_also_lakitu); - - init_texture_object(objectIndex, tlut, sLakituSecondLapTextures, 0x48U, (u16) 0x00000038); - object = &gObjectList[objectIndex]; - object->activeTexture = *gObjectList[objectIndex].textureList; - object->vertex = vtx; - object->pos[2] = 5000.0f; - object->pos[1] = 5000.0f; - object->pos[0] = 5000.0f; - object->sizeScaling = 0.15f; - clear_object_flag(objectIndex, 0x00000010); - func_80086F10(objectIndex, 5, &D_800E694C); - object_next_state(objectIndex); -} - -void update_object_lakitu_second_lap(s32 objectIndex, s32 playerIndex) { - switch (gObjectList[objectIndex].state) { - case 0: - break; - case 1: - func_8007A060(objectIndex, playerIndex); - break; - case 2: - set_object_flag(objectIndex, 0x00000010); - object_next_state(objectIndex); - break; - case 3: - set_and_run_timer_object(objectIndex, 0x00000014); - break; - case 4: - func_80072E54(objectIndex, 0, 0x0000000F, 1, 2, 1); - break; - case 5: - set_and_run_timer_object(objectIndex, 0x0000003C); - break; - case 6: - func_80072F88(objectIndex, 0x0000000F, 0, 1, 2, 1); - break; - case 7: - if (gObjectList[objectIndex].unk_0AE == 0) { - func_80072428(objectIndex); - } - break; - } -} - -static const char* sLakituFinalLapTextures[] = { - gTextureLakituFinalLap01, gTextureLakituFinalLap02, gTextureLakituFinalLap03, gTextureLakituFinalLap04, - gTextureLakituFinalLap05, gTextureLakituFinalLap06, gTextureLakituFinalLap07, gTextureLakituFinalLap08, - gTextureLakituFinalLap09, gTextureLakituFinalLap10, gTextureLakituFinalLap11, gTextureLakituFinalLap12, - gTextureLakituFinalLap13, gTextureLakituFinalLap14, gTextureLakituFinalLap15, gTextureLakituFinalLap16, -}; - -void func_8007A228(s32 objectIndex, s32 playerIndex) { - Object* object; - - func_800791F0(objectIndex, playerIndex); - - u8* tlut = (u8*) LOAD_ASSET(common_tlut_lakitu_final_lap); - Vtx* vtx = (Vtx*) LOAD_ASSET(common_vtx_also_lakitu); - - init_texture_object(objectIndex, tlut, sLakituFinalLapTextures, 0x48U, (u16) 0x00000038); - object = &gObjectList[objectIndex]; - object->activeTexture = *gObjectList[objectIndex].textureList; - object->vertex = vtx; - object->pos[2] = 5000.0f; - object->pos[1] = 5000.0f; - object->pos[0] = 5000.0f; - object->sizeScaling = 0.15f; - clear_object_flag(objectIndex, 0x00000010); - func_80086F10(objectIndex, 5, &D_800E694C); - object_next_state(objectIndex); -} - -void update_object_lakitu_final_lap(s32 objectIndex, s32 playerIndex) { - switch (gObjectList[objectIndex].state) { - case 0: - break; - case 1: - func_8007A228(objectIndex, playerIndex); - break; - case 2: - set_object_flag(objectIndex, 0x00000010); - object_next_state(objectIndex); - break; - case 3: - set_and_run_timer_object(objectIndex, 0x00000014); - break; - case 4: - func_80072E54(objectIndex, 0, 0x0000000F, 1, 2, 1); - break; - case 5: - set_and_run_timer_object(objectIndex, 0x0000003C); - break; - case 6: - func_80072F88(objectIndex, 0x0000000F, 0, 1, 2, 1); - break; - case 7: - if (gObjectList[objectIndex].unk_0AE == 0) { - func_80072428(objectIndex); - } - break; - } -} - -static const char* sLakituReverseTextures[] = { - gTextureLakituReverse01, gTextureLakituReverse02, gTextureLakituReverse03, gTextureLakituReverse04, - gTextureLakituReverse05, gTextureLakituReverse06, gTextureLakituReverse07, gTextureLakituReverse08, - gTextureLakituReverse09, gTextureLakituReverse10, gTextureLakituReverse11, gTextureLakituReverse12, - gTextureLakituReverse13, gTextureLakituReverse14, gTextureLakituReverse15, gTextureLakituReverse16 -}; - -void func_8007A3F0(s32 objectIndex, s32 arg1) { - f32 var = 5000.0f; - func_800791F0(objectIndex, arg1); - - u8* tlut = (u8*) LOAD_ASSET(common_tlut_lakitu_reverse); - Vtx* vtx = (Vtx*) LOAD_ASSET(common_vtx_also_lakitu); - - init_texture_object(objectIndex, tlut, sLakituReverseTextures, 72, (u16) 56); - gObjectList[objectIndex].activeTexture = *gObjectList[objectIndex].textureList; - gObjectList[objectIndex].vertex = vtx; - gObjectList[objectIndex].pos[2] = var; - gObjectList[objectIndex].pos[1] = var; - gObjectList[objectIndex].pos[0] = var; - gObjectList[objectIndex].sizeScaling = 0.15f; - clear_object_flag(objectIndex, 0x00000010); - func_80086F10(objectIndex, 6, &D_800E69B0); - gObjectList[objectIndex].unk_0D6 = 0; - object_next_state(objectIndex); - func_800C8F80((u8) arg1, 0x0100FA28); -} - -void update_object_lakitu_reverse(s32 objectIndex, s32 playerId) { - Player* sp2C = &gPlayerOne[playerId]; - - switch (gObjectList[objectIndex].state) { - case 0: - break; - case 1: - func_8007A3F0(objectIndex, playerId); - break; - case 2: - set_object_flag(objectIndex, 0x00000010); - gObjectList[objectIndex].unk_0D6 = 1; - object_next_state(objectIndex); - break; - case 3: - func_800730BC(objectIndex, 0, 0x0000000F, 1, 2, -1); - break; - case 4: - func_80072428(objectIndex); - break; - } - switch (gObjectList[objectIndex].unk_0D6) { /* switch 1; irregular */ - case 1: /* switch 1 */ - if ((gObjectList[objectIndex].state >= 3) && (!(sp2C->effects & 0x400000))) { - func_80086F10(objectIndex, 6, &D_800E69F4); - gObjectList[objectIndex].unk_0D6 = 2; - gObjectList[objectIndex].unk_04C = 0x00000050; - func_800C9018((u8) playerId, SOUND_ARG_LOAD(0x01, 0x00, 0xFA, 0x28)); - return; - } - return; - case 2: /* switch 1 */ - gObjectList[objectIndex].unk_04C--; - if (gObjectList[objectIndex].unk_04C == 0) { - object_next_state(objectIndex); - gObjectList[objectIndex].unk_0D6 = 0; - } - break; - } -} - -void func_8007A66C(s32 objectIndex, Player* player, Camera* camera) { - u16 temp_t8; - - temp_t8 = 0x8000 - camera->rot[1]; - gObjectList[objectIndex].pos[0] = - (player->pos[0] + - (coss(temp_t8) * (gObjectList[objectIndex].origin_pos[0] + gObjectList[objectIndex].offset[0]))) - - (sins(temp_t8) * (gObjectList[objectIndex].origin_pos[2] + gObjectList[objectIndex].offset[2])); - gObjectList[objectIndex].pos[1] = - player->unk_074 + gObjectList[objectIndex].origin_pos[1] + gObjectList[objectIndex].offset[1]; - gObjectList[objectIndex].pos[2] = - (player->pos[2] + - (sins(temp_t8) * (gObjectList[objectIndex].origin_pos[0] + gObjectList[objectIndex].offset[0]))) + - (coss(temp_t8) * (gObjectList[objectIndex].origin_pos[2] + gObjectList[objectIndex].offset[2])); -} - -void func_8007A778(s32 objectIndex, Player* player, Camera* camera) { - u16 temp_t8; - - temp_t8 = 0x8000 - camera->rot[1]; - gObjectList[objectIndex].pos[0] = - (player->pos[0] + - (coss(temp_t8) * (gObjectList[objectIndex].origin_pos[0] + gObjectList[objectIndex].offset[0]))) - - (sins(temp_t8) * (gObjectList[objectIndex].origin_pos[2] + gObjectList[objectIndex].offset[2])); - gObjectList[objectIndex].pos[1] = - player->pos[1] + gObjectList[objectIndex].origin_pos[1] + gObjectList[objectIndex].offset[1]; - gObjectList[objectIndex].pos[2] = - (player->pos[2] + - (sins(temp_t8) * (gObjectList[objectIndex].origin_pos[0] + gObjectList[objectIndex].offset[0]))) + - (coss(temp_t8) * (gObjectList[objectIndex].origin_pos[2] + gObjectList[objectIndex].offset[2])); -} - -UNUSED void func_8007A884(void) { -} - -void func_8007A88C(s32 playerId) { - s32 objectIndex; - Player* player; - - objectIndex = gIndexLakituList[playerId]; - player = &gPlayerOne[playerId]; - - if ((gObjectList[objectIndex].state == 0) && (player->effects & 0x400000)) { - func_800790E4(playerId); - } -} - -void func_8007A910(s32 arg0) { - if (D_801657B4 == 0) { - func_8007A88C(arg0); - } - func_80079860(arg0); -} - -void update_object_lakitu(s32 playerId) { - s32 objectIndex = gIndexLakituList[playerId]; - - switch (gObjectList[objectIndex].unk_0D8) { - case 0: - break; - case 1: - update_object_lakitu_countdown(objectIndex, playerId); - func_8008BFFC(objectIndex); - break; - case 2: - update_object_lakitu_red_flag(objectIndex, playerId); - func_8008BFFC(objectIndex); - break; - case 3: - update_object_lakitu_fishing(objectIndex, playerId); - break; - case 4: - update_object_lakitu_second_lap(objectIndex, playerId); - func_8008BFFC(objectIndex); - break; - case 5: - update_object_lakitu_final_lap(objectIndex, playerId); - func_8008BFFC(objectIndex); - break; - case 6: - update_object_lakitu_reverse(objectIndex, playerId); - func_8008BFFC(objectIndex); - break; - case 7: - update_object_lakitu_fishing2(objectIndex, playerId); - break; - } -} - -// animate lakitu? -void func_8007AA44(s32 playerId) { - s32 objectIndex; - - func_8007A910(playerId); - objectIndex = gIndexLakituList[playerId]; - gLakituTexturePtr = &gLakituTextureBuffer[playerId]; - switch (gObjectList[objectIndex].unk_0D8) { - case 1: - func_80079114(objectIndex, playerId, 2); - func_8007A66C(objectIndex, D_8018CF1C, D_8018CF14); - break; - case 2: - func_80079114(objectIndex, playerId, 0); - func_8007A66C(objectIndex, D_8018CF1C, D_8018CF14); - break; - case 3: - func_80079114(objectIndex, playerId, 0); - func_8007A778(objectIndex, D_8018CF1C, D_8018CF14); - break; - case 4: - func_80079114(objectIndex, playerId, 0); - func_8007A66C(objectIndex, D_8018CF1C, D_8018CF14); - break; - case 5: - func_80079114(objectIndex, playerId, 0); - func_8007A66C(objectIndex, D_8018CF1C, D_8018CF14); - break; - case 6: - func_80079114(objectIndex, playerId, 0); - func_8007A66C(objectIndex, D_8018CF1C, D_8018CF14); - break; - case 7: - func_80079114(objectIndex, playerId, 0); - func_8007A778(objectIndex, D_8018CF1C, D_8018CF14); - break; - case 0: - default: - break; - } -} void func_8007ABFC(s32 playerId, bool arg1) { s32 itemWindow; diff --git a/src/update_objects.h b/src/update_objects.h index bbaf92d9f..50ef50919 100644 --- a/src/update_objects.h +++ b/src/update_objects.h @@ -193,7 +193,6 @@ void func_800797AC(s32); void func_80079860(s32); void func_8007993C(s32, Player*); void func_80079A5C(s32, Player*); -void func_8007A66C(s32, Player*, Camera*); void func_8007A778(s32, Player*, Camera*); void func_8007A884(void); void func_8007A88C(s32); From 9c4b35206a2c697acc7345e91587c52a09240eb9 Mon Sep 17 00:00:00 2001 From: MegaMech Date: Sat, 28 Dec 2024 20:30:18 -0700 Subject: [PATCH 15/21] Fix podium ceremony. Wip particle emitters --- src/code_80057C60.c | 29 ++-- src/ending/code_80281780.c | 3 +- src/ending/code_80281780.h | 2 +- src/ending/code_80281C40.c | 2 +- src/engine/World.cpp | 16 ++ src/engine/World.h | 4 + src/engine/courses/PodiumCeremony.cpp | 8 +- src/engine/objects/CheepCheep.cpp | 1 - src/engine/objects/Object.h | 4 +- src/engine/objects/Podium.cpp | 30 ++-- src/engine/objects/Podium.h | 1 + src/engine/objects/Trophy.cpp | 92 +++++++++-- src/engine/objects/Trophy.h | 3 + src/engine/particles/StarEmitter.cpp | 152 ++++++++++++++++- src/engine/particles/StarEmitter.h | 11 +- src/main.c | 2 +- src/port/Game.cpp | 84 +++++++++- src/port/Game.h | 16 +- src/racing/actors.c | 4 +- src/racing/memory.c | 18 +- src/racing/memory.h | 1 - src/racing/race_logic.c | 2 +- src/render_objects.c | 12 -- src/render_objects.h | 2 - src/update_objects.c | 230 -------------------------- src/update_objects.h | 3 - 26 files changed, 407 insertions(+), 325 deletions(-) diff --git a/src/code_80057C60.c b/src/code_80057C60.c index 549b2bc95..a4fb77372 100644 --- a/src/code_80057C60.c +++ b/src/code_80057C60.c @@ -551,22 +551,21 @@ void render_object(u32 arg0) { } void render_object_p1(void) { - gDPSetTexturePersp(gDisplayListHead++, G_TP_PERSP); gSPMatrix(gDisplayListHead++, VIRTUAL_TO_PHYSICAL(&gGfxPool->mtxPersp[0]), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_PROJECTION); gSPMatrix(gDisplayListHead++, VIRTUAL_TO_PHYSICAL(&gGfxPool->mtxLookAt[0]), G_MTX_NOPUSH | G_MTX_MUL | G_MTX_PROJECTION); - CourseManager_DrawBombKarts(PLAYER_ONE); - //render_bomb_karts_wrap(PLAYER_ONE); - if (gGamestate == ENDING) { - //func_80055F48(PLAYER_ONE); - //func_80056160(PLAYER_ONE); - //func_8005217C(PLAYER_ONE); - //func_80054BE8(PLAYER_ONE); - return; - } + CourseManager_DrawBombKarts(PLAYER_ONE); // render_bomb_karts_wrap(PLAYER_ONE); + + // if (gGamestate == ENDING) { + // //func_80055F48(PLAYER_ONE); + // //func_80056160(PLAYER_ONE); + // //func_8005217C(PLAYER_ONE); + // //func_80054BE8(PLAYER_ONE); + // return; + // } render_object_for_player(PLAYER_ONE); } @@ -690,8 +689,8 @@ void render_player_snow_effect_four(void) { } void render_object_for_player(s32 cameraId) { - CourseManager_DrawObjects(cameraId); + CM_DrawParticles(cameraId); // CourseManager_RenderCourseObjects(cameraId); // CourseManager_TrainSmokeDraw(cameraId); @@ -1408,6 +1407,7 @@ void func_80059D00(void) { } update_object(); CourseManager_TickObjects(); + CM_TickParticles(); func_800744CC(); } } @@ -1423,12 +1423,15 @@ void func_8005A070(void) { //func_80086604(); //func_80086D80(); //update_cheep_cheep(1); - func_80077640(); + //func_80077640(); + CourseManager_TickObjects(); + CM_TickParticles(); } else if (gGamestate == CREDITS_SEQUENCE) { func_80059820(PLAYER_ONE); func_80078C70(0); CourseManager_TickObjects(); - } else { + CM_TickParticles(); + } else { // normal gameplay func_80059D00(); } } diff --git a/src/ending/code_80281780.c b/src/ending/code_80281780.c index ca20c998c..ec370711c 100644 --- a/src/ending/code_80281780.c +++ b/src/ending/code_80281780.c @@ -89,7 +89,7 @@ void func_802818BC(void) { } } -void load_ceremony_cutscene(void) { +void setup_podium_ceremony(void) { Camera* camera = &cameras[0]; gCurrentCourseId = COURSE_ROYAL_RACEWAY; @@ -164,6 +164,7 @@ void load_ceremony_cutscene(void) { balloons_and_fireworks_init(); init_camera_podium_ceremony(); func_80093E60(); + CourseManager_SpawnActors(); D_801625F8 = (uintptr_t) gHeapEndPtr - gNextFreeMemoryAddress; D_801625FC = ((f32) D_801625F8 / 1000.0f); } diff --git a/src/ending/code_80281780.h b/src/ending/code_80281780.h index cb90e1053..47857bda6 100644 --- a/src/ending/code_80281780.h +++ b/src/ending/code_80281780.h @@ -6,7 +6,7 @@ void debug_switch_character_ceremony_cutscene(void); s32 func_80281880(s32 arg0); void func_802818BC(void); -void load_ceremony_cutscene(void); +void setup_podium_ceremony(void); extern s32 D_80287554; extern f32 D_801647A4; diff --git a/src/ending/code_80281C40.c b/src/ending/code_80281C40.c index ebdcd38f9..50a2b7839 100644 --- a/src/ending/code_80281C40.c +++ b/src/ending/code_80281C40.c @@ -131,7 +131,7 @@ void func_80281D00(void) { render_players_on_screen_one(); gSPDisplayList(gDisplayListHead++, VIRTUAL_TO_PHYSICAL2(&D_80284EE0)); update_actors_loop(); - render_object(PLAYER_ONE + SCREEN_MODE_1P); + render_object(RENDER_SCREEN_MODE_1P_PLAYER_ONE); func_80021B0C(); gSPDisplayList(gDisplayListHead++, VIRTUAL_TO_PHYSICAL2(&D_80284EE0)); func_80093F10(); diff --git a/src/engine/World.cpp b/src/engine/World.cpp index b14c45219..5cd85213b 100644 --- a/src/engine/World.cpp +++ b/src/engine/World.cpp @@ -254,6 +254,10 @@ void World::TickObjects60fps() { } } +ParticleEmitter* World::AddEmitter(ParticleEmitter* emitter) { + Emitters.push_back(emitter); + return Emitters.back(); +} void World::DrawObjects(s32 cameraId) { for (const auto& object : Objects) { @@ -261,6 +265,18 @@ void World::DrawObjects(s32 cameraId) { } } +void World::TickParticles() { + for (const auto& emitter : Emitters) { + emitter->Tick(); + } +} + +void World::DrawParticles(s32 cameraId) { + for (const auto& emitter : Emitters) { + emitter->Draw(cameraId); + } +} + Object* World::GetObjectByIndex(size_t index) { //if (index < this->Objects.size()) { // Assuming GameActor::a is accessible, use reinterpret_cast if needed diff --git a/src/engine/World.h b/src/engine/World.h index 403a708c2..3fa687e76 100644 --- a/src/engine/World.h +++ b/src/engine/World.h @@ -164,6 +164,10 @@ public: void DrawObjects(s32 cameraId); Object *GetObjectByIndex(size_t); + void TickParticles(); + void DrawParticles(s32 cameraId); + ParticleEmitter* AddEmitter(ParticleEmitter* emitter); + void AddCup(Cup*); void SetCup(Cup* cup); const char* GetCupName(); diff --git a/src/engine/courses/PodiumCeremony.cpp b/src/engine/courses/PodiumCeremony.cpp index 6f04bd291..5c4bbe7fb 100644 --- a/src/engine/courses/PodiumCeremony.cpp +++ b/src/engine/courses/PodiumCeremony.cpp @@ -165,11 +165,11 @@ void PodiumCeremony::SpawnActors() { spawn_all_item_boxes((struct ActorSpawnData*)LOAD_ASSET_RAW(d_course_royal_raceway_item_box_spawns)); spawn_piranha_plants((struct ActorSpawnData*)LOAD_ASSET_RAW(d_course_royal_raceway_piranha_plant_spawn)); - gWorldInstance.AddObject(new OCheepCheep(FVector((f32)0xf37e, (f32)0x0013, (f32)0xfe22), OCheepCheep::CheepType::PODIUM_CEREMONY, IPathSpan(0, 0))); - gWorldInstance.AddObject(new OPodium(FVector((f32)0xf37e, (f32)0x0013, (f32)0xfe22))); + gWorldInstance.AddObject(new OCheepCheep(FVector((f32)-3202, (f32)19, (f32)-478), OCheepCheep::CheepType::PODIUM_CEREMONY, IPathSpan(0, 0))); + gWorldInstance.AddObject(new OPodium(FVector((f32)-3202, (f32)19, (f32)-478))); - FVector pos = {0,0,0}; - pos.y = 90.0f; + FVector pos = {0, 90.0f, 0}; + OTrophy::TrophyType type = OTrophy::TrophyType::BRONZE; switch(D_802874D8.unk1D) { case 0: // Bronze diff --git a/src/engine/objects/CheepCheep.cpp b/src/engine/objects/CheepCheep.cpp index e81ba7c24..10cdf6602 100644 --- a/src/engine/objects/CheepCheep.cpp +++ b/src/engine/objects/CheepCheep.cpp @@ -52,7 +52,6 @@ void OCheepCheep::Draw(s32 cameraId) { // func_8005217C Lights1* D_800E45C0l = (Lights1*) (D_800E45C0); Object* object; s32 temp_a3; - temp_a3 = indexObjectList2[0]; object = &gObjectList[temp_a3]; if (object->state >= 2) { diff --git a/src/engine/objects/Object.h b/src/engine/objects/Object.h index c41cfae6d..af2df81b5 100644 --- a/src/engine/objects/Object.h +++ b/src/engine/objects/Object.h @@ -11,14 +11,16 @@ class OObject { public: uint8_t uuid[16]; Object o; + bool PendingDestroy = false; virtual ~OObject() = default; explicit OObject(); virtual void Tick(); + virtual void Tick60fps(); virtual void Draw(s32 cameraId); virtual void Collision(); virtual void Expire(); - virtual void Destroy(); + virtual void Destroy(); // Mark object for deletion at the start of the next frame }; diff --git a/src/engine/objects/Podium.cpp b/src/engine/objects/Podium.cpp index 426a65b60..1922c98a5 100644 --- a/src/engine/objects/Podium.cpp +++ b/src/engine/objects/Podium.cpp @@ -27,24 +27,26 @@ extern Vec3s D_800E634C[]; OPodium::OPodium(const FVector& pos) { + _pos = pos; + for (size_t i = 0; i < NUM_PODIUMS; i++) { s32 objectIndex = indexObjectList1[i]; - init_object(objectIndex, 0); - set_obj_origin_pos(objectIndex, pos.x - 1.5, pos.y, pos.z); + //init_object(objectIndex, 0); + //set_obj_origin_pos(objectIndex, pos.x - 1.5, pos.y, pos.z); } } void OPodium::Tick() { // func_80086604 s32 objectIndex; - // if ((D_8016347C != 0) && (D_802874D8.unk1D < 3)) { - // if (D_801658C6 == 0) { - // for (size_t i = 0; i < 3; i++) { - // objectIndex = indexObjectList1[i]; - // init_object(objectIndex, 0); - // } - // D_801658C6 = 1; - // } - // } + if ((D_8016347C != 0) && (D_802874D8.unk1D < 3)) { + if (D_801658C6 == 0) { + for (size_t i = 0; i < 3; i++) { + objectIndex = indexObjectList1[i]; + init_object(objectIndex, 0); + } + D_801658C6 = 1; + } + } for (size_t i = 0; i != NUM_PODIUMS; i++) { objectIndex = indexObjectList1[i]; if (gObjectList[objectIndex].state != 0) { @@ -58,9 +60,9 @@ void OPodium::Draw(s32 cameraId) { // func_80055F48 for (size_t i = 0; i < NUM_PODIUMS; i++) { Object* object; - object = &gObjectList[i]; + object = &gObjectList[indexObjectList1[i]]; if (object->state >= 2) { - func_80043220(object->pos, object->direction_angle, object->sizeScaling, object->model); + //func_80043220(object->pos, object->direction_angle, object->sizeScaling, object->model); rsp_set_matrix_transformation(object->pos, object->direction_angle, object->sizeScaling); gSPDisplayList(gDisplayListHead++, (Gfx*)D_0D0077A0); gSPDisplayList(gDisplayListHead++, object->model); @@ -86,7 +88,7 @@ void OPodium::func_8008629C(s32 objectIndex, s32 arg1) { break; } gObjectList[objectIndex].sizeScaling = 1.0f; - //set_obj_origin_pos(objectIndex, D_800E634C[0][0] - 1.5, D_800E634C[0][1], D_800E634C[0][2]); + set_obj_origin_pos(objectIndex, _pos.x - 1.5, _pos.y, _pos.z); set_obj_origin_offset(objectIndex, 0.0f, -10.0f, 0.0f); set_obj_direction_angle(objectIndex, 0U, 0xF8E4U, 0U); gObjectList[objectIndex].unk_048 = 0; diff --git a/src/engine/objects/Podium.h b/src/engine/objects/Podium.h index 2b3a1033a..ea79d7232 100644 --- a/src/engine/objects/Podium.h +++ b/src/engine/objects/Podium.h @@ -35,4 +35,5 @@ public: private: s32 _idx; + FVector _pos; }; diff --git a/src/engine/objects/Trophy.cpp b/src/engine/objects/Trophy.cpp index 5ac54f5ec..c14cc23ca 100644 --- a/src/engine/objects/Trophy.cpp +++ b/src/engine/objects/Trophy.cpp @@ -24,7 +24,18 @@ OTrophy::OTrophy(const FVector& pos, TrophyType trophy, Behaviour bhv) { _spawnPos.y += 16.0f; // Adjust the height so the trophy sits on the surface when positioned to 0,0,0 _bhv = bhv; - init_object(objectIndex, 0); + if (bhv == OTrophy::Behaviour::PODIUM_CEREMONY) { + _toggleVisibility = &D_801658CE; + } else { + int8_t toggle = 1; + _toggleVisibility = &toggle; + _isMod = true; + } + + // This allows spawning for mods + if (*_toggleVisibility == true) { + init_object(objectIndex, 0); + } switch (trophy) { case TrophyType::GOLD: @@ -47,13 +58,6 @@ OTrophy::OTrophy(const FVector& pos, TrophyType trophy, Behaviour bhv) { break; } - if (OTrophy::Behaviour::PODIUM_CEREMONY) { - _toggleVisibility = &D_801658CE; - } else { - int8_t toggle = 1; - _toggleVisibility = &toggle; - } - // Set defaults for modded behaviours if (_bhv != OTrophy::Behaviour::PODIUM_CEREMONY) { gObjectList[objectIndex].sizeScaling = 0.025f; @@ -81,15 +85,15 @@ void OTrophy::Tick() { // func_80086D80 s32 objectIndex = indexObjectList1[3]; s32 var_s0; - // if ((D_801658CE != 0) && (D_801658DC == 0)) { - // temp_s2 = indexObjectList1[3]; - // init_object(temp_s2, 0); - // D_801658DC = 1; - // } + // Fallback for podium ceremony where the trophy is not spawned until it is needed + if ((*_toggleVisibility == true) && (D_801658DC == 0) && (_isMod == false)) { + init_object(objectIndex, 0); + D_801658DC = 1; + } switch(_bhv) { case OTrophy::Behaviour::PODIUM_CEREMONY: - if (gObjectList[objectIndex].state != 0) { + if (gObjectList[objectIndex].state != 0 && (*_toggleVisibility == true)) { OTrophy::func_80086C14(objectIndex); OTrophy::func_80086940(objectIndex); if (D_801658F4 != 0) { @@ -197,8 +201,7 @@ void OTrophy::Draw(s32 cameraId) { Mat4 someMatrix1; Mat4 someMatrix2; Object* object; - - if (_toggleVisibility) { + if (*_toggleVisibility == true) { object = &gObjectList[listIndex]; if (object->state >= 2) { gSPMatrix(gDisplayListHead++, VIRTUAL_TO_PHYSICAL(&gGfxPool->mtxPersp[0]), @@ -332,3 +335,60 @@ void OTrophy::func_80086C6C(s32 objectIndex) { } func_800773D8(sp24, (s32) D_801658F4); } + +void OTrophy::func_800773D8(f32* arg0, s32 arg1) { + s32 objectIndex = add_unused_obj_index(gObjectParticle3, &gNextFreeObjectParticle3, gObjectParticle3_SIZE); + if (objectIndex != NULL_OBJECT_ID) { + func_80077138(objectIndex, arg0, arg1); + } +} + +void OTrophy::func_80077138(s32 objectIndex, Vec3f arg1, s32 arg2) { + s8 temp_v0_3; + Vec3s sp30; + + init_object(objectIndex, arg2); + gObjectList[objectIndex].unk_0D5 = 0x0C; + gObjectList[objectIndex].sizeScaling = 0.05f; + set_obj_origin_pos(objectIndex, arg1[0], arg1[1], arg1[2]); + set_obj_orientation(objectIndex, 0U, 0U, 0U); + set_obj_origin_offset(objectIndex, 0.0f, 0.0f, 0.0f); + switch (arg2) { + case 0: + gObjectList[objectIndex].velocity[1] = -1.0f; + gObjectList[objectIndex].unk_034 = (f32) ((random_int(0x004BU) * 0.01) + 0.25); + gObjectList[objectIndex].direction_angle[1] = random_int(0x0040U) << 0xA; + func_8008751C(objectIndex); + gObjectList[objectIndex].unk_084[5] = 0x001E; + break; + case 1: + gObjectList[objectIndex].velocity[1] = 1.5f; + gObjectList[objectIndex].unk_034 = (f32) ((random_int(0x0064U) * 0.01) + 0.5); + gObjectList[objectIndex].direction_angle[1] = random_int(0x0040U) << 0xA; + func_8008751C(objectIndex); + gObjectList[objectIndex].unk_084[5] = 0x0032; + break; + } + temp_v0_3 = random_int(0x000CU); + if (temp_v0_3 < 9) { + func_8005C674(temp_v0_3, &sp30[2], &sp30[1], sp30); + gObjectList[objectIndex].unk_048 = 0; + gObjectList[objectIndex].unk_084[0] = sp30[2]; + gObjectList[objectIndex].unk_084[1] = sp30[1]; + gObjectList[objectIndex].unk_084[2] = sp30[0]; + } else { + temp_v0_3 = random_int(3U); + func_8005C6B4(temp_v0_3, &sp30[2], &sp30[1], sp30); + gObjectList[objectIndex].unk_084[0] = sp30[2]; + gObjectList[objectIndex].unk_084[1] = sp30[1]; + gObjectList[objectIndex].unk_084[2] = sp30[0]; + gObjectList[objectIndex].unk_084[4] = temp_v0_3; + gObjectList[objectIndex].unk_048 = 1; + } + gObjectList[objectIndex].primAlpha = 0x00FF; + gObjectList[objectIndex].unk_084[3] = random_int(0x0800U) + 0x400; + if ((gObjectList[objectIndex].direction_angle[1] < 0x3000) || + (gObjectList[objectIndex].direction_angle[1] >= 0xB001)) { + gObjectList[objectIndex].unk_084[3] = -gObjectList[objectIndex].unk_084[3]; + } +} \ No newline at end of file diff --git a/src/engine/objects/Trophy.h b/src/engine/objects/Trophy.h index d413faf12..a227ef5b9 100644 --- a/src/engine/objects/Trophy.h +++ b/src/engine/objects/Trophy.h @@ -43,6 +43,8 @@ public: void func_80086940(s32 objectIndex); void func_80086C14(s32 objectIndex); void func_80086C6C(s32 objectIndex); + void func_800773D8(f32* arg0, s32 arg1); + void func_80077138(s32 objectIndex, Vec3f arg1, s32 arg2); private: @@ -52,4 +54,5 @@ private: Behaviour _bhv; int8_t *_toggleVisibility; Vec3f _oldPos; + bool _isMod = false; }; diff --git a/src/engine/particles/StarEmitter.cpp b/src/engine/particles/StarEmitter.cpp index b717f177d..14745d39a 100644 --- a/src/engine/particles/StarEmitter.cpp +++ b/src/engine/particles/StarEmitter.cpp @@ -6,10 +6,89 @@ extern "C" { #include "render_objects.h" #include "common_data.h" #include "code_80057C60.h" +#include "update_objects.h" +#include "code_80086E70.h" +#include "math_util.h" +#include "math_util_2.h" } -void StarEmitter::Tick() { +StarEmitter::StarEmitter(FVector pos) { + s32 objectIndex = add_unused_obj_index(gObjectParticle3, &gNextFreeObjectParticle3, gObjectParticle3_SIZE); + s8 temp_v0_3; + Vec3s sp30; + if (objectIndex == NULL_OBJECT_ID) { + return; + //func_80077138(objectIndex, arg0, arg1); + } + + D_801658F4 = 1; + + init_object(objectIndex, D_801658F4); + gObjectList[objectIndex].unk_0D5 = 0x0C; + gObjectList[objectIndex].sizeScaling = 0.05f; + set_obj_origin_pos(objectIndex, pos.x, pos.y, pos.z); + set_obj_orientation(objectIndex, 0U, 0U, 0U); + set_obj_origin_offset(objectIndex, 0.0f, 0.0f, 0.0f); + switch (D_801658F4) { + case 0: + gObjectList[objectIndex].velocity[1] = -1.0f; + gObjectList[objectIndex].unk_034 = (f32) ((random_int(0x004BU) * 0.01) + 0.25); + gObjectList[objectIndex].direction_angle[1] = random_int(0x0040U) << 0xA; + func_8008751C(objectIndex); + gObjectList[objectIndex].unk_084[5] = 0x001E; + break; + case 1: + gObjectList[objectIndex].velocity[1] = 1.5f; + gObjectList[objectIndex].unk_034 = (f32) ((random_int(0x0064U) * 0.01) + 0.5); + gObjectList[objectIndex].direction_angle[1] = random_int(0x0040U) << 0xA; + func_8008751C(objectIndex); + gObjectList[objectIndex].unk_084[5] = 0x0032; + break; + } + temp_v0_3 = random_int(0x000CU); + if (temp_v0_3 < 9) { + func_8005C674(temp_v0_3, &sp30[2], &sp30[1], sp30); + gObjectList[objectIndex].unk_048 = 0; + gObjectList[objectIndex].unk_084[0] = sp30[2]; + gObjectList[objectIndex].unk_084[1] = sp30[1]; + gObjectList[objectIndex].unk_084[2] = sp30[0]; + } else { + temp_v0_3 = random_int(3U); + func_8005C6B4(temp_v0_3, &sp30[2], &sp30[1], sp30); + gObjectList[objectIndex].unk_084[0] = sp30[2]; + gObjectList[objectIndex].unk_084[1] = sp30[1]; + gObjectList[objectIndex].unk_084[2] = sp30[0]; + gObjectList[objectIndex].unk_084[4] = temp_v0_3; + gObjectList[objectIndex].unk_048 = 1; + } + gObjectList[objectIndex].primAlpha = 0x00FF; + gObjectList[objectIndex].unk_084[3] = random_int(0x0800U) + 0x400; + if ((gObjectList[objectIndex].direction_angle[1] < 0x3000) || + (gObjectList[objectIndex].direction_angle[1] >= 0xB001)) { + gObjectList[objectIndex].unk_084[3] = -gObjectList[objectIndex].unk_084[3]; + } +} + +void StarEmitter::Tick() { // func_80077640 + s32 someIndex; + s32 objectIndex; + Object* object; + + for (someIndex = 0; someIndex < gObjectParticle3_SIZE; someIndex++) { + objectIndex = gObjectParticle3[someIndex]; + if (objectIndex != DELETED_OBJECT_ID) { + object = &gObjectList[objectIndex]; + printf("Tick Star %d\n", object->state); + if (object->state != 0) { + StarEmitter::func_80077450(objectIndex); + StarEmitter::func_80077584(objectIndex); + if (object->state == 0) { + delete_object_wrapper(&gObjectParticle3[someIndex]); + } + } + } + } } void StarEmitter::Draw(s32 cameraId) { // func_80054BE8 @@ -22,10 +101,79 @@ void StarEmitter::Draw(s32 cameraId) { // func_80054BE8 load_texture_block_ia8_nomirror(D_8018D488, 0x00000020, 0x00000020); func_8004B35C(0x000000FF, 0x000000FF, 0, 0x000000FF); D_80183E80[0] = 0; + printf("Draw Star\n"); for (var_s0 = 0; var_s0 < gObjectParticle3_SIZE; var_s0++) { temp_a0 = gObjectParticle3[var_s0]; if ((temp_a0 != -1) && (gObjectList[temp_a0].state >= 2)) { - func_80054AFC(temp_a0, camera->pos); + StarEmitter::func_80054AFC(temp_a0, camera->pos); } } } + +void StarEmitter::func_80054AFC(s32 objectIndex, Vec3f arg1) { + printf("Drawing Star!\n"); + D_80183E80[0] = func_800418E8(gObjectList[objectIndex].pos[2], gObjectList[objectIndex].pos[1], arg1); + D_80183E80[1] = func_800418AC(gObjectList[objectIndex].pos[0], gObjectList[objectIndex].pos[2], arg1); + D_80183E80[2] = (u16) gObjectList[objectIndex].orientation[2]; + func_8004B138((s32) gObjectList[objectIndex].unk_084[0], (s32) gObjectList[objectIndex].unk_084[1], + (s32) gObjectList[objectIndex].unk_084[2], (s32) gObjectList[objectIndex].primAlpha); + rsp_set_matrix_transformation(gObjectList[objectIndex].pos, (u16*) D_80183E80, + gObjectList[objectIndex].sizeScaling); + gSPVertex(gDisplayListHead++, (uintptr_t)D_0D005AE0, 4, 0); + gSPDisplayList(gDisplayListHead++, (Gfx*)common_rectangle_display); +} + +void StarEmitter::func_80077428(s32 objectIndex) { + object_next_state(objectIndex); + func_80086E70(objectIndex); +} + +void StarEmitter::func_80077584(s32 objectIndex) { + Object* object; + + object = &gObjectList[objectIndex]; + if ((object->unk_0AE != 0) && (object->unk_0AE == 1) && ((u8) object->unk_0D8 != 0)) { + if (object->velocity[1] >= -0.5) { + object->velocity[1] -= 0.15; + } else { + object->velocity[2] = 0.0f; + object->velocity[0] = 0.0f; + } + } + object->orientation[2] += object->unk_084[3]; + object_add_velocity_offset_xyz(objectIndex); + object_calculate_new_pos_offset(objectIndex); +} + +void StarEmitter::func_80077450(s32 objectIndex) { + UNUSED s16 stackPadding0; + s16 sp3C; + s16 sp3A; + s16 sp38; + + switch (gObjectList[objectIndex].state) { + case 0: + break; + case 1: + StarEmitter::func_80077428(objectIndex); + break; + case 2: + f32_step_up_towards(&gObjectList[objectIndex].sizeScaling, 0.1f, 0.01f); + if ((gObjectList[objectIndex].pos[1] <= gObjectList[objectIndex].unk_084[5]) && + (func_80073B00(objectIndex, &gObjectList[objectIndex].primAlpha, 0x000000FF, 0, 0x00000010, 0, 0) != + 0)) { + func_80086F60(objectIndex); + func_80072428(objectIndex); + } + break; + } + if (gObjectList[objectIndex].unk_048 != 0) { + printf("SOME THING\n"); + + gObjectList[objectIndex].unk_084[4] = (s16) ((s32) (gObjectList[objectIndex].unk_084[4] + 1) % 3); + func_8005C6B4(gObjectList[objectIndex].unk_084[4], &sp3C, &sp3A, &sp38); + gObjectList[objectIndex].unk_084[0] = sp3C; + gObjectList[objectIndex].unk_084[1] = sp3A; + gObjectList[objectIndex].unk_084[2] = sp38; + } +} \ No newline at end of file diff --git a/src/engine/particles/StarEmitter.h b/src/engine/particles/StarEmitter.h index 20841598c..285c959f4 100644 --- a/src/engine/particles/StarEmitter.h +++ b/src/engine/particles/StarEmitter.h @@ -3,6 +3,7 @@ #include #include #include "ParticleEmitter.h" +#include "World.h" extern "C" { #include "macros.h" @@ -27,14 +28,14 @@ public: f32 Diameter = 0.0f; // Waddle in a circle around the spawn point at this diameter. uint16_t MirrorModeAngleOffset; - explicit StarEmitter(Vec3f pos); + explicit StarEmitter(FVector pos); virtual void Tick() override; virtual void Draw(s32 cameraId) override; - void func_80086700(s32 objectIndex); - void func_80086940(s32 objectIndex); - void func_80086C14(s32 objectIndex); - void func_80086C6C(s32 objectIndex); + void func_80077428(s32 objectIndex); + void func_80077584(s32 objectIndex); + void func_80077450(s32 objectIndex); + void func_80054AFC(s32 objectIndex, Vec3f arg1); private: diff --git a/src/main.c b/src/main.c index b932c7a12..ed98b5f3f 100644 --- a/src/main.c +++ b/src/main.c @@ -1205,7 +1205,7 @@ void update_gamestate(void) { case ENDING: gCurrentlyLoadedCourseId = COURSE_NULL; init_segment_ending_sequences(); - load_ceremony_cutscene(); + setup_podium_ceremony(); break; case CREDITS_SEQUENCE: gCurrentlyLoadedCourseId = COURSE_NULL; diff --git a/src/port/Game.cpp b/src/port/Game.cpp index d6cf9643c..90869508e 100644 --- a/src/port/Game.cpp +++ b/src/port/Game.cpp @@ -31,8 +31,11 @@ #include "engine/courses/PodiumCeremony.h" +#include "engine/GarbageCollector.h" + #include "engine/TrainCrossing.h" -#include "src/engine/objects/BombKart.h" +#include "engine/objects/BombKart.h" +#include "engine/objects/Lakitu.h" #include "Smoke.h" @@ -365,7 +368,7 @@ extern "C" { } } - void CourseManager_DrawActor(Camera* camera, struct Actor* actor) { + void CourseManager_DrawActors(Camera* camera, struct Actor* actor) { AActor* a = gWorldInstance.ConvertActorToAActor(actor); if (a->IsMod()) { a->Draw(camera); @@ -384,12 +387,32 @@ extern "C" { } } + // A couple objects such as lakitu are ticked inside of process_game_tick which support 60fps. + // This is a fallback to support that. + void CourseManager_TickObjects60fps() { + if (gWorldInstance.CurrentCourse) { + gWorldInstance.TickObjects60fps(); + } + } + void CourseManager_DrawObjects(s32 cameraId) { if (gWorldInstance.CurrentCourse) { gWorldInstance.DrawObjects(cameraId); } } + void CM_TickParticles() { + if (gWorldInstance.CurrentCourse) { + gWorldInstance.TickParticles(); + } + } + + void CM_DrawParticles(s32 cameraId) { + if (gWorldInstance.CurrentCourse) { + gWorldInstance.DrawParticles(cameraId); + } + } + // Helps prevents users from forgetting to add a finishline to their course bool cm_DoesFinishlineExist() { for (AActor* actor : gWorldInstance.Actors) { @@ -503,6 +526,50 @@ extern "C" { } } + /** + * This should only be ran once per course, otherwise animation/timings might become sped up. + */ + void CM_SpawnStarterLakitu() { + if ((gDemoMode) || (gGamestate == CREDITS_SEQUENCE)) { + return; + } + + for (size_t i = 0; i < gPlayerCountSelection1; i++) { + OLakitu* lakitu = new OLakitu(i, OLakitu::LakituType::STARTER); + gWorldInstance.Lakitus[i] = lakitu; + gWorldInstance.AddObject(lakitu); + } + } + + // Checkered flag lakitu + void CM_ActivateFinishLakitu(s32 playerId) { + if ((gDemoMode) || (gGamestate == CREDITS_SEQUENCE)) { + return; + } + gWorldInstance.Lakitus[playerId]->Activate(OLakitu::LakituType::FINISH); + } + + void CM_ActivateSecondLapLakitu(s32 playerId) { + if ((gDemoMode) || (gGamestate == CREDITS_SEQUENCE)) { + return; + } + gWorldInstance.Lakitus[playerId]->Activate(OLakitu::LakituType::SECOND_LAP); + } + + void CM_ActivateFinalLapLakitu(s32 playerId) { + if ((gDemoMode) || (gGamestate == CREDITS_SEQUENCE)) { + return; + } + gWorldInstance.Lakitus[playerId]->Activate(OLakitu::LakituType::FINAL_LAP); + } + + void CM_ActivateReverseLakitu(s32 playerId) { + if ((gDemoMode) || (gGamestate == CREDITS_SEQUENCE)) { + return; + } + gWorldInstance.Lakitus[playerId]->Activate(OLakitu::LakituType::REVERSE); + } + extern Vec3su D_80165834; void CourseManager_TickThwomps() { // TickLights @@ -614,8 +681,14 @@ extern "C" { } } - void m_ClearActors(void) { + /** + * Clean up actors and other game objects. + */ + void CM_CleanWorld(void) { gWorldInstance.Actors.clear(); + gWorldInstance.Objects.clear(); + gWorldInstance.Emitters.clear(); + gWorldInstance.Lakitus.clear(); } struct Actor* m_AddBaseActor(void) { @@ -737,6 +810,11 @@ extern "C" { void* GetBattleCup(void) { return gBattleCup; } + + // End of frame cleanup of actors, objects, etc. + void CM_RunGarbageCollector(void) { + RunGarbageCollector(); + } } void push_frame() { diff --git a/src/port/Game.h b/src/port/Game.h index 008d86ef7..76ae4ac2d 100644 --- a/src/port/Game.h +++ b/src/port/Game.h @@ -43,15 +43,25 @@ void CourseManager_RenderCredits(); void CourseManager_SpawnActors(); +void CM_SpawnStarterLakitu(); +void CM_ActivateFinishLakitu(s32 playerId); +void CM_ActivateSecondLapLakitu(s32 playerId); +void CM_ActivateFinalLapLakitu(s32 playerId); +void CM_ActivateReverseLakitu(s32 playerId); + bool cm_DoesFinishlineExist(); void CourseManager_InitClouds(); -void CourseManager_DrawActor(Camera* camera, struct Actor* actor); +void CourseManager_DrawActors(Camera* camera, struct Actor* actor); void CourseManager_TickObjects(); +void CourseManager_TickObjects60fps(); void CourseManager_DrawObjects(s32 cameraId); +void CM_TickParticles(void); +void CM_DrawParticles(s32 cameraId); + void CourseManager_UpdateClouds(s32 arg0, Camera* camera); void CourseManager_Waypoints(Player* player, int8_t playerId); @@ -149,7 +159,7 @@ struct Actor* m_AddBaseActor(void); size_t m_GetActorSize(); size_t m_FindActorIndex(struct Actor* actor); void m_ActorCollision(Player* player, struct Actor* actor); -void m_ClearActors(void); +void CM_CleanWorld(void); void* GetMarioRaceway(void); @@ -205,6 +215,8 @@ void* GetBattleCup(void); void* GetCup(); +void CM_RunGarbageCollector(void); + #ifdef __cplusplus } #endif diff --git a/src/racing/actors.c b/src/racing/actors.c index bc031a568..45330916c 100644 --- a/src/racing/actors.c +++ b/src/racing/actors.c @@ -1214,7 +1214,7 @@ void init_actors_and_load_textures(void) { init_red_shell_texture(); destroy_all_actors(); - m_ClearActors(); + CM_CleanWorld(); spawn_course_actors(); CourseManager_VehiclesSpawn(); @@ -2428,7 +2428,7 @@ void render_course_actors(struct UnkStruct_800DC5EC* arg0) { } switch (actor->type) { default: // Draw custom actor - CourseManager_DrawActor(D_800DC5EC->camera, actor); + CourseManager_DrawActors(D_800DC5EC->camera, actor); break; case ACTOR_TREE_MARIO_RACEWAY: render_actor_tree_mario_raceway(camera, sBillBoardMtx, actor); diff --git a/src/racing/memory.c b/src/racing/memory.c index 4538fd1ec..ac16e7b51 100644 --- a/src/racing/memory.c +++ b/src/racing/memory.c @@ -489,7 +489,7 @@ u8* dma_textures(const char* texture, size_t arg1, size_t arg2) { #ifdef TARGET_N64 temp_v0 = (u8*) gNextFreeMemoryAddress; #else - //u8* tex = (u8*) LOAD_ASSET(texture); + u8* tex = (u8*) LOAD_ASSET(texture); temp_v0 = (u8*) allocate_memory(arg2); #endif @@ -504,8 +504,8 @@ u8* dma_textures(const char* texture, size_t arg1, size_t arg2) { mio0decode((u8*) temp_a0, temp_v0); gNextFreeMemoryAddress += arg2; #else - //memcpy(temp_v0, tex, arg2); - strcpy(temp_v0, texture); + memcpy(temp_v0, tex, arg2); + //strcpy(temp_v0, texture); #endif return temp_v0; } @@ -1483,10 +1483,6 @@ uintptr_t texSegEnd; size_t texSegSize; Gfx* testaaa; -/** - * @brief Loads & DMAs course data. Vtx, textures, displaylists, etc. - * @param courseId - */ u8* load_lakitu_tlut_x64(const char** textureList, size_t length) { // Calculate lakitu texture size to allocate size_t size = 0; @@ -1498,7 +1494,7 @@ u8* load_lakitu_tlut_x64(const char** textureList, size_t length) { gNextFreeMemoryAddress += size; size_t offset = 0; for (size_t i = 0; i < length; i++) { - u8* tex = (u8*) LOAD_ASSET(textureList[i]); + u8* tex = (u8*) LOAD_ASSET_RAW(textureList[i]); size_t texSize = ResourceGetTexSizeByName(textureList[i]); // printf("\nTEX SIZE: %X\n\n", texSize); memcpy(&textures[offset], tex, texSize); @@ -1507,9 +1503,13 @@ u8* load_lakitu_tlut_x64(const char** textureList, size_t length) { return textures; } +/** + * @brief Loads & DMAs course data. Vtx, textures, displaylists, etc. + * @param courseId + */ void load_course(s32 courseId) { printf("Loading Course %d\n", courseId); gNextFreeMemoryAddress = gFreeMemoryResetAnchor; - m_ClearActors(); + CM_CleanWorld(); LoadCourse(); } diff --git a/src/racing/memory.h b/src/racing/memory.h index 9fbcd2e6d..8f4fbe2b5 100644 --- a/src/racing/memory.h +++ b/src/racing/memory.h @@ -42,7 +42,6 @@ struct AllocOnlyPool { extern f32 vtxStretchY; -u8* load_lakitu_textures_x64(const char** textureList, size_t length); u8* load_lakitu_tlut_x64(const char** textureList, size_t length); void* get_next_available_memory_addr(uintptr_t); uintptr_t set_segment_base_addr(s32, void*); diff --git a/src/racing/race_logic.c b/src/racing/race_logic.c index 025b50d79..655a8093b 100644 --- a/src/racing/race_logic.c +++ b/src/racing/race_logic.c @@ -904,7 +904,7 @@ void func_8028FCBC(void) { D_800DC510 = 2; D_800DC5B0 = 0; D_800DC5B8 = 1; - func_80078F64(); + CM_SpawnStarterLakitu(); // func_80078F64(); if ((gModeSelection == TIME_TRIALS) && (D_80162DD6 == 0)) { phi_v0_4 = 0x1; for (i = 0; i < gCurrentCourseId; i++) { diff --git a/src/render_objects.c b/src/render_objects.c index ac53334fa..f747f50d2 100644 --- a/src/render_objects.c +++ b/src/render_objects.c @@ -3836,18 +3836,6 @@ void render_object_smoke_particles(s32 cameraId) { } } -void func_80054AFC(s32 objectIndex, Vec3f arg1) { - D_80183E80[0] = func_800418E8(gObjectList[objectIndex].pos[2], gObjectList[objectIndex].pos[1], arg1); - D_80183E80[1] = func_800418AC(gObjectList[objectIndex].pos[0], gObjectList[objectIndex].pos[2], arg1); - D_80183E80[2] = (u16) gObjectList[objectIndex].orientation[2]; - func_8004B138((s32) gObjectList[objectIndex].unk_084[0], (s32) gObjectList[objectIndex].unk_084[1], - (s32) gObjectList[objectIndex].unk_084[2], (s32) gObjectList[objectIndex].primAlpha); - rsp_set_matrix_transformation(gObjectList[objectIndex].pos, (u16*) D_80183E80, - gObjectList[objectIndex].sizeScaling); - gSPVertex(gDisplayListHead++, D_0D005AE0, 4, 0); - gSPDisplayList(gDisplayListHead++, common_rectangle_display); -} - void func_80055164(s32 objectIndex) { if (gObjectList[objectIndex].state >= 2) { gSPDisplayList(gDisplayListHead++, D_0D0077A0); diff --git a/src/render_objects.h b/src/render_objects.h index ec95a0832..045262029 100644 --- a/src/render_objects.h +++ b/src/render_objects.h @@ -358,7 +358,6 @@ void render_object_bowser_flame_particle(s32, s32); void render_object_bowser_flame(s32); void func_8005477C(s32, u8, Vec3f); void render_object_smoke_particles(s32); -void func_80054AFC(s32, Vec3f); void func_80054D00(s32, s32); void func_80054E10(s32); void func_80054EB8(s32); @@ -381,7 +380,6 @@ void func_80055CCC(s32, s32); void render_object_hot_air_balloon(s32); void func_80055EF4(s32, s32); void func_80055F48(s32); -void func_80055FA0(s32, s32); void func_80056160(s32); void render_object_neon(s32); diff --git a/src/update_objects.c b/src/update_objects.c index ba56a65a5..148ba7b50 100644 --- a/src/update_objects.c +++ b/src/update_objects.c @@ -2206,160 +2206,6 @@ void init_smoke_particles(s32 arg0) { } } -void func_80077138(s32 objectIndex, Vec3f arg1, s32 arg2) { - s8 temp_v0_3; - Vec3s sp30; - - init_object(objectIndex, arg2); - gObjectList[objectIndex].unk_0D5 = 0x0C; - gObjectList[objectIndex].sizeScaling = 0.05f; - set_obj_origin_pos(objectIndex, arg1[0], arg1[1], arg1[2]); - set_obj_orientation(objectIndex, 0U, 0U, 0U); - set_obj_origin_offset(objectIndex, 0.0f, 0.0f, 0.0f); - switch (arg2) { - case 0: - gObjectList[objectIndex].velocity[1] = -1.0f; - gObjectList[objectIndex].unk_034 = (f32) ((random_int(0x004BU) * 0.01) + 0.25); - gObjectList[objectIndex].direction_angle[1] = random_int(0x0040U) << 0xA; - func_8008751C(objectIndex); - gObjectList[objectIndex].unk_084[5] = 0x001E; - break; - case 1: - gObjectList[objectIndex].velocity[1] = 1.5f; - gObjectList[objectIndex].unk_034 = (f32) ((random_int(0x0064U) * 0.01) + 0.5); - gObjectList[objectIndex].direction_angle[1] = random_int(0x0040U) << 0xA; - func_8008751C(objectIndex); - gObjectList[objectIndex].unk_084[5] = 0x0032; - break; - } - temp_v0_3 = random_int(0x000CU); - if (temp_v0_3 < 9) { - func_8005C674(temp_v0_3, &sp30[2], &sp30[1], sp30); - gObjectList[objectIndex].unk_048 = 0; - gObjectList[objectIndex].unk_084[0] = sp30[2]; - gObjectList[objectIndex].unk_084[1] = sp30[1]; - gObjectList[objectIndex].unk_084[2] = sp30[0]; - } else { - temp_v0_3 = random_int(3U); - func_8005C6B4(temp_v0_3, &sp30[2], &sp30[1], sp30); - gObjectList[objectIndex].unk_084[0] = sp30[2]; - gObjectList[objectIndex].unk_084[1] = sp30[1]; - gObjectList[objectIndex].unk_084[2] = sp30[0]; - gObjectList[objectIndex].unk_084[4] = temp_v0_3; - gObjectList[objectIndex].unk_048 = 1; - } - gObjectList[objectIndex].primAlpha = 0x00FF; - gObjectList[objectIndex].unk_084[3] = random_int(0x0800U) + 0x400; - if ((gObjectList[objectIndex].direction_angle[1] < 0x3000) || - (gObjectList[objectIndex].direction_angle[1] >= 0xB001)) { - gObjectList[objectIndex].unk_084[3] = -gObjectList[objectIndex].unk_084[3]; - } -} - -void func_800773D8(f32* arg0, s32 arg1) { - s32 objectIndex = add_unused_obj_index(gObjectParticle3, &gNextFreeObjectParticle3, gObjectParticle3_SIZE); - if (objectIndex != NULL_OBJECT_ID) { - func_80077138(objectIndex, arg0, arg1); - } -} - -void func_80077428(s32 arg0) { - object_next_state(arg0); - func_80086E70(arg0); -} - - - - - - - - - - - - - -void func_80077450(s32 objectIndex) { - UNUSED s16 stackPadding0; - s16 sp3C; - s16 sp3A; - s16 sp38; - - switch (gObjectList[objectIndex].state) { - case 0: - break; - case 1: - func_80077428(objectIndex); - break; - case 2: - f32_step_up_towards(&gObjectList[objectIndex].sizeScaling, 0.1f, 0.01f); - if ((gObjectList[objectIndex].pos[1] <= gObjectList[objectIndex].unk_084[5]) && - (func_80073B00(objectIndex, &gObjectList[objectIndex].primAlpha, 0x000000FF, 0, 0x00000010, 0, 0) != - 0)) { - func_80086F60(objectIndex); - func_80072428(objectIndex); - } - break; - } - if (gObjectList[objectIndex].unk_048 != 0) { - gObjectList[objectIndex].unk_084[4] = (s16) ((s32) (gObjectList[objectIndex].unk_084[4] + 1) % 3); - func_8005C6B4(gObjectList[objectIndex].unk_084[4], &sp3C, &sp3A, &sp38); - gObjectList[objectIndex].unk_084[0] = sp3C; - gObjectList[objectIndex].unk_084[1] = sp3A; - gObjectList[objectIndex].unk_084[2] = sp38; - } -} - -void func_80077584(s32 objectIndex) { - Object* object; - - object = &gObjectList[objectIndex]; - if ((object->unk_0AE != 0) && (object->unk_0AE == 1) && ((u8) object->unk_0D8 != 0)) { - if (object->velocity[1] >= -0.5) { - object->velocity[1] -= 0.15; - } else { - object->velocity[2] = 0.0f; - object->velocity[0] = 0.0f; - } - } - object->orientation[2] += object->unk_084[3]; - object_add_velocity_offset_xyz(objectIndex); - object_calculate_new_pos_offset(objectIndex); -} - -void func_80077640(void) { - s32 someIndex; - s32 objectIndex; - Object* object; - - for (someIndex = 0; someIndex < gObjectParticle3_SIZE; someIndex++) { - objectIndex = gObjectParticle3[someIndex]; - if (objectIndex != DELETED_OBJECT_ID) { - object = &gObjectList[objectIndex]; - if (object->state != 0) { - func_80077450(objectIndex); - func_80077584(objectIndex); - if (object->state == 0) { - delete_object_wrapper(&gObjectParticle3[someIndex]); - } - } - } - } -} - - - - - - - - - - - - - void init_object_leaf_particle(s32 objectIndex, Vec3f arg1, s32 num) { @@ -4375,54 +4221,6 @@ void func_8007DDC0(s32 objectIndex) { } } - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - void func_8007E1F4(s32 objectIndex) { f32 sp2C; Object* object; @@ -4555,34 +4353,6 @@ void func_8008153C(s32 objectIndex) { } } - - - - - - - - - - - - - - - - - - - - - - - - - - - - #ifdef NON_MATCHING // https://decomp.me/scratch/PYAg4 // Stack issue caused by the `test` variable, but removing it causes much, much larger differences diff --git a/src/update_objects.h b/src/update_objects.h index 50ef50919..8ac2848dd 100644 --- a/src/update_objects.h +++ b/src/update_objects.h @@ -160,9 +160,6 @@ void func_80076F2C(void); void init_object_smoke_particle2(s32, s32); void init_smoke_particles(s32); void func_800773D8(f32*, s32); -void func_80077428(s32); -void func_80077450(s32); -void func_80077584(s32); void func_80077640(void); void init_object_leaf_particle(s32, Vec3f, s32); s32 init_leaf_particle(Vec3f, s32); From e4737ce2f5bd75a3153dbe52684677964faa4ccc Mon Sep 17 00:00:00 2001 From: MegaMech Date: Sun, 29 Dec 2024 16:52:26 -0700 Subject: [PATCH 16/21] Impl Hedgehog and Flagpole --- .../update_objects/func_80082F1C.s | 4 +- include/objects.h | 2 +- src/data/some_data.c | 2 +- src/data/some_data.h | 2 +- src/engine/World.h | 16 ++ src/engine/courses/TestCourse.cpp | 11 +- src/engine/courses/YoshiValley.cpp | 59 +++-- src/engine/objects/Flagpole.cpp | 85 +++++++ src/engine/objects/Flagpole.h | 45 ++++ src/engine/objects/Hedgehog.cpp | 183 ++++++++++++++++ src/engine/objects/Hedgehog.h | 53 +++++ src/engine/objects/Seagull.cpp | 18 +- src/engine/objects/Seagull.h | 1 + src/engine/objects/Snowman.cpp | 49 ++++- src/engine/objects/Snowman.h | 2 + src/engine/particles/StarEmitter.cpp | 11 +- src/render_objects.c | 107 --------- src/render_objects.h | 6 - src/update_objects.c | 207 ------------------ src/update_objects.h | 5 - 20 files changed, 496 insertions(+), 372 deletions(-) create mode 100644 src/engine/objects/Flagpole.cpp create mode 100644 src/engine/objects/Flagpole.h create mode 100644 src/engine/objects/Hedgehog.cpp create mode 100644 src/engine/objects/Hedgehog.h diff --git a/asm/non_matchings/update_objects/func_80082F1C.s b/asm/non_matchings/update_objects/func_80082F1C.s index bc5df84bf..61ac0e470 100644 --- a/asm/non_matchings/update_objects/func_80082F1C.s +++ b/asm/non_matchings/update_objects/func_80082F1C.s @@ -28,8 +28,8 @@ glabel func_80082F1C /* 083B68 80082F68 0C01C922 */ jal object_next_state /* 083B6C 80082F6C E4440000 */ swc1 $f4, ($v0) /* 083B70 80082F70 8FA9002C */ lw $t1, 0x2c($sp) -/* 083B74 80082F74 3C0B800E */ lui $t3, %hi(D_800E5DF4) # $t3, 0x800e -/* 083B78 80082F78 256B5DF4 */ addiu $t3, %lo(D_800E5DF4) # addiu $t3, $t3, 0x5df4 +/* 083B74 80082F74 3C0B800E */ lui $t3, %hi(gFlagpoleSpawns) # $t3, 0x800e +/* 083B78 80082F78 256B5DF4 */ addiu $t3, %lo(gFlagpoleSpawns) # addiu $t3, $t3, 0x5df4 /* 083B7C 80082F7C 000950C0 */ sll $t2, $t1, 3 /* 083B80 80082F80 014B1021 */ addu $v0, $t2, $t3 /* 083B84 80082F84 844C0000 */ lh $t4, ($v0) diff --git a/include/objects.h b/include/objects.h index d4da8cd95..fecc902a3 100644 --- a/include/objects.h +++ b/include/objects.h @@ -223,7 +223,7 @@ typedef struct { /* 0x6 */ u16 rot; } YVFlagPoleSpawn; // size = 0x8; -extern YVFlagPoleSpawn D_800E5DF4[]; +extern YVFlagPoleSpawn gFlagpoleSpawns[]; #define NUM_CRABS 0xA diff --git a/src/data/some_data.c b/src/data/some_data.c index 431e60247..1a2acd086 100644 --- a/src/data/some_data.c +++ b/src/data/some_data.c @@ -439,7 +439,7 @@ s8 D_800E5DB4[] = { 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, }; -YVFlagPoleSpawn D_800E5DF4[] = { +YVFlagPoleSpawn gFlagpoleSpawns[] = { { { 0xfc7a, 0x0046, 0xfa82 }, 0x3800 }, { { 0xfc4c, 0x0046, 0xfa03 }, 0x3800 }, { { 0xf786, 0x0000, 0x02d3 }, 0x0400 }, diff --git a/src/data/some_data.h b/src/data/some_data.h index 90b9b13ac..6ee5272b0 100644 --- a/src/data/some_data.h +++ b/src/data/some_data.h @@ -50,7 +50,7 @@ extern SplineData D_800E5D78; extern SplineData* D_800E5D9C[]; extern SplineData* D_800E5DB0; extern s8 D_800E5DB4[]; -extern YVFlagPoleSpawn D_800E5DF4[]; +extern YVFlagPoleSpawn gFlagpoleSpawns[]; extern HegdehogSpawn gHedgehogSpawns[]; extern Vec3s gHedgehogPatrolPoints[]; extern SnowmanSpawn gSnowmanSpawns[]; diff --git a/src/engine/World.h b/src/engine/World.h index 3fa687e76..1aa09fb57 100644 --- a/src/engine/World.h +++ b/src/engine/World.h @@ -35,6 +35,22 @@ struct FVector { } }; +/** + * For providing X and Z when you do not need Y + * Some actors set themselves on the surface automatically + * which means it does not use a Y coordinate + * The train follows a set Y value. The hedgehog's patrolPoint only uses X and Z. + */ +struct FVector2D { + float x, z; + + FVector2D& operator=(const FVector2D& other) { + x = other.x; + z = other.z; + return *this; + } +}; + struct FRotation { float pitch, yaw, roll; diff --git a/src/engine/courses/TestCourse.cpp b/src/engine/courses/TestCourse.cpp index ce8d8ca62..3f95dc56b 100644 --- a/src/engine/courses/TestCourse.cpp +++ b/src/engine/courses/TestCourse.cpp @@ -18,6 +18,9 @@ #include "engine/objects/CheepCheep.h" #include "engine/objects/Snowman.h" #include "engine/objects/TrashBin.h" +#include "engine/objects/Hedgehog.h" +#include "engine/objects/Flagpole.h" +#include "engine/particles/StarEmitter.h" extern "C" { #include "main.h" @@ -201,8 +204,12 @@ void TestCourse::SpawnActors() { // gWorldInstance.AddActor(new OSeagull(3, pos)); // gWorldInstance.AddObject(new OCheepCheep(FVector(0, 40, 0), OCheepCheep::CheepType::RACE, IPathSpan(0, 10))); // gWorldInstance.AddObject(new OTrophy(FVector(0,0,0), OTrophy::TrophyType::GOLD, OTrophy::Behaviour::GO_FISH)); - gWorldInstance.AddObject(new OSnowman(FVector(0, 0, 0))); - gWorldInstance.AddObject(new OTrashBin(FVector(0.0f, 0.0f, 0.0f), FRotation(0, 90, 0), 1.0f)); + //gWorldInstance.AddObject(new OSnowman(FVector(0, 0, 0))); + //gWorldInstance.AddObject(new OTrashBin(FVector(0.0f, 0.0f, 0.0f), FRotation(0, 90, 0), 1.0f)); + +//gWorldInstance.AddEmitter(new StarEmitter(FVector(0,50,0))); + //gWorldInstance.AddObject(new OHedgehog(FVector(0, 0, 0), FVector2D(0, -200), 9)); + //gWorldInstance.AddObject(new OFlagpole(FVector(0, 0, -200), 0x400)); } // Likely sets minimap boundaries diff --git a/src/engine/courses/YoshiValley.cpp b/src/engine/courses/YoshiValley.cpp index 770e5ae1d..25c11daf8 100644 --- a/src/engine/courses/YoshiValley.cpp +++ b/src/engine/courses/YoshiValley.cpp @@ -7,6 +7,8 @@ #include "World.h" #include "engine/actors/AFinishline.h" #include "engine/objects/BombKart.h" +#include "engine/objects/Hedgehog.h" +#include "engine/objects/Flagpole.h" #include "assets/yoshi_valley_data.h" #include "assets/boo_frames.h" @@ -147,6 +149,30 @@ void YoshiValley::SpawnActors() { vec3f_set(position, -2300.0f, 0.0f, 634.0f); position[0] *= gCourseDirection; add_actor_to_empty_slot(position, rotation, velocity, ACTOR_YOSHI_EGG); + + if (gGamestate != CREDITS_SEQUENCE) { + //! @bug Skip spawning in credits due to animation crash for now + gWorldInstance.AddObject(new OFlagpole(FVector(-902, 70, -1406), 0x3800)); + gWorldInstance.AddObject(new OFlagpole(FVector(-948, 70, -1533), 0x3800)); + gWorldInstance.AddObject(new OFlagpole(FVector(-2170, 0, 723), 0x400)); + gWorldInstance.AddObject(new OFlagpole(FVector(-2193, 0, 761), 0x400)); + + gWorldInstance.AddObject(new OHedgehog(FVector(-1683, -80, -88), FVector2D(-1650, -114), 9)); + gWorldInstance.AddObject(new OHedgehog(FVector(-1636, -93, -147), FVector2D(-1661, -151), 9)); + gWorldInstance.AddObject(new OHedgehog(FVector(-1628, -86, -108), FVector2D(-1666, -58), 9)); + gWorldInstance.AddObject(new OHedgehog(FVector(-1676, -69, -30), FVector2D(-1651, -26), 9)); + gWorldInstance.AddObject(new OHedgehog(FVector(-1227, -27, -989), FVector2D(-1194, -999), 26)); + gWorldInstance.AddObject(new OHedgehog(FVector(-1261, -41, -880), FVector2D(-1213, -864), 26)); + gWorldInstance.AddObject(new OHedgehog(FVector(-1342, -60, -830), FVector2D(-1249, -927), 26)); + gWorldInstance.AddObject(new OHedgehog(FVector(-1429, -78, -849), FVector2D(-1347, -866), 26)); + gWorldInstance.AddObject(new OHedgehog(FVector(-1492, -94, -774), FVector2D(-1427, -891), 26)); + gWorldInstance.AddObject(new OHedgehog(FVector(-1453, -87, -784), FVector2D(-1509, -809), 26)); + gWorldInstance.AddObject(new OHedgehog(FVector(-1488, 89, -852), FVector2D(-1464, -822), 26)); + gWorldInstance.AddObject(new OHedgehog(FVector(-1301, 47, -904), FVector2D(-1537, -854), 26)); + gWorldInstance.AddObject(new OHedgehog(FVector(-2587, 56, -259), FVector2D(-2624, -241), 28)); + gWorldInstance.AddObject(new OHedgehog(FVector(-2493, 94, -454), FVector2D(-2505, -397), 28)); + gWorldInstance.AddObject(new OHedgehog(FVector(-2477, 3, -57), FVector2D(-2539, -66), 28)); + } } // Likely sets minimap boundaries @@ -158,31 +184,6 @@ 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); - } - if (gGamestate != CREDITS_SEQUENCE) { - for (i = 0; i < NUM_HEDGEHOGS; i++) { - objectId = indexObjectList2[i]; - init_object(objectId, 0); - gObjectList[objectId].pos[0] = gObjectList[objectId].origin_pos[0] = - gHedgehogSpawns[i].pos[0] * xOrientation; - gObjectList[objectId].pos[1] = gObjectList[objectId].surfaceHeight = - gHedgehogSpawns[i].pos[1] + 6.0; - gObjectList[objectId].pos[2] = gObjectList[objectId].origin_pos[2] = gHedgehogSpawns[i].pos[2]; - gObjectList[objectId].unk_0D5 = gHedgehogSpawns[i].unk_06; - gObjectList[objectId].unk_09C = gHedgehogPatrolPoints[i][0] * xOrientation; - gObjectList[objectId].unk_09E = gHedgehogPatrolPoints[i][2]; - } - } } void YoshiValley::SpawnVehicles() { @@ -210,17 +211,9 @@ void YoshiValley::SpawnVehicles() { } void YoshiValley::UpdateCourseObjects() { - func_80083080(); - if (gGamestate != CREDITS_SEQUENCE) { - update_hedgehogs(); - } } void YoshiValley::RenderCourseObjects(s32 cameraId) { - func_80055228(cameraId); - if (gGamestate != CREDITS_SEQUENCE) { - render_object_hedgehogs(cameraId); - } } void YoshiValley::SomeSounds() { diff --git a/src/engine/objects/Flagpole.cpp b/src/engine/objects/Flagpole.cpp new file mode 100644 index 000000000..682f74915 --- /dev/null +++ b/src/engine/objects/Flagpole.cpp @@ -0,0 +1,85 @@ +#include "Flagpole.h" +#include "World.h" + +extern "C" { +#include "code_800029B0.h" +#include "render_objects.h" +#include "update_objects.h" +#include "assets/yoshi_valley_data.h" +#include "assets/common_data.h" +#include "math_util.h" +#include "math_util_2.h" +#include "code_80086E70.h" +#include "code_80057C60.h" +} + +size_t OFlagpole::_count = 0; + +OFlagpole::OFlagpole(const FVector& pos, s16 direction) { + _idx = _count; + _pos = pos; + _direction = direction; + + init_object(indexObjectList1[_idx], 0); + + _count++; +} + +void OFlagpole::Tick() { // func_80083080 + s32 objectIndex = indexObjectList1[_idx]; + + if (gObjectList[objectIndex].state != 0) { + OFlagpole::func_80083018(objectIndex); + OFlagpole::func_80083060(objectIndex); + } +} + +void OFlagpole::Draw(s32 cameraId) { // func_80055228 + s32 objectIndex = indexObjectList1[_idx]; + + func_8008A364(objectIndex, cameraId, 0x4000U, 0x000005DC); + if (is_obj_flag_status_active(objectIndex, VISIBLE) != 0) { + OFlagpole::func_80055164(objectIndex); + } +} + +void OFlagpole::func_80055164(s32 objectIndex) { // func_80055164 + if (gObjectList[objectIndex].state >= 2) { + gSPDisplayList(gDisplayListHead++, (Gfx*)D_0D0077A0); + rsp_set_matrix_transformation(gObjectList[objectIndex].pos, gObjectList[objectIndex].direction_angle, + gObjectList[objectIndex].sizeScaling); + if (gIsGamePaused == 0) { + gObjectList[objectIndex].unk_0A2 = render_animated_model((Armature*) gObjectList[objectIndex].model, + (Animation**) gObjectList[objectIndex].vertex, 0, + gObjectList[objectIndex].unk_0A2); + } else { + render_animated_model((Armature*) gObjectList[objectIndex].model, + (Animation**) gObjectList[objectIndex].vertex, 0, gObjectList[objectIndex].unk_0A2); + } + } +} + +void OFlagpole::func_80082F1C(s32 objectIndex) { + gObjectList[objectIndex].model = (Gfx*) d_course_yoshi_valley_unk5; + gObjectList[objectIndex].vertex = (Vtx*) d_course_yoshi_valley_unk4; + gObjectList[objectIndex].sizeScaling = 0.027f; + object_next_state(objectIndex); + set_obj_origin_pos(objectIndex, _pos.x * xOrientation, _pos.y, _pos.z); + set_obj_origin_offset(objectIndex, 0.0f, 0.0f, 0.0f); + set_obj_direction_angle(objectIndex, 0U, _direction, 0U); +} + +void OFlagpole::func_80083018(s32 objectIndex) { + switch (gObjectList[objectIndex].state) { + case 1: + OFlagpole::func_80082F1C(objectIndex); + break; + case 0: + default: + break; + } +} + +void OFlagpole::func_80083060(s32 objectIndex) { + object_calculate_new_pos_offset(objectIndex); +} diff --git a/src/engine/objects/Flagpole.h b/src/engine/objects/Flagpole.h new file mode 100644 index 000000000..5824fcf18 --- /dev/null +++ b/src/engine/objects/Flagpole.h @@ -0,0 +1,45 @@ +#pragma once + +#include +#include +#include "Object.h" + +#include "World.h" + +extern "C" { +#include "macros.h" +#include "main.h" +#include "vehicles.h" +#include "waypoints.h" +#include "common_structs.h" +#include "objects.h" +#include "camera.h" +#include "some_data.h" +} + +class OFlagpole : public OObject { +public: + explicit OFlagpole(const FVector& pos, s16 direction); + + ~OFlagpole() { + _count--; + } + + static size_t GetCount() { + return _count; + } + + virtual void Tick() override; + virtual void Draw(s32 cameraId) override; + + void func_80055164(s32 objectIndex); + void func_80082F1C(s32 objectIndex); + void func_80083018(s32 objectIndex); + void func_80083060(s32 objectIndex); + +private: + FVector _pos; + s16 _direction; + static size_t _count; + size_t _idx; +}; diff --git a/src/engine/objects/Hedgehog.cpp b/src/engine/objects/Hedgehog.cpp new file mode 100644 index 000000000..133a1f38d --- /dev/null +++ b/src/engine/objects/Hedgehog.cpp @@ -0,0 +1,183 @@ +#include "Hedgehog.h" +#include "World.h" + +extern "C" { +#include "render_objects.h" +#include "update_objects.h" +#include "assets/yoshi_valley_data.h" +#include "assets/common_data.h" +#include "math_util.h" +#include "math_util_2.h" +#include "code_80086E70.h" +#include "code_80057C60.h" +} + +size_t OHedgehog::_count = 0; + +OHedgehog::OHedgehog(const FVector& pos, const FVector2D& patrolPoint, s16 unk) { + _idx = _count; + _pos = pos; + + s32 objectId = indexObjectList2[_idx]; + init_object(objectId, 0); + gObjectList[objectId].pos[0] = gObjectList[objectId].origin_pos[0] = pos.x * xOrientation; + gObjectList[objectId].pos[1] = gObjectList[objectId].surfaceHeight = pos.y + 6.0; + gObjectList[objectId].pos[2] = gObjectList[objectId].origin_pos[2] = pos.z; + gObjectList[objectId].unk_0D5 = (u8)unk; + gObjectList[objectId].unk_09C = patrolPoint.x * xOrientation; + gObjectList[objectId].unk_09E = patrolPoint.z; + + _count++; +} + +void OHedgehog::Tick() { + s32 objectIndex = indexObjectList2[_idx]; + + OHedgehog::func_800833D0(objectIndex, _idx); + OHedgehog::func_80083248(objectIndex); + OHedgehog::func_80083474(objectIndex); + + // This func clears a bit from all hedgehogs. This results in setting the height of all hedgehogs to zero. + // The solution is to only clear the bit from the current instance; `self` or `this` + //func_80072120(indexObjectList2, NUM_HEDGEHOGS); + clear_object_flag(objectIndex, 0x00600000); // The fix +} + +void OHedgehog::Draw(s32 cameraId) { + s32 objectIndex = indexObjectList2[_idx]; + u32 something = func_8008A364(objectIndex, cameraId, 0x4000U, 0x000003E8); + + if (CVarGetInteger("gNoCulling", 0) == 1) { + something = MIN(something, 0x52211U - 1); + } + if (is_obj_flag_status_active(objectIndex, VISIBLE) != 0) { + set_object_flag(objectIndex, 0x00200000); + if (something < 0x2711U) { + set_object_flag(objectIndex, 0x00000020); + } else { + clear_object_flag(objectIndex, 0x00000020); + } + if (something < 0x57E41U) { + set_object_flag(objectIndex, 0x00400000); + } + if (something < 0x52211U) { + OHedgehog::func_800555BC(objectIndex, cameraId); + } + } +} + +void OHedgehog::func_800555BC(s32 objectIndex, s32 cameraId) { + Camera* camera; + + if (gObjectList[objectIndex].state >= 2) { + camera = &camera1[cameraId]; + OHedgehog::func_8004A870(objectIndex, 0.7f); + gObjectList[objectIndex].orientation[1] = + func_800418AC(gObjectList[objectIndex].pos[0], gObjectList[objectIndex].pos[2], camera->pos); + draw_2d_texture_at(gObjectList[objectIndex].pos, gObjectList[objectIndex].orientation, + gObjectList[objectIndex].sizeScaling, (u8*) gObjectList[objectIndex].activeTLUT, + (u8*)gObjectList[objectIndex].activeTexture, gObjectList[objectIndex].vertex, 64, 64, 64, 32); + } +} + +void OHedgehog::func_8004A870(s32 objectIndex, f32 arg1) { + Mat4 mtx; + Object* object; + + if ((is_obj_flag_status_active(objectIndex, 0x00000020) != 0) && + (is_obj_flag_status_active(objectIndex, 0x00800000) != 0)) { + object = &gObjectList[objectIndex]; + D_80183E50[0] = object->pos[0]; + D_80183E50[1] = object->surfaceHeight + 0.8; + D_80183E50[2] = object->pos[2]; + set_transform_matrix(mtx, object->unk_01C, D_80183E50, 0U, arg1); + // convert_to_fixed_point_matrix(&gGfxPool->mtxHud[gMatrixHudCount], mtx); + // gSPMatrix(gDisplayListHead++, VIRTUAL_TO_PHYSICAL(&gGfxPool->mtxHud[gMatrixHudCount++]), + // G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + + AddHudMatrix(mtx, G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + gSPDisplayList(gDisplayListHead++, (Gfx*)D_0D007B98); + } +} + +const char* sHedgehogTexList[] = { d_course_yoshi_valley_hedgehog }; + +void OHedgehog::func_8008311C(s32 objectIndex, s32 arg1) { + Object* object; + Vtx* vtx = (Vtx*) LOAD_ASSET_RAW(common_vtx_hedgehog); + + init_texture_object(objectIndex, (u8*)d_course_yoshi_valley_hedgehog_tlut, sHedgehogTexList, 0x40U, (u16) 0x00000040); + object = &gObjectList[objectIndex]; + object->activeTLUT = d_course_yoshi_valley_hedgehog_tlut; + object->activeTexture = d_course_yoshi_valley_hedgehog; + object->vertex = vtx; + object->sizeScaling = 0.2f; + object->textureListIndex = 0; + object_next_state(objectIndex); + set_obj_origin_offset(objectIndex, 0.0f, 0.0f, 0.0f); + set_obj_orientation(objectIndex, 0U, 0U, 0x8000U); + object->unk_034 = ((arg1 % 6) * 0.1) + 0.5; + func_80086E70(objectIndex); + set_object_flag(objectIndex, 0x04000600); + object->boundingBoxSize = 2; +} + +void OHedgehog::func_80083248(s32 objectIndex) { + switch (gObjectList[objectIndex].unk_0AE) { + case 0: + break; + case 1: + if (func_80087A0C(objectIndex, gObjectList[objectIndex].origin_pos[0], gObjectList[objectIndex].unk_09C, + gObjectList[objectIndex].origin_pos[2], gObjectList[objectIndex].unk_09E) != 0) { + func_80086FD4(objectIndex); + } + break; + case 2: + func_800871AC(objectIndex, 0x0000003C); + break; + case 3: + if (func_80087A0C(objectIndex, gObjectList[objectIndex].unk_09C, gObjectList[objectIndex].origin_pos[0], + gObjectList[objectIndex].unk_09E, gObjectList[objectIndex].origin_pos[2]) != 0) { + func_80086FD4(objectIndex); + } + break; + case 4: + if (func_80087060(objectIndex, 0x0000003C) != 0) { + func_8008701C(objectIndex, 1); + } + break; + } + object_calculate_new_pos_offset(objectIndex); + if (is_obj_flag_status_active(objectIndex, 0x00200000) != 0) { + if (is_obj_flag_status_active(objectIndex, 0x00400000) != 0) { + func_8008861C(objectIndex); + } + gObjectList[objectIndex].pos[1] = gObjectList[objectIndex].surfaceHeight + 6.0; + } +} + +void OHedgehog::func_800833D0(s32 objectIndex, s32 arg1) { + switch (gObjectList[objectIndex].state) { + case 0: + break; + case 1: + OHedgehog::func_8008311C(objectIndex, arg1); + break; + case 2: + func_80072D3C(objectIndex, 0, 1, 4, -1); + break; + } + if (gObjectList[objectIndex].textureListIndex == 0) { + Vtx* vtx = (Vtx*) LOAD_ASSET_RAW(common_vtx_hedgehog); + gObjectList[objectIndex].vertex = vtx; + } else { + Vtx* vtx = (Vtx*) LOAD_ASSET_RAW(D_0D006130); + gObjectList[objectIndex].vertex = vtx; + } +} + +void OHedgehog::func_80083474(s32 objectIndex) { + if (gObjectList[objectIndex].state >= 2) { + func_80089F24(objectIndex); + } +} diff --git a/src/engine/objects/Hedgehog.h b/src/engine/objects/Hedgehog.h new file mode 100644 index 000000000..dab8cf15a --- /dev/null +++ b/src/engine/objects/Hedgehog.h @@ -0,0 +1,53 @@ +#pragma once + +#include +#include +#include "Object.h" + +#include "World.h" + +extern "C" { +#include "macros.h" +#include "main.h" +#include "vehicles.h" +#include "waypoints.h" +#include "common_structs.h" +#include "objects.h" +#include "camera.h" +#include "some_data.h" +} + +/** + * @arg pos FVector xyz spawn position + * @arg patrolPoint FVector2D xz patrol to location. Actor automatically calculates the Y value + * @arg unk unknown. Likely actor type. + */ +class OHedgehog : public OObject { +public: + explicit OHedgehog(const FVector& pos, const FVector2D& patrolPoint, s16 unk); + + ~OHedgehog() { + _count--; + } + + static size_t GetCount() { + return _count; + } + + virtual void Tick() override; + virtual void Draw(s32 cameraId) override; + + void func_800555BC(s32 objectIndex, s32 cameraId); + void func_8004A870(s32 objectIndex, f32 arg1); + + void func_8008311C(s32 objectIndex, s32 arg1); + void func_80083248(s32 objectIndex); + void func_800833D0(s32 objectIndex, s32 arg1); + void func_80083474(s32 objectIndex); + + +private: + FVector _pos; + static size_t _count; + size_t _idx; +}; diff --git a/src/engine/objects/Seagull.cpp b/src/engine/objects/Seagull.cpp index b641ab5b4..5f0b12a7e 100644 --- a/src/engine/objects/Seagull.cpp +++ b/src/engine/objects/Seagull.cpp @@ -124,11 +124,27 @@ void OSeagull::Draw(Camera* camera) { // render_object_seagulls _toggle = true; //} //if (is_obj_flag_status_active(var_s1, VISIBLE) != 0) { - func_800552BC(var_s1); + OSeagull::func_800552BC(var_s1); //} //} } +void OSeagull::func_800552BC(s32 objectIndex) { + if (gObjectList[objectIndex].state >= 2) { + rsp_set_matrix_transformation(gObjectList[objectIndex].pos, gObjectList[objectIndex].direction_angle, + gObjectList[objectIndex].sizeScaling); + gSPDisplayList(gDisplayListHead++, (Gfx*)D_0D0077D0); + if (gIsGamePaused == 0) { + gObjectList[objectIndex].unk_0A2 = render_animated_model((Armature*) gObjectList[objectIndex].model, + (Animation**) gObjectList[objectIndex].vertex, 0, + gObjectList[objectIndex].unk_0A2); + } else { + render_animated_model((Armature*) gObjectList[objectIndex].model, + (Animation**) gObjectList[objectIndex].vertex, 0, gObjectList[objectIndex].unk_0A2); + } + } +} + void OSeagull::func_8008275C(s32 objectIndex) { UNUSED s32 stackPadding; switch (gObjectList[objectIndex].unk_0DD) { diff --git a/src/engine/objects/Seagull.h b/src/engine/objects/Seagull.h index 798d25f8d..528da0708 100644 --- a/src/engine/objects/Seagull.h +++ b/src/engine/objects/Seagull.h @@ -26,6 +26,7 @@ public: virtual void Tick() override; virtual void Draw(Camera*) override; + void func_800552BC(s32 objectIndex); void func_8008275C(s32 objectIndex); void func_8008241C(s32 objectIndex, s32 arg1); diff --git a/src/engine/objects/Snowman.cpp b/src/engine/objects/Snowman.cpp index 93286845f..c05f464ef 100644 --- a/src/engine/objects/Snowman.cpp +++ b/src/engine/objects/Snowman.cpp @@ -17,8 +17,8 @@ static const char* sSnowmanHeadList[] = { d_course_frappe_snowland_snowman_head size_t OSnowman::_count = 0; OSnowman::OSnowman(const FVector& pos) { - _pos = pos; _idx = _count; + _pos = pos; s32 objectId = indexObjectList2[_idx]; init_object(objectId, 0); @@ -106,7 +106,7 @@ void OSnowman::func_800836F0(Vec3f pos) { if (objectIndex == NULL_OBJECT_ID) { break; } - func_80083538(objectIndex, pos, i, D_8018D3BC); + OSnowman::func_80083538(objectIndex, pos, i, D_8018D3BC); } } @@ -297,4 +297,47 @@ void OSnowman::func_80083B0C(s32 objectIndex) { gObjectList[objectIndex].boundingBoxSize = 2; gObjectList[objectIndex].unk_034 = 1.5f; set_object_flag(objectIndex, 0x04000210); -} \ No newline at end of file +} + + +void OSnowman::func_80083538(s32 objectIndex, Vec3f arg1, s32 arg2, s32 arg3) { + Object* object; + + init_object(objectIndex, 0); + object = &gObjectList[objectIndex]; + object->activeTexture = (const char*)d_course_frappe_snowland_snow; + object->textureList = (const char**)d_course_frappe_snowland_snow; + object->activeTLUT = d_course_frappe_snowland_snow_tlut; + object->tlutList = (u8*)d_course_frappe_snowland_snow_tlut; + object->sizeScaling = random_int(0x0064U); + object->sizeScaling = (object->sizeScaling * 0.001) + 0.05; + object->velocity[1] = random_int(0x0014U); + object->velocity[1] = (object->velocity[1] * 0.5) + 2.6; + object->unk_034 = random_int(0x000AU); + object->unk_034 = (object->unk_034 * 0.1) + 4.5; + object->direction_angle[1] = (arg2 << 0x10) / arg3; + object->origin_pos[0] = arg1[0]; + object->origin_pos[1] = arg1[1]; + object->origin_pos[2] = arg1[2]; + object->primAlpha = random_int(0x4000U) + 0x1000; +} + +void OSnowman::func_8008379C(s32 objectIndex) { + switch (gObjectList[objectIndex].state) { + case 0: + break; + case 1: + if (func_80087E08(objectIndex, gObjectList[objectIndex].velocity[1], 0.74f, + gObjectList[objectIndex].unk_034, gObjectList[objectIndex].direction_angle[1], + 0x00000064) != 0) { + object_next_state(objectIndex); + } + break; + case 2: + func_80086F60(objectIndex); + func_80072428(objectIndex); + break; + } + object_calculate_new_pos_offset(objectIndex); + gObjectList[objectIndex].orientation[2] += gObjectList[objectIndex].primAlpha; +} diff --git a/src/engine/objects/Snowman.h b/src/engine/objects/Snowman.h index cd2c09244..e3e2a0138 100644 --- a/src/engine/objects/Snowman.h +++ b/src/engine/objects/Snowman.h @@ -43,6 +43,8 @@ public: void func_80083BE4(s32); void func_800836F0(Vec3f); bool func_80073D0C(s32 objectIndex, s16* arg1, s32 arg2, s32 arg3, s32 arg4, s32 arg5, s32 arg6); + void func_80083538(s32 objectIndex, Vec3f arg1, s32 arg2, s32 arg3); + void func_8008379C(s32 objectIndex); private: diff --git a/src/engine/particles/StarEmitter.cpp b/src/engine/particles/StarEmitter.cpp index 14745d39a..e700b4c8c 100644 --- a/src/engine/particles/StarEmitter.cpp +++ b/src/engine/particles/StarEmitter.cpp @@ -17,6 +17,11 @@ StarEmitter::StarEmitter(FVector pos) { s8 temp_v0_3; Vec3s sp30; + for (size_t i = 0; i < D_80165738; i++) { + find_unused_obj_index(&gObjectParticle3[i]); + init_object(gObjectParticle3[i], 0); + } + if (objectIndex == NULL_OBJECT_ID) { return; //func_80077138(objectIndex, arg0, arg1); @@ -84,7 +89,7 @@ void StarEmitter::Tick() { // func_80077640 StarEmitter::func_80077450(objectIndex); StarEmitter::func_80077584(objectIndex); if (object->state == 0) { - delete_object_wrapper(&gObjectParticle3[someIndex]); + //delete_object_wrapper(&gObjectParticle3[someIndex]); } } } @@ -101,10 +106,10 @@ void StarEmitter::Draw(s32 cameraId) { // func_80054BE8 load_texture_block_ia8_nomirror(D_8018D488, 0x00000020, 0x00000020); func_8004B35C(0x000000FF, 0x000000FF, 0, 0x000000FF); D_80183E80[0] = 0; - printf("Draw Star\n"); for (var_s0 = 0; var_s0 < gObjectParticle3_SIZE; var_s0++) { temp_a0 = gObjectParticle3[var_s0]; if ((temp_a0 != -1) && (gObjectList[temp_a0].state >= 2)) { + printf("Draw Star\n"); StarEmitter::func_80054AFC(temp_a0, camera->pos); } } @@ -163,7 +168,7 @@ void StarEmitter::func_80077450(s32 objectIndex) { (func_80073B00(objectIndex, &gObjectList[objectIndex].primAlpha, 0x000000FF, 0, 0x00000010, 0, 0) != 0)) { func_80086F60(objectIndex); - func_80072428(objectIndex); + //func_80072428(objectIndex); } break; } diff --git a/src/render_objects.c b/src/render_objects.c index f747f50d2..35a1ec775 100644 --- a/src/render_objects.c +++ b/src/render_objects.c @@ -1361,26 +1361,6 @@ void func_8004A7AC(s32 objectIndex, f32 arg1) { } } -void func_8004A870(s32 objectIndex, f32 arg1) { - Mat4 mtx; - Object* object; - - if ((is_obj_flag_status_active(objectIndex, 0x00000020) != 0) && - (is_obj_flag_status_active(objectIndex, 0x00800000) != 0)) { - object = &gObjectList[objectIndex]; - D_80183E50[0] = object->pos[0]; - D_80183E50[1] = object->surfaceHeight + 0.8; - D_80183E50[2] = object->pos[2]; - set_transform_matrix(mtx, object->unk_01C, D_80183E50, 0U, arg1); - // convert_to_fixed_point_matrix(&gGfxPool->mtxHud[gMatrixHudCount], mtx); - // gSPMatrix(gDisplayListHead++, VIRTUAL_TO_PHYSICAL(&gGfxPool->mtxHud[gMatrixHudCount++]), - // G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); - - AddHudMatrix(mtx, G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); - gSPDisplayList(gDisplayListHead++, D_0D007B98); - } -} - void func_8004A9B8(f32 arg0) { rsp_set_matrix_transl_rot_scale(D_80183E50, D_80183E70, arg0); gSPDisplayList(gDisplayListHead++, D_0D007C10); @@ -3836,93 +3816,6 @@ void render_object_smoke_particles(s32 cameraId) { } } -void func_80055164(s32 objectIndex) { - if (gObjectList[objectIndex].state >= 2) { - gSPDisplayList(gDisplayListHead++, D_0D0077A0); - rsp_set_matrix_transformation(gObjectList[objectIndex].pos, gObjectList[objectIndex].direction_angle, - gObjectList[objectIndex].sizeScaling); - if (gIsGamePaused == 0) { - gObjectList[objectIndex].unk_0A2 = render_animated_model((Armature*) gObjectList[objectIndex].model, - (Animation**) gObjectList[objectIndex].vertex, 0, - gObjectList[objectIndex].unk_0A2); - } else { - render_animated_model((Armature*) gObjectList[objectIndex].model, - (Animation**) gObjectList[objectIndex].vertex, 0, gObjectList[objectIndex].unk_0A2); - } - } -} - -void func_80055228(s32 cameraId) { - s32 var_s1; - s32 temp_s0; - - for (var_s1 = 0; var_s1 < 4; var_s1++) { - temp_s0 = indexObjectList1[var_s1]; - func_8008A364(temp_s0, cameraId, 0x4000U, 0x000005DC); - if (is_obj_flag_status_active(temp_s0, VISIBLE) != 0) { - func_80055164(temp_s0); - } - } -} - -void func_800552BC(s32 objectIndex) { - if (gObjectList[objectIndex].state >= 2) { - rsp_set_matrix_transformation(gObjectList[objectIndex].pos, gObjectList[objectIndex].direction_angle, - gObjectList[objectIndex].sizeScaling); - gSPDisplayList(gDisplayListHead++, D_0D0077D0); - if (gIsGamePaused == 0) { - gObjectList[objectIndex].unk_0A2 = render_animated_model((Armature*) gObjectList[objectIndex].model, - (Animation**) gObjectList[objectIndex].vertex, 0, - gObjectList[objectIndex].unk_0A2); - } else { - render_animated_model((Armature*) gObjectList[objectIndex].model, - (Animation**) gObjectList[objectIndex].vertex, 0, gObjectList[objectIndex].unk_0A2); - } - } -} - -void func_800555BC(s32 objectIndex, s32 cameraId) { - Camera* camera; - - if (gObjectList[objectIndex].state >= 2) { - camera = &camera1[cameraId]; - func_8004A870(objectIndex, 0.7f); - gObjectList[objectIndex].orientation[1] = - func_800418AC(gObjectList[objectIndex].pos[0], gObjectList[objectIndex].pos[2], camera->pos); - draw_2d_texture_at(gObjectList[objectIndex].pos, gObjectList[objectIndex].orientation, - gObjectList[objectIndex].sizeScaling, (u8*) gObjectList[objectIndex].activeTLUT, - gObjectList[objectIndex].activeTexture, gObjectList[objectIndex].vertex, 64, 64, 64, 32); - } -} - -void render_object_hedgehogs(s32 arg0) { - s32 test; - u32 something; - s32 someIndex; - - for (someIndex = 0; someIndex < NUM_HEDGEHOGS; someIndex++) { - test = indexObjectList2[someIndex]; - something = func_8008A364(test, arg0, 0x4000U, 0x000003E8); - if (CVarGetInteger("gNoCulling", 0) == 1) { - something = MIN(something, 0x52211U - 1); - } - if (is_obj_flag_status_active(test, VISIBLE) != 0) { - set_object_flag(test, 0x00200000); - if (something < 0x2711U) { - set_object_flag(test, 0x00000020); - } else { - clear_object_flag(test, 0x00000020); - } - if (something < 0x57E41U) { - set_object_flag(test, 0x00400000); - } - if (something < 0x52211U) { - func_800555BC(test, arg0); - } - } - } -} - UNUSED void func_800557AC() { } diff --git a/src/render_objects.h b/src/render_objects.h index 045262029..ed14fb684 100644 --- a/src/render_objects.h +++ b/src/render_objects.h @@ -170,7 +170,6 @@ void func_8004A5E4(Vec3f, Vec3su, f32, u8*, Vtx*); void func_8004A630(Collision*, Vec3f, f32); void func_8004A6EC(s32, f32); void func_8004A7AC(s32, f32); -void func_8004A870(s32, f32); void func_8004A9B8(f32); void func_8004AA10(Vec3f, Vec3su, f32, u8*, Vtx*, s32, s32, s32, s32); void func_8004AAA0(s32, s32, u16, f32, u8*, Vtx*); @@ -242,7 +241,6 @@ void func_8004CD18(s32, s32, u8*); void func_8004CF9C(s32, s32, u8*, s32, s32, s32, s32); void func_8004CFF0(s32, s32, u8*, s32, s32, s32, s32); -void func_800552BC(s32); void func_800450C8(u8*, s32, s32); void func_80044F34(u8*, s32, s32); void func_8004D044(s32, s32, u8*, s32, s32, s32, s32, s32, s32, s32, s32); @@ -364,13 +362,9 @@ void func_80054EB8(s32); void func_80054F04(s32); void render_object_moles(s32); -void func_80055164(s32); void func_80055228(s32); -void func_800552BC(s32); void render_object_seagulls(s32); void render_object_crabs(s32); -void func_800555BC(s32, s32); -void render_object_hedgehogs(s32); void func_800557AC(void); void func_800557B4(s32, u32, u32); void render_object_train_penguins(s32); diff --git a/src/update_objects.c b/src/update_objects.c index 148ba7b50..80edaaf19 100644 --- a/src/update_objects.c +++ b/src/update_objects.c @@ -4353,213 +4353,6 @@ void func_8008153C(s32 objectIndex) { } } -#ifdef NON_MATCHING -// https://decomp.me/scratch/PYAg4 -// Stack issue caused by the `test` variable, but removing it causes much, much larger differences -//! @todo Fix flag animations -void func_80082F1C(s32 objectIndex, s32 arg1) { - YVFlagPoleSpawn* test; - gObjectList[objectIndex].model = (Gfx*) d_course_yoshi_valley_unk5; - gObjectList[objectIndex].vertex = (Vtx*) d_course_yoshi_valley_unk4; - gObjectList[objectIndex].sizeScaling = 0.027f; - // if (test->rot && test->rot) {} - test = &D_800E5DF4[arg1]; - object_next_state(objectIndex); - set_obj_origin_pos(objectIndex, test->pos[0] * xOrientation, test->pos[1], test->pos[2]); - set_obj_origin_offset(objectIndex, 0.0f, 0.0f, 0.0f); - set_obj_direction_angle(objectIndex, 0U, test->rot, 0U); -} -#else -GLOBAL_ASM("asm/non_matchings/update_objects/func_80082F1C.s") -#endif - -void func_80083018(s32 objectIndex, s32 arg1) { - switch (gObjectList[objectIndex].state) { - case 1: - func_80082F1C(objectIndex, arg1); - break; - case 0: - default: - break; - } -} - -void func_80083060(s32 objectIndex) { - object_calculate_new_pos_offset(objectIndex); -} - -void func_80083080(void) { - s32 objectIndex; - s32 var_s1; - - for (var_s1 = 0; var_s1 < NUM_YV_FLAG_POLES; var_s1++) { - objectIndex = indexObjectList1[var_s1]; - if (gObjectList[objectIndex].state != 0) { - func_80083018(objectIndex, var_s1); - func_80083060(objectIndex); - } - } -} - -const char* sHedgehogTexList[] = { d_course_yoshi_valley_hedgehog }; - -void func_8008311C(s32 objectIndex, s32 arg1) { - Object* object; - Vtx* vtx = (Vtx*) LOAD_ASSET(common_vtx_hedgehog); - - init_texture_object(objectIndex, d_course_yoshi_valley_hedgehog_tlut, sHedgehogTexList, 0x40U, (u16) 0x00000040); - object = &gObjectList[objectIndex]; - object->activeTLUT = d_course_yoshi_valley_hedgehog_tlut; - object->activeTexture = d_course_yoshi_valley_hedgehog; - object->vertex = vtx; - object->sizeScaling = 0.2f; - object->textureListIndex = 0; - object_next_state(objectIndex); - set_obj_origin_offset(objectIndex, 0.0f, 0.0f, 0.0f); - set_obj_orientation(objectIndex, 0U, 0U, 0x8000U); - object->unk_034 = ((arg1 % 6) * 0.1) + 0.5; - func_80086E70(objectIndex); - set_object_flag(objectIndex, 0x04000600); - object->boundingBoxSize = 2; -} - -void func_80083248(s32 objectIndex) { - switch (gObjectList[objectIndex].unk_0AE) { - case 0: - break; - case 1: - if (func_80087A0C(objectIndex, gObjectList[objectIndex].origin_pos[0], gObjectList[objectIndex].unk_09C, - gObjectList[objectIndex].origin_pos[2], gObjectList[objectIndex].unk_09E) != 0) { - func_80086FD4(objectIndex); - } - break; - case 2: - func_800871AC(objectIndex, 0x0000003C); - break; - case 3: - if (func_80087A0C(objectIndex, gObjectList[objectIndex].unk_09C, gObjectList[objectIndex].origin_pos[0], - gObjectList[objectIndex].unk_09E, gObjectList[objectIndex].origin_pos[2]) != 0) { - func_80086FD4(objectIndex); - } - break; - case 4: - if (func_80087060(objectIndex, 0x0000003C) != 0) { - func_8008701C(objectIndex, 1); - } - break; - } - object_calculate_new_pos_offset(objectIndex); - if (is_obj_flag_status_active(objectIndex, 0x00200000) != 0) { - if (is_obj_flag_status_active(objectIndex, 0x00400000) != 0) { - func_8008861C(objectIndex); - } - gObjectList[objectIndex].pos[1] = gObjectList[objectIndex].surfaceHeight + 6.0; - } -} - -void func_800833D0(s32 objectIndex, s32 arg1) { - switch (gObjectList[objectIndex].state) { /* irregular */ - case 0: - break; - case 1: - func_8008311C(objectIndex, arg1); - break; - case 2: - func_80072D3C(objectIndex, 0, 1, 4, -1); - break; - } - if (gObjectList[objectIndex].textureListIndex == 0) { - Vtx* vtx = (Vtx*) LOAD_ASSET(common_vtx_hedgehog); - gObjectList[objectIndex].vertex = vtx; - } else { - Vtx* vtx = (Vtx*) LOAD_ASSET(D_0D006130); - gObjectList[objectIndex].vertex = vtx; - } -} - -void func_80083474(s32 objectIndex) { - if (gObjectList[objectIndex].state >= 2) { - func_80089F24(objectIndex); - } -} - -void update_hedgehogs(void) { - s32 temp_s1; - s32 var_s0; - - for (var_s0 = 0; var_s0 < NUM_HEDGEHOGS; var_s0++) { - temp_s1 = indexObjectList2[var_s0]; - func_800833D0(temp_s1, var_s0); - func_80083248(temp_s1); - func_80083474(temp_s1); - } - func_80072120(indexObjectList2, 0x0000000F); -} - -void func_80083538(s32 objectIndex, Vec3f arg1, s32 arg2, s32 arg3) { - Object* object; - - init_object(objectIndex, 0); - object = &gObjectList[objectIndex]; - object->activeTexture = d_course_frappe_snowland_snow; - object->textureList = d_course_frappe_snowland_snow; - object->activeTLUT = d_course_frappe_snowland_snow_tlut; - object->tlutList = d_course_frappe_snowland_snow_tlut; - object->sizeScaling = random_int(0x0064U); - object->sizeScaling = (object->sizeScaling * 0.001) + 0.05; - object->velocity[1] = random_int(0x0014U); - object->velocity[1] = (object->velocity[1] * 0.5) + 2.6; - object->unk_034 = random_int(0x000AU); - object->unk_034 = (object->unk_034 * 0.1) + 4.5; - object->direction_angle[1] = (arg2 << 0x10) / arg3; - object->origin_pos[0] = arg1[0]; - object->origin_pos[1] = arg1[1]; - object->origin_pos[2] = arg1[2]; - object->primAlpha = random_int(0x4000U) + 0x1000; -} - -void func_8008379C(s32 objectIndex) { - switch (gObjectList[objectIndex].state) { - case 0: - break; - case 1: - if (func_80087E08(objectIndex, gObjectList[objectIndex].velocity[1], 0.74f, - gObjectList[objectIndex].unk_034, gObjectList[objectIndex].direction_angle[1], - 0x00000064) != 0) { - object_next_state(objectIndex); - } - break; - case 2: - func_80086F60(objectIndex); - func_80072428(objectIndex); - break; - } - object_calculate_new_pos_offset(objectIndex); - gObjectList[objectIndex].orientation[2] += gObjectList[objectIndex].primAlpha; -} - -static const char* sSnowmanHeadList[] = { d_course_frappe_snowland_snowman_head }; - -void func_80083868(s32 objectIndex) { - Object* object; - Vtx* vtx = (Vtx*) LOAD_ASSET(D_0D0061B0); - init_texture_object(objectIndex, d_course_frappe_snowland_snowman_tlut, sSnowmanHeadList, 0x40U, (u16) 0x00000040); - object = &gObjectList[objectIndex]; - object->vertex = vtx; - object->sizeScaling = 0.1f; - object->textureListIndex = 0; - object_next_state(objectIndex); - set_obj_origin_offset(objectIndex, 0.0f, 0.0f, 0.0f); - object->orientation[0] = 0; - object->orientation[1] = 0; - object->orientation[2] = 0x8000; - object->primAlpha = random_int(0x2000U) - 0x1000; - func_80086E70(objectIndex); - object->unk_034 = 1.5f; - set_object_flag(objectIndex, 0x00000200); -} - - void func_80083F18(s32 objectIndex) { switch (gObjectList[objectIndex].state) { case 0: diff --git a/src/update_objects.h b/src/update_objects.h index 8ac2848dd..9e3cd61b7 100644 --- a/src/update_objects.h +++ b/src/update_objects.h @@ -304,16 +304,11 @@ void func_80082B34(s32, s32); void func_80082C30(s32); void func_80082E18(s32); void update_crabs(void); -void func_80082F1C(s32, s32); -void func_80083018(s32, s32); -void func_80083060(s32); void func_80083080(void); void func_8008311C(s32, s32); void func_80083248(s32); void func_800833D0(s32, s32); void func_80083474(s32); -void update_hedgehogs(void); -void func_80083538(s32, Vec3f, s32, s32); void func_8008379C(s32); void func_80083868(s32); void func_80083948(s32); From 64b9dcbb30c5007466c14da7d78d081189810308 Mon Sep 17 00:00:00 2001 From: MegaMech Date: Sun, 29 Dec 2024 20:19:59 -0700 Subject: [PATCH 17/21] impl hot air balloon --- src/engine/courses/LuigiRaceway.cpp | 16 +-- src/engine/courses/TestCourse.cpp | 2 + src/engine/objects/HotAirBalloon.cpp | 174 +++++++++++++++++++++++++++ src/engine/objects/HotAirBalloon.h | 34 ++++++ src/render_objects.c | 44 ------- src/render_objects.h | 2 - src/update_objects.c | 96 --------------- 7 files changed, 218 insertions(+), 150 deletions(-) create mode 100644 src/engine/objects/HotAirBalloon.cpp create mode 100644 src/engine/objects/HotAirBalloon.h diff --git a/src/engine/courses/LuigiRaceway.cpp b/src/engine/courses/LuigiRaceway.cpp index 7740ebf49..6020b72d1 100644 --- a/src/engine/courses/LuigiRaceway.cpp +++ b/src/engine/courses/LuigiRaceway.cpp @@ -7,6 +7,7 @@ #include "World.h" #include "engine/objects/BombKart.h" #include "assets/luigi_raceway_data.h" +#include "engine/objects/HotAirBalloon.h" #include "engine/actors/AFinishline.h" extern "C" { @@ -168,6 +169,12 @@ void LuigiRaceway::SpawnActors() { gWorldInstance.AddActor(new AFinishline()); spawn_foliage((struct ActorSpawnData*)LOAD_ASSET_RAW(d_course_luigi_raceway_tree_spawn)); spawn_all_item_boxes((struct ActorSpawnData*)LOAD_ASSET_RAW(d_course_luigi_raceway_item_box_spawns)); + + if (gGamestate == CREDITS_SEQUENCE) { + gWorldInstance.AddObject(new OHotAirBalloon(FVector(-1250.0f, 0.0f, 1110.0f))); + } else { // Normal gameplay + gWorldInstance.AddObject(new OHotAirBalloon(FVector(-176.0, 0.0f, -2323.0f))); + } } void LuigiRaceway::SpawnVehicles() { @@ -202,8 +209,7 @@ void LuigiRaceway::InitCourseObjects() { if (gModeSelection == GRAND_PRIX) { func_80070714(); } - D_80165898 = 0; - init_object(indexObjectList1[0], 0); + for (i = 0; i < D_80165738; i++) { find_unused_obj_index(&gObjectParticle3[i]); init_object(gObjectParticle3[i], 0); @@ -212,15 +218,9 @@ void LuigiRaceway::InitCourseObjects() { } void LuigiRaceway::UpdateCourseObjects() { - if (D_80165898 != 0) { - update_hot_air_balloon(); - } } void LuigiRaceway::RenderCourseObjects(s32 cameraId) { - if (D_80165898 != 0) { - render_object_hot_air_balloon(cameraId); - } } void LuigiRaceway::SomeSounds() { diff --git a/src/engine/courses/TestCourse.cpp b/src/engine/courses/TestCourse.cpp index 3f95dc56b..40b03059e 100644 --- a/src/engine/courses/TestCourse.cpp +++ b/src/engine/courses/TestCourse.cpp @@ -20,6 +20,7 @@ #include "engine/objects/TrashBin.h" #include "engine/objects/Hedgehog.h" #include "engine/objects/Flagpole.h" +#include "engine/objects/HotAirBalloon.h" #include "engine/particles/StarEmitter.h" extern "C" { @@ -210,6 +211,7 @@ void TestCourse::SpawnActors() { //gWorldInstance.AddEmitter(new StarEmitter(FVector(0,50,0))); //gWorldInstance.AddObject(new OHedgehog(FVector(0, 0, 0), FVector2D(0, -200), 9)); //gWorldInstance.AddObject(new OFlagpole(FVector(0, 0, -200), 0x400)); + gWorldInstance.AddObject(new OHotAirBalloon(FVector(0.0, 20.0f, -200.0f))); } // Likely sets minimap boundaries diff --git a/src/engine/objects/HotAirBalloon.cpp b/src/engine/objects/HotAirBalloon.cpp new file mode 100644 index 000000000..234eef6d9 --- /dev/null +++ b/src/engine/objects/HotAirBalloon.cpp @@ -0,0 +1,174 @@ +#include "HotAirBalloon.h" +#include "World.h" +#include "port/Game.h" + +extern "C" { +#include "render_objects.h" +#include "update_objects.h" +#include "assets/luigi_raceway_data.h" +#include "assets/common_data.h" +#include "math_util.h" +#include "math_util_2.h" +#include "code_80086E70.h" +#include "code_80057C60.h" +#include "actors.h" +} + +OHotAirBalloon::OHotAirBalloon(const FVector& pos) { + _pos = pos; + + D_80165898 = 0; + + // Spawn balloon on second lap. + if (GetCourse() == GetLuigiRaceway()) { + _visible = (bool*)&D_80165898; + } else { // Spawn balloon on race start + bool mod = true; + _visible = &mod; + } + + init_object(indexObjectList1[0], 0); +} + +void OHotAirBalloon::Tick() { + s32 objectIndex = indexObjectList1[0]; + + if (*_visible) { + if (gObjectList[objectIndex].state != 0) { + OHotAirBalloon::func_80085768(objectIndex); + OHotAirBalloon::func_80085534(objectIndex); + object_calculate_new_pos_offset(objectIndex); + if (gObjectList[objectIndex].state >= 2) { + gActorHotAirBalloonItemBox->pos[0] = gObjectList[objectIndex].pos[0]; + gActorHotAirBalloonItemBox->pos[1] = gObjectList[objectIndex].pos[1] - 10.0; + gActorHotAirBalloonItemBox->pos[2] = gObjectList[objectIndex].pos[2]; + } + } + } +} + +void OHotAirBalloon::Draw(s32 cameraId) { + s32 objectIndex; + objectIndex = indexObjectList1[0]; + if (*_visible) { + if (gGamestate != CREDITS_SEQUENCE) { + func_8008A1D0(objectIndex, cameraId, 0x000005DC, 0x00000BB8); + if (is_obj_flag_status_active(objectIndex, VISIBLE) != 0) { + OHotAirBalloon::func_80055CCC(objectIndex, cameraId); + } + } else { + clear_object_flag(objectIndex, 0x00100000); + OHotAirBalloon::func_80055CCC(objectIndex, cameraId); + } + } +} + +void OHotAirBalloon::func_80055CCC(s32 objectIndex, s32 cameraId) { + UNUSED s32 pad; + f32 test; + Camera* camera; + + camera = &camera1[cameraId]; + if (gObjectList[objectIndex].state >= 2) { + func_8008A454(objectIndex, cameraId, 0x0000012C); + test = gObjectList[objectIndex].pos[1] - gObjectList[objectIndex].surfaceHeight; + func_8004A6EC(objectIndex, (20.0 / test) + 0.5); + if (is_obj_index_flag_status_inactive(objectIndex, 0x00100000) != 0) { + func_80043328(gObjectList[objectIndex].pos, (u16*) gObjectList[objectIndex].direction_angle, + gObjectList[objectIndex].sizeScaling, (Gfx*)d_course_luigi_raceway_dl_F960); + gSPDisplayList(gDisplayListHead++, (Gfx*)d_course_luigi_raceway_dl_F650); + } else { + D_80183E80[0] = (s16) gObjectList[objectIndex].direction_angle[0]; + D_80183E80[1] = + (s16) (func_800418AC(gObjectList[objectIndex].pos[0], gObjectList[objectIndex].pos[2], camera->pos) + + 0x8000); + D_80183E80[2] = (u16) gObjectList[objectIndex].direction_angle[2]; + func_80043328(gObjectList[objectIndex].pos, D_80183E80, gObjectList[objectIndex].sizeScaling, + (Gfx*)d_course_luigi_raceway_dl_FBE0); + gSPDisplayList(gDisplayListHead++, (Gfx*)d_course_luigi_raceway_dl_FA20); + if (gPlayerCountSelection1 == 1) { + gObjectList[objectIndex].direction_angle[1] = 0; + } + } + } +} + +void OHotAirBalloon::init_hot_air_balloon(s32 objectIndex) { + gObjectList[objectIndex].sizeScaling = 1.0f; + gObjectList[objectIndex].model = (Gfx*)d_course_luigi_raceway_dl_F960; + if (gGamestate != CREDITS_SEQUENCE) { + set_obj_origin_pos(objectIndex, xOrientation * _pos.x, _pos.y, _pos.z); + set_obj_origin_offset(objectIndex, 0.0f, 300.0f, 0.0f); + } else { + set_obj_origin_pos(objectIndex, xOrientation * _pos.x, _pos.y, _pos.z); + set_obj_origin_offset(objectIndex, 0.0f, 300.0f, 0.0f); + } + func_8008B844(objectIndex); + func_800886F4(objectIndex); + func_80086EF0(objectIndex); + gObjectList[objectIndex].velocity[1] = -2.0f; + init_actor_hot_air_balloon_item_box(0.0f, 0.0f, 0.0f); + object_next_state(objectIndex); +} + +void OHotAirBalloon::func_80085534(s32 objectIndex) { + switch (gObjectList[objectIndex].unk_0AE) { + case 1: + if (gObjectList[objectIndex].offset[1] <= 18.0) { + func_80086FD4(objectIndex); + } + break; + case 2: + f32_step_towards(&gObjectList[objectIndex].velocity[1], 0.0f, 0.05f); + if (gObjectList[objectIndex].velocity[1] == 0.0) { + func_80086FD4(objectIndex); + } + break; + case 3: + func_800871AC(objectIndex, 1); + break; + case 4: + f32_step_towards(&gObjectList[objectIndex].velocity[1], 1.0f, 0.05f); + if (gObjectList[objectIndex].velocity[1] == 1.0) { + func_80086FD4(objectIndex); + } + break; + case 5: + func_800871AC(objectIndex, 90); + break; + case 6: + f32_step_towards(&gObjectList[objectIndex].velocity[1], 0.0f, 0.05f); + if (gObjectList[objectIndex].velocity[1] == 0.0) { + func_80086FD4(objectIndex); + } + break; + case 7: + f32_step_towards(&gObjectList[objectIndex].velocity[1], -1.0f, 0.05f); + if (gObjectList[objectIndex].velocity[1] == -1.0) { + func_80086FD4(objectIndex); + } + break; + case 8: + func_800871AC(objectIndex, 90); + break; + case 9: + f32_step_towards(&gObjectList[objectIndex].velocity[1], 0.0f, 0.05f); + if (func_80087060(objectIndex, 90) != 0) { + func_8008701C(objectIndex, 3); + } + break; + } + object_add_velocity_offset_y(objectIndex); + gObjectList[objectIndex].direction_angle[1] += 0x100; +} + +void OHotAirBalloon::func_80085768(s32 objectIndex) { + switch (gObjectList[objectIndex].state) { /* irregular */ + case 1: + OHotAirBalloon::init_hot_air_balloon(objectIndex); + break; + case 0: + case 2: + break; + } +} diff --git a/src/engine/objects/HotAirBalloon.h b/src/engine/objects/HotAirBalloon.h new file mode 100644 index 000000000..301e111c4 --- /dev/null +++ b/src/engine/objects/HotAirBalloon.h @@ -0,0 +1,34 @@ +#pragma once + +#include +#include +#include "Object.h" + +#include "World.h" + +extern "C" { +#include "macros.h" +#include "main.h" +#include "vehicles.h" +#include "waypoints.h" +#include "common_structs.h" +#include "objects.h" +#include "camera.h" +#include "some_data.h" +} + +class OHotAirBalloon : public OObject { +public: + explicit OHotAirBalloon(const FVector& pos); + + virtual void Tick() override; + virtual void Draw(s32 cameraId) override; + void func_80055CCC(s32 objectIndex, s32 cameraId); + void init_hot_air_balloon(s32 objectIndex); + void func_80085534(s32 objectIndex); + void func_80085768(s32 objectIndex); + +private: + FVector _pos; + bool *_visible; +}; diff --git a/src/render_objects.c b/src/render_objects.c index 35a1ec775..0571da4ce 100644 --- a/src/render_objects.c +++ b/src/render_objects.c @@ -3931,50 +3931,6 @@ void render_object_chain_chomps(s32 cameraId) { } } -void func_80055CCC(s32 objectIndex, s32 cameraId) { - UNUSED s32 pad; - f32 test; - Camera* camera; - - camera = &camera1[cameraId]; - if (gObjectList[objectIndex].state >= 2) { - func_8008A454(objectIndex, cameraId, 0x0000012C); - test = gObjectList[objectIndex].pos[1] - gObjectList[objectIndex].surfaceHeight; - func_8004A6EC(objectIndex, (20.0 / test) + 0.5); - if (is_obj_index_flag_status_inactive(objectIndex, 0x00100000) != 0) { - func_80043328(gObjectList[objectIndex].pos, (u16*) gObjectList[objectIndex].direction_angle, - gObjectList[objectIndex].sizeScaling, d_course_luigi_raceway_dl_F960); - gSPDisplayList(gDisplayListHead++, d_course_luigi_raceway_dl_F650); - } else { - D_80183E80[0] = (s16) gObjectList[objectIndex].direction_angle[0]; - D_80183E80[1] = - (s16) (func_800418AC(gObjectList[objectIndex].pos[0], gObjectList[objectIndex].pos[2], camera->pos) + - 0x8000); - D_80183E80[2] = (u16) gObjectList[objectIndex].direction_angle[2]; - func_80043328(gObjectList[objectIndex].pos, D_80183E80, gObjectList[objectIndex].sizeScaling, - d_course_luigi_raceway_dl_FBE0); - gSPDisplayList(gDisplayListHead++, d_course_luigi_raceway_dl_FA20); - if (gPlayerCountSelection1 == 1) { - gObjectList[objectIndex].direction_angle[1] = 0; - } - } - } -} - -void render_object_hot_air_balloon(s32 arg0) { - s32 objectIndex; - objectIndex = indexObjectList1[0]; - if (gGamestate != 9) { - func_8008A1D0(objectIndex, arg0, 0x000005DC, 0x00000BB8); - if (is_obj_flag_status_active(objectIndex, VISIBLE) != 0) { - func_80055CCC(objectIndex, arg0); - } - } else { - clear_object_flag(objectIndex, 0x00100000); - func_80055CCC(objectIndex, arg0); - } -} - void func_80055EF4(s32 objectIndex, UNUSED s32 arg1) { Object* object; diff --git a/src/render_objects.h b/src/render_objects.h index ed14fb684..6474e8db2 100644 --- a/src/render_objects.h +++ b/src/render_objects.h @@ -370,8 +370,6 @@ void func_800557B4(s32, u32, u32); void render_object_train_penguins(s32); void func_80055AB8(s32, s32); void render_object_chain_chomps(s32); -void func_80055CCC(s32, s32); -void render_object_hot_air_balloon(s32); void func_80055EF4(s32, s32); void func_80055F48(s32); diff --git a/src/update_objects.c b/src/update_objects.c index 80edaaf19..e806d43d2 100644 --- a/src/update_objects.c +++ b/src/update_objects.c @@ -4434,102 +4434,6 @@ void func_800842C8(void) { } } -void init_hot_air_balloon(s32 objectIndex) { - gObjectList[objectIndex].sizeScaling = 1.0f; - gObjectList[objectIndex].model = d_course_luigi_raceway_dl_F960; - if (gGamestate != 9) { - set_obj_origin_pos(objectIndex, xOrientation * -176.0, 0.0f, -2323.0f); - set_obj_origin_offset(objectIndex, 0.0f, 300.0f, 0.0f); - } else { - set_obj_origin_pos(objectIndex, xOrientation * -1250.0, 0.0f, 1110.0f); - set_obj_origin_offset(objectIndex, 0.0f, 300.0f, 0.0f); - } - func_8008B844(objectIndex); - func_800886F4(objectIndex); - func_80086EF0(objectIndex); - gObjectList[objectIndex].velocity[1] = -2.0f; - init_actor_hot_air_balloon_item_box(0.0f, 0.0f, 0.0f); - object_next_state(objectIndex); -} - -void func_80085534(s32 objectIndex) { - switch (gObjectList[objectIndex].unk_0AE) { - case 1: - if (gObjectList[objectIndex].offset[1] <= 18.0) { - func_80086FD4(objectIndex); - } - break; - case 2: - f32_step_towards(&gObjectList[objectIndex].velocity[1], 0.0f, 0.05f); - if (gObjectList[objectIndex].velocity[1] == 0.0) { - func_80086FD4(objectIndex); - } - break; - case 3: - func_800871AC(objectIndex, 1); - break; - case 4: - f32_step_towards(&gObjectList[objectIndex].velocity[1], 1.0f, 0.05f); - if (gObjectList[objectIndex].velocity[1] == 1.0) { - func_80086FD4(objectIndex); - } - break; - case 5: - func_800871AC(objectIndex, 0x0000005A); - break; - case 6: - f32_step_towards(&gObjectList[objectIndex].velocity[1], 0.0f, 0.05f); - if (gObjectList[objectIndex].velocity[1] == 0.0) { - func_80086FD4(objectIndex); - } - break; - case 7: - f32_step_towards(&gObjectList[objectIndex].velocity[1], -1.0f, 0.05f); - if (gObjectList[objectIndex].velocity[1] == -1.0) { - func_80086FD4(objectIndex); - } - break; - case 8: - func_800871AC(objectIndex, 0x0000005A); - break; - case 9: - f32_step_towards(&gObjectList[objectIndex].velocity[1], 0.0f, 0.05f); - if (func_80087060(objectIndex, 0x0000005A) != 0) { - func_8008701C(objectIndex, 3); - } - break; - } - object_add_velocity_offset_y(objectIndex); - gObjectList[objectIndex].direction_angle[1] += 0x100; -} - -void func_80085768(s32 objectIndex) { - switch (gObjectList[objectIndex].state) { /* irregular */ - case 1: - init_hot_air_balloon(objectIndex); - break; - case 0: - case 2: - break; - } -} - -void update_hot_air_balloon(void) { - s32 objectIndex; - - objectIndex = indexObjectList1[0]; - if (gObjectList[objectIndex].state != 0) { - func_80085768(objectIndex); - func_80085534(objectIndex); - object_calculate_new_pos_offset(objectIndex); - if (gObjectList[objectIndex].state >= 2) { - gActorHotAirBalloonItemBox->pos[0] = gObjectList[objectIndex].pos[0]; - gActorHotAirBalloonItemBox->pos[1] = gObjectList[objectIndex].pos[1] - 10.0; - gActorHotAirBalloonItemBox->pos[2] = gObjectList[objectIndex].pos[2]; - } - } -} - void func_80085878(s32 objectIndex, s32 arg1) { TrackWaypoint* temp_v0; Object* object; From 08e4bf37979131e76e617beafb3f5ca6286e5ebb Mon Sep 17 00:00:00 2001 From: MegaMech Date: Sun, 29 Dec 2024 21:37:06 -0700 Subject: [PATCH 18/21] Fix Crab Impl --- src/engine/courses/KoopaTroopaBeach.cpp | 27 ++++++++++---------- src/engine/courses/TestCourse.cpp | 5 +++- src/engine/objects/Crab.cpp | 30 +++++++++++----------- src/engine/objects/Crab.h | 33 +++++++++++++++---------- 4 files changed, 53 insertions(+), 42 deletions(-) diff --git a/src/engine/courses/KoopaTroopaBeach.cpp b/src/engine/courses/KoopaTroopaBeach.cpp index eb4c3c45f..daaba1ad8 100644 --- a/src/engine/courses/KoopaTroopaBeach.cpp +++ b/src/engine/courses/KoopaTroopaBeach.cpp @@ -7,6 +7,7 @@ #include "World.h" #include "engine/actors/AFinishline.h" #include "engine/objects/BombKart.h" +#include "engine/objects/Crab.h" #include "assets/koopa_troopa_beach_data.h" extern "C" { @@ -144,6 +145,19 @@ void KoopaTroopaBeach::SpawnActors() { init_actor_hot_air_balloon_item_box(328.0f * gCourseDirection, 70.0f, 2541.0f); spawn_all_item_boxes((struct ActorSpawnData*)LOAD_ASSET_RAW(d_course_koopa_troopa_beach_item_box_spawns)); spawn_palm_trees((struct ActorSpawnData*)LOAD_ASSET_RAW(d_course_koopa_troopa_beach_tree_spawn)); + + if (gGamestate != CREDITS_SEQUENCE) { + gWorldInstance.AddObject(new OCrab(FVector2D(-1809, 625), FVector2D(-1666, 594))); + gWorldInstance.AddObject(new OCrab(FVector2D(-1852, 757), FVector2D(-1620, 740))); + gWorldInstance.AddObject(new OCrab(FVector2D(-1478, 1842), FVector2D(-1453, 1833))); + gWorldInstance.AddObject(new OCrab(FVector2D(-1418, 1967), FVector2D(-1455, 1962))); + gWorldInstance.AddObject(new OCrab(FVector2D(-1472, 2112), FVector2D(-1417, 2100))); + gWorldInstance.AddObject(new OCrab(FVector2D(-1389, 2152), FVector2D(-1335, 2136))); + gWorldInstance.AddObject(new OCrab(FVector2D(218, 693), FVector2D(69, 696))); + gWorldInstance.AddObject(new OCrab(FVector2D(235, 528), FVector2D(24, 501))); + gWorldInstance.AddObject(new OCrab(FVector2D(268, 406), FVector2D(101, 394))); + gWorldInstance.AddObject(new OCrab(FVector2D(223, 318), FVector2D(86, 308))); + } } void KoopaTroopaBeach::SpawnVehicles() { @@ -173,19 +187,6 @@ void KoopaTroopaBeach::InitCourseObjects() { size_t objectId; size_t i; - if (gGamestate != CREDITS_SEQUENCE) { - for (i = 0; i < NUM_CRABS; i++) { - objectId = indexObjectList1[i]; - init_object(objectId, 0); - gObjectList[objectId].pos[0] = gObjectList[objectId].origin_pos[0] = - gCrabSpawns[i].startX * xOrientation; - gObjectList[objectId].unk_01C[0] = gCrabSpawns[i].patrolX * xOrientation; - - gObjectList[objectId].pos[2] = gObjectList[objectId].origin_pos[2] = gCrabSpawns[i].startZ; - gObjectList[objectId].unk_01C[2] = gCrabSpawns[i].patrolZ; - } - } - if (gGamestate == CREDITS_SEQUENCE) { Vec3f pos = {-360.0f, 60.0f, -1300.0f}; for (size_t i = 0; i < NUM_SEAGULLS; i++) { diff --git a/src/engine/courses/TestCourse.cpp b/src/engine/courses/TestCourse.cpp index 40b03059e..682db53c5 100644 --- a/src/engine/courses/TestCourse.cpp +++ b/src/engine/courses/TestCourse.cpp @@ -21,6 +21,7 @@ #include "engine/objects/Hedgehog.h" #include "engine/objects/Flagpole.h" #include "engine/objects/HotAirBalloon.h" +#include "engine/objects/Crab.h" #include "engine/particles/StarEmitter.h" extern "C" { @@ -211,7 +212,9 @@ void TestCourse::SpawnActors() { //gWorldInstance.AddEmitter(new StarEmitter(FVector(0,50,0))); //gWorldInstance.AddObject(new OHedgehog(FVector(0, 0, 0), FVector2D(0, -200), 9)); //gWorldInstance.AddObject(new OFlagpole(FVector(0, 0, -200), 0x400)); - gWorldInstance.AddObject(new OHotAirBalloon(FVector(0.0, 20.0f, -200.0f))); +// gWorldInstance.AddObject(new OHotAirBalloon(FVector(0.0, 20.0f, -200.0f))); + + gWorldInstance.AddObject(new OCrab(FVector2D(0, 0), FVector2D(0, -200))); } // Likely sets minimap boundaries diff --git a/src/engine/objects/Crab.cpp b/src/engine/objects/Crab.cpp index cfb84f259..b05bc85e3 100644 --- a/src/engine/objects/Crab.cpp +++ b/src/engine/objects/Crab.cpp @@ -23,25 +23,28 @@ extern "C" { #include "assets/koopa_troopa_beach_data.h" } -OCrab::OCrab(s32 i, Vec3f pos) { +size_t OCrab::_count = 0; + +OCrab::OCrab(const FVector2D& start, const FVector2D& end) { s32 objectId; - //for (i = 0; i < NUM_CRABS; i++) { - _idx = i; - objectId = indexObjectList1[i]; + _idx = _count; + _start = start; + _end = end; + + objectId = indexObjectList1[_idx]; init_object(objectId, 0); - gObjectList[objectId].pos[0] = gObjectList[objectId].origin_pos[0] = - gCrabSpawns[i].startX * xOrientation; + gObjectList[objectId].pos[0] = gObjectList[objectId].origin_pos[0] = start.x * xOrientation; + gObjectList[objectId].pos[2] = gObjectList[objectId].origin_pos[2] = start.z; - gObjectList[objectId].unk_01C[0] = gCrabSpawns[i].patrolX * xOrientation; + gObjectList[objectId].unk_01C[0] = end.x * xOrientation; + gObjectList[objectId].unk_01C[2] = end.z; - gObjectList[objectId].pos[2] = gObjectList[objectId].origin_pos[2] = gCrabSpawns[i].startZ; - gObjectList[objectId].unk_01C[2] = gCrabSpawns[i].patrolZ; + _count++; } void OCrab::Tick(void) { s32 objectIndex; - //for (var_s1 = 0; var_s1 < NUM_CRABS; var_s1++) { objectIndex = indexObjectList1[_idx]; if (gObjectList[objectIndex].state != 0) { OCrab::func_80082B34(objectIndex); @@ -49,12 +52,11 @@ void OCrab::Tick(void) { OCrab::func_80082C30(objectIndex); OCrab::func_80082E18(objectIndex); } - //} } -void OCrab::Draw(s32 objectIndex, s32 cameraId) { +void OCrab::Draw(s32 cameraId) { Camera* camera; - + s32 objectIndex = indexObjectList1[_idx]; if (gObjectList[objectIndex].state >= 2) { Vtx* vtx = (Vtx*) LOAD_ASSET_RAW(common_vtx_hedgehog); camera = &camera1[cameraId]; @@ -72,7 +74,6 @@ void OCrab::DrawModel(s32 cameraId) { s32 someIndex; s32 test; - //for (someIndex = 0; someIndex < NUM_CRABS; someIndex++) { test = indexObjectList1[_idx]; func_8008A364(test, cameraId, 0x2AABU, 800); if (is_obj_flag_status_active(test, VISIBLE) != 0) { @@ -86,7 +87,6 @@ void OCrab::DrawModel(s32 cameraId) { draw_2d_texture_at(gObjectList[objectIndex].pos, gObjectList[objectIndex].orientation, gObjectList[objectIndex].sizeScaling, (u8*) gObjectList[objectIndex].activeTLUT, (u8*)gObjectList[objectIndex].activeTexture, (Vtx*)common_vtx_hedgehog, 0x00000040, 0x00000040, 0x00000040, 0x00000020); } } - //} } void OCrab::init_ktb_crab(s32 objectIndex) { diff --git a/src/engine/objects/Crab.h b/src/engine/objects/Crab.h index 697a8bd7b..281b080ca 100644 --- a/src/engine/objects/Crab.h +++ b/src/engine/objects/Crab.h @@ -2,6 +2,8 @@ #include #include +#include "engine/objects/Object.h" +#include "World.h" extern "C" { #include "macros.h" @@ -14,20 +16,23 @@ extern "C" { #include "some_data.h" } - -class OCrab { +/** + * @arg start x and z spawn location + * @arg end x and z patrol location + * + * Crab patrols between start and end. + * The game automatically places the actor on the course surface. + * Therefore, providing a Y height is unnecessary. + * + * Crab appears to have a maximum patrolling distance and will patrol between + * end --> max distance rather than start --> end or start --> max distance. + */ +class OCrab : public OObject { public: - enum Behaviour : uint16_t { - }; + explicit OCrab(const FVector2D& start, const FVector2D& end); -public: - f32 Diameter = 0.0f; // Waddle in a circle around the spawn point at this diameter. - uint16_t MirrorModeAngleOffset; - - explicit OCrab(s32 i, Vec3f pos); - - void Tick(); - void Draw(s32 objectIndex, s32 cameraId); + virtual void Tick() override; + virtual void Draw(s32 cameraId) override; void DrawModel(s32 cameraId); void init_ktb_crab(s32 objectIndex); @@ -36,6 +41,8 @@ public: void func_80082E18(s32 objectIndex); private: - + FVector2D _start; + FVector2D _end; + static size_t _count; s32 _idx; }; From 2bd41c6d90995cff7387e11374843cbe9e62b10f Mon Sep 17 00:00:00 2001 From: MegaMech Date: Sun, 29 Dec 2024 23:57:26 -0700 Subject: [PATCH 19/21] Fix Seagull, classes count their own instances --> cleanup --- src/code_80057C60.c | 12 --- src/engine/Smoke.cpp | 8 +- src/engine/TrainCrossing.cpp | 2 +- src/engine/World.cpp | 76 +------------- src/engine/World.h | 27 +---- src/engine/courses/BowsersCastle.cpp | 83 +++++++-------- src/engine/courses/DKJungle.cpp | 3 +- src/engine/courses/KalimariDesert.cpp | 3 +- src/engine/courses/KoopaTroopaBeach.cpp | 39 +++---- src/engine/courses/KoopaTroopaBeach.h | 2 + src/engine/courses/SherbetLand.cpp | 129 ++++++++++++------------ src/engine/courses/ToadsTurnpike.cpp | 12 ++- src/engine/objects/BombKart.cpp | 10 +- src/engine/objects/BombKart.h | 14 ++- src/engine/objects/Hedgehog.h | 2 +- src/engine/objects/Penguin.cpp | 18 ++-- src/engine/objects/Penguin.h | 21 +++- src/engine/objects/Seagull.cpp | 127 ++++++++++------------- src/engine/objects/Seagull.h | 32 +++--- src/engine/objects/Thwomp.cpp | 28 +++-- src/engine/objects/Thwomp.h | 20 +++- src/engine/vehicles/Boat.cpp | 8 +- src/engine/vehicles/Boat.h | 12 ++- src/engine/vehicles/Bus.cpp | 8 +- src/engine/vehicles/Bus.h | 13 ++- src/engine/vehicles/Car.cpp | 8 +- src/engine/vehicles/Car.h | 12 ++- src/engine/vehicles/TankerTruck.cpp | 8 +- src/engine/vehicles/TankerTruck.h | 13 ++- src/engine/vehicles/Train.cpp | 8 +- src/engine/vehicles/Train.h | 17 +++- src/engine/vehicles/Truck.cpp | 8 +- src/engine/vehicles/Truck.h | 13 ++- src/port/Game.cpp | 57 ----------- src/port/Game.h | 12 --- 35 files changed, 422 insertions(+), 443 deletions(-) diff --git a/src/code_80057C60.c b/src/code_80057C60.c index a4fb77372..d9be361fa 100644 --- a/src/code_80057C60.c +++ b/src/code_80057C60.c @@ -692,12 +692,6 @@ void render_object_for_player(s32 cameraId) { CourseManager_DrawObjects(cameraId); CM_DrawParticles(cameraId); - // CourseManager_RenderCourseObjects(cameraId); - // CourseManager_TrainSmokeDraw(cameraId); - // CourseManager_DrawThwomps(cameraId); - // CourseManager_DrawPenguins(cameraId); - // CourseManager_DrawSeagulls(cameraId); - // switch (gCurrentCourseId) { // case COURSE_MARIO_RACEWAY: // break; @@ -1287,9 +1281,6 @@ void func_80059AC8(void) { } CourseManager_TickObjects60fps(); - - CourseManager_TickThwomps(); // func_8005A71C(); - } } @@ -1579,9 +1570,6 @@ void func_8005A71C(void) { void update_object(void) { CourseManager_UpdateCourseObjects(); - // CourseManager_TrainSmokeTick(); - // CourseManager_TickPenguins(); - // CourseManager_TickSeagulls(); // switch (gCurrentCourseId) { // case COURSE_MARIO_RACEWAY: diff --git a/src/engine/Smoke.cpp b/src/engine/Smoke.cpp index 9d74397dc..9841bfffb 100644 --- a/src/engine/Smoke.cpp +++ b/src/engine/Smoke.cpp @@ -24,7 +24,7 @@ void TrainSmokeTick() { Object* object; for (auto& vehicle : gWorldInstance.Vehicles) { - if (auto train = dynamic_cast(vehicle.get())) { + if (auto train = dynamic_cast(vehicle)) { if (train->SmokeTimer != 0) { train->SmokeTimer -= 1; } @@ -48,7 +48,7 @@ void TrainSmokeTick() { train->SmokeTimer = 100; } } - } else if (auto boat = dynamic_cast(vehicle.get())) { + } else if (auto boat = dynamic_cast(vehicle)) { if (boat->SmokeTimer != 0) { boat->SmokeTimer -= 1; } @@ -79,7 +79,7 @@ void TrainSmokeTick() { void TrainSmokeDraw(s32 cameraId) { Camera* camera = &camera1[cameraId]; for (auto& vehicle : gWorldInstance.Vehicles) { - if (auto train = dynamic_cast(vehicle.get())) { + if (auto train = dynamic_cast(vehicle)) { gSPDisplayList(gDisplayListHead++, (Gfx*)D_0D007AE0); load_texture_block_i8_nomirror((uint8_t*)D_0D029458, 32, 32); func_8004B72C(255, 255, 255, 255, 255, 255, 255); @@ -92,7 +92,7 @@ void TrainSmokeDraw(s32 cameraId) { render_object_train_smoke_particle(train->SmokeParticles[i], cameraId); } } - } else if (auto boat = dynamic_cast(vehicle.get())) { + } else if (auto boat = dynamic_cast(vehicle)) { gSPDisplayList(gDisplayListHead++, (Gfx*)D_0D007AE0); load_texture_block_i8_nomirror((uint8_t*)D_0D029458, 32, 32); diff --git a/src/engine/TrainCrossing.cpp b/src/engine/TrainCrossing.cpp index 13232c962..98c7c766b 100644 --- a/src/engine/TrainCrossing.cpp +++ b/src/engine/TrainCrossing.cpp @@ -30,7 +30,7 @@ void TrainCrossing::CrossingTrigger() { for (const auto& vehicle : gWorldInstance.Vehicles) { - if (auto train = dynamic_cast(vehicle.get())) {; + if (auto train = dynamic_cast(vehicle)) {; f32 radius = DynamicRadius(train->Locomotive.position, train->Locomotive.velocity, Position); if (Distance(train->Locomotive.position, Position) < radius) { diff --git a/src/engine/World.cpp b/src/engine/World.cpp index 5cd85213b..ded60a262 100644 --- a/src/engine/World.cpp +++ b/src/engine/World.cpp @@ -3,14 +3,7 @@ #include "Cup.h" #include "courses/Course.h" #include "vehicles/Vehicle.h" -#include "vehicles/Train.h" -#include "vehicles/Boat.h" -#include "vehicles/Truck.h" -#include "vehicles/Bus.h" -#include "vehicles/TankerTruck.h" -#include "vehicles/Car.h" #include "objects/BombKart.h" -#include "objects/Penguin.h" #include "TrainCrossing.h" #include #include "objects/Object.h" @@ -40,53 +33,13 @@ void World::SetCourseFromCup() { CurrentCourse = CurrentCup->GetCourse(); } -// Required for spawning vehicles in divisions across path points -static size_t trains; -static size_t trucks; -static size_t busses; -static size_t tankerTrucks; -static size_t cars; -static size_t boats; -static size_t thwomps; -static size_t penguins; -static size_t seagulls; -/** - * Note that you can only remove the tender if there are no carriages - * @arg waypoint initial waypoint to spawn at. - */ -void World::AddTrain(ATrain::TenderStatus tender, size_t numCarriages, f32 speed, uint32_t waypoint) { - Vehicles.push_back(std::make_unique(trains, tender, numCarriages, speed, waypoint)); - trains++; -} - -void World::AddBoat(f32 speed, uint32_t waypoint) { - Vehicles.push_back(std::make_unique(boats, speed, waypoint)); - boats++; -} - -void World::AddTruck(f32 speedA, f32 speedB, TrackWaypoint* path, uint32_t waypoint) { - Vehicles.push_back(std::make_unique(trucks, speedA, speedB, path, waypoint)); - trucks++; -} - -void World::AddBus(f32 speedA, f32 speedB, TrackWaypoint* path, uint32_t waypoint) { - Vehicles.push_back(std::make_unique(busses, speedA, speedB, path, waypoint)); - busses++; -} - -void World::AddTankerTruck(f32 speedA, f32 speedB, TrackWaypoint* path, uint32_t waypoint) { - Vehicles.push_back(std::make_unique(tankerTrucks, speedA, speedB, path, waypoint)); - tankerTrucks++; -} - -void World::AddCar(f32 speedA, f32 speedB, TrackWaypoint* path, uint32_t waypoint) { - Vehicles.push_back(std::make_unique(cars, speedA, speedB, path, waypoint)); - cars++; +AVehicle* World::AddVehicle(AVehicle* vehicle) { + Vehicles.push_back(vehicle); + return Vehicles.back(); } void World::ClearVehicles(void) { - trains = trucks = busses = tankerTrucks = cars = boats = thwomps = 0; Vehicles.clear(); } @@ -97,28 +50,7 @@ TrainCrossing* World::AddCrossing(Vec3f position, u32 waypointMin, u32 waypointM } void World::AddBombKart(Vec3f pos, TrackWaypoint* waypoint, uint16_t waypointIndex, uint16_t state, f32 unk_3C) { - BombKarts.push_back(std::make_unique(pos, waypoint, waypointIndex, state, unk_3C)); -} - -void World::AddThwomp(s16 x, s16 z, s16 direction, f32 scale, s16 behaviour, s16 primAlpha, u16 boundingBoxSize) { - Thwomps.push_back( - std::make_unique(thwomps, x, z, direction, scale, behaviour, primAlpha, boundingBoxSize)); - thwomps++; - 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; -} - -std::shared_ptr World::AddSeagull(Vec3f pos) { - auto seagull = std::make_shared(seagulls, pos); - Seagulls.push_back(seagull); - seagulls++; - return seagull; + BombKarts.push_back(new OBombKart(pos, waypoint, waypointIndex, state, unk_3C)); } u32 World::GetCupIndex() { diff --git a/src/engine/World.h b/src/engine/World.h index 1aa09fb57..4fdf55bc8 100644 --- a/src/engine/World.h +++ b/src/engine/World.h @@ -102,11 +102,8 @@ class OObject; class Cup; // <-- Forward declaration class Course; class AVehicle; -class ATrain; -class ACar; +class OBombKart; class TrainCrossing; -class OThwomp; -class OSeagull; class OLakitu; class World { @@ -212,33 +209,19 @@ public: std::vector Actors; std::vector Objects; + std::vector Vehicles; + std::vector BombKarts; std::vector Emitters; std::unordered_map Lakitus; - /** Actors */ - void AddBoat(f32 speed, uint32_t waypoint); - void AddTrain(ATrain::TenderStatus tender, size_t numCarriages, f32 speed, uint32_t waypoint); - void AddTruck(f32 speedA, f32 speedB, TrackWaypoint* path, uint32_t waypoint); - void AddBus(f32 speedA, f32 speedB, TrackWaypoint* path, uint32_t waypoint); - void AddTankerTruck(f32 speedA, f32 speedB, TrackWaypoint* path, uint32_t waypoint); - void AddCar(f32 speedA, f32 speedB, TrackWaypoint* path, uint32_t waypoint); - std::vector> Vehicles; + AVehicle* AddVehicle(AVehicle* vehicle); + void ClearVehicles(void); /** Objects **/ - std::vector> BombKarts; void AddBombKart(Vec3f pos, TrackWaypoint* waypoint, uint16_t waypointIndex, uint16_t state, f32 unk_3C); - 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); - - std::vector> Seagulls; - std::shared_ptr AddSeagull(Vec3f pos); - TrainCrossing* AddCrossing(Vec3f position, u32 waypointMin, u32 waypointMax, f32 approachRadius, f32 exitRadius); std::vector> Crossings; diff --git a/src/engine/courses/BowsersCastle.cpp b/src/engine/courses/BowsersCastle.cpp index d5766b668..49ae93385 100644 --- a/src/engine/courses/BowsersCastle.cpp +++ b/src/engine/courses/BowsersCastle.cpp @@ -7,6 +7,7 @@ #include "World.h" #include "engine/actors/AFinishline.h" #include "engine/objects/BombKart.h" +#include "engine/objects/Thwomp.h" #include "bowsers_castle_data.h" extern "C" { @@ -153,6 +154,47 @@ void BowsersCastle::SpawnActors() { spawn_foliage((struct ActorSpawnData*)LOAD_ASSET_RAW(d_course_bowsers_castle_tree_spawn)); spawn_all_item_boxes((struct ActorSpawnData*)LOAD_ASSET_RAW(d_course_bowsers_castle_item_box_spawns)); + + switch (gCCSelection) { + case CC_100: + case CC_EXTRA: + gWorldInstance.AddObject(new OThwomp(0x0320, 0xf92a, 0xC000, 1.0f, 1, 0)); + gWorldInstance.AddObject(new OThwomp(0x044c, 0xf92a, 0xC000, 1.0f, 1, 1)); + gWorldInstance.AddObject(new OThwomp(0x02bc, 0xf95c, 0xC000, 1.0f, 2, 0)); + gWorldInstance.AddObject(new OThwomp(0x04b0, 0xf8f8, 0xC000, 1.0f, 2, 1)); + gWorldInstance.AddObject(new OThwomp(0x04b0, 0xf5ba, 0xC000, 1.0f, 3, 0)); + gWorldInstance.AddObject(new OThwomp(0x04b0, 0xf592, 0xC000, 1.0f, 3, 1)); + gWorldInstance.AddObject(new OThwomp(0x091a, 0xf5bf, 0xC000, 1.0f, 4, 0)); + gWorldInstance.AddObject(new OThwomp(0x091a, 0xf597, 0xC000, 1.0f, 4, 1)); + gWorldInstance.AddObject(new OThwomp(0x0596, 0xf92f, 0xC000, 1.5f, 6, 0)); + gWorldInstance.AddObject(new OThwomp(0x082a, 0xf9f2, 0x4000, 1.0f, 5, 0)); + gWorldInstance.AddObject(new OThwomp(0x073a, 0xf9f2, 0x4000, 1.0f, 5, 1)); + break; + case CC_50: + gWorldInstance.AddObject(new OThwomp(0x3B6, 0xF92A, 0xC000, 1.0f, 1, 0)); + gWorldInstance.AddObject(new OThwomp(0x0352, 0xf95c, 0xC000, 1.0f, 2, 0)); + gWorldInstance.AddObject(new OThwomp(0x04b0, 0xf5ba, 0xC000, 1.0f, 3, 0)); + gWorldInstance.AddObject(new OThwomp(0x04b0, 0xf592, 0xC000, 1.0f, 3, 1)); + gWorldInstance.AddObject(new OThwomp(0x091a, 0xf5b0, 0xC000, 1.0f, 4, 0)); + gWorldInstance.AddObject(new OThwomp(0x0596, 0xf92f, 0xC000, 1.5f, 6, 0)); + gWorldInstance.AddObject(new OThwomp(0x082a, 0xf9f2, 0x4000, 1.0f, 5, 0)); + gWorldInstance.AddObject(new OThwomp(0x073a, 0xf9f2, 0x4000, 1.0f, 5, 1)); + break; + case CC_150: + gWorldInstance.AddObject(new OThwomp(0x0320, 0xf92a, 0xC000, 1.0f, 1, 0)); + gWorldInstance.AddObject(new OThwomp(0x044c, 0xf92a, 0xC000, 1.0f, 1, 1)); + gWorldInstance.AddObject(new OThwomp(0x02bc, 0xf95c, 0xC000, 1.0f, 2, 0)); + gWorldInstance.AddObject(new OThwomp(0x04b0, 0xf8f8, 0xC000, 1.0f, 2, 1)); + gWorldInstance.AddObject(new OThwomp(0x04b0, 0xf5ba, 0xC000, 1.0f, 3, 0)); + gWorldInstance.AddObject(new OThwomp(0x04b0, 0xf592, 0xC000, 1.0f, 3, 1)); + gWorldInstance.AddObject(new OThwomp(0x091a, 0xf5c9, 0xC000, 1.0f, 4, 0)); + gWorldInstance.AddObject(new OThwomp(0x091a, 0xf5ab, 0xC000, 1.0f, 4, 1)); + gWorldInstance.AddObject(new OThwomp(0x091a, 0xf58d, 0xC000, 1.0f, 4, 2)); + gWorldInstance.AddObject(new OThwomp(0x0596, 0xf92f, 0xC000, 1.5f, 6, 0)); + gWorldInstance.AddObject(new OThwomp(0x082a, 0xf9f2, 0x4000, 1.0f, 5, 0)); + gWorldInstance.AddObject(new OThwomp(0x073a, 0xf9f2, 0x4000, 1.0f, 5, 1)); + break; + } } void BowsersCastle::SpawnVehicles() { @@ -181,47 +223,6 @@ void BowsersCastle::InitCourseObjects() { size_t objectId; size_t i; - switch (gCCSelection) { - case CC_100: - case CC_EXTRA: - gWorldInstance.AddThwomp(0x0320, 0xf92a, 0xC000, 1.0f, 1, 0); - gWorldInstance.AddThwomp(0x044c, 0xf92a, 0xC000, 1.0f, 1, 1); - gWorldInstance.AddThwomp(0x02bc, 0xf95c, 0xC000, 1.0f, 2, 0); - gWorldInstance.AddThwomp(0x04b0, 0xf8f8, 0xC000, 1.0f, 2, 1); - gWorldInstance.AddThwomp(0x04b0, 0xf5ba, 0xC000, 1.0f, 3, 0); - gWorldInstance.AddThwomp(0x04b0, 0xf592, 0xC000, 1.0f, 3, 1); - gWorldInstance.AddThwomp(0x091a, 0xf5bf, 0xC000, 1.0f, 4, 0); - gWorldInstance.AddThwomp(0x091a, 0xf597, 0xC000, 1.0f, 4, 1); - gWorldInstance.AddThwomp(0x0596, 0xf92f, 0xC000, 1.5f, 6, 0); - gWorldInstance.AddThwomp(0x082a, 0xf9f2, 0x4000, 1.0f, 5, 0); - gWorldInstance.AddThwomp(0x073a, 0xf9f2, 0x4000, 1.0f, 5, 1); - break; - case CC_50: - gWorldInstance.AddThwomp(0x3B6, 0xF92A, 0xC000, 1.0f, 1, 0); - gWorldInstance.AddThwomp(0x0352, 0xf95c, 0xC000, 1.0f, 2, 0); - gWorldInstance.AddThwomp(0x04b0, 0xf5ba, 0xC000, 1.0f, 3, 0); - gWorldInstance.AddThwomp(0x04b0, 0xf592, 0xC000, 1.0f, 3, 1); - gWorldInstance.AddThwomp(0x091a, 0xf5b0, 0xC000, 1.0f, 4, 0); - gWorldInstance.AddThwomp(0x0596, 0xf92f, 0xC000, 1.5f, 6, 0); - gWorldInstance.AddThwomp(0x082a, 0xf9f2, 0x4000, 1.0f, 5, 0); - gWorldInstance.AddThwomp(0x073a, 0xf9f2, 0x4000, 1.0f, 5, 1); - break; - case CC_150: - gWorldInstance.AddThwomp(0x0320, 0xf92a, 0xC000, 1.0f, 1, 0); - gWorldInstance.AddThwomp(0x044c, 0xf92a, 0xC000, 1.0f, 1, 1); - gWorldInstance.AddThwomp(0x02bc, 0xf95c, 0xC000, 1.0f, 2, 0); - gWorldInstance.AddThwomp(0x04b0, 0xf8f8, 0xC000, 1.0f, 2, 1); - gWorldInstance.AddThwomp(0x04b0, 0xf5ba, 0xC000, 1.0f, 3, 0); - gWorldInstance.AddThwomp(0x04b0, 0xf592, 0xC000, 1.0f, 3, 1); - gWorldInstance.AddThwomp(0x091a, 0xf5c9, 0xC000, 1.0f, 4, 0); - gWorldInstance.AddThwomp(0x091a, 0xf5ab, 0xC000, 1.0f, 4, 1); - gWorldInstance.AddThwomp(0x091a, 0xf58d, 0xC000, 1.0f, 4, 2); - gWorldInstance.AddThwomp(0x0596, 0xf92f, 0xC000, 1.5f, 6, 0); - gWorldInstance.AddThwomp(0x082a, 0xf9f2, 0x4000, 1.0f, 5, 0); - gWorldInstance.AddThwomp(0x073a, 0xf9f2, 0x4000, 1.0f, 5, 1); - break; - } - // Handle the big statue's fire breath objectId = indexObjectList2[0]; init_object(objectId, 0); diff --git a/src/engine/courses/DKJungle.cpp b/src/engine/courses/DKJungle.cpp index 941ccdb22..9daf7ad3f 100644 --- a/src/engine/courses/DKJungle.cpp +++ b/src/engine/courses/DKJungle.cpp @@ -9,6 +9,7 @@ #include "engine/objects/BombKart.h" #include "assets/dks_jungle_parkway_data.h" +#include "engine/vehicles/Boat.h" #include "engine/vehicles/Utils.h" extern "C" { @@ -278,7 +279,7 @@ void DKJungle::SpawnVehicles() { // The original game only ran vehicle logic every second frame. // Thus the speed gets divided by two to set speed to match properly - gWorldInstance.AddBoat((0.6666666f)/4, 0); + gWorldInstance.AddVehicle(new ABoat((0.6666666f)/4, 0)); if (gModeSelection == VERSUS) { Vec3f pos = {0, 0, 0}; diff --git a/src/engine/courses/KalimariDesert.cpp b/src/engine/courses/KalimariDesert.cpp index 2440e8b01..8f00441ec 100644 --- a/src/engine/courses/KalimariDesert.cpp +++ b/src/engine/courses/KalimariDesert.cpp @@ -10,6 +10,7 @@ #include "kalimari_desert_data.h" #include "engine/vehicles/Utils.h" +#include "engine/vehicles/Train.h" #include "engine/vehicles/Vehicle.h" extern "C" { @@ -237,7 +238,7 @@ void KalimariDesert::SpawnVehicles() { } } - gWorldInstance.AddTrain(_tender, _numCarriages, 2.5f, waypoint); + gWorldInstance.AddVehicle(new ATrain(_tender, _numCarriages, 2.5f, waypoint)); } if (gModeSelection == VERSUS) { diff --git a/src/engine/courses/KoopaTroopaBeach.cpp b/src/engine/courses/KoopaTroopaBeach.cpp index daaba1ad8..499a62bf7 100644 --- a/src/engine/courses/KoopaTroopaBeach.cpp +++ b/src/engine/courses/KoopaTroopaBeach.cpp @@ -158,6 +158,26 @@ void KoopaTroopaBeach::SpawnActors() { gWorldInstance.AddObject(new OCrab(FVector2D(268, 406), FVector2D(101, 394))); gWorldInstance.AddObject(new OCrab(FVector2D(223, 318), FVector2D(86, 308))); } + + if (gGamestate == CREDITS_SEQUENCE) { + for (size_t i = 0; i < NUM_SEAGULLS; i++) { + //gWorldInstance.AddObject(new OSeagull(FVector(-360.0f, 60.0f, -1300.0f))); + Vec3f pos = {-360.0f, 60.0f, -1300.0f}; + gWorldInstance.AddObject(new OSeagull(pos)); + } + } else { // Normal gameplay + for (size_t i = 0; i < 4; i++) { + Vec3f pos = {-985.0f, 15.0f, 1200.0f}; + gWorldInstance.AddObject(new OSeagull(pos)); + //gWorldInstance.AddObject(new OSeagull(FVector(-985.0f, 15.0f, 1200.0f))); + } + + for (size_t i = 0; i < 6; i++) { + //gWorldInstance.AddObject(new OSeagull(FVector(328.0f, 20.0f, 2541.0f))); + Vec3f pos2 = {328.0f, 20.0f, 2541.0f}; + gWorldInstance.AddObject(new OSeagull(pos2)); + } + } } void KoopaTroopaBeach::SpawnVehicles() { @@ -184,25 +204,6 @@ void KoopaTroopaBeach::MinimapSettings() { } void KoopaTroopaBeach::InitCourseObjects() { - size_t objectId; - size_t i; - - if (gGamestate == CREDITS_SEQUENCE) { - Vec3f pos = {-360.0f, 60.0f, -1300.0f}; - for (size_t i = 0; i < NUM_SEAGULLS; i++) { - gWorldInstance.AddSeagull(pos); - } - } else { // Normal gameplay - Vec3f pos = {-985.0f, 15.0f, 1200.0f}; - for (size_t i = 0; i < 4; i++) { - gWorldInstance.AddSeagull(pos); - } - - Vec3f pos2 = {328.0f, 20.0f, 2541.0f}; - for (size_t i = 0; i < 6; i++) { - gWorldInstance.AddSeagull(pos2); - } - } } void KoopaTroopaBeach::UpdateCourseObjects() { diff --git a/src/engine/courses/KoopaTroopaBeach.h b/src/engine/courses/KoopaTroopaBeach.h index 4dc51313e..8237b7628 100644 --- a/src/engine/courses/KoopaTroopaBeach.h +++ b/src/engine/courses/KoopaTroopaBeach.h @@ -3,6 +3,8 @@ #include #include "Course.h" +#include "World.h" + extern "C" { #include "assets/koopa_troopa_beach_vertices.h" #include "assets/koopa_troopa_beach_displaylists.h" diff --git a/src/engine/courses/SherbetLand.cpp b/src/engine/courses/SherbetLand.cpp index e14b2c7e0..0153bf0a8 100644 --- a/src/engine/courses/SherbetLand.cpp +++ b/src/engine/courses/SherbetLand.cpp @@ -134,6 +134,72 @@ void SherbetLand::SpawnActors() { gWorldInstance.AddActor(new AFinishline()); spawn_all_item_boxes((struct ActorSpawnData*)LOAD_ASSET_RAW(d_course_sherbet_land_item_box_spawns)); + + + +// Originally, multiplayer did not spawn the big penguin +// if (gPlayerCountSelection1 == 1) { + Vec3f pos = {-383.0f, 2.0f, -690.0f}; + gWorldInstance.AddObject(new OPenguin(pos, 0, OPenguin::PenguinType::EMPEROR, OPenguin::Behaviour::STRUT)); +// } + + //! @bug Skip spawning penguins due to animation crash for now + if (gGamestate == CREDITS_SEQUENCE) { + return; + } + + Vec3f pos2 = {-2960.0f, -80.0f, 1521.0f}; + auto penguin = reinterpret_cast(gWorldInstance.AddObject(new OPenguin(pos2, 0x150, OPenguin::PenguinType::ADULT, OPenguin::Behaviour::CIRCLE))); + auto penguin2 = reinterpret_cast(gWorldInstance.AddObject(new OPenguin(pos2, 0x150, OPenguin::PenguinType::ADULT, OPenguin::Behaviour::CIRCLE))); + penguin->Diameter = penguin2->Diameter = 100.0f; + + Vec3f pos3 = {-2490.0f, -80.0f, 1612.0f}; + auto penguin3 = reinterpret_cast(gWorldInstance.AddObject(new OPenguin(pos3, 0x100, OPenguin::PenguinType::ADULT, OPenguin::Behaviour::CIRCLE))); + auto penguin4 = reinterpret_cast(gWorldInstance.AddObject(new OPenguin(pos3, 0x100, OPenguin::PenguinType::ADULT, OPenguin::Behaviour::CIRCLE))); + penguin3->Diameter = penguin4->Diameter = 80.0f; + + Vec3f pos4 = {-2098.0f, -80.0f, 1624.0f}; + auto penguin5 = reinterpret_cast(gWorldInstance.AddObject(new OPenguin(pos4, 0xFF00, OPenguin::PenguinType::ADULT, OPenguin::Behaviour::CIRCLE))); + auto penguin6 = reinterpret_cast(gWorldInstance.AddObject(new OPenguin(pos4, 0xFF00, OPenguin::PenguinType::ADULT, OPenguin::Behaviour::CIRCLE))); + penguin5->Diameter = penguin6->Diameter = 80.0f; + + + Vec3f pos5 = {-2080.0f, -80.0f, 1171.0f}; + auto penguin7 = reinterpret_cast(gWorldInstance.AddObject(new OPenguin(pos5, 0x150, OPenguin::PenguinType::ADULT, OPenguin::Behaviour::CIRCLE))); + auto penguin8 = reinterpret_cast(gWorldInstance.AddObject(new OPenguin(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 = reinterpret_cast(gWorldInstance.AddObject(new OPenguin(pos6, 0x9000, OPenguin::PenguinType::CREDITS, OPenguin::Behaviour::SLIDE3))); + penguin9->MirrorModeAngleOffset = -0x4000; + } else { + Vec3f pos6 = {146.0f, 0.0f, -380.0f}; + auto penguin9 = reinterpret_cast(gWorldInstance.AddObject(new OPenguin(pos6, 0x9000, OPenguin::PenguinType::CHICK, OPenguin::Behaviour::SLIDE3))); + penguin9->MirrorModeAngleOffset = -0x4000; + } + + Vec3f pos7 = {380.0f, 0.0f, -766.0f}; + auto penguin10 = reinterpret_cast(gWorldInstance.AddObject(new OPenguin(pos7, 0x5000, OPenguin::PenguinType::CHICK, OPenguin::Behaviour::SLIDE4))); + penguin10->MirrorModeAngleOffset = 0x8000; + + Vec3f pos8 = {-2300.0f, 0.0f, -210.0f}; + auto penguin11 = reinterpret_cast(gWorldInstance.AddObject(new OPenguin(pos8, 0xC000, OPenguin::PenguinType::CHICK, OPenguin::Behaviour::SLIDE6))); + penguin11->MirrorModeAngleOffset = 0x8000; + + Vec3f pos9 = {-2500.0f, 0.0f, -250.0f}; + auto penguin12 = reinterpret_cast(gWorldInstance.AddObject(new OPenguin(pos9, 0x4000, OPenguin::PenguinType::CHICK, OPenguin::Behaviour::SLIDE6))); + penguin12->MirrorModeAngleOffset = 0x8000; + + Vec3f pos10 = {-535.0f, 0.0f, 875.0f}; + auto penguin13 = reinterpret_cast(gWorldInstance.AddObject(new OPenguin(pos10, 0x8000, OPenguin::PenguinType::CHICK, OPenguin::Behaviour::SLIDE6))); + penguin13->MirrorModeAngleOffset = -0x4000; + + Vec3f pos11 = {-250.0f, 0.0f, 953.0f}; + auto penguin14 = reinterpret_cast(gWorldInstance.AddObject(new OPenguin(pos11, 0x9000, OPenguin::PenguinType::CHICK, OPenguin::Behaviour::SLIDE6))); + penguin14->MirrorModeAngleOffset = -0x4000; + } void SherbetLand::SpawnVehicles() { @@ -163,69 +229,6 @@ void SherbetLand::MinimapSettings() { } void SherbetLand::InitCourseObjects() { - //! @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() { diff --git a/src/engine/courses/ToadsTurnpike.cpp b/src/engine/courses/ToadsTurnpike.cpp index 4acdcd466..47ed10111 100644 --- a/src/engine/courses/ToadsTurnpike.cpp +++ b/src/engine/courses/ToadsTurnpike.cpp @@ -8,6 +8,10 @@ #include "engine/objects/BombKart.h" #include "assets/toads_turnpike_data.h" #include "engine/actors/AFinishline.h" +#include "engine/vehicles/Bus.h" +#include "engine/vehicles/Car.h" +#include "engine/vehicles/Truck.h" +#include "engine/vehicles/TankerTruck.h" #include "engine/vehicles/Utils.h" @@ -257,22 +261,22 @@ void ToadsTurnpike::SpawnVehicles() { for (size_t i = 0; i < _numTrucks; i++) { waypoint = CalculateWaypointDistribution(i, _numTrucks, gWaypointCountByPathIndex[0], 0); - gWorldInstance.AddTruck(a, b, &D_80164550[0][0], waypoint); + gWorldInstance.AddVehicle(new ATruck(a, b, &D_80164550[0][0], waypoint)); } for (size_t i = 0; i < _numBuses; i++) { waypoint = CalculateWaypointDistribution(i, _numBuses, gWaypointCountByPathIndex[0], 75); - gWorldInstance.AddBus(a, b,&D_80164550[0][0], waypoint); + gWorldInstance.AddVehicle(new ABus(a, b,&D_80164550[0][0], waypoint)); } for (size_t i = 0; i < _numTankerTrucks; i++) { waypoint = CalculateWaypointDistribution(i, _numTankerTrucks, gWaypointCountByPathIndex[0], 50); - gWorldInstance.AddTankerTruck(a, b, &D_80164550[0][0], waypoint); + gWorldInstance.AddVehicle(new ATankerTruck(a, b, &D_80164550[0][0], waypoint)); } for (size_t i = 0; i < _numCars; i++) { waypoint = CalculateWaypointDistribution(i, _numCars, gWaypointCountByPathIndex[0], 25); - gWorldInstance.AddCar(a, b, &D_80164550[0][0], waypoint); + gWorldInstance.AddVehicle(new ACar(a, b, &D_80164550[0][0], waypoint)); } if (gModeSelection == VERSUS) { diff --git a/src/engine/objects/BombKart.cpp b/src/engine/objects/BombKart.cpp index 42506f826..c33b4b107 100644 --- a/src/engine/objects/BombKart.cpp +++ b/src/engine/objects/BombKart.cpp @@ -26,8 +26,10 @@ extern "C" { extern s8 gPlayerCount; } -OBombKart::OBombKart(Vec3f pos, TrackWaypoint* waypoint, uint16_t waypointIndex, uint16_t state, f32 unk_3C) { +size_t OBombKart::_count = 0; +OBombKart::OBombKart(Vec3f pos, TrackWaypoint* waypoint, uint16_t waypointIndex, uint16_t state, f32 unk_3C) { + _idx = _count; Vec3f _pos = {0, 0, 0}; if (waypoint) { // Spawn kart on waypoint @@ -68,6 +70,8 @@ OBombKart::OBombKart(Vec3f pos, TrackWaypoint* waypoint, uint16_t waypointIndex, WheelPos[3][1] = _pos[1]; WheelPos[3][2] = _pos[2]; check_bounding_collision(&_Collision, 2.0f, _pos[0], _pos[1], _pos[2]); + + _count++; } void OBombKart::Spawn() { @@ -334,9 +338,7 @@ void OBombKart::Draw(s32 cameraId) { } if (GetCourse() == GetPodiumCeremony()) { - // This isn't functionally equivallent. - // Technicaly it should be if (kart[0].WaypointIndex < 16) - if (WaypointIndex < 16) { + if ((_idx == 0) && (WaypointIndex < 16)) { return; } else { cameraId = PLAYER_FOUR; diff --git a/src/engine/objects/BombKart.h b/src/engine/objects/BombKart.h index 4500e41c2..7ceba7ecb 100644 --- a/src/engine/objects/BombKart.h +++ b/src/engine/objects/BombKart.h @@ -5,6 +5,8 @@ #include #include "engine/Matrix.h" +#include "World.h" + extern "C" { #include "macros.h" #include "main.h" @@ -53,16 +55,26 @@ public: // Set waypoint to NULL if using a spawn position and not a waypoint. explicit OBombKart(Vec3f pos, TrackWaypoint* waypoint, uint16_t waypointIndex, uint16_t state, f32 unk_3C); + ~OBombKart() { + _count--; + } + + static size_t GetCount() { + return _count; + } + void Spawn(); void BeginPlay(); void Tick(); - void Draw(s32 playerId); + void Draw(s32 cameraId); void DrawBattle(s32 cameraId); void Collision(s32 playerId, Player* player); void SomeRender(Vec3f arg1); void LoadMtx(); void Waypoint(s32 screenId); private: + static size_t _count; + s32 _idx; Player* FindTarget(); void Chase(Player*, Vec3f pos); diff --git a/src/engine/objects/Hedgehog.h b/src/engine/objects/Hedgehog.h index dab8cf15a..2057d894d 100644 --- a/src/engine/objects/Hedgehog.h +++ b/src/engine/objects/Hedgehog.h @@ -4,7 +4,7 @@ #include #include "Object.h" -#include "World.h" +#include "engine/World.h" extern "C" { #include "macros.h" diff --git a/src/engine/objects/Penguin.cpp b/src/engine/objects/Penguin.cpp index c126174a1..c690e1ef2 100644 --- a/src/engine/objects/Penguin.cpp +++ b/src/engine/objects/Penguin.cpp @@ -33,16 +33,19 @@ extern "C" { 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; +size_t OPenguin::_count = 0; + +OPenguin::OPenguin(Vec3f pos, u16 direction, PenguinType type, Behaviour behaviour) { + _idx = _count; _type = type; _bhv = behaviour; - s32 objectIndex = indexObjectList1[i]; + if (_idx >= 32) { + printf("MAX penguin REACHED (32), skipping\n"); + return; + } + + s32 objectIndex = indexObjectList1[_idx]; init_object(objectIndex, 0); Object *object = &gObjectList[objectIndex]; @@ -73,6 +76,7 @@ OPenguin::OPenguin(s32 i, Vec3f pos, u16 direction, PenguinType type, Behaviour break; } + _count++; } void OPenguin::Tick(void) { diff --git a/src/engine/objects/Penguin.h b/src/engine/objects/Penguin.h index 0e9c36f49..63c2207c1 100644 --- a/src/engine/objects/Penguin.h +++ b/src/engine/objects/Penguin.h @@ -2,6 +2,8 @@ #include #include +#include "engine/World.h" +#include "engine/objects/Object.h" extern "C" { #include "macros.h" @@ -13,7 +15,7 @@ extern "C" { #include "course_offsets.h" } -class OPenguin { +class OPenguin : public OObject { public: enum PenguinType : uint32_t { CHICK, @@ -36,10 +38,19 @@ 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); + explicit OPenguin(Vec3f pos, u16 direction, PenguinType type, Behaviour behaviour); - void Tick(); - void Draw(s32 playerId); + ~OPenguin() { + _count--; + } + + static size_t GetCount() { + return _count; + } + + + virtual void Tick() override; + virtual void Draw(s32 cameraId) override; private: void Behaviours(s32 objectIndex, s32 arg1); void EmperorPenguin(s32 objectIndex); @@ -51,7 +62,7 @@ private: void OtherPenguin(s32 objectIndex); void InitOtherPenguin(s32 objectIndex); - + static size_t _count; s32 _idx; PenguinType _type; Behaviour _bhv; diff --git a/src/engine/objects/Seagull.cpp b/src/engine/objects/Seagull.cpp index 5f0b12a7e..cced70348 100644 --- a/src/engine/objects/Seagull.cpp +++ b/src/engine/objects/Seagull.cpp @@ -1,8 +1,8 @@ #include #include #include "Seagull.h" -#include "engine/Actor.h" #include +#include "World.h" #include "port/Game.h" @@ -29,9 +29,14 @@ extern SplineData D_800E6280; SplineData* D_800E633C[] = { &D_800E6034, &D_800E60F0, &D_800E61B4, &D_800E6280 }; -OSeagull::OSeagull(s32 i, Vec3f pos) { - size_t objectId; - _idx = i; +size_t OSeagull::_count = 0; + +OSeagull::OSeagull(Vec3f pos) { + size_t objectIndex; + _idx = _count; + _pos[0] = pos[0]; + _pos[1] = pos[1]; + _pos[2] = pos[2]; s16 randZ; s16 randX; @@ -40,60 +45,48 @@ OSeagull::OSeagull(s32 i, Vec3f pos) { randY = random_int(20); randZ = random_int(200) + -100.0; - SpawnPos[0] = pos[0] + randX; - SpawnPos[1] = pos[1] + randY; - SpawnPos[2] = pos[2] + randZ; - //for (i = 0; i < NUM_SEAGULLS; i++) { - //objectId = indexObjectList2[i]; - //init_object(objectId, 0); + objectIndex = indexObjectList2[_idx]; + init_object(objectIndex, 0); - //set_obj_origin_pos(objectId, pos[0], pos[1], pos[2]); - //if (i < (NUM_SEAGULLS / 2)) { - //gObjectList[objectId].unk_0D5 = 0; - //} else { - // gObjectList[objectId].unk_0D5 = 1; - //} - //} + set_obj_origin_pos(objectIndex, pos[0], pos[1], pos[2]); + if (_idx < (NUM_SEAGULLS / 2)) { + gObjectList[objectIndex].unk_0D5 = 0; + } else { + gObjectList[objectIndex].unk_0D5 = 1; + } + + _count++; } -bool OSeagull::IsMod() { return true; } - void OSeagull::Tick() { Object* object; - UNUSED s32* var_s4; - s32 temp_s0; + s32 objectIndex = indexObjectList2[_idx]; - //for (var_s3 = 0; var_s3 < NUM_SEAGULLS; var_s3++) { - //temp_s0 = indexObjectList2[_idx]; - - //object = &gObjectList[temp_s0]; - if (_state == 0) { + object = &gObjectList[objectIndex]; + if (object->state == 0) { return; } - OSeagull::func_80082714(temp_s0, _idx); - OSeagull::func_8008275C(temp_s0); - if (_toggle) { - _toggle = false; + OSeagull::func_80082714(objectIndex, _idx); + OSeagull::func_8008275C(objectIndex); + if (func_80072320(objectIndex, 2) != 0) { + func_800722CC(objectIndex, 2); if (D_80165A90 != 0) { D_80165A90 = 0; D_80183E40[0] = 0.0f; D_80183E40[1] = 0.0f; D_80183E40[2] = 0.0f; if (gGamestate != CREDITS_SEQUENCE) { - func_800C98B8(Pos, D_80183E40, SOUND_ARG_LOAD(0x19, 0x01, 0x70, 0x43)); + func_800C98B8(object->pos, D_80183E40, SOUND_ARG_LOAD(0x19, 0x01, 0x70, 0x43)); } else { - //temp_s0 = indexObjectList2[1]; - //! @todo confirm this is equivallent to indexObjectList2[1]; - if (_idx == 1) { - if (gCutsceneShotTimer <= 150) { - //object = &gObjectList[temp_s0]; - func_800C98B8(Pos, D_80183E40, SOUND_ARG_LOAD(0x19, 0x01, 0x70, 0x43)); - } + objectIndex = indexObjectList2[1]; + if (gCutsceneShotTimer <= 150) { + object = &gObjectList[objectIndex]; + func_800C98B8(object->pos, D_80183E40, SOUND_ARG_LOAD(0x19, 0x01, 0x70, 0x43)); } } } @@ -114,19 +107,16 @@ void OSeagull::Tick() { D_80165908 = 0; } -void OSeagull::Draw(Camera* camera) { // render_object_seagulls - s32 var_s1; - //for (i = 0; i < NUM_SEAGULLS; i++) { - var_s1 = indexObjectList2[_idx]; - //! @todo: Quick hack to let seagull work in actor system. Should be cameraId not camera->playerId - //if (func_8008A364(var_s1, camera->playerId, 0x5555U, 0x000005DC) < 0x9C401 && CVarGetInteger("gNoCulling", 0) == 0) { - D_80165908 = 1; - _toggle = true; - //} - //if (is_obj_flag_status_active(var_s1, VISIBLE) != 0) { - OSeagull::func_800552BC(var_s1); - //} - //} +void OSeagull::Draw(s32 cameraId) { // render_object_seagulls + s32 objectIndex = indexObjectList2[_idx]; + + if (func_8008A364(objectIndex, cameraId, 0x5555U, 0x000005DC) < 0x9C401 && CVarGetInteger("gNoCulling", 0) == 0) { + D_80165908 = 1; + _toggle = true; + } + if (is_obj_flag_status_active(objectIndex, VISIBLE) != 0) { + OSeagull::func_800552BC(objectIndex); + } } void OSeagull::func_800552BC(s32 objectIndex) { @@ -155,11 +145,11 @@ void OSeagull::func_8008275C(s32 objectIndex) { case 2: func_8008B78C(objectIndex); vec3f_copy(gObjectList[objectIndex].unk_01C, gObjectList[objectIndex].pos); - func_8000D940(SpawnPos, (s16*) &gObjectList[objectIndex].unk_0C6, + func_8000D940(gObjectList[objectIndex].origin_pos, (s16*) &gObjectList[objectIndex].unk_0C6, gObjectList[objectIndex].unk_034, 0.0f, 0); - Offset[0] *= 2.0; - Offset[1] *= 2.5; - Offset[2] *= 2.0; + gObjectList[objectIndex].offset[0] *= 2.0; + gObjectList[objectIndex].offset[1] *= 2.5; + gObjectList[objectIndex].offset[2] *= 2.0; object_calculate_new_pos_offset(objectIndex); gObjectList[objectIndex].direction_angle[1] = get_angle_between_two_vectors(gObjectList[objectIndex].unk_01C, gObjectList[objectIndex].pos); @@ -169,31 +159,26 @@ void OSeagull::func_8008275C(s32 objectIndex) { } void OSeagull::func_8008241C(s32 objectIndex, s32 arg1) { - UNUSED s16 stackPadding0; + s16 randZ; + s16 randX; + s16 randY; gObjectList[objectIndex].unk_0D8 = 1; gObjectList[objectIndex].model = (Gfx*) d_course_koopa_troopa_beach_unk4; gObjectList[objectIndex].vertex = (Vtx*) d_course_koopa_troopa_beach_unk_data5; gObjectList[objectIndex].sizeScaling = 0.2f; gObjectList[objectIndex].unk_0DD = 1; - // if (gGamestate == CREDITS_SEQUENCE) { - // set_obj_origin_pos(objectIndex, randX + -360.0, randY + 60.0, randZ + -1300.0); - // } else if (gObjectList[objectIndex].unk_0D5 != 0) { - // set_obj_origin_pos(objectIndex, (randX + 328.0) * xOrientation, randY + 20.0, randZ + 2541.0); - // } else { - // set_obj_origin_pos(objectIndex, (randX + -985.0) * xOrientation, randY + 15.0, randZ + 1200.0); - // } + randX = random_int(0x00C8) + -100.0; + randY = random_int(0x0014); + randZ = random_int(0x00C8) + -100.0; + + set_obj_origin_pos(objectIndex, (randX + _pos[0]) * xOrientation, randY + _pos[1], randZ + _pos[2]); set_obj_direction_angle(objectIndex, 0U, 0U, 0U); gObjectList[objectIndex].unk_034 = 1.0f; func_80086EF0(objectIndex); - //gObjectList[objectIndex].spline = D_800E633C[arg1 % 4]; - spline = D_800E633C[arg1 % 4]; - //set_object_flag(objectIndex, 0x800); - //object_next_state(objectIndex); - _status |= 0x800; - _timer = 0; - _status &= ~0x2000; - _state++; + gObjectList[objectIndex].spline = D_800E633C[arg1 % 4]; + set_object_flag(objectIndex, 0x00000800); + object_next_state(objectIndex); } diff --git a/src/engine/objects/Seagull.h b/src/engine/objects/Seagull.h index 528da0708..d575e3721 100644 --- a/src/engine/objects/Seagull.h +++ b/src/engine/objects/Seagull.h @@ -2,7 +2,9 @@ #include #include -#include "engine/Actor.h" +#include "Object.h" + +#include "engine/World.h" extern "C" { #include "macros.h" @@ -11,34 +13,34 @@ extern "C" { #include "waypoints.h" #include "common_structs.h" #include "objects.h" -#include "course_offsets.h" -#include "some_data.h" +#include "camera.h" } -class OSeagull : public AActor { +class OSeagull : public OObject { public: - enum Behaviour : uint16_t { - }; + explicit OSeagull(Vec3f pos); -public: - explicit OSeagull(s32 i, Vec3f pos); + ~OSeagull() { + _count--; + } + + static size_t GetCount() { + return _count; + } virtual void Tick() override; - virtual void Draw(Camera*) override; + virtual void Draw(s32 cameraId) override; + void func_800552BC(s32 objectIndex); void func_8008275C(s32 objectIndex); void func_8008241C(s32 objectIndex, s32 arg1); void func_80082714(s32 objectIndex, s32 arg1); - virtual bool IsMod() override; - Vec3f Offset; - Vec3f SpawnPos; private: + Vec3f _pos; + static size_t _count; s32 _idx; - s32 _state; - s32 _timer; - s32 _status; bool _toggle; SplineData *spline; diff --git a/src/engine/objects/Thwomp.cpp b/src/engine/objects/Thwomp.cpp index 87d670cfd..afa12b03b 100644 --- a/src/engine/objects/Thwomp.cpp +++ b/src/engine/objects/Thwomp.cpp @@ -44,16 +44,19 @@ f32 D_800E594C[][2] = { s16 D_800E597C[] = { 0x0000, 0x0000, 0x4000, 0x8000, 0x8000, 0xc000 }; -OThwomp::OThwomp(s32 i, s16 x, s16 z, s16 direction, f32 scale, s16 behaviour, s16 primAlpha, u16 boundingBoxSize) { - if (i >= 32) { - printf("MAX THWOMPS REACHED (32), skipping\n"); - return; - } - _idx = i; +size_t OThwomp::_count = 0; + +OThwomp::OThwomp(s16 x, s16 z, s16 direction, f32 scale, s16 behaviour, s16 primAlpha, u16 boundingBoxSize) { + _idx = _count; _faceDirection = direction; _boundingBoxSize = boundingBoxSize; State = (States)behaviour; - s32 objectId = indexObjectList1[i]; + + if (_idx >= 32) { + printf("MAX THWOMPS REACHED (32), skipping\n"); + return; + } + s32 objectId = indexObjectList1[_idx]; init_object(objectId, 0); gObjectList[objectId].origin_pos[0] = x * xOrientation; gObjectList[objectId].origin_pos[2] = z; @@ -66,9 +69,11 @@ OThwomp::OThwomp(s32 i, s16 x, s16 z, s16 direction, f32 scale, s16 behaviour, s } gObjectList[objectId].sizeScaling = scale; + + _count++; } -void OThwomp::Tick() { // func_80081210 +void OThwomp::Tick60fps() { // func_80081210 Player* player; s32 objectIndex; s32 var_s2_3; @@ -80,6 +85,13 @@ void OThwomp::Tick() { // func_80081210 OThwomp::func_8007F8D8(); + // Tick lights only one time. This gets applied to every thwomp. + // Running this more than once per frame will result in the lights moving at a high rate of speed. + if (_idx == 0) { + D_80165834[0] += 0x100; + D_80165834[1] += 0x200; + } + objectIndex = indexObjectList1[_idx]; if (gObjectList[objectIndex].state != 0) { switch (State) { diff --git a/src/engine/objects/Thwomp.h b/src/engine/objects/Thwomp.h index f64318e4d..22c674bb5 100644 --- a/src/engine/objects/Thwomp.h +++ b/src/engine/objects/Thwomp.h @@ -3,6 +3,9 @@ #include #include +#include "engine/World.h" +#include "engine/objects/Object.h" + extern "C" { #include "macros.h" #include "main.h" @@ -27,7 +30,7 @@ extern "C" { * @arg primAlpha unknown * @arg boundingBoxSize optional. The size of the bounding box for the thwomp. Default value is 12 */ -class OThwomp { +class OThwomp : public OObject { private: enum States : uint16_t { DISABLED, @@ -42,12 +45,20 @@ private: public: States State = States::DISABLED; - explicit OThwomp(s32 i, s16 x, s16 z, s16 direction, f32 scale, s16 behaviour, s16 primAlpha, u16 boundingBoxSize); + explicit OThwomp(s16 x, s16 z, s16 direction, f32 scale, s16 behaviour, s16 primAlpha, u16 boundingBoxSize = 7); - void Tick(); + ~OThwomp() { + _count--; + } + + static size_t GetCount() { + return _count; + } + + virtual void Tick60fps() override; + virtual void Draw(s32 cameraId) override; void SetVisibility(s32 objectIndex); void func_80080B28(s32 objectIndex, s32 playerId); - void Draw(s32 playerId); void DrawModel(s32); void TranslateThwompLights(); void ThwompLights(s32 objectIndex); @@ -100,6 +111,7 @@ public: void func_8007E63C(s32 objectIndex); private: + static size_t _count; s32 _idx; s16 _faceDirection; //! @todo Write this better. This effects the squish size and the bounding box size. diff --git a/src/engine/vehicles/Boat.cpp b/src/engine/vehicles/Boat.cpp index c1d7803bb..6a3c2beb1 100644 --- a/src/engine/vehicles/Boat.cpp +++ b/src/engine/vehicles/Boat.cpp @@ -14,10 +14,12 @@ extern "C" { extern s8 gPlayerCount; } -ABoat::ABoat(size_t idx, f32 speed, u32 waypoint) { +size_t ABoat::_count = 0; + +ABoat::ABoat(f32 speed, u32 waypoint) { Path2D* temp_a2; u16 waypointOffset; - Index = idx; + Index = _count; Speed = speed; // Set to the default value @@ -36,6 +38,8 @@ ABoat::ABoat(size_t idx, f32 speed, u32 waypoint) { Velocity[0] = 0.0f; Velocity[1] = 0.0f; Velocity[2] = 0.0f; + + _count++; } void ABoat::Spawn() { diff --git a/src/engine/vehicles/Boat.h b/src/engine/vehicles/Boat.h index 988f498ab..4a1e2d124 100644 --- a/src/engine/vehicles/Boat.h +++ b/src/engine/vehicles/Boat.h @@ -30,7 +30,15 @@ class ABoat : public AVehicle { int16_t AnotherSmokeTimer = 0; int16_t SmokeTimer = 0; - explicit ABoat(size_t idx, f32 speed, uint32_t waypoint); + explicit ABoat(f32 speed, uint32_t waypoint); + + ~ABoat() { + _count--; + } + + static size_t GetCount() { + return _count; + } virtual void Spawn() override; virtual void BeginPlay() override; @@ -38,5 +46,7 @@ class ABoat : public AVehicle { virtual void Draw(s32 playerId) override; virtual void Collision(s32 playerId, Player* player) override; virtual s32 AddSmoke(size_t, Vec3f, f32); +private: + static size_t _count; }; \ No newline at end of file diff --git a/src/engine/vehicles/Bus.cpp b/src/engine/vehicles/Bus.cpp index 36bb576c6..c8b81b4c5 100644 --- a/src/engine/vehicles/Bus.cpp +++ b/src/engine/vehicles/Bus.cpp @@ -16,12 +16,14 @@ extern "C" { extern s8 gPlayerCount; } -ABus::ABus(size_t idx, f32 speedA, f32 speedB, TrackWaypoint* path, uint32_t waypoint) { +size_t ABus::_count = 0; + +ABus::ABus(f32 speedA, f32 speedB, TrackWaypoint* path, uint32_t waypoint) { TrackWaypoint* temp_v0; u16 waypointOffset; s32 numWaypoints = gWaypointCountByPathIndex[0]; - Index = idx; + Index = _count; waypointOffset = waypoint; temp_v0 = &path[waypointOffset]; @@ -54,6 +56,8 @@ ABus::ABus(size_t idx, f32 speedA, f32 speedB, TrackWaypoint* path, uint32_t way func_8000D940(Position, (s16*) &WaypointIndex, Speed, SomeMultiplierTheSequel, 0); } D_801631C8 = 10; + + _count++; } void ABus::Spawn() { diff --git a/src/engine/vehicles/Bus.h b/src/engine/vehicles/Bus.h index ff75d5aff..a7ba3d3e5 100644 --- a/src/engine/vehicles/Bus.h +++ b/src/engine/vehicles/Bus.h @@ -33,11 +33,22 @@ class ABus : public AVehicle { f32 SomeArg4 = 12.5f; u32 SoundBits = SOUND_ARG_LOAD(0x51, 0x01, 0x80, 0x03); - explicit ABus(size_t idx, f32 speedA, f32 speedB, TrackWaypoint* path, uint32_t waypoint); + explicit ABus(f32 speedA, f32 speedB, TrackWaypoint* path, uint32_t waypoint); + + ~ABus() { + _count--; + } + + static size_t GetCount() { + return _count; + } virtual void Spawn() override; virtual void BeginPlay() override; virtual void Tick() override; virtual void Draw(s32 playerId) override; virtual void Collision(s32 playerId, Player* player) override; + +private: + static size_t _count; }; \ No newline at end of file diff --git a/src/engine/vehicles/Car.cpp b/src/engine/vehicles/Car.cpp index 604fe5f2f..8f8d24d1f 100644 --- a/src/engine/vehicles/Car.cpp +++ b/src/engine/vehicles/Car.cpp @@ -16,12 +16,14 @@ extern "C" { extern s8 gPlayerCount; } -ACar::ACar(size_t idx, f32 speedA, f32 speedB, TrackWaypoint* path, uint32_t waypoint) { +size_t ACar::_count = 0; + +ACar::ACar(f32 speedA, f32 speedB, TrackWaypoint* path, uint32_t waypoint) { TrackWaypoint* temp_v0; u16 waypointOffset; s32 numWaypoints = gWaypointCountByPathIndex[0]; - Index = idx; + Index = _count; waypointOffset = waypoint; temp_v0 = &path[waypointOffset]; @@ -54,6 +56,8 @@ ACar::ACar(size_t idx, f32 speedA, f32 speedB, TrackWaypoint* path, uint32_t way func_8000D940(Position, (s16*) &WaypointIndex, Speed, SomeMultiplierTheSequel, 0); } D_801631C8 = 10; + + _count++; } void ACar::Spawn() { diff --git a/src/engine/vehicles/Car.h b/src/engine/vehicles/Car.h index 8ac7421aa..6613e4c56 100644 --- a/src/engine/vehicles/Car.h +++ b/src/engine/vehicles/Car.h @@ -16,7 +16,15 @@ class AVehicle; // Forward declare class ACar : public AVehicle { public: - explicit ACar(size_t idx, f32 speedA, f32 speedB, TrackWaypoint* path, uint32_t waypoint); + explicit ACar(f32 speedA, f32 speedB, TrackWaypoint* path, uint32_t waypoint); + + ~ACar() { + _count--; + } + + static size_t GetCount() { + return _count; + } const char* Type; size_t Index; @@ -40,4 +48,6 @@ class ACar : public AVehicle { virtual void Tick() override; virtual void Draw(s32 playerId) override; virtual void Collision(s32 playerId, Player* player) override; +private: + static size_t _count; }; \ No newline at end of file diff --git a/src/engine/vehicles/TankerTruck.cpp b/src/engine/vehicles/TankerTruck.cpp index 8acd7984c..2c32d5bd6 100644 --- a/src/engine/vehicles/TankerTruck.cpp +++ b/src/engine/vehicles/TankerTruck.cpp @@ -16,12 +16,14 @@ extern "C" { extern s8 gPlayerCount; } -ATankerTruck::ATankerTruck(size_t idx, f32 speedA, f32 speedB, TrackWaypoint* path, uint32_t waypoint) { +size_t ATankerTruck::_count = 0; + +ATankerTruck::ATankerTruck(f32 speedA, f32 speedB, TrackWaypoint* path, uint32_t waypoint) { TrackWaypoint* temp_v0; u16 waypointOffset; s32 numWaypoints = gWaypointCountByPathIndex[0]; - Index = idx; + Index = _count; waypointOffset = waypoint; temp_v0 = &path[waypointOffset]; @@ -54,6 +56,8 @@ ATankerTruck::ATankerTruck(size_t idx, f32 speedA, f32 speedB, TrackWaypoint* pa func_8000D940(Position, (s16*) &WaypointIndex, Speed, SomeMultiplierTheSequel, 0); } D_801631C8 = 10; + + _count++; } void ATankerTruck::Spawn() { diff --git a/src/engine/vehicles/TankerTruck.h b/src/engine/vehicles/TankerTruck.h index 961d5a0fb..fdf838d99 100644 --- a/src/engine/vehicles/TankerTruck.h +++ b/src/engine/vehicles/TankerTruck.h @@ -33,11 +33,22 @@ class ATankerTruck : public AVehicle { f32 SomeArg4 = 12.5f; u32 SoundBits = SOUND_ARG_LOAD(0x51, 0x01, 0x80, 0x03); - explicit ATankerTruck(size_t idx, f32 speedA, f32 speedB, TrackWaypoint* path, uint32_t waypoint); + explicit ATankerTruck(f32 speedA, f32 speedB, TrackWaypoint* path, uint32_t waypoint); + + ~ATankerTruck() { + _count--; + } + + static size_t GetCount() { + return _count; + } virtual void Spawn() override; virtual void BeginPlay() override; virtual void Tick() override; virtual void Draw(s32 playerId) override; virtual void Collision(s32 playerId, Player* player) override; + +private: + static size_t _count; }; \ No newline at end of file diff --git a/src/engine/vehicles/Train.cpp b/src/engine/vehicles/Train.cpp index c34ac1cf3..0e9af21ed 100644 --- a/src/engine/vehicles/Train.cpp +++ b/src/engine/vehicles/Train.cpp @@ -22,12 +22,14 @@ extern "C" { // #include "common_structs.h" } -ATrain::ATrain(size_t idx, ATrain::TenderStatus tender, size_t numCarriages, f32 speed, uint32_t waypoint) { +size_t ATrain::_count = 0; + +ATrain::ATrain(ATrain::TenderStatus tender, size_t numCarriages, f32 speed, uint32_t waypoint) { u16 waypointOffset; TrainCarStuff* ptr1; Path2D* pos; - Index = idx; + Index = _count; Speed = speed; // Set to the default value @@ -73,6 +75,8 @@ ATrain::ATrain(size_t idx, ATrain::TenderStatus tender, size_t numCarriages, f32 NumCars = NUM_TENDERS + numCarriages; AnotherSmokeTimer = 0; + + _count++; } void ATrain::Spawn() { diff --git a/src/engine/vehicles/Train.h b/src/engine/vehicles/Train.h index 0964c8cf9..e2c1d89f4 100644 --- a/src/engine/vehicles/Train.h +++ b/src/engine/vehicles/Train.h @@ -11,6 +11,10 @@ extern "C" { class AVehicle; // Forward declare +/** + * Note that you can only remove the tender if there are no carriages + * @arg waypoint initial waypoint to spawn at. + */ class ATrain : public AVehicle { public: @@ -35,7 +39,15 @@ class ATrain : public AVehicle { int16_t AnotherSmokeTimer = 0; int16_t SmokeTimer = 0; - explicit ATrain(size_t idx, ATrain::TenderStatus tender, size_t numCarriages, f32 speed, uint32_t waypoint); + explicit ATrain(ATrain::TenderStatus tender, size_t numCarriages, f32 speed, uint32_t waypoint); + + ~ATrain() { + _count--; + } + + static size_t GetCount() { + return _count; + } virtual void Spawn() override; virtual void BeginPlay() override; @@ -44,4 +56,7 @@ class ATrain : public AVehicle { virtual void Collision(s32 playerId, Player* player) override; s32 AddSmoke(s32 trainIndex, Vec3f pos, f32 velocity); void SyncComponents(TrainCarStuff* trainCar, s16 orientationY); + +private: + static size_t _count; }; \ No newline at end of file diff --git a/src/engine/vehicles/Truck.cpp b/src/engine/vehicles/Truck.cpp index 139edc644..c865fed70 100644 --- a/src/engine/vehicles/Truck.cpp +++ b/src/engine/vehicles/Truck.cpp @@ -16,12 +16,14 @@ extern "C" { extern s8 gPlayerCount; } -ATruck::ATruck(size_t idx, f32 speedA, f32 speedB, TrackWaypoint* path, uint32_t waypoint) { +size_t ATruck::_count = 0; + +ATruck::ATruck(f32 speedA, f32 speedB, TrackWaypoint* path, uint32_t waypoint) { TrackWaypoint* temp_v0; u16 waypointOffset; s32 numWaypoints = gWaypointCountByPathIndex[0]; - Index = idx; + Index = _count; waypointOffset = waypoint; temp_v0 = &path[waypointOffset]; @@ -54,6 +56,8 @@ ATruck::ATruck(size_t idx, f32 speedA, f32 speedB, TrackWaypoint* path, uint32_t func_8000D940(Position, (s16*) &WaypointIndex, Speed, SomeMultiplierTheSequel, 0); } D_801631C8 = 10; + + _count++; } void ATruck::Spawn() { diff --git a/src/engine/vehicles/Truck.h b/src/engine/vehicles/Truck.h index 8781feaad..f9f65b2fc 100644 --- a/src/engine/vehicles/Truck.h +++ b/src/engine/vehicles/Truck.h @@ -33,11 +33,22 @@ class ATruck : public AVehicle { f32 SomeArg4 = 12.5f; u32 SoundBits = SOUND_ARG_LOAD(0x51, 0x01, 0x80, 0x03); - explicit ATruck(size_t idx, f32 speedA, f32 speedB, TrackWaypoint* path, uint32_t waypoint); + explicit ATruck(f32 speedA, f32 speedB, TrackWaypoint* path, uint32_t waypoint); + + ~ATruck() { + _count--; + } + + static size_t GetCount() { + return _count; + } virtual void Spawn() override; virtual void BeginPlay() override; virtual void Tick() override; virtual void Draw(s32 playerId) override; virtual void Collision(s32 playerId, Player* player) override; + +private: + static size_t _count; }; \ No newline at end of file diff --git a/src/port/Game.cpp b/src/port/Game.cpp index 90869508e..70634713a 100644 --- a/src/port/Game.cpp +++ b/src/port/Game.cpp @@ -301,8 +301,6 @@ extern "C" { gWorldInstance.ClearVehicles(); gWorldInstance.Crossings.clear(); gWorldInstance.BombKarts.clear(); - gWorldInstance.Thwomps.clear(); - gWorldInstance.Penguins.clear(); } void CourseManager_CrossingTrigger() { @@ -570,61 +568,6 @@ extern "C" { gWorldInstance.Lakitus[playerId]->Activate(OLakitu::LakituType::REVERSE); } - extern Vec3su D_80165834; - void CourseManager_TickThwomps() { - // TickLights - if (gWorldInstance.Thwomps.size()) { - D_80165834[0] += 0x100; - D_80165834[1] += 0x200; - } - - for (auto& thwomp : gWorldInstance.Thwomps) { - if (thwomp) { - thwomp->Tick(); - } - } - } - - void CourseManager_DrawThwomps(s32 cameraId) { - for (auto& thwomp : gWorldInstance.Thwomps) { - if (thwomp) { - thwomp->Draw(cameraId); - } - } - } - - void CourseManager_TickPenguins(void) { - for (auto& penguin : gWorldInstance.Penguins) { - if (penguin) { - penguin->Tick(); - } - } - } - - void CourseManager_DrawSeagulls(s32 cameraId) { - for (auto& seagull : gWorldInstance.Seagulls) { - if (seagull) { - // seagull->Draw(cameraId); - } - } - } - - void CourseManager_TickSeagulls(void) { - for (auto& seagull : gWorldInstance.Seagulls) { - if (seagull) { - //seagull->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 76ae4ac2d..ba4e1d359 100644 --- a/src/port/Game.h +++ b/src/port/Game.h @@ -109,18 +109,6 @@ void CourseManager_ClearVehicles(void); void CourseManager_DrawVehicles(s32 playerId); -void CourseManager_DrawThwomps(s32 cameraId); - -void CourseManager_TickThwomps(); - -void CourseManager_DrawSeagulls(s32 cameraId); - -void CourseManager_TickSeagulls(); - -void CourseManager_DrawPenguins(s32 cameraId); - -void CourseManager_TickPenguins(); - void CourseManager_CrossingTrigger(); void CourseManager_VehiclesCollision(s32 playerId, Player* player); From 57afb90c3901b4c5dc586f1be3f6604c52c423d6 Mon Sep 17 00:00:00 2001 From: MegaMech Date: Sun, 29 Dec 2024 23:58:52 -0700 Subject: [PATCH 20/21] Add todo --- src/engine/objects/Seagull.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/engine/objects/Seagull.h b/src/engine/objects/Seagull.h index d575e3721..c6898dcc2 100644 --- a/src/engine/objects/Seagull.h +++ b/src/engine/objects/Seagull.h @@ -16,7 +16,7 @@ extern "C" { #include "camera.h" } - +//! @todo unk_0D5 needs to be a struct variable probably. What does it do? Behaviour? class OSeagull : public OObject { public: explicit OSeagull(Vec3f pos); From 41fb92b7b989290947d8f39c442219afe12d0215 Mon Sep 17 00:00:00 2001 From: MegaMech <7255464+MegaMech@users.noreply.github.com> Date: Mon, 30 Dec 2024 20:39:14 -0700 Subject: [PATCH 21/21] Impl trashbin --- src/engine/courses/BansheeBoardwalk.cpp | 14 ++- src/engine/objects/TrashBin.cpp | 132 +++++++++++++++++++++--- src/engine/objects/TrashBin.h | 13 ++- 3 files changed, 141 insertions(+), 18 deletions(-) diff --git a/src/engine/courses/BansheeBoardwalk.cpp b/src/engine/courses/BansheeBoardwalk.cpp index 92551f058..7f1847900 100644 --- a/src/engine/courses/BansheeBoardwalk.cpp +++ b/src/engine/courses/BansheeBoardwalk.cpp @@ -156,10 +156,17 @@ void BansheeBoardwalk::SpawnActors() { gWorldInstance.AddObject(new OCheepCheep(FVector(xOrientation * -1650.0, -200.0f, -1650.0f), OCheepCheep::CheepType::RACE, IPathSpan(160, 170))); - if (gIsMirrorMode) { - gWorldInstance.AddObject(new OTrashBin(FVector(1765.0f, 45.0f, 195.0f), FRotation(0, 180.0f, 0), 1.0f)); + OTrashBin::Behaviour bhv; + if (gModeSelection == TIME_TRIALS) { + bhv = OTrashBin::Behaviour::STATIC; } else { - gWorldInstance.AddObject(new OTrashBin(FVector(-1765.0f, 45.0f, 70.0f), FRotation(0, 0, 0), 1.0f)); + bhv = OTrashBin::Behaviour::MUNCHING; + } + + if (gIsMirrorMode) { + gWorldInstance.AddObject(new OTrashBin(FVector(1765.0f, 45.0f, 195.0f), FRotation(0, 180.0f, 0), 1.0f, bhv)); + } else { + gWorldInstance.AddObject(new OTrashBin(FVector(-1765.0f, 45.0f, 70.0f), FRotation(0, 0, 0), 1.0f, bhv)); } } @@ -197,7 +204,6 @@ void BansheeBoardwalk::InitCourseObjects() { gObjectList[objectId].orientation[0] = 0; gObjectList[objectId].orientation[1] = 0; gObjectList[objectId].orientation[2] = 0x8000; - init_object(indexObjectList1[1], 0); init_object(indexObjectList1[2], 0); } } diff --git a/src/engine/objects/TrashBin.cpp b/src/engine/objects/TrashBin.cpp index 8a090be5d..43d43b1fc 100644 --- a/src/engine/objects/TrashBin.cpp +++ b/src/engine/objects/TrashBin.cpp @@ -1,7 +1,11 @@ +#include +#include #include "TrashBin.h" #include "World.h" +#include "port/Game.h" extern "C" { +#include "main.h" #include "code_800029B0.h" #include "render_objects.h" #include "update_objects.h" @@ -16,27 +20,29 @@ extern "C" { #define DEGREES_FLOAT_TO_SHORT(Degrees) ((s16)((Degrees) * (0x8000 / 180.0f))) -OTrashBin::OTrashBin(const FVector& pos, const FRotation& rotation, f32 scale) { +OTrashBin::OTrashBin(const FVector& pos, const FRotation& rotation, f32 scale, OTrashBin::Behaviour bhv) { _pos = pos; _rot = rotation; _scale = scale; + _bhv = bhv; - // if (gIsMirrorMode != 0) { - // gObjectList[objectIndex].pos[0] = 1765.0f; - // gObjectList[objectIndex].pos[2] = 195.0f; - // gObjectList[objectIndex].orientation[1] = (s16) rotation.y; - // } else { - // gObjectList[objectIndex].pos[0] = -1765.0f; - // gObjectList[objectIndex].pos[2] = 70.0f; - // } + init_object(indexObjectList1[1], 0); + if (GetCourse() != GetBansheeBoardwalk()) { + _drawBin = true; + } } void OTrashBin::Tick() { s32 objectIndex = indexObjectList1[1]; OTrashBin::func_8007E00C(objectIndex); - if (gModeSelection != TIME_TRIALS) { - func_8007DDC0(objectIndex); + + switch(_bhv) { + case STATIC: + break; + case MUNCHING: + func_8007DDC0(objectIndex); + break; } } @@ -51,11 +57,22 @@ void OTrashBin::Draw(s32 cameraId) { if (object->state >= 2) { func_80043220(object->pos, object->orientation, object->sizeScaling, object->model); } + + if (_drawBin) { + Mat4 mtx; + Vec3f Pos = { _pos.x + 63, _pos.y + 12, _pos.z + 25 }; + Vec3s Rot = { 0, 0x4000, 0 }; + mtxf_pos_rotation_xyz(mtx, Pos, Rot); + //mtxf_scale(mtx, 1.0f); + if (render_set_position(mtx, 0) != 0) { + gSPDisplayList(gDisplayListHead++, BinMod); + } + } } } void OTrashBin::init_bb_trash_bin(s32 objectIndex) { - gObjectList[objectIndex].sizeScaling = _scale; + gObjectList[objectIndex].sizeScaling = 1.0f; gObjectList[objectIndex].model = (Gfx*)d_course_banshee_boardwalk_dl_trash_bin; gObjectList[objectIndex].unk_04C = 0; gObjectList[objectIndex].unk_084[7] = 0; @@ -64,7 +81,15 @@ void OTrashBin::init_bb_trash_bin(s32 objectIndex) { gObjectList[objectIndex].orientation[1] = DEGREES_FLOAT_TO_SHORT(_rot.yaw); gObjectList[objectIndex].orientation[2] = DEGREES_FLOAT_TO_SHORT(_rot.roll); gObjectList[objectIndex].pos[0] = _pos.x; - gObjectList[objectIndex].pos[1] = _pos.y; + if (_drawBin) { + // Position the lid on-top of the box. + // This might not be the best fix, but this allows the box to be placed on a surface + // when spawned at 0,0,0 + gObjectList[objectIndex].pos[0] = _pos.y + 32.0f; + } else { + // Stock implementation for banshee boardwalk + gObjectList[objectIndex].pos[1] = _pos.y; + } gObjectList[objectIndex].pos[2] = _pos.z; set_obj_velocity(objectIndex, 0.0f, 0.0f, 0.0f); gObjectList[objectIndex].type = 0; @@ -123,3 +148,84 @@ void OTrashBin::func_8007E00C(s32 objectIndex) { break; } } + +Gfx OTrashBin::BinMod[] = +{ + gsSPTexture(0xFFFF, 0xFFFF, 0, G_TX_RENDERTILE, G_ON), + gsDPTileSync(), + gsDPSetTile(G_IM_FMT_RGBA, G_IM_SIZ_16b, 8, 0x0000, G_TX_RENDERTILE, 0, G_TX_NOMIRROR | G_TX_WRAP, 5, G_TX_NOLOD, G_TX_NOMIRROR | G_TX_WRAP, 5, G_TX_NOLOD), + gsDPSetTileSize(G_TX_RENDERTILE, 0, 0, 0x007C, 0x007C), + gsDPSetTextureImage(G_IM_FMT_RGBA, G_IM_SIZ_16b, 1, gTexture651B20), + gsDPTileSync(), + gsDPSetTile(G_IM_FMT_RGBA, G_IM_SIZ_16b, 0, 0x0000, G_TX_LOADTILE, 0, G_TX_NOMIRROR | G_TX_WRAP, G_TX_NOMASK, G_TX_NOLOD, G_TX_NOMIRROR | G_TX_WRAP, G_TX_NOMASK, G_TX_NOLOD), + gsDPLoadSync(), + gsDPLoadBlock(G_TX_LOADTILE, 0, 0, 1023, 256), + gsSPVertex(BinVtx, 20, 0), + gsSP2Triangles(0, 1, 2, 0, 0, 2, 3, 0), + gsSP2Triangles(4, 5, 6, 0, 4, 6, 7, 0), + gsSP2Triangles(8, 9, 10, 0, 8, 10, 11, 0), + gsSP2Triangles(12, 13, 14, 0, 12, 14, 15, 0), + gsSP2Triangles(16, 17, 18, 0, 16, 18, 19, 0), + gsSPVertex(BinVtx2, 20, 0), + gsSP2Triangles(0, 1, 2, 0, 0, 2, 3, 0), + gsSP2Triangles(4, 5, 6, 0, 4, 6, 7, 0), + gsSP2Triangles(8, 9, 10, 0, 8, 10, 11, 0), + gsSP2Triangles(12, 13, 14, 0, 12, 14, 15, 0), + gsSP2Triangles(16, 17, 18, 0, 16, 18, 19, 0), + gsDPPipeSync(), + gsDPSetCombineLERP(0, 0, 0, SHADE, 0, 0, 0, ENVIRONMENT, 0, 0, 0, SHADE, 0, 0, 0, ENVIRONMENT), + gsSPTexture(65535, 65535, 0, 0, 0), + gsSPEndDisplayList(), +}; + + + + + + + +Vtx OTrashBin::BinVtx[20] = { + {{ {25, -13, 62}, 0, {0, -2303}, {255, 255, 255, 0} }}, + {{ {-25, -13, 62}, 0, {1280, -2303}, {255, 255, 255, 0} }}, + {{ {-25, -13, -63}, 0, {1280, 896}, {255, 255, 255, 0} }}, + {{ {25, -13, -63}, 0, {0, 895}, {255, 255, 255, 0} }}, + {{ {25, -13, -63}, 0, {0, 1113}, {255, 255, 255, 0} }}, + {{ {25, 20, -63}, 0, {0, 256}, {255, 255, 255, 0} }}, + {{ {25, 20, 62}, 0, {3199, 256}, {255, 255, 255, 0} }}, + {{ {25, -13, 62}, 0, {3199, 1113}, {255, 255, 255, 0} }}, + {{ {-25, -13, -63}, 0, {0, 1113}, {255, 255, 255, 0} }}, + {{ {-25, 20, -63}, 0, {0, 255}, {255, 255, 255, 0} }}, + {{ {25, 20, -63}, 0, {1280, 255}, {255, 255, 255, 0} }}, + {{ {25, -13, -63}, 0, {1280, 1113}, {255, 255, 255, 0} }}, + {{ {-25, -13, 62}, 0, {0, 1113}, {255, 255, 255, 0} }}, + {{ {-25, 20, 62}, 0, {0, 255}, {255, 255, 255, 0} }}, + {{ {-25, 20, -63}, 0, {3200, 255}, {255, 255, 255, 0} }}, + {{ {-25, -13, -63}, 0, {3200, 1113}, {255, 255, 255, 0} }}, + {{ {25, -13, 62}, 0, {0, 1113}, {255, 255, 255, 0} }}, + {{ {25, 20, 62}, 0, {0, 256}, {255, 255, 255, 0} }}, + {{ {-25, 20, 62}, 0, {1279, 256}, {255, 255, 255, 0} }}, + {{ {-25, -13, 62}, 0, {1279, 1113}, {255, 255, 255, 0} }}, +}; + +Vtx OTrashBin::BinVtx2[20] = { + {{ {19, -8, 52}, 0, {3199, 1113}, {255, 255, 255, 0} }}, + {{ {25, 20, 62}, 0, {3199, 256}, {255, 255, 255, 0} }}, + {{ {25, 20, -63}, 0, {0, 256}, {255, 255, 255, 0} }}, + {{ {19, -8, -52}, 0, {0, 1113}, {255, 255, 255, 0} }}, + {{ {19, -8, -52}, 0, {1280, 1113}, {255, 255, 255, 0} }}, + {{ {25, 20, -63}, 0, {1280, 255}, {255, 255, 255, 0} }}, + {{ {-25, 20, -63}, 0, {0, 255}, {255, 255, 255, 0} }}, + {{ {-19, -8, -52}, 0, {0, 1113}, {255, 255, 255, 0} }}, + {{ {-19, -8, 52}, 0, {1279, 1113}, {255, 255, 255, 0} }}, + {{ {-25, 20, 62}, 0, {1279, 256}, {255, 255, 255, 0} }}, + {{ {25, 20, 62}, 0, {0, 256}, {255, 255, 255, 0} }}, + {{ {19, -8, 52}, 0, {0, 1113}, {255, 255, 255, 0} }}, + {{ {19, -8, -52}, 0, {0, 895}, {255, 255, 255, 0} }}, + {{ {-19, -8, -52}, 0, {1280, 896}, {255, 255, 255, 0} }}, + {{ {-19, -8, 52}, 0, {1280, -2303}, {255, 255, 255, 0} }}, + {{ {19, -8, 52}, 0, {0, -2303}, {255, 255, 255, 0} }}, + {{ {-19, -8, -52}, 0, {3200, 1113}, {255, 255, 255, 0} }}, + {{ {-25, 20, -63}, 0, {3200, 255}, {255, 255, 255, 0} }}, + {{ {-25, 20, 62}, 0, {0, 255}, {255, 255, 255, 0} }}, + {{ {-19, -8, 52}, 0, {0, 1113}, {255, 255, 255, 0} }}, +}; diff --git a/src/engine/objects/TrashBin.h b/src/engine/objects/TrashBin.h index 328cb4778..2ef500f92 100644 --- a/src/engine/objects/TrashBin.h +++ b/src/engine/objects/TrashBin.h @@ -19,7 +19,12 @@ extern "C" { class OTrashBin : public OObject { public: - explicit OTrashBin(const FVector& pos, const FRotation& rotation, f32 scale); + + enum Behaviour { + STATIC, // The lid stays shut + MUNCHING // The lid opens/closes in a scary munching manner + }; + explicit OTrashBin(const FVector& pos, const FRotation& rotation, f32 scale, OTrashBin::Behaviour bhv); virtual void Tick() override; virtual void Draw(s32 cameraId) override; @@ -27,8 +32,14 @@ public: void init_bb_trash_bin(s32); private: + static Gfx BinMod[]; + static Vtx BinVtx[]; + static Vtx BinVtx2[]; + + Behaviour _bhv; FVector _pos; FRotation _rot; float _scale; size_t _idx; + bool _drawBin = false; };