From 4a5640272366c3f5446d8f2e49f24e79fa513a66 Mon Sep 17 00:00:00 2001 From: Dominik Peters Date: Wed, 7 May 2025 15:31:38 +0200 Subject: [PATCH] match: func_800135B8 (#559) * match: func_800135B8 * fix: format * Update src/objects.c * Update src/objects.c * Update src/objects.c * Update src/objects.c * Update src/objects.c Co-authored-by: Fazana <52551480+FazanaJ@users.noreply.github.com> --------- Co-authored-by: Fazana <52551480+FazanaJ@users.noreply.github.com> --- README.md | 12 +- include/structs.h | 19 ++- src/game_ui.c | 365 +++++++++++++++++++++++----------------------- src/objects.c | 89 +++++++++-- src/objects.h | 13 ++ 5 files changed, 293 insertions(+), 205 deletions(-) diff --git a/README.md b/README.md index 5121154b..a0f38fe7 100644 --- a/README.md +++ b/README.md @@ -5,9 +5,9 @@ This repo contains a work-in-progress decompilation of Diddy Kong Racing for the All versions are supported, and the US 1.0 version (SHA1 = 0cb115d8716dbbc2922fda38e533b9fe63bb9670) of the game is the default if not specified. -As of May 6, 2025, this is our current score: +As of May 7, 2025, this is our current score: -    Decomp progress: 85.64% +    Decomp progress: 85.73%     Documentation progress: 56.69% @@ -117,13 +117,13 @@ s32 is_drumstick_unlocked(void) { ``` -As of May 6, 2025, this is our current score: +As of May 7, 2025, this is our current score: ``` ===================================================================== ADVENTURE ONE (ASM -> C Decompilation) - --------------- 85.64% Complete (86.80% NON_MATCHING) --------------- - # Decompiled functions: 1882 - # GLOBAL_ASM remaining: 69 + --------------- 85.73% Complete (86.89% NON_MATCHING) --------------- + # Decompiled functions: 1883 + # GLOBAL_ASM remaining: 68 # NON_MATCHING functions: 7 # NON_EQUIVALENT WIP functions: 25 ---------------------------- Game Status ---------------------------- diff --git a/include/structs.h b/include/structs.h index e4196c9e..b5cae4b4 100644 --- a/include/structs.h +++ b/include/structs.h @@ -1052,10 +1052,23 @@ typedef struct Object_Fish { /* 0x11c */ f32 unk11C; } Object_Fish; +typedef struct Object_Boost_Inner { + Vec3f position; + f32 unkC; + f32 unk10; + u8 pad[0x24 - 0x14]; +} Object_Boost_Inner; + typedef struct Object_Boost { - /* 0x000 */ u8 pad[0x70]; - /* 0x070 */ u8 unk70; - /* 0x074 */ f32 unk74; + Object_Boost_Inner unk0; + Object_Boost_Inner unk24; + Object_Boost_Inner unk48; + u8 pad6C[4]; + u8 unk70; + u8 unk71; + u8 unk72; + u8 unk73; + f32 unk74; } Object_Boost; typedef struct Object_EffectBox { diff --git a/src/game_ui.c b/src/game_ui.c index dbb64cc2..93a9217a 100644 --- a/src/game_ui.c +++ b/src/game_ui.c @@ -3581,191 +3581,192 @@ void hud_render_general(Gfx **dList, MatrixS **mtx, Vertex **vtx, s32 updateRate *dList = gHudDL; *mtx = gHudMtx; *vtx = gHudVtx; - if (!(gHudLevelHeader->unkBC & 1)) { - sp113 = TRUE; - for (i = 0; i < objectCount; i++) { - someRacer = (Object_Racer *) objectGroup[i]->unk64; - if (someRacer != NULL && someRacer->playerIndex != PLAYER_COMPUTER && someRacer->raceFinished == FALSE) { - sp113 = FALSE; - } - } - if ((gHUDNumPlayers == THREE_PLAYERS && is_postrace_viewport_active()) || check_if_showing_cutscene_camera() || - sp113) { - goto test; - } else if (gHudToggleSettings[gHUDNumPlayers] != 1) { - test: - return; - } else { - rendermode_reset(&gHudDL); - set_ortho_matrix_view(&gHudDL, &gHudMtx); - lvlMdl = get_current_level_model(); - if (lvlMdl == NULL) { - return; - } - someObjSeg = get_active_camera_segment(); - sprite_anim_off(TRUE); - minimap = (Sprite *) lvlMdl->minimapSpriteIndex; - switch (gHUDNumPlayers) { - case TWO_PLAYERS: - gMinimapScreenX = 135; - gMinimapScreenY = -gMinimapDotOffsetY / 2; - break; - case THREE_PLAYERS: - if (get_current_level_race_type() == RACETYPE_CHALLENGE_EGGS || - get_current_level_race_type() == RACETYPE_CHALLENGE_BATTLE || - get_current_level_race_type() == RACETYPE_CHALLENGE_BANANAS) { - gMinimapScreenX = (gMinimapDotOffsetX / 2) - 8; - gMinimapScreenY = -gMinimapDotOffsetY / 2; - } else { - gMinimapScreenX = (gMinimapDotOffsetX / 2) + 72; - gMinimapScreenY = -60 - (gMinimapDotOffsetY / 2); - } - break; - case FOUR_PLAYERS: - gMinimapScreenX = (gMinimapDotOffsetX / 2) - 8; - gMinimapScreenY = -gMinimapDotOffsetY / 2; - break; - default: - gMinimapScreenX = 135; - gMinimapScreenY = -98; - break; - } - if (osTvType == OS_TV_TYPE_PAL) { - gMinimapScreenY *= 1.2; - } - sprite_opaque(FALSE); - hudElem.pos.x = gMinimapScreenX + gHudOffsetX + gHudBounceX; - hudElem.pos.y = gMinimapScreenY; - if (osTvType == OS_TV_TYPE_PAL) { - hudElem.pos.x -= 4.0f; - } - hudElem.rotation.z_rotation = -someObjSeg->trans.rotation.z_rotation; - hudElem.rotation.x_rotation = 0; - if (get_filtered_cheats() & CHEAT_MIRRORED_TRACKS) { - hudElem.rotation.y_rotation = -0x8000; - hudElem.pos.x -= gMinimapDotOffsetX; - } else { - hudElem.rotation.y_rotation = 0; - } - hudElem.spriteOffset = 0; - hudElem.pos.z = 0.0f; - hudElem.scale = 1.0f; - opacity = mapOpacity; - if (mapOpacity > 160) { - mapOpacity = 160; - } - if (gNumActivePlayers == 3) { - gDPSetPrimColor(gHudDL++, 0, 0, 255, 255, 255, mapOpacity); - } else { - gDPSetPrimColor(gHudDL++, 0, 0, gMinimapRed, gMinimapGreen, gMinimapBlue, mapOpacity); - } - render_ortho_triangle_image(&gHudDL, &gHudMtx, &gHudVtx, (ObjectSegment *) &hudElem, minimap, 0); - sp11C = (lvlMdl->upperXBounds - lvlMdl->lowerXBounds) / (f32) (lvlMdl->upperZBounds - lvlMdl->lowerZBounds); - sp118 = coss_f((lvlMdl->minimapRotation * 0xFFFF) / 360); - sp114 = sins_f((lvlMdl->minimapRotation * 0xFFFF) / 360); - if (is_in_time_trial() && timetrial_valid_player_ghost()) { - temp_v0_8 = timetrial_player_ghost(); - if (temp_v0_8 != NULL) { - minimap_marker_pos(temp_v0_8->segment.trans.x_position, temp_v0_8->segment.trans.z_position, sp114, - sp118, sp11C); - gCurrentHud->entry[HUD_MINIMAP_MARKER].spriteID = HUD_SPRITE_MAP_DOT; - gCurrentHud->entry[HUD_MINIMAP_MARKER].rotation.z_rotation = 0; - gCurrentHud->entry[HUD_MINIMAP_MARKER].scale = 1.0f; - tempVar1 = (opacity * (f32) temp_v0_8->segment.object.opacity) * (1.0 / 128.0); - gDPSetPrimColor(gHudDL++, 0, 0, 60, 60, 60, tempVar1); - hud_element_render(&gHudDL, &gHudMtx, &gHudVtx, &gCurrentHud->entry[HUD_MINIMAP_MARKER]); - } - } - temp_v0_8 = timetrial_ghost_staff(); - if (temp_v0_8 != NULL) { - minimap_marker_pos(temp_v0_8->segment.trans.x_position, temp_v0_8->segment.trans.z_position, sp114, - sp118, sp11C); - gCurrentHud->entry[HUD_MINIMAP_MARKER].rotation.z_rotation = 0; - tempVar1 = (opacity * (f32) temp_v0_8->segment.object.opacity) * (1.0 / 128.0); - gDPSetPrimColor(gHudDL++, 0, 0, gHudMinimapColours[8].red, gHudMinimapColours[8].green, - gHudMinimapColours[8].blue, tempVar1); - gCurrentHud->entry[HUD_MINIMAP_MARKER].scale = 1.0f; - gCurrentHud->entry[HUD_MINIMAP_MARKER].spriteID = HUD_SPRITE_MAP_DOT; - hud_element_render(&gHudDL, &gHudMtx, &gHudVtx, &gCurrentHud->entry[HUD_MINIMAP_MARKER]); - } - // Draw Taj's minimap icon. - if (gHudLevelHeader->race_type == RACETYPE_HUBWORLD) { - temp_v0_8 = find_taj_object(); - if (temp_v0_8 != NULL) { - gCurrentHud->entry[HUD_MINIMAP_MARKER].spriteID = HUD_SPRITE_MAP_DOT; - minimap_marker_pos(temp_v0_8->segment.trans.x_position, temp_v0_8->segment.trans.z_position, sp114, - sp118, sp11C); - gCurrentHud->entry[HUD_MINIMAP_MARKER].rotation.z_rotation = 0; - gDPSetPrimColor(gHudDL++, 0, 0, 255, 0, 255, opacity); - gCurrentHud->entry[HUD_MINIMAP_MARKER].scale = 1.0f; - hud_element_render(&gHudDL, &gHudMtx, &gHudVtx, &gCurrentHud->entry[HUD_MINIMAP_MARKER]); - } - } - // Draw racer minimap icons. - // Non AI players get an arrow instead of a blob that rotates. - for (i = objectCount - 1; i >= 0; i--) { - temp_v0_8 = objectGroup[i]; - someRacer = (Object_Racer *) objectGroup[i]->unk64; - if (someRacer != NULL) { - minimap_marker_pos(objectGroup[i]->segment.trans.x_position, - objectGroup[i]->segment.trans.z_position, sp114, sp118, sp11C); - if (someRacer->playerIndex != PLAYER_COMPUTER) { - gCurrentHud->entry[HUD_MINIMAP_MARKER].pos.y -= 1.0f; - gCurrentHud->entry[HUD_MINIMAP_MARKER].spriteID = HUD_SPRITE_MAP_ARROW; - gCurrentHud->entry[HUD_MINIMAP_MARKER].rotation.z_rotation = - (objectGroup[i]->segment.trans.rotation.y_rotation - - ((lvlMdl->minimapRotation * 0xFFFF) / 360)) & - 0xFFFF; + if ((gHudLevelHeader->unkBC & 1)) { + return; + } - if (get_filtered_cheats() & CHEAT_MIRRORED_TRACKS) { - gCurrentHud->entry[HUD_MINIMAP_MARKER].rotation.z_rotation = - 0xFFFF - gCurrentHud->entry[HUD_MINIMAP_MARKER].rotation.z_rotation; - } - sprite_opaque(TRUE); - } else { - gCurrentHud->entry[HUD_MINIMAP_MARKER].rotation.z_rotation = 0; - gCurrentHud->entry[HUD_MINIMAP_MARKER].spriteID = HUD_SPRITE_MAP_DOT; - } - if (is_taj_challenge() && someRacer->vehicleID == VEHICLE_CARPET) { - gDPSetPrimColor(gHudDL++, 0, 0, 255, 0, 255, opacity); - } else { - gDPSetPrimColor(gHudDL++, 0, 0, gHudMinimapColours[someRacer->characterId].red, - gHudMinimapColours[someRacer->characterId].green, - gHudMinimapColours[someRacer->characterId].blue, opacity); - } - if (!(get_current_level_race_type() & RACETYPE_CHALLENGE) || (!someRacer->raceFinished)) { - if (osTvType == OS_TV_TYPE_PAL) { - gCurrentHud->entry[HUD_MINIMAP_MARKER].pos.x -= 4.0f; - } - if (get_current_level_race_type() == RACETYPE_CHALLENGE_BATTLE) { - switch (someRacer->elevation) { - case ELEVATION_LOW: - gCurrentHud->entry[HUD_MINIMAP_MARKER].scale = 0.8f; - break; - case ELEVATION_NORMAL: - gCurrentHud->entry[HUD_MINIMAP_MARKER].scale = 1.0f; - break; - case ELEVATION_HIGH: - case ELEVATION_HIGHEST: - gCurrentHud->entry[HUD_MINIMAP_MARKER].scale = 1.2f; - break; - } - } else { - gCurrentHud->entry[HUD_MINIMAP_MARKER].scale = 1.0f; - } - hud_element_render(&gHudDL, &gHudMtx, &gHudVtx, &gCurrentHud->entry[HUD_MINIMAP_MARKER]); - } - sprite_opaque(FALSE); - } - } - gDPPipeSync(gHudDL++); - sprite_anim_off(FALSE); - sprite_opaque(TRUE); - *dList = gHudDL; - *mtx = gHudMtx; - *vtx = gHudVtx; + sp113 = TRUE; + for (i = 0; i < objectCount; i++) { + someRacer = (Object_Racer *) objectGroup[i]->unk64; + if (someRacer != NULL && someRacer->playerIndex != PLAYER_COMPUTER && someRacer->raceFinished == FALSE) { + sp113 = FALSE; } } + if ((gHUDNumPlayers == THREE_PLAYERS && is_postrace_viewport_active()) || check_if_showing_cutscene_camera() || + sp113) { + goto test; + } else if (gHudToggleSettings[gHUDNumPlayers] != 1) { + test: + return; + } + + rendermode_reset(&gHudDL); + set_ortho_matrix_view(&gHudDL, &gHudMtx); + lvlMdl = get_current_level_model(); + if (lvlMdl == NULL) { + return; + } + someObjSeg = get_active_camera_segment(); + sprite_anim_off(TRUE); + minimap = (Sprite *) lvlMdl->minimapSpriteIndex; + switch (gHUDNumPlayers) { + case TWO_PLAYERS: + gMinimapScreenX = 135; + gMinimapScreenY = -gMinimapDotOffsetY / 2; + break; + case THREE_PLAYERS: + if (get_current_level_race_type() == RACETYPE_CHALLENGE_EGGS || + get_current_level_race_type() == RACETYPE_CHALLENGE_BATTLE || + get_current_level_race_type() == RACETYPE_CHALLENGE_BANANAS) { + gMinimapScreenX = (gMinimapDotOffsetX / 2) - 8; + gMinimapScreenY = -gMinimapDotOffsetY / 2; + } else { + gMinimapScreenX = (gMinimapDotOffsetX / 2) + 72; + gMinimapScreenY = -60 - (gMinimapDotOffsetY / 2); + } + break; + case FOUR_PLAYERS: + gMinimapScreenX = (gMinimapDotOffsetX / 2) - 8; + gMinimapScreenY = -gMinimapDotOffsetY / 2; + break; + default: + gMinimapScreenX = 135; + gMinimapScreenY = -98; + break; + } + if (osTvType == OS_TV_TYPE_PAL) { + gMinimapScreenY *= 1.2; + } + sprite_opaque(FALSE); + hudElem.pos.x = gMinimapScreenX + gHudOffsetX + gHudBounceX; + hudElem.pos.y = gMinimapScreenY; + if (osTvType == OS_TV_TYPE_PAL) { + hudElem.pos.x -= 4.0f; + } + hudElem.rotation.z_rotation = -someObjSeg->trans.rotation.z_rotation; + hudElem.rotation.x_rotation = 0; + if (get_filtered_cheats() & CHEAT_MIRRORED_TRACKS) { + hudElem.rotation.y_rotation = -0x8000; + hudElem.pos.x -= gMinimapDotOffsetX; + } else { + hudElem.rotation.y_rotation = 0; + } + hudElem.spriteOffset = 0; + hudElem.pos.z = 0.0f; + hudElem.scale = 1.0f; + opacity = mapOpacity; + if (mapOpacity > 160) { + mapOpacity = 160; + } + if (gNumActivePlayers == 3) { + gDPSetPrimColor(gHudDL++, 0, 0, 255, 255, 255, mapOpacity); + } else { + gDPSetPrimColor(gHudDL++, 0, 0, gMinimapRed, gMinimapGreen, gMinimapBlue, mapOpacity); + } + render_ortho_triangle_image(&gHudDL, &gHudMtx, &gHudVtx, (ObjectSegment *) &hudElem, minimap, 0); + sp11C = (lvlMdl->upperXBounds - lvlMdl->lowerXBounds) / (f32) (lvlMdl->upperZBounds - lvlMdl->lowerZBounds); + sp118 = coss_f((lvlMdl->minimapRotation * 0xFFFF) / 360); + sp114 = sins_f((lvlMdl->minimapRotation * 0xFFFF) / 360); + if (is_in_time_trial() && timetrial_valid_player_ghost()) { + temp_v0_8 = timetrial_player_ghost(); + if (temp_v0_8 != NULL) { + minimap_marker_pos(temp_v0_8->segment.trans.x_position, temp_v0_8->segment.trans.z_position, sp114, sp118, + sp11C); + gCurrentHud->entry[HUD_MINIMAP_MARKER].spriteID = HUD_SPRITE_MAP_DOT; + gCurrentHud->entry[HUD_MINIMAP_MARKER].rotation.z_rotation = 0; + gCurrentHud->entry[HUD_MINIMAP_MARKER].scale = 1.0f; + tempVar1 = (opacity * (f32) temp_v0_8->segment.object.opacity) * (1.0 / 128.0); + gDPSetPrimColor(gHudDL++, 0, 0, 60, 60, 60, tempVar1); + hud_element_render(&gHudDL, &gHudMtx, &gHudVtx, &gCurrentHud->entry[HUD_MINIMAP_MARKER]); + } + } + temp_v0_8 = timetrial_ghost_staff(); + if (temp_v0_8 != NULL) { + minimap_marker_pos(temp_v0_8->segment.trans.x_position, temp_v0_8->segment.trans.z_position, sp114, sp118, + sp11C); + gCurrentHud->entry[HUD_MINIMAP_MARKER].rotation.z_rotation = 0; + tempVar1 = (opacity * (f32) temp_v0_8->segment.object.opacity) * (1.0 / 128.0); + gDPSetPrimColor(gHudDL++, 0, 0, gHudMinimapColours[8].red, gHudMinimapColours[8].green, + gHudMinimapColours[8].blue, tempVar1); + gCurrentHud->entry[HUD_MINIMAP_MARKER].scale = 1.0f; + gCurrentHud->entry[HUD_MINIMAP_MARKER].spriteID = HUD_SPRITE_MAP_DOT; + hud_element_render(&gHudDL, &gHudMtx, &gHudVtx, &gCurrentHud->entry[HUD_MINIMAP_MARKER]); + } + // Draw Taj's minimap icon. + if (gHudLevelHeader->race_type == RACETYPE_HUBWORLD) { + temp_v0_8 = find_taj_object(); + if (temp_v0_8 != NULL) { + gCurrentHud->entry[HUD_MINIMAP_MARKER].spriteID = HUD_SPRITE_MAP_DOT; + minimap_marker_pos(temp_v0_8->segment.trans.x_position, temp_v0_8->segment.trans.z_position, sp114, sp118, + sp11C); + gCurrentHud->entry[HUD_MINIMAP_MARKER].rotation.z_rotation = 0; + gDPSetPrimColor(gHudDL++, 0, 0, 255, 0, 255, opacity); + gCurrentHud->entry[HUD_MINIMAP_MARKER].scale = 1.0f; + hud_element_render(&gHudDL, &gHudMtx, &gHudVtx, &gCurrentHud->entry[HUD_MINIMAP_MARKER]); + } + } + // Draw racer minimap icons. + // Non AI players get an arrow instead of a blob that rotates. + for (i = objectCount - 1; i >= 0; i--) { + temp_v0_8 = objectGroup[i]; + someRacer = (Object_Racer *) objectGroup[i]->unk64; + if (someRacer != NULL) { + minimap_marker_pos(objectGroup[i]->segment.trans.x_position, objectGroup[i]->segment.trans.z_position, + sp114, sp118, sp11C); + if (someRacer->playerIndex != PLAYER_COMPUTER) { + gCurrentHud->entry[HUD_MINIMAP_MARKER].pos.y -= 1.0f; + gCurrentHud->entry[HUD_MINIMAP_MARKER].spriteID = HUD_SPRITE_MAP_ARROW; + gCurrentHud->entry[HUD_MINIMAP_MARKER].rotation.z_rotation = + (objectGroup[i]->segment.trans.rotation.y_rotation - ((lvlMdl->minimapRotation * 0xFFFF) / 360)) & + 0xFFFF; + + if (get_filtered_cheats() & CHEAT_MIRRORED_TRACKS) { + gCurrentHud->entry[HUD_MINIMAP_MARKER].rotation.z_rotation = + 0xFFFF - gCurrentHud->entry[HUD_MINIMAP_MARKER].rotation.z_rotation; + } + sprite_opaque(TRUE); + } else { + gCurrentHud->entry[HUD_MINIMAP_MARKER].rotation.z_rotation = 0; + gCurrentHud->entry[HUD_MINIMAP_MARKER].spriteID = HUD_SPRITE_MAP_DOT; + } + if (is_taj_challenge() && someRacer->vehicleID == VEHICLE_CARPET) { + gDPSetPrimColor(gHudDL++, 0, 0, 255, 0, 255, opacity); + } else { + gDPSetPrimColor(gHudDL++, 0, 0, gHudMinimapColours[someRacer->characterId].red, + gHudMinimapColours[someRacer->characterId].green, + gHudMinimapColours[someRacer->characterId].blue, opacity); + } + if (!(get_current_level_race_type() & RACETYPE_CHALLENGE) || (!someRacer->raceFinished)) { + if (osTvType == OS_TV_TYPE_PAL) { + gCurrentHud->entry[HUD_MINIMAP_MARKER].pos.x -= 4.0f; + } + if (get_current_level_race_type() == RACETYPE_CHALLENGE_BATTLE) { + switch (someRacer->elevation) { + case ELEVATION_LOW: + gCurrentHud->entry[HUD_MINIMAP_MARKER].scale = 0.8f; + break; + case ELEVATION_NORMAL: + gCurrentHud->entry[HUD_MINIMAP_MARKER].scale = 1.0f; + break; + case ELEVATION_HIGH: + case ELEVATION_HIGHEST: + gCurrentHud->entry[HUD_MINIMAP_MARKER].scale = 1.2f; + break; + } + } else { + gCurrentHud->entry[HUD_MINIMAP_MARKER].scale = 1.0f; + } + hud_element_render(&gHudDL, &gHudMtx, &gHudVtx, &gCurrentHud->entry[HUD_MINIMAP_MARKER]); + } + sprite_opaque(FALSE); + } + } + gDPPipeSync(gHudDL++); + sprite_anim_off(FALSE); + sprite_opaque(TRUE); + *dList = gHudDL; + *mtx = gHudMtx; + *vtx = gHudVtx; } /** diff --git a/src/objects.c b/src/objects.c index 05c52dea..9763d7e4 100644 --- a/src/objects.c +++ b/src/objects.c @@ -60,8 +60,8 @@ s8 D_800DC73C = 0; s8 D_800DC740 = 0; s8 gSwapLeadPlayer = FALSE; s8 D_800DC748 = FALSE; -s32 D_800DC74C[2] = { 0, 0 }; // Have a feeling these are both the same array. -s32 D_800DC754[2] = { 0, 0 }; +Vertex *D_800DC74C[2] = { 0, 0 }; +Triangle *D_800DC754[2] = { 0, 0 }; Object *gShieldEffectObject = NULL; s32 D_800DC760 = 9; // Currently unknown, might be a different type. Object *gMagnetEffectObject = NULL; @@ -319,11 +319,11 @@ s32 D_8011AFF8; s32 D_8011AFFC; s32 D_8011B000; s32 D_8011B004; -s32 D_8011B008; +s32 D_8011B008; // indexes D_800DC74C and D_800DC754 u8 D_8011B010[16]; Object *D_8011B020[NUMBER_OF_CHARACTERS]; -s32 D_8011B048[4]; -s32 D_8011B058[4]; +u8 D_8011B048[16]; +u8 D_8011B058[16]; u8 D_8011B068[16]; ColourRGBA D_8011B078[NUMBER_OF_CHARACTERS]; // Note: D_8011B078 might not be a ColourRGBA. @@ -342,10 +342,11 @@ void func_8000B020(s32 numberOfVertices, s32 numberOfTriangles) { LevelObjectEntry_unk8000B020 objEntry; s32 i; - D_800DC754[0] = (s32) mempool_alloc_safe(((numberOfTriangles * 16) + (numberOfVertices * 10)) * 2, COLOUR_TAG_BLUE); - D_800DC754[1] = D_800DC754[0] + (numberOfTriangles * 16); - D_800DC74C[0] = D_800DC754[1] + (numberOfTriangles * 16); - D_800DC74C[1] = D_800DC74C[0] + (numberOfVertices * 10); + D_800DC754[0] = (Triangle *) mempool_alloc_safe( + ((numberOfTriangles * sizeof(Triangle)) + (numberOfVertices * sizeof(Vertex))) * 2, COLOUR_TAG_BLUE); + D_800DC754[1] = (Triangle *) ((u32) D_800DC754[0] + numberOfTriangles * sizeof(Triangle)); + D_800DC74C[0] = (Vertex *) ((u32) D_800DC754[1] + numberOfTriangles * sizeof(Triangle)); + D_800DC74C[1] = (Vertex *) ((u32) D_800DC74C[0] + numberOfVertices * sizeof(Vertex)); D_8011AFF8 = numberOfVertices; D_8011AFFC = 0; D_8011B000 = numberOfTriangles; @@ -397,13 +398,11 @@ void func_8000B020(s32 numberOfVertices, s32 numberOfTriangles) { void func_8000B290(void) { Sprite *sprite; TextureHeader *texture; - s32 temp_a0; Asset20 *asset20; u32 i; - temp_a0 = D_800DC754[0]; - if (temp_a0 != 0) { - mempool_free((void *) temp_a0); + if (D_800DC754[0] != 0) { + mempool_free(D_800DC754[0]); D_800DC754[0] = 0; D_800DC754[1] = 0; D_800DC74C[0] = 0; @@ -3360,7 +3359,69 @@ void unset_temp_model_transforms(Object *obj) { } } -#pragma GLOBAL_ASM("asm/nonmatchings/objects/func_800135B8.s") +// Renders the boost graphics. +void func_800135B8(Object *boostObj) { + Vertex *vtx; + Triangle *tri; + ObjectTransform_800135B8 objTransform; + Object_Boost_Inner *boostData; + Object_Boost *boost; + UnkAsset_800135B8 *asset; + s32 hasTexture; + s32 idx; + + idx = (boostObj->properties.common.unk4 >> 0x1C) & 0xF; + boost = &boostObj->unk64->boost; + switch (D_8011B048[idx]) { + case 0: + boostData = &boost->unk0; + break; + case 1: + boostData = &boost->unk24; + break; + default: + boostData = &boost->unk48; + break; + } + asset = (UnkAsset_800135B8 *)get_misc_asset(20); + asset = &asset[D_8011B058[idx]]; + object_do_player_tumble((Object *) boostObj->properties.common.unk0); + camera_push_model_mtx(&gObjectCurrDisplayList, &gObjectCurrMatrix, + (ObjectTransform *) boostObj->properties.common.unk0, 1.0f, 0.0f); + object_undo_player_tumble((Object *) boostObj->properties.common.unk0); + objTransform.trans.x_position = boostData->position.x; + objTransform.trans.y_position = boostData->position.y; + objTransform.trans.z_position = boostData->position.z; + objTransform.trans.scale = boostData->unkC + (boostData->unk10 * coss_f(boost->unk72 << 0xC)); + if (boost->unk70 < 2) { + objTransform.trans.scale *= boost->unk74; + } + if (D_8011B058[idx] != 0) { + objTransform.trans.scale *= 1.15f; + } + objTransform.trans.rotation.z_rotation = 0; + objTransform.trans.rotation.x_rotation = 0; + objTransform.trans.rotation.y_rotation = 0; + objTransform.unk18 = 0; + gDPSetPrimColor(gObjectCurrDisplayList++, 0, 0, 255, 255, 255, 255); + gDPSetEnvColor(gObjectCurrDisplayList++, 255, 255, 255, 0); + render_sprite_billboard(&gObjectCurrDisplayList, &gObjectCurrMatrix, &gObjectCurrVertexList, + (Object *) &objTransform, asset->unk78, 0x10A); + if (boost->unk70 == 2) { + material_set(&gObjectCurrDisplayList, asset->unk7C, 0xE, 0); + if (asset->unk7C != NULL) { + hasTexture = 1; + } else { + hasTexture = 0; + } + + vtx = &D_800DC74C[D_8011B008][(boostObj->properties.common.unk4 >> 14) & 0x3FFF]; + tri = &D_800DC754[D_8011B008][boostObj->properties.common.unk4 & 0x3FFF]; + gSPVertexDKR(gObjectCurrDisplayList++, OS_K0_TO_PHYSICAL(vtx), 9, 0); + gSPPolygon(gObjectCurrDisplayList++, OS_K0_TO_PHYSICAL(tri), 8, hasTexture); + } + apply_matrix_from_stack(&gObjectCurrDisplayList); +} /** * Render the bubble trap weapon. diff --git a/src/objects.h b/src/objects.h index bd90c9fb..ef002226 100644 --- a/src/objects.h +++ b/src/objects.h @@ -306,6 +306,19 @@ typedef struct unk80022CFC_1 { s32 unk78; } unk80022CFC_1; +/* Size: 0x1A bytes */ +typedef struct ObjectTransform_800135B8 { + ObjectTransform trans; + s16 unk18; +} ObjectTransform_800135B8; + +/* Size: 0x80 bytes */ +typedef struct UnkAsset_800135B8 { + u8 pad0[0x78]; + unk80068514_arg4 *unk78; + TextureHeader *unk7C; +} UnkAsset_800135B8; + typedef struct unk8001A7D8_arg0 { u8 pad0[4]; s32 *unk4;