Fixes as per Sonic (#154)

* Fix imGUI game reset button

* Fix course select cursor sound oob

* Fix cloud rendering

* Fix centering of tt race data cannot be saved by ghost

* Impl chain chomp & bats

* Fix retry crash

* DebugMode On Skips intro logo menu

* rename
This commit is contained in:
MegaMech
2025-01-13 21:15:16 -07:00
committed by GitHub
parent 389f0f4951
commit 04d56d6ba0
20 changed files with 711 additions and 355 deletions
+3 -3
View File
@@ -115,7 +115,7 @@ UNUSED u32 D_8015F718[3]; // Likely held ptrs to segmented data.
size_t gFreeMemorySize;
uintptr_t gNextFreeMemoryAddress;
uintptr_t gHeapEndPtr;
u32 D_8015F730;
uintptr_t gFreeMemoryCourseAnchor; // Reset gNextFreeMemoryAddress to just after courses were loaded
uintptr_t gFreeMemoryResetAnchor;
Vec3f D_8015F738;
Vec3f D_8015F748;
@@ -204,9 +204,9 @@ void setup_race(void) {
gNextFreeMemoryAddress = gFreeMemoryResetAnchor;
load_course(gCurrentCourseId);
course_init();
D_8015F730 = gNextFreeMemoryAddress;
gFreeMemoryCourseAnchor = gNextFreeMemoryAddress;
} else {
gNextFreeMemoryAddress = D_8015F730;
gNextFreeMemoryAddress = gFreeMemoryCourseAnchor;
}
func_802969F8();
func_80005310();
+8 -1
View File
@@ -102,7 +102,14 @@ extern size_t gFreeMemorySize;
extern uintptr_t gNextFreeMemoryAddress;
extern uintptr_t gHeapEndPtr;
extern u32 D_8015F730;
/**
* This repoints gNextFreeMemoryAddress to the point in the memory pool just after a course was loaded.
* This allows players to retry or reset a course without reloading the whole course.
* Memory allocated after course load is not zeroed or reset. But should get overwritten by future allocations.
*
* This is a relatively unsafe way to architect a memory pool as old memory could accidentally be used if future allocations do not zero or fully overwrite their free memory.
*/
extern uintptr_t gFreeMemoryCourseAnchor;
extern uintptr_t gFreeMemoryResetAnchor;
extern Vec3f D_8015F738;
extern Vec3f D_8015F748;
-2
View File
@@ -770,8 +770,6 @@ void func_80070714(void) {
D_80165748 = 0xA;
}
// const char* sBoardwalkTexList[] = { gTextureBat1, gTextureBat2, gTextureBat3, gTextureBat4 };
void init_course_object(void) {
s32 objectId;
s32 i;
-18
View File
@@ -1154,24 +1154,6 @@ void func_80089820(s32 objectIndex, f32 arg1, f32 arg2, u32 arg3) {
}
}
void func_80089A04(s32 objectIndex, f32 arg1, f32 arg2) {
Player* player;
s32 var_s1;
player = gPlayerOne;
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 | STAR_EFFECT)) &&
(has_collided_with_player(objectIndex, player) != 0)) {
func_8008933C(player, objectIndex, arg1, arg2 * 1.1);
if (is_obj_flag_status_active(objectIndex, 0x04000000) != 0) {
func_80072180();
}
}
}
}
}
s32 func_80089B50(s32 objectIndex) {
Player* player;
s32 sp40;
+1 -1
View File
@@ -148,7 +148,7 @@ void load_credits(void) {
gActiveScreenMode = SCREEN_MODE_1P;
gNextFreeMemoryAddress = gFreeMemoryResetAnchor;
load_course(gCurrentCourseId);
D_8015F730 = gNextFreeMemoryAddress;
gFreeMemoryCourseAnchor = gNextFreeMemoryAddress;
#ifdef TARGET_N64
set_segment_base_addr(0xB, (void*) decompress_segments((u8*) CEREMONY_DATA_ROM_START, (u8*) CEREMONY_DATA_ROM_END));
#endif
+1 -1
View File
@@ -111,7 +111,7 @@ void setup_podium_ceremony(void) {
gActiveScreenMode = SCREEN_MODE_1P;
gModeSelection = GRAND_PRIX;
load_course(gCurrentCourseId);
D_8015F730 = (s32) gNextFreeMemoryAddress;
gFreeMemoryCourseAnchor = (s32) gNextFreeMemoryAddress;
#ifdef TARGET_N64
set_segment_base_addr(0xB, (void*) decompress_segments((u8*) CEREMONY_DATA_ROM_START, (u8*) CEREMONY_DATA_ROM_END));
set_segment_base_addr(6, (void*) decompress_segments((u8*) &_course_banshee_boardwalk_dl_mio0SegmentRomStart,
+6
View File
@@ -14,6 +14,8 @@ extern "C" {
#include "main.h"
#include "engine/Engine.h"
#include "defines.h"
#include "audio/external.h"
#include "menus.h"
}
World::World() {}
@@ -69,6 +71,8 @@ u32 World::NextCup() {
CupIndex++;
CurrentCup = Cups[CupIndex];
CurrentCup->CursorPosition = 0;
reset_cycle_flash_menu();
play_sound2(SOUND_MENU_CURSOR_MOVE);
return CupIndex;
}
return Cups.size() - hack;
@@ -79,6 +83,8 @@ u32 World::PreviousCup() {
CupIndex--;
CurrentCup = Cups[CupIndex];
CurrentCup->CursorPosition = 0;
reset_cycle_flash_menu();
play_sound2(SOUND_MENU_CURSOR_MOVE);
return CupIndex;
}
return 0;
+7 -10
View File
@@ -9,6 +9,7 @@
#include "engine/objects/BombKart.h"
#include "engine/objects/CheepCheep.h"
#include "engine/objects/TrashBin.h"
#include "engine/objects/Bat.h"
#include "assets/banshee_boardwalk_data.h"
#include "assets/boo_frames.h"
@@ -167,6 +168,10 @@ void BansheeBoardwalk::SpawnActors() {
} else {
gWorldInstance.AddObject(new OTrashBin(FVector(-1765.0f, 45.0f, 70.0f), FRotation(0, 0, 0), 1.0f, bhv));
}
if ((gGamestate != CREDITS_SEQUENCE) && (gModeSelection != TIME_TRIALS)) {
gWorldInstance.AddObject(new OBat(FVector(0,0,0), FRotation(0, 0, 90.0f)));
}
}
void BansheeBoardwalk::SpawnVehicles() {
@@ -192,17 +197,9 @@ void BansheeBoardwalk::MinimapSettings() {
D_8018D2E8 = 39;
}
const char* sBoardwalkTexList[] = { gTextureBat1, gTextureBat2, gTextureBat3, gTextureBat4 };
void BansheeBoardwalk::InitCourseObjects() {
size_t objectId = 0;
if (gGamestate != CREDITS_SEQUENCE) {
objectId = indexObjectList1[0];
init_texture_object(objectId, (uint8_t*)d_course_banshee_boardwalk_bat_tlut, sBoardwalkTexList, 0x20U,
(u16) 0x00000040);
gObjectList[objectId].orientation[0] = 0;
gObjectList[objectId].orientation[1] = 0;
gObjectList[objectId].orientation[2] = 0x8000;
init_object(indexObjectList1[2], 0);
}
}
@@ -211,7 +208,7 @@ void BansheeBoardwalk::UpdateCourseObjects() {
if (gGamestate != CREDITS_SEQUENCE) {
func_8007E4C4();
if (gModeSelection != TIME_TRIALS) {
update_bat();
//update_bat();
}
wrapper_update_boos();
}
@@ -219,7 +216,7 @@ void BansheeBoardwalk::UpdateCourseObjects() {
void BansheeBoardwalk::RenderCourseObjects(s32 cameraId) {
if (gGamestate != CREDITS_SEQUENCE) {
render_object_bat(cameraId);
//render_object_bat(cameraId);
render_object_boos(cameraId);
}
}
+13 -5
View File
@@ -6,6 +6,7 @@
#include "RainbowRoad.h"
#include "World.h"
#include "engine/actors/AFinishline.h"
#include "engine/objects/ChainChomp.h"
#include "engine/objects/BombKart.h"
#include "assets/rainbow_road_data.h"
@@ -136,6 +137,16 @@ void RainbowRoad::SpawnActors() {
gWorldInstance.AddActor(new AFinishline());
spawn_all_item_boxes((struct ActorSpawnData*)LOAD_ASSET_RAW(d_course_rainbow_road_item_box_spawns));
if (gGamestate != CREDITS_SEQUENCE) {
gWorldInstance.AddObject(new OChainChomp());
gWorldInstance.AddObject(new OChainChomp());
gWorldInstance.AddObject(new OChainChomp());
gWorldInstance.AddObject(new OChainChomp());
gWorldInstance.AddObject(new OChainChomp());
gWorldInstance.AddObject(new OChainChomp());
gWorldInstance.AddObject(new OChainChomp());
}
}
void RainbowRoad::SpawnVehicles() {
@@ -175,23 +186,20 @@ void RainbowRoad::InitCourseObjects() {
for (i = 0; i < NUM_NEON_SIGNS; i++) {
init_object(indexObjectList1[i], 0);
}
for (i = 0; i < NUM_CHAIN_CHOMPS; i++) {
init_object(indexObjectList2[i], 0);
}
}
}
void RainbowRoad::UpdateCourseObjects() {
if (gGamestate != CREDITS_SEQUENCE) {
update_neon();
update_chain_chomps();
//update_chain_chomps();
}
}
void RainbowRoad::RenderCourseObjects(s32 cameraId) {
if (gGamestate != CREDITS_SEQUENCE) {
render_object_neon(cameraId);
render_object_chain_chomps(cameraId);
//render_object_chain_chomps(cameraId);
}
}
+256
View File
@@ -0,0 +1,256 @@
#include "Bat.h"
#include "World.h"
#include "CoreMath.h"
extern "C" {
#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 "code_800029B0.h"
}
const char* sBoardwalkTexList[] = { gTextureBat1, gTextureBat2, gTextureBat3, gTextureBat4 };
size_t OBat::_count = 0;
OBat::OBat(const FVector& pos, const FRotation& rot) {
s32 objectId = indexObjectList1[0];
init_texture_object(objectId, (uint8_t*)d_course_banshee_boardwalk_bat_tlut, sBoardwalkTexList, 0x20U,
(u16) 0x00000040);
gObjectList[objectId].orientation[0] = rot.pitch;
gObjectList[objectId].orientation[1] = rot.roll;
gObjectList[objectId].orientation[2] = rot.yaw; // 0x8000
_count++;
}
void OBat::Tick() {
s32 var_s2;
s32 temp_s0;
Object* object;
if (D_8018CFC8 != 0) {
D_8018CFC8 -= 1;
}
if (D_8018D000 != 0) {
D_8018D000 -= 1;
}
temp_s0 = indexObjectList1[0];
func_80072E54(temp_s0, 0, 3, 1, 0, -1);
func_80073514(temp_s0);
object = &gObjectList[temp_s0];
func_80073CB0(temp_s0, &object->primAlpha, -0x00001000, 0x00001000, 0x00000400, 0, -1);
object->orientation[2] = object->primAlpha + 0x8000;
if ((D_8018CFB0 != 0) || (D_8018CFC8 != 0)) {
D_8018CFD8 = 0;
for (var_s2 = 0; var_s2 < 40; var_s2++) {
temp_s0 = gObjectParticle2[var_s2];
if (temp_s0 == -1) {
continue;
}
object = &gObjectList[temp_s0];
if (object->state == 0) {
continue;
}
OBat::func_8007D8D4(temp_s0, 1);
OBat::func_8007DAF8(temp_s0, 1);
OBat::func_8007D794(temp_s0);
if (object->state == 0) {
delete_object_wrapper(&gObjectParticle2[var_s2]);
}
D_8018CFD8 += 1;
}
if (D_8018CFD8 != 0) {
D_8018CFC8 = 0x012C;
}
}
if ((D_8018CFE8 != 0) || (D_8018D000 != 0)) {
D_8018D010 = 0;
for (var_s2 = 0; var_s2 < 30; var_s2++) {
temp_s0 = gObjectParticle3[var_s2];
if (temp_s0 == -1) {
continue;
}
object = &gObjectList[temp_s0];
if (object->state == 0) {
continue;
}
OBat::func_8007D8D4(temp_s0, 2);
OBat::func_8007DAF8(temp_s0, 2);
OBat::func_8007D794(temp_s0);
if (object->state == 0) {
delete_object_wrapper(&gObjectParticle3[var_s2]);
}
D_8018D010 += 1;
}
if (D_8018D010 != 0) {
D_8018D000 = 0x012C;
}
}
}
void OBat::Draw(s32 cameraId) {
s32 var_s2;
s32 objectIndex;
Camera* temp_s7;
objectIndex = indexObjectList1[0];
temp_s7 = &camera1[cameraId];
OBat::func_80046F60((u8*)gObjectList[objectIndex].activeTLUT, (u8*)gObjectList[objectIndex].activeTexture, 0x00000020, 0x00000040,
5);
D_80183E80[0] = gObjectList[objectIndex].orientation[0];
D_80183E80[2] = gObjectList[objectIndex].orientation[2];
if ((D_8018CFB0 != 0) || (D_8018CFC8 != 0)) {
for (var_s2 = 0; var_s2 < 40; var_s2++) {
objectIndex = gObjectParticle2[var_s2];
if (objectIndex == -1) {
continue;
}
if ((gObjectList[objectIndex].state >= 2) && (gMatrixHudCount < 0x2EF)) {
D_80183E80[1] =
func_800418AC(gObjectList[objectIndex].pos[0], gObjectList[objectIndex].pos[2], temp_s7->pos);
func_800431B0(gObjectList[objectIndex].pos, D_80183E80, gObjectList[objectIndex].sizeScaling,
(Vtx*)D_0D0062B0);
}
}
}
if ((D_8018CFE8 != 0) || (D_8018D000 != 0)) {
for (var_s2 = 0; var_s2 < 30; var_s2++) {
objectIndex = gObjectParticle3[var_s2];
if (objectIndex == -1) {
continue;
}
if ((gObjectList[objectIndex].state >= 2) && (gMatrixHudCount < 0x2EF)) {
D_80183E80[1] =
func_800418AC(gObjectList[objectIndex].pos[0], gObjectList[objectIndex].pos[2], temp_s7->pos);
func_800431B0(gObjectList[objectIndex].pos, D_80183E80, gObjectList[objectIndex].sizeScaling,
(Vtx*)D_0D0062B0);
}
}
}
gSPTexture(gDisplayListHead++, 0x0001, 0x0001, 0, G_TX_RENDERTILE, G_OFF);
}
void OBat::func_80046F60(u8* tlut, u8* arg1, s32 arg2, s32 arg3, s32 arg4) {
gSPDisplayList(gDisplayListHead++, (Gfx*)D_0D007D78);
gDPLoadTLUT_pal256(gDisplayListHead++, tlut);
rsp_load_texture_mask(arg1, arg2, arg3, arg4);
}
void OBat::func_8007D8AC(s32 arg0) {
object_next_state(arg0);
func_80086E70(arg0);
}
s32 OBat::func_8007D804(s32 objectIndex) {
s32 loopIndex;
s32 someCount;
someCount = 0;
for (loopIndex = 0; loopIndex < gPlayerCountSelection1; loopIndex++) {
if (is_object_visible_on_camera(objectIndex, &camera1[loopIndex], 0x4000U) != 0) {
someCount += 1;
}
}
return someCount;
}
void OBat::func_8007D8D4(s32 objectIndex, s32 arg1) {
switch (gObjectList[objectIndex].state) {
case 1:
OBat::func_8007D8AC(objectIndex);
break;
case 2:
if (OBat::func_8007D804(objectIndex) == 0) {
func_80072428(objectIndex);
}
if (arg1 == 1) {
if (gIsMirrorMode != 0) {
if (gObjectList[objectIndex].pos[0] >= 2540.0) {
func_80072428(objectIndex);
}
} else if (gObjectList[objectIndex].pos[0] <= -2540.0) {
func_80072428(objectIndex);
}
} else if (gIsMirrorMode != 0) {
if (gObjectList[objectIndex].pos[0] >= 2150.0) {
func_80072428(objectIndex);
}
} else {
if (gObjectList[objectIndex].pos[0] <= -2150.0) {
func_80072428(objectIndex);
}
}
break;
case 0:
break;
}
}
void OBat::func_8007DA74(s32 objectIndex) {
UNUSED s32 pad;
if ((gObjectList[objectIndex].unk_0AE != 0) && (gObjectList[objectIndex].unk_0AE == 1)) {
if (func_80087060(objectIndex, 0x0000001E) != 0) {
gObjectList[objectIndex].unk_0C6 = 0U;
}
}
gObjectList[objectIndex].direction_angle[0] =
func_800417B4(gObjectList[objectIndex].direction_angle[0], gObjectList[objectIndex].unk_0C6);
func_80087844(objectIndex);
object_calculate_new_pos_offset(objectIndex);
}
void OBat::func_8007DA4C(s32 objectIndex) {
func_8008781C(objectIndex);
object_calculate_new_pos_offset(objectIndex);
}
void OBat::func_8007DAF8(s32 objectIndex, s32 arg1) {
switch (arg1) {
case 1:
OBat::func_8007DA74(objectIndex);
return;
case 2:
OBat::func_8007DA4C(objectIndex);
return;
}
}
void OBat::func_80089A04(s32 objectIndex, f32 arg1, f32 arg2) {
Player* player;
s32 var_s1;
player = gPlayerOne;
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 | STAR_EFFECT)) &&
(has_collided_with_player(objectIndex, player) != 0)) {
func_8008933C(player, objectIndex, arg1, arg2 * 1.1);
if (is_obj_flag_status_active(objectIndex, 0x04000000) != 0) {
func_80072180();
}
}
}
}
}
void OBat::func_8007D794(s32 objectIndex) {
if (gCCSelection == CC_50) {
OBat::func_80089A04(objectIndex, 0.5f, 0.2f);
} else if (gCCSelection == CC_100) {
OBat::func_80089A04(objectIndex, 0.4f, 0.15f);
} else {
OBat::func_80089A04(objectIndex, 0.25f, 0.1f);
}
}
+59
View File
@@ -0,0 +1,59 @@
#pragma once
#include <libultraship.h>
#include <vector>
#include "Object.h"
#include "World.h"
#include "CoreMath.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"
}
/**
* OBat
*
* FRotation does not appear to do anything.
* Could not find where origin_pos was at.
* So pos does not work either
*
*/
class OBat : public OObject {
public:
explicit OBat(const FVector& pos, const FRotation& rot);
~OBat() {
_count--;
}
static size_t GetCount() {
return _count;
}
virtual void Tick() override;
virtual void Draw(s32 cameraId) override;
void func_80046F60(u8* tlut, u8* arg1, s32 arg2, s32 arg3, s32 arg4);
void func_8007D8AC(s32 arg0);
s32 func_8007D804(s32 objectIndex);
void func_8007D8D4(s32 objectIndex, s32 arg1);
void func_8007DA74(s32 objectIndex);
void func_8007DAF8(s32 objectIndex, s32 arg1);
void func_80089A04(s32 objectIndex, f32 arg1, f32 arg2);
void func_8007D794(s32 objectIndex);
void func_8007DA4C(s32 objectIndex);
private:
FVector _pos;
static size_t _count;
size_t _idx;
};
+125
View File
@@ -0,0 +1,125 @@
#include "ChainChomp.h"
#include "World.h"
extern "C" {
#include "render_objects.h"
#include "update_objects.h"
#include "assets/rainbow_road_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 "code_80005FD0.h"
#include "external.h"
}
size_t OChainChomp::_count = 0;
OChainChomp::OChainChomp() {
_idx = _count;
init_object(indexObjectList2[_count], 0);
_count++;
}
void OChainChomp::Tick() {
s32 objectIndex;
Object* object;
objectIndex = indexObjectList2[_idx];
object = &gObjectList[objectIndex];
if (object->state != 0) {
OChainChomp::func_800859C8(objectIndex, _idx);
vec3f_copy(object->unk_01C, object->offset);
// This should be spawn pos or follow path
func_8000D940(object->offset, &object->unk_084[8], object->unk_034, object->surfaceHeight, 0);
object->direction_angle[1] = get_angle_between_two_vectors(object->unk_01C, object->offset);
object_calculate_new_pos_offset(objectIndex);
func_80089CBC(objectIndex, 30.0f);
}
}
void OChainChomp::Draw(s32 cameraId) {
s32 objectIndex;
objectIndex = indexObjectList2[_idx];
func_8008A1D0(objectIndex, cameraId, 0x000005DC, 0x000009C4);
if (is_obj_flag_status_active(objectIndex, VISIBLE) != 0) {
func_80055AB8(objectIndex, cameraId);
}
}
void OChainChomp::func_80055AB8(s32 objectIndex, s32 cameraId) {
Camera* camera;
camera = &camera1[cameraId];
if (gObjectList[objectIndex].state >= 2) {
if (is_obj_flag_status_active(objectIndex, 0x00100000) != 0) {
D_80183E40[0] = gObjectList[objectIndex].pos[0];
D_80183E40[1] = gObjectList[objectIndex].pos[1] + 16.0;
D_80183E40[2] = gObjectList[objectIndex].pos[2];
D_80183E80[0] = 0;
D_80183E80[1] =
func_800418AC(gObjectList[objectIndex].pos[0], gObjectList[objectIndex].pos[2], camera->pos);
D_80183E80[2] = 0x8000;
func_800468E0(D_80183E40, D_80183E80, 0.54f, (u8*)d_course_rainbow_road_sphere, (Vtx*)D_0D0062B0, 0x00000020,
0x00000040, 0x00000020, 0x00000040, 5);
} else {
rsp_set_matrix_transformation(gObjectList[objectIndex].pos, gObjectList[objectIndex].direction_angle,
gObjectList[objectIndex].sizeScaling);
gSPDisplayList(gDisplayListHead++, (Gfx*)D_0D0077D0);
render_animated_model((Armature*) gObjectList[objectIndex].model,
(Animation**) gObjectList[objectIndex].vertex, 0,
(s16) gObjectList[objectIndex].textureListIndex);
}
}
}
void OChainChomp::func_80085878(s32 objectIndex, s32 arg1) {
TrackWaypoint* temp_v0;
Object* object;
object = &gObjectList[objectIndex];
object->unk_0D8 = 1;
object->model = (Gfx*) d_rainbow_road_unk4;
object->vertex = (Vtx*) d_rainbow_road_unk3;
object->sizeScaling = 0.03f;
object->boundingBoxSize = 0x000A;
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]];
set_obj_origin_offset(objectIndex, temp_v0->posX, temp_v0->posY, temp_v0->posZ);
set_obj_direction_angle(objectIndex, 0U, 0U, 0U);
object->unk_034 = 4.0f;
object->type = get_animation_length(d_rainbow_road_unk3, 0);
object_next_state(objectIndex);
}
void OChainChomp::func_800859C8(s32 objectIndex, s32 arg1) {
Object* object;
object = &gObjectList[objectIndex];
switch (object->state) { /* irregular */
case 0:
break;
case 1:
OChainChomp::func_80085878(objectIndex, arg1);
break;
case 2:
func_80072E54(objectIndex, 0, (s32) object->type, 1, 0, -1);
break;
}
if (D_8018D40C == 0) {
func_800C98B8(object->pos, object->velocity, SOUND_ARG_LOAD(0x19, 0x01, 0x80, 0x57));
}
func_80074344(objectIndex, &object->surfaceHeight, -0.8f, 0.8f, 0.03f, 0, -1);
}
+47
View File
@@ -0,0 +1,47 @@
#pragma once
#include <libultraship.h>
#include <vector>
#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"
}
/**
* Animation crash for custom courses
*/
class OChainChomp : public OObject {
public:
explicit OChainChomp();
~OChainChomp() {
_count--;
}
static size_t GetCount() {
return _count;
}
virtual void Tick() override;
virtual void Draw(s32 cameraId) override;
void func_80055AB8(s32 objectIndex, s32 cameraId);
void func_80085878(s32 objectIndex, s32 arg1);
void func_800859C8(s32 objectIndex, s32 arg1);
private:
FVector _pos;
static size_t _count;
size_t _idx;
};
+165 -2
View File
@@ -1879,6 +1879,38 @@ void print_text0(s32 column, s32 row, char* text, s32 tracking, f32 scaleX, f32
gSPDisplayList(gDisplayListHead++, D_020077D8);
}
// Time trials
void print_text0_wide_right(s32 column, s32 row, char* text, s32 tracking, f32 scaleX, f32 scaleY, s32 mode) {
s32 stringWidth = 0;
s32 glyphIndex;
gSPDisplayList(gDisplayListHead++, D_020077A8);
if (*text != 0) {
do {
glyphIndex = char_to_glyph_index(text);
if (glyphIndex >= 0) {
load_menu_img((MenuTexture*) segmented_to_virtual_dupe((const void*) gGlyphTextureLUT[glyphIndex]));
gDisplayListHead =
print_letter_wide_right(gDisplayListHead,
(MenuTexture*) segmented_to_virtual_dupe((const void*) gGlyphTextureLUT[glyphIndex]),
column + (stringWidth * scaleX), row, mode, scaleX, scaleY);
stringWidth += gGlyphDisplayWidth[glyphIndex] + tracking;
} else if ((glyphIndex != -2) && (glyphIndex == -1)) {
stringWidth += tracking + 7;
} else {
gSPDisplayList(gDisplayListHead++, D_020077D8);
return;
}
if (glyphIndex >= 0x30) {
text += 2;
} else {
text += 1;
}
} while (*text != 0);
}
gSPDisplayList(gDisplayListHead++, D_020077D8);
}
void print_text_mode_1(s32 column, s32 row, char* text, s32 tracking, f32 scaleX, f32 scaleY) {
print_text0(column, row, text, tracking, scaleX, scaleY, 1);
}
@@ -1887,6 +1919,10 @@ void print_text_mode_2(s32 column, s32 row, char* text, s32 tracking, f32 scaleX
print_text0(column, row, text, tracking, scaleX, scaleY, 2);
}
void print_text_mode_2_wide_right(s32 column, s32 row, char* text, s32 tracking, f32 scaleX, f32 scaleY) {
print_text0_wide_right(column, row, text, tracking, scaleX, scaleY, 2);
}
// "tracking" is a uniform spacing between all characters in a given word
void print_text1(s32 column, s32 row, char* text, s32 tracking, f32 scaleX, f32 scaleY, s32 arg6) {
char* temp_string = text;
@@ -2715,6 +2751,43 @@ func_80095BD0_label2:
return func_800959F8(displayListHead, var_a1);
}
Gfx* func_80095BD0_wide_right(Gfx* displayListHead, u8* arg1, f32 arg2, f32 arg3, u32 arg4, u32 arg5, f32 arg6, f32 arg7) {
Vtx* var_a1;
// A match is a match, but why are goto's required here?
if (gMatrixEffectCount >= 0x2F7) {
goto func_80095BD0_label1;
}
if (gMatrixEffectCount < 0) {
rmonPrintf("effectcount < 0 !!!!!!(kawano)\n");
}
goto func_80095BD0_label2;
func_80095BD0_label1:
rmonPrintf("MAX effectcount(760) over!!!!(kawano)\n");
return displayListHead;
func_80095BD0_label2:
func_80095AE0(&gGfxPool->mtxEffect[gMatrixEffectCount], OTRGetDimensionFromRightEdge(arg2), arg3, arg6, arg7);
gSPMatrix(displayListHead++, VIRTUAL_TO_PHYSICAL(&gGfxPool->mtxEffect[gMatrixEffectCount++]),
G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
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:
var_a1 = D_02007CD8;
break;
case 16:
var_a1 = D_02007CD8;
break;
case 26:
var_a1 = D_02007BB8;
break;
case 30:
var_a1 = D_02007DF8;
break;
}
return func_800959F8(displayListHead, var_a1);
}
// Player select menu character border
Gfx* func_80095E10(Gfx* displayListHead, s8 textureFormat, s32 texScaleS, s32 texScaleT, s32 srcX, s32 srcY,
s32 srcWidth, s32 srcHeight, s32 screenX, s32 screenY, u8* textureData, u32 texWidth,
@@ -3248,6 +3321,44 @@ Gfx* draw_box_wide(Gfx* displayListHead, s32 ulx, s32 uly, s32 lrx, s32 lry, u32
return displayListHead;
}
// Time trials race data cannot be saved for ghost box
Gfx* draw_box_wide_right(Gfx* displayListHead, s32 ulx, s32 uly, s32 lrx, s32 lry, u32 red, u32 green, u32 blue, u32 alpha) {
red &= 0xFF;
green &= 0xFF;
blue &= 0xFF;
alpha &= 0xFF;
if (lrx < ulx) {
swap_values(&ulx, &lrx);
}
if (lry < uly) {
swap_values(&uly, &lry);
}
if ((ulx >= 0x140) || (uly >= 0xF0)) {
return displayListHead;
}
if (ulx < 0) {
ulx = 0;
}
if (uly < 0) {
uly = 0;
}
if ((lrx < 0) || (lry < 0)) {
return displayListHead;
}
if (lrx >= 0x141) {
lrx = 0x140;
}
if (lry >= 0xF1) {
lry = 0xF0;
}
gSPDisplayList(displayListHead++, D_02008008);
gDPSetPrimColor(displayListHead++, 0, 0, red, green, blue, alpha);
gDPFillWideRectangle(displayListHead++, OTRGetRectDimensionFromRightEdge(ulx), uly,
OTRGetRectDimensionFromRightEdge(lrx), lry);
gDPPipeSync(displayListHead++);
return displayListHead;
}
// Renders pause background
Gfx* draw_box_wide_pause_background(Gfx* displayListHead, s32 ulx, s32 uly, s32 lrx, s32 lry, u32 red, u32 green,
u32 blue, u32 alpha) {
@@ -4341,6 +4452,58 @@ Gfx* print_letter(Gfx* arg0, MenuTexture* glyphTexture, f32 arg2, f32 arg3, s32
return arg0;
}
Gfx* print_letter_wide_right(Gfx* arg0, MenuTexture* glyphTexture, f32 arg2, f32 arg3, s32 mode, f32 scaleX, f32 scaleY) {
s32 var_v0;
u8* temp_v0_2;
f32 thing0;
f32 thing1;
MenuTexture* var_s0;
var_s0 = segmented_to_virtual_dupe(glyphTexture);
while (var_s0->textureData != NULL) {
var_v0 = 0;
thing0 = var_s0->dX + arg2;
if (thing0 > 320.0f) {
var_v0 = 1;
}
thing0 += var_s0->width * scaleX;
if (thing0 < 0.0f) {
var_v0 += 1;
}
thing1 = var_s0->dY + arg3;
if (thing1 < 0.0f) {
var_v0 += 1;
}
thing1 -= var_s0->height * scaleY;
if (thing1 > 240.0f) {
var_v0 += 1;
}
if (var_v0 != 0) {
var_s0++;
} else {
temp_v0_2 = (u8*) func_8009B8C4(var_s0->textureData);
if (temp_v0_2 != 0) {
switch (mode) {
case 1:
gSPDisplayList(arg0++, D_020077F8);
arg0 = func_80095BD0_wide_right(arg0, temp_v0_2, var_s0->dX + arg2, var_s0->dY + arg3, var_s0->width,
var_s0->height, scaleX, scaleY);
break;
case 2:
gSPDisplayList(arg0++, D_02007818);
arg0 = func_80095BD0_wide_right(arg0, temp_v0_2, var_s0->dX + arg2, var_s0->dY + arg3, var_s0->width,
var_s0->height, scaleX, scaleY);
break;
}
}
var_s0++;
}
}
return arg0;
}
Gfx* func_8009C204(Gfx* arg0, MenuTexture* arg1, s32 arg2, s32 arg3, s32 arg4) {
s32 var_s2;
u8* temp_t0;
@@ -8322,7 +8485,7 @@ void func_800A70E8(MenuItem* arg0) {
var_s0 = temp_f6;
}
gDisplayListHead =
draw_box(gDisplayListHead, 0x000000C0, 0x00000022, var_s0 + 0xC6, 0x00000039, 0, 0, 0, 0x00000096);
draw_box_wide_right(gDisplayListHead, (192), 34, (var_s0 + 198), 57, 0, 0, 0, 150);
alpha = 0x180 - ((arg0->param1 % 32) * 8);
if (alpha >= 0x100) {
alpha = 0xFF;
@@ -8330,7 +8493,7 @@ void func_800A70E8(MenuItem* arg0) {
gDPSetPrimColor(gDisplayListHead++, 0, 0, 0x00, 0x00, 0x00, alpha);
set_text_color(TEXT_RED);
for (loopIndex = 0x2C, stringIndex = 0; loopIndex < 0x40; loopIndex += 0xA, stringIndex++) {
print_text_mode_2(0x000000C0, loopIndex, D_800E7A34[stringIndex], 0, 0.45f, 0.45f);
print_text_mode_2_wide_right(192, loopIndex, D_800E7A34[stringIndex], 0, 0.45f, 0.45f);
}
}
}
+3
View File
@@ -366,8 +366,10 @@ s32 get_string_width(char*);
void set_text_color(s32);
void func_800930E4(s32, s32, char*);
void print_text0(s32, s32, char*, s32, f32, f32, s32);
void print_text0_wide_right(s32 column, s32 row, char* text, s32 tracking, f32 scaleX, f32 scaleY, s32 mode);
void print_text_mode_1(s32, s32, char*, s32, f32, f32);
void print_text_mode_2(s32, s32, char*, s32, f32, f32);
void print_text_mode_2_wide_right(s32 column, s32 row, char* text, s32 tracking, f32 scaleX, f32 scaleY);
void print_text1(s32, s32, char*, s32, f32, f32, s32);
void print_text1_left(s32, s32, char*, s32, f32, f32);
void print_text1_center_mode_1(s32, s32, char*, s32, f32, f32);
@@ -452,6 +454,7 @@ Gfx* func_8009B9D0(Gfx*, MenuTexture*);
Gfx* render_menu_textures(Gfx*, MenuTexture*, s32, s32);
Gfx* func_8009BC9C(Gfx*, MenuTexture*, s32, s32, s32, s32);
Gfx* print_letter(Gfx*, MenuTexture*, f32, f32, s32, f32, f32);
Gfx* print_letter_wide_right(Gfx* arg0, MenuTexture* glyphTexture, f32 arg2, f32 arg3, s32 mode, f32 scaleX, f32 scaleY);
Gfx* func_8009C204(Gfx*, MenuTexture*, s32, s32, s32);
Gfx* func_8009C434(Gfx*, struct_8018DEE0_entry*, s32, s32, s32);
Gfx* func_8009C708(Gfx*, struct_8018DEE0_entry*, s32, s32, s32, s32);
+4 -4
View File
@@ -1744,14 +1744,14 @@ void course_select_menu_act(struct Controller* controller, u16 controllerIdx) {
if ((btnAndStick & R_JPAD) != 0) {
sTempCupSelection = WorldNextCup();
//++gCupSelection;
reset_cycle_flash_menu();
play_sound2(SOUND_MENU_CURSOR_MOVE);
//reset_cycle_flash_menu();
//play_sound2(SOUND_MENU_CURSOR_MOVE);
}
if (((btnAndStick & L_JPAD) != 0)) {
sTempCupSelection = WorldPreviousCup();
//--gCupSelection;
reset_cycle_flash_menu();
play_sound2(SOUND_MENU_CURSOR_MOVE);
//reset_cycle_flash_menu();
//play_sound2(SOUND_MENU_CURSOR_MOVE);
}
D_800DC540 = GetCupIndex();
+6
View File
@@ -48,6 +48,7 @@ extern "C" {
#include "audio/external.h"
#include "networking/networking.h"
#include "render_courses.h"
#include "menus.h"
//#include "engine/wasm.h"
}
@@ -803,6 +804,11 @@ int main(int argc, char* argv[]) {
sound_init();
CustomEngineInit();
if (CVarGetInteger("gEnableDebugMode", 0) == true) {
gMenuSelection = START_MENU;
}
thread5_game_loop();
while (WindowIsRunning()) {
push_frame();
+5 -1
View File
@@ -451,7 +451,11 @@ void DrawGameMenu() {
#endif
)) {
gGamestateNext = MAIN_MENU_FROM_QUIT;
gMenuSelection = START_MENU;
if (CVarGetInteger("gEnableDebugMode", 0) == true) {
gMenuSelection = START_MENU;
} else {
gMenuSelection = LOGO_INTRO_MENU;
}
}
#if !defined(__SWITCH__) && !defined(__WIIU__)
+2 -91
View File
@@ -687,12 +687,6 @@ void load_texture_and_tlut(u8* tlut, u8* texture, s32 width, s32 height) {
rsp_load_texture(texture, width, height);
}
void func_80046F60(u8* tlut, u8* arg1, s32 arg2, s32 arg3, s32 arg4) {
gSPDisplayList(gDisplayListHead++, D_0D007D78);
gDPLoadTLUT_pal256(gDisplayListHead++, tlut);
rsp_load_texture_mask(arg1, arg2, arg3, arg4);
}
void func_80047068(u8* tlut, u8* texture, Vtx* arg2, UNUSED s32 arg3, s32 arg4, s32 width, s32 height) {
s32 heightIndex;
s32 vertexIndex = 0;
@@ -3340,7 +3334,7 @@ void func_800518F8(s32 objectIndex, s16 arg1, s16 arg2) {
func_80044DA0(gObjectList[objectIndex].activeTexture, gObjectList[objectIndex].textureWidth,
gObjectList[objectIndex].textureHeight);
}
func_80042330(arg1, arg2, 0U, gObjectList[objectIndex].sizeScaling);
func_80042330_unchanged(arg1, arg2, 0U, gObjectList[objectIndex].sizeScaling);
gSPVertex(gDisplayListHead++, gObjectList[objectIndex].vertex, 4, 0);
gSPDisplayList(gDisplayListHead++, common_rectangle_display);
}
@@ -3354,7 +3348,7 @@ void func_800519D4(s32 objectIndex, s16 arg1, s16 arg2) {
gObjectList[objectIndex].textureHeight);
}
func_8004B138(0x000000FF, 0x000000FF, 0x000000FF, gObjectList[objectIndex].primAlpha);
func_80042330(arg1, arg2, 0U, gObjectList[objectIndex].sizeScaling);
func_80042330_unchanged(arg1, arg2, 0U, gObjectList[objectIndex].sizeScaling);
gSPVertex(gDisplayListHead++, gObjectList[objectIndex].vertex, 4, 0);
gSPDisplayList(gDisplayListHead++, common_rectangle_display);
}
@@ -3522,50 +3516,6 @@ void render_object_boos(s32 arg0) {
}
}
void render_object_bat(s32 cameraId) {
s32 var_s2;
s32 objectIndex;
Camera* temp_s7;
objectIndex = indexObjectList1[0];
temp_s7 = &camera1[cameraId];
func_80046F60(gObjectList[objectIndex].activeTLUT, gObjectList[objectIndex].activeTexture, 0x00000020, 0x00000040,
5);
D_80183E80[0] = gObjectList[objectIndex].orientation[0];
D_80183E80[2] = gObjectList[objectIndex].orientation[2];
if ((D_8018CFB0 != 0) || (D_8018CFC8 != 0)) {
for (var_s2 = 0; var_s2 < 40; var_s2++) {
objectIndex = gObjectParticle2[var_s2];
if (objectIndex == -1) {
continue;
}
if ((gObjectList[objectIndex].state >= 2) && (gMatrixHudCount < 0x2EF)) {
D_80183E80[1] =
func_800418AC(gObjectList[objectIndex].pos[0], gObjectList[objectIndex].pos[2], temp_s7->pos);
func_800431B0(gObjectList[objectIndex].pos, D_80183E80, gObjectList[objectIndex].sizeScaling,
D_0D0062B0);
}
}
}
if ((D_8018CFE8 != 0) || (D_8018D000 != 0)) {
for (var_s2 = 0; var_s2 < 30; var_s2++) {
objectIndex = gObjectParticle3[var_s2];
if (objectIndex == -1) {
continue;
}
if ((gObjectList[objectIndex].state >= 2) && (gMatrixHudCount < 0x2EF)) {
D_80183E80[1] =
func_800418AC(gObjectList[objectIndex].pos[0], gObjectList[objectIndex].pos[2], temp_s7->pos);
func_800431B0(gObjectList[objectIndex].pos, D_80183E80, gObjectList[objectIndex].sizeScaling,
D_0D0062B0);
}
}
}
gSPTexture(gDisplayListHead++, 0x0001, 0x0001, 0, G_TX_RENDERTILE, G_OFF);
}
void func_8005285C(s32 arg0) {
Player* temp_v0;
@@ -3992,45 +3942,6 @@ void render_object_train_penguins(s32 cameraId) {
}
}
void func_80055AB8(s32 objectIndex, s32 cameraId) {
Camera* camera;
camera = &camera1[cameraId];
if (gObjectList[objectIndex].state >= 2) {
if (is_obj_flag_status_active(objectIndex, 0x00100000) != 0) {
D_80183E40[0] = gObjectList[objectIndex].pos[0];
D_80183E40[1] = gObjectList[objectIndex].pos[1] + 16.0;
D_80183E40[2] = gObjectList[objectIndex].pos[2];
D_80183E80[0] = 0;
D_80183E80[1] =
func_800418AC(gObjectList[objectIndex].pos[0], gObjectList[objectIndex].pos[2], camera->pos);
D_80183E80[2] = 0x8000;
func_800468E0(D_80183E40, D_80183E80, 0.54f, d_course_rainbow_road_sphere, D_0D0062B0, 0x00000020,
0x00000040, 0x00000020, 0x00000040, 5);
} else {
rsp_set_matrix_transformation(gObjectList[objectIndex].pos, gObjectList[objectIndex].direction_angle,
gObjectList[objectIndex].sizeScaling);
gSPDisplayList(gDisplayListHead++, D_0D0077D0);
render_animated_model((Armature*) gObjectList[objectIndex].model,
(Animation**) gObjectList[objectIndex].vertex, 0,
(s16) gObjectList[objectIndex].textureListIndex);
}
}
}
void render_object_chain_chomps(s32 cameraId) {
s32 var_s1;
s32 objectIndex;
for (var_s1 = 0; var_s1 < NUM_CHAIN_CHOMPS; var_s1++) {
objectIndex = indexObjectList2[var_s1];
func_8008A1D0(objectIndex, cameraId, 0x000005DC, 0x000009C4);
if (is_obj_flag_status_active(objectIndex, VISIBLE) != 0) {
func_80055AB8(objectIndex, cameraId);
}
}
}
void func_80055EF4(s32 objectIndex, UNUSED s32 arg1) {
Object* object;
-216
View File
@@ -4022,164 +4022,6 @@ void func_8007D714(s32 arg0) {
}
}
void func_8007D794(s32 objectIndex) {
if (gCCSelection == CC_50) {
func_80089A04(objectIndex, 0.5f, 0.2f);
} else if (gCCSelection == CC_100) {
func_80089A04(objectIndex, 0.4f, 0.15f);
} else {
func_80089A04(objectIndex, 0.25f, 0.1f);
}
}
s32 func_8007D804(s32 objectIndex) {
s32 loopIndex;
s32 someCount;
someCount = 0;
for (loopIndex = 0; loopIndex < gPlayerCountSelection1; loopIndex++) {
if (is_object_visible_on_camera(objectIndex, &camera1[loopIndex], 0x4000U) != 0) {
someCount += 1;
}
}
return someCount;
}
void func_8007D8AC(s32 arg0) {
object_next_state(arg0);
func_80086E70(arg0);
}
void func_8007D8D4(s32 objectIndex, s32 arg1) {
switch (gObjectList[objectIndex].state) {
case 1:
func_8007D8AC(objectIndex);
break;
case 2:
if (func_8007D804(objectIndex) == 0) {
func_80072428(objectIndex);
}
if (arg1 == 1) {
if (gIsMirrorMode != 0) {
if (gObjectList[objectIndex].pos[0] >= 2540.0) {
func_80072428(objectIndex);
}
} else if (gObjectList[objectIndex].pos[0] <= -2540.0) {
func_80072428(objectIndex);
}
} else if (gIsMirrorMode != 0) {
if (gObjectList[objectIndex].pos[0] >= 2150.0) {
func_80072428(objectIndex);
}
} else {
if (gObjectList[objectIndex].pos[0] <= -2150.0) {
func_80072428(objectIndex);
}
}
break;
case 0:
break;
}
}
void func_8007DA4C(s32 objectIndex) {
func_8008781C(objectIndex);
object_calculate_new_pos_offset(objectIndex);
}
void func_8007DA74(s32 objectIndex) {
UNUSED s32 pad;
if ((gObjectList[objectIndex].unk_0AE != 0) && (gObjectList[objectIndex].unk_0AE == 1)) {
if (func_80087060(objectIndex, 0x0000001E) != 0) {
gObjectList[objectIndex].unk_0C6 = 0U;
}
}
gObjectList[objectIndex].direction_angle[0] =
func_800417B4(gObjectList[objectIndex].direction_angle[0], gObjectList[objectIndex].unk_0C6);
func_80087844(objectIndex);
object_calculate_new_pos_offset(objectIndex);
}
void func_8007DAF8(s32 objectIndex, s32 arg1) {
switch (arg1) { /* irregular */
case 1:
func_8007DA74(objectIndex);
return;
case 2:
func_8007DA4C(objectIndex);
return;
}
}
void update_bat(void) {
s32 var_s2;
s32 temp_s0;
Object* object;
if (D_8018CFC8 != 0) {
D_8018CFC8 -= 1;
}
if (D_8018D000 != 0) {
D_8018D000 -= 1;
}
temp_s0 = indexObjectList1[0];
func_80072E54(temp_s0, 0, 3, 1, 0, -1);
func_80073514(temp_s0);
object = &gObjectList[temp_s0];
func_80073CB0(temp_s0, &object->primAlpha, -0x00001000, 0x00001000, 0x00000400, 0, -1);
object->orientation[2] = object->primAlpha + 0x8000;
if ((D_8018CFB0 != 0) || (D_8018CFC8 != 0)) {
D_8018CFD8 = 0;
for (var_s2 = 0; var_s2 < 40; var_s2++) {
temp_s0 = gObjectParticle2[var_s2];
if (temp_s0 == -1) {
continue;
}
object = &gObjectList[temp_s0];
if (object->state == 0) {
continue;
}
func_8007D8D4(temp_s0, 1);
func_8007DAF8(temp_s0, 1);
func_8007D794(temp_s0);
if (object->state == 0) {
delete_object_wrapper(&gObjectParticle2[var_s2]);
}
D_8018CFD8 += 1;
}
if (D_8018CFD8 != 0) {
D_8018CFC8 = 0x012C;
}
}
if ((D_8018CFE8 != 0) || (D_8018D000 != 0)) {
D_8018D010 = 0;
for (var_s2 = 0; var_s2 < 30; var_s2++) {
temp_s0 = gObjectParticle3[var_s2];
if (temp_s0 == -1) {
continue;
}
object = &gObjectList[temp_s0];
if (object->state == 0) {
continue;
}
func_8007D8D4(temp_s0, 2);
func_8007DAF8(temp_s0, 2);
func_8007D794(temp_s0);
if (object->state == 0) {
delete_object_wrapper(&gObjectParticle3[var_s2]);
}
D_8018D010 += 1;
}
if (D_8018D010 != 0) {
D_8018D000 = 0x012C;
}
}
}
void func_8007DDC0(s32 objectIndex) {
f32 sp2C;
Object* object;
@@ -4434,65 +4276,7 @@ void func_800842C8(void) {
}
}
void func_80085878(s32 objectIndex, s32 arg1) {
TrackWaypoint* temp_v0;
Object* object;
object = &gObjectList[objectIndex];
object->unk_0D8 = 1;
object->model = (Gfx*) d_rainbow_road_unk4;
object->vertex = (Vtx*) d_rainbow_road_unk3;
object->sizeScaling = 0.03f;
object->boundingBoxSize = 0x000A;
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]];
set_obj_origin_offset(objectIndex, temp_v0->posX, temp_v0->posY, temp_v0->posZ);
set_obj_direction_angle(objectIndex, 0U, 0U, 0U);
object->unk_034 = 4.0f;
object->type = get_animation_length(d_rainbow_road_unk3, 0);
object_next_state(objectIndex);
}
void func_800859C8(s32 objectIndex, s32 arg1) {
Object* object;
object = &gObjectList[objectIndex];
switch (object->state) { /* irregular */
case 0:
break;
case 1:
func_80085878(objectIndex, arg1);
break;
case 2:
func_80072E54(objectIndex, 0, (s32) object->type, 1, 0, -1);
break;
}
if (D_8018D40C == 0) {
func_800C98B8(object->pos, object->velocity, SOUND_ARG_LOAD(0x19, 0x01, 0x80, 0x57));
}
func_80074344(objectIndex, &object->surfaceHeight, -0.8f, 0.8f, 0.03f, 0, -1);
}
void update_chain_chomps(void) {
s32 objectIndex;
s32 var_s4;
Object* object;
for (var_s4 = 0; var_s4 < NUM_CHAIN_CHOMPS; var_s4++) {
objectIndex = indexObjectList2[var_s4];
object = &gObjectList[objectIndex];
if (object->state != 0) {
func_800859C8(objectIndex, var_s4);
vec3f_copy(object->unk_01C, object->offset);
func_8000D940(object->offset, &object->unk_084[8], object->unk_034, object->surfaceHeight, 0);
object->direction_angle[1] = get_angle_between_two_vectors(object->unk_01C, object->offset);
object_calculate_new_pos_offset(objectIndex);
func_80089CBC(objectIndex, 30.0f);
}
}
}
void func_80085BB4(s32 objectIndex) {
gObjectList[objectIndex].sizeScaling = 8.0f;