From 475f167bb2803999c5116bc285601d1f9a05d7de Mon Sep 17 00:00:00 2001 From: MegaMech Date: Thu, 14 Nov 2024 23:32:55 -0700 Subject: [PATCH] [modding] Big Update PR (#118) * Implement kart vehicle * Fix menu CC * Actors * variable framerate * Implement Actors vector * Fix water & scrolling textures * Finish ACoin * Refactor finishline * Refactor mtx to vector * Fix refactored screen code bugs * Fix playlist bug * Switching courses working now * Fix podium ceremony * Mostly Fix Demo and Credits * Credits Load Actors and Textures * Fix credits * Formatting * Update lus and torch * Fix water features * Fix crabs * Combine function * Fix wheels * Add Moon Jump Cheat * Wheel Change * Fix smoke due to wheel change * Fix screens for wheels * Fix transparency * Fix staff ghost * Fix lakitu transition widescreen * Rename and export credits text * Fixes --------- Co-authored-by: MegaMech <7255464+MegaMech@users.noreply.github.com> --- courses/staff_ghost_data.c | 3 +- courses/staff_ghost_data.h | 14 + enhancements/flycam.patch | 4 +- include/actor_types.h | 7 +- include/bomb_kart.h | 5 +- include/mk64.h | 2 +- libultraship | 2 +- src/actors/banana/update.inc.c | 2 +- src/actors/blue_and_red_shells/update.inc.c | 10 +- src/actors/falling_rock/update.inc.c | 2 +- src/actors/green_shell/update.inc.c | 8 +- src/actors/trees/render.inc.c | 2 - src/animation.c | 10 +- src/code_800029B0.c | 127 +--- src/code_800029B0.h | 4 +- src/code_80005FD0.c | 100 ++- src/code_80005FD0.h | 2 +- src/code_80057C60.c | 132 ++-- src/code_8006E9C0.c | 14 +- src/code_80091750.c | 152 ++-- src/code_80091750.h | 8 - src/code_800AF9B0.c | 6 +- src/data/path_spawn_metadata.c | 41 -- src/data/path_spawn_metadata.h | 9 - src/ending/ceremony_and_credits.c | 2 +- src/ending/ceremony_and_credits.h | 2 +- src/ending/code_80280000.c | 15 +- src/ending/credits.c | 2 +- src/ending/credits.h | 2 +- src/ending/podium_ceremony_actors.c | 10 +- src/engine/Actor.cpp | 8 +- src/engine/Actor.h | 11 +- src/engine/Matrix.cpp | 123 ++++ src/engine/Matrix.h | 27 + src/engine/World.cpp | 59 +- src/engine/World.h | 28 +- src/engine/actors/ABanana.cpp | 2 +- src/engine/actors/ABanana.h | 2 +- src/engine/actors/ACloud.cpp | 136 ++++ src/engine/actors/ACloud.h | 39 ++ src/engine/actors/AFinishline.cpp | 80 +++ src/engine/actors/AFinishline.h | 40 ++ src/engine/actors/ATree.cpp | 66 ++ src/engine/actors/ATree.h | 35 + src/engine/actors/AWarioSign.cpp | 1 - src/engine/courses/BansheeBoardwalk.cpp | 77 +- src/engine/courses/BansheeBoardwalk.h | 10 +- src/engine/courses/BigDonut.cpp | 53 +- src/engine/courses/BigDonut.h | 6 +- src/engine/courses/BlockFort.cpp | 39 +- src/engine/courses/BlockFort.h | 6 +- src/engine/courses/BombKart.cpp | 28 - src/engine/courses/BombKart.h | 38 - src/engine/courses/BowsersCastle.cpp | 74 +- src/engine/courses/BowsersCastle.h | 8 +- src/engine/courses/ChocoMountain.cpp | 97 +-- src/engine/courses/ChocoMountain.h | 7 +- src/engine/courses/Course.cpp | 37 +- src/engine/courses/Course.h | 10 +- src/engine/courses/DKJungle.cpp | 234 ++++++- src/engine/courses/DKJungle.h | 8 +- src/engine/courses/DoubleDeck.cpp | 39 +- src/engine/courses/DoubleDeck.h | 6 +- src/engine/courses/FrappeSnowland.cpp | 50 +- src/engine/courses/FrappeSnowland.h | 8 +- src/engine/courses/KalimariDesert.cpp | 62 +- src/engine/courses/KalimariDesert.h | 5 +- src/engine/courses/KoopaTroopaBeach.cpp | 97 ++- src/engine/courses/KoopaTroopaBeach.h | 9 +- src/engine/courses/LuigiRaceway.cpp | 51 +- src/engine/courses/LuigiRaceway.h | 5 +- src/engine/courses/MarioRaceway.cpp | 68 +- src/engine/courses/MarioRaceway.h | 6 +- src/engine/courses/MooMooFarm.cpp | 59 +- src/engine/courses/MooMooFarm.h | 7 +- src/engine/courses/PodiumCeremony.cpp | 66 +- src/engine/courses/PodiumCeremony.h | 6 +- src/engine/courses/RainbowRoad.cpp | 90 ++- src/engine/courses/RainbowRoad.h | 8 +- src/engine/courses/RoyalRaceway.cpp | 56 +- src/engine/courses/RoyalRaceway.h | 6 +- src/engine/courses/SherbetLand.cpp | 80 ++- src/engine/courses/SherbetLand.h | 8 +- src/engine/courses/Skyscraper.cpp | 47 +- src/engine/courses/Skyscraper.h | 6 +- src/engine/courses/TestCourse.cpp | 113 +-- src/engine/courses/TestCourse.h | 4 - src/engine/courses/ToadsTurnpike.cpp | 60 +- src/engine/courses/ToadsTurnpike.h | 5 +- src/engine/courses/WarioStadium.cpp | 125 +++- src/engine/courses/WarioStadium.h | 8 +- src/engine/courses/YoshiValley.cpp | 74 +- src/engine/courses/YoshiValley.h | 9 +- src/engine/readme.txt | 3 + src/engine/vehicles/Boat.cpp | 2 +- src/engine/vehicles/Bus.cpp | 2 +- src/engine/vehicles/Car.cpp | 2 +- src/engine/vehicles/OBombKart.cpp | 449 ++++++++++++ src/engine/vehicles/OBombKart.h | 64 ++ src/engine/vehicles/TankerTruck.cpp | 2 +- src/engine/vehicles/Train.cpp | 2 +- src/engine/vehicles/Truck.cpp | 2 +- src/engine/wasm.cpp | 412 +++++------ src/enhancements/moon_jump.c | 12 + src/enhancements/moon_jump.h | 10 + src/kart_dma.c | 8 +- src/kart_dma.h | 2 +- src/main.c | 511 +++++++------- src/main.h | 5 +- src/math_util_2.c | 48 +- src/menus.c | 6 +- src/player_controller.c | 9 + src/port/Engine.cpp | 2 +- src/port/Game.cpp | 139 +++- src/port/Game.h | 16 +- src/port/ui/ImguiUI.cpp | 5 +- src/port/ui/MultiplayerWindow.cpp | 1 - src/port/ui/ResolutionEditor.cpp | 4 +- src/port/ui/UIWidgets.cpp | 34 +- src/racing/actors.c | 202 +++--- src/racing/actors.h | 4 +- src/racing/actors_extended.c | 90 +-- src/racing/math_util.c | 24 +- src/racing/memory.c | 2 + src/racing/race_logic.c | 8 +- src/racing/race_logic.h | 2 +- src/racing/render_courses.c | 576 ++++++++------- src/racing/skybox_and_splitscreen.c | 738 ++++---------------- src/racing/skybox_and_splitscreen.h | 1 + src/render_objects.c | 69 +- src/render_objects.h | 8 +- src/render_player.c | 300 ++++---- src/staff_ghosts.c | 3 +- src/staff_ghosts.h | 4 - src/update_objects.c | 4 +- torch | 2 +- yamls/us/credits_text.yml | 14 + 137 files changed, 4173 insertions(+), 2961 deletions(-) create mode 100644 courses/staff_ghost_data.h create mode 100644 src/engine/Matrix.cpp create mode 100644 src/engine/Matrix.h create mode 100644 src/engine/actors/ACloud.cpp create mode 100644 src/engine/actors/ACloud.h create mode 100644 src/engine/actors/AFinishline.cpp create mode 100644 src/engine/actors/AFinishline.h create mode 100644 src/engine/actors/ATree.cpp create mode 100644 src/engine/actors/ATree.h delete mode 100644 src/engine/courses/BombKart.cpp delete mode 100644 src/engine/courses/BombKart.h create mode 100644 src/engine/readme.txt create mode 100644 src/engine/vehicles/OBombKart.cpp create mode 100644 src/engine/vehicles/OBombKart.h create mode 100644 src/enhancements/moon_jump.c create mode 100644 src/enhancements/moon_jump.h create mode 100644 yamls/us/credits_text.yml diff --git a/courses/staff_ghost_data.c b/courses/staff_ghost_data.c index f872a846e..664d625be 100644 --- a/courses/staff_ghost_data.c +++ b/courses/staff_ghost_data.c @@ -1,6 +1,7 @@ #include #include #include +#include "staff_ghost_data.h" /* * This file is required for data alignment @@ -11,7 +12,7 @@ StaffGhost d_mario_raceway_staff_ghost[] = { #include "courses/mario_raceway/staff_ghost.inc.c" }; -StaffGhost d_luigi_raceway_staff_ghost[1046] = { +StaffGhost d_luigi_raceway_staff_ghost[] = { #include "courses/luigi_raceway/staff_ghost.inc.c" }; diff --git a/courses/staff_ghost_data.h b/courses/staff_ghost_data.h new file mode 100644 index 000000000..dd9650995 --- /dev/null +++ b/courses/staff_ghost_data.h @@ -0,0 +1,14 @@ +#ifndef _STAFF_GHOST_DATA +#define _STAFF_GHOST_DATA + +#include +#include +#include + +extern StaffGhost d_mario_raceway_staff_ghost[]; +extern StaffGhost d_royal_raceway_staff_ghost[]; +extern StaffGhost d_luigi_raceway_staff_ghost[]; + + + +#endif // _STAFF_GHOST_DATA \ No newline at end of file diff --git a/enhancements/flycam.patch b/enhancements/flycam.patch index 20dd276c5..8e5ebb4f2 100644 --- a/enhancements/flycam.patch +++ b/enhancements/flycam.patch @@ -411,11 +411,11 @@ index 7c90951..135e98c 100644 --- a/src/main.c +++ b/src/main.c @@ -578,6 +578,7 @@ void race_logic_loop(void) { - gTickSpeed = 2; + gTickLogic = 2; staff_ghosts_loop(); if (gIsGamePaused == 0) { + func_8001EE98(gPlayerOneCopy, camera1, 0); - for (i = 0; i < gTickSpeed; i++) { + for (i = 0; i < gTickLogic; i++) { if (D_8015011E) { gCourseTimer += 0.01666666; // 1 / 60 @@ -585,7 +586,6 @@ void race_logic_loop(void) { diff --git a/include/actor_types.h b/include/actor_types.h index 387aa285e..2b600ec13 100644 --- a/include/actor_types.h +++ b/include/actor_types.h @@ -83,8 +83,11 @@ enum ActorType { ACTOR_CAR, ACTOR_KIWANO_FRUIT }; +size_t m_GetActorSize(void); +#define ACTOR_LIST_SIZE m_GetActorSize() -#define ACTOR_LIST_SIZE 100 +struct Actor* m_GetActor(size_t); +#define GET_ACTOR(index) m_GetActor(index) // Actor flags #define ACTOR_IS_NOT_EXPIRED 0xF // The actor possesses some kind of collision and can be removed @@ -133,7 +136,7 @@ struct Actor { }; // size = 0x70 // Duplicate declare for simplicity when externing actors & packed files. -extern struct Actor gActorList[ACTOR_LIST_SIZE]; // D_8015F9B8 +extern struct Actor gActorList[100]; // D_8015F9B8 /* Specialized actor types diff --git a/include/bomb_kart.h b/include/bomb_kart.h index 0ae47f309..d8dc260f0 100644 --- a/include/bomb_kart.h +++ b/include/bomb_kart.h @@ -56,9 +56,6 @@ typedef struct { extern s32 gIndexObjectBombKart[NUM_BOMB_KARTS_MAX]; extern BombKart gBombKarts[NUM_BOMB_KARTS_MAX]; -extern Collision D_80164038[NUM_BOMB_KARTS_MAX]; - -// data/data_0DD0A0_1.s -extern BombKartSpawn gBombKartSpawns[NUM_COURSES][NUM_BOMB_KARTS_MAX]; +extern Collision gBombKartCollision[NUM_BOMB_KARTS_MAX]; #endif diff --git a/include/mk64.h b/include/mk64.h index 1e8066bc5..97d5ffb84 100644 --- a/include/mk64.h +++ b/include/mk64.h @@ -43,7 +43,7 @@ typedef enum { /* 0x08 */ COURSE_LUIGI_RACEWAY, /* 0x09 */ COURSE_MOO_MOO_FARM, /* 0x0A */ COURSE_TOADS_TURNPIKE, - /* 0x0B */ COURSE_KALAMARI_DESERT, + /* 0x0B */ COURSE_KALIMARI_DESERT, /* 0x0C */ COURSE_SHERBET_LAND, /* 0x0D */ COURSE_RAINBOW_ROAD, /* 0x0E */ COURSE_WARIO_STADIUM, diff --git a/libultraship b/libultraship index da9e33418..00c6bcc88 160000 --- a/libultraship +++ b/libultraship @@ -1 +1 @@ -Subproject commit da9e334188169ec95cc1af3468dda7146df49928 +Subproject commit 00c6bcc88286173ce22b8a6656373d3aa5830c62 diff --git a/src/actors/banana/update.inc.c b/src/actors/banana/update.inc.c index cb21a3166..cd7b70078 100644 --- a/src/actors/banana/update.inc.c +++ b/src/actors/banana/update.inc.c @@ -146,7 +146,7 @@ void update_actor_banana(struct BananaActor* banana) { func_802B4E30((struct Actor*) banana); break; case BANANA_BUNCH_BANANA: - elderBanana = (struct BananaActor*) &gActorList[banana->elderIndex]; + elderBanana = (struct BananaActor*) GET_ACTOR(banana->elderIndex); temp_f2 = elderBanana->pos[0] - banana->pos[0]; temp_f14 = elderBanana->pos[1] - banana->pos[1]; temp_f16 = elderBanana->pos[2] - banana->pos[2]; diff --git a/src/actors/blue_and_red_shells/update.inc.c b/src/actors/blue_and_red_shells/update.inc.c index a6eb2f269..861433446 100644 --- a/src/actors/blue_and_red_shells/update.inc.c +++ b/src/actors/blue_and_red_shells/update.inc.c @@ -293,9 +293,9 @@ void update_actor_red_blue_shell(struct ShellActor* shell) { func_800C90F4(shell->playerId, (player->characterId * 0x10) + SOUND_ARG_LOAD(0x29, 0x00, 0x80, 0x00)); if (pad13 == ACTOR_RED_SHELL) { - add_red_shell_in_unexpired_actor_list((struct Actor*) shell - gActorList); + add_red_shell_in_unexpired_actor_list(m_FindActorIndex(shell)); } else { - add_blue_shell_in_unexpired_actor_list((struct Actor*) shell - gActorList); + add_blue_shell_in_unexpired_actor_list(m_FindActorIndex(shell)); func_800C9D80(shell->pos, shell->velocity, SOUND_ARG_LOAD(0x51, 0x01, 0x80, 0x08)); } } @@ -307,9 +307,9 @@ void update_actor_red_blue_shell(struct ShellActor* shell) { func_800C90F4(shell->playerId, (player->characterId * 0x10) + SOUND_ARG_LOAD(0x29, 0x00, 0x80, 0x00)); if (pad13 == ACTOR_RED_SHELL) { - add_red_shell_in_unexpired_actor_list((struct Actor*) shell - gActorList); + add_red_shell_in_unexpired_actor_list(m_FindActorIndex(shell)); } else { - add_blue_shell_in_unexpired_actor_list((struct Actor*) shell - gActorList); + add_blue_shell_in_unexpired_actor_list(m_FindActorIndex(shell)); func_800C9D80(shell->pos, shell->velocity, SOUND_ARG_LOAD(0x51, 0x01, 0x80, 0x08)); } } @@ -429,7 +429,7 @@ void update_actor_red_blue_shell(struct ShellActor* shell) { break; case TRIPLE_RED_SHELL: player = &gPlayers[shell->playerId]; - parent = (TripleShellParent*) &gActorList[shell->parentIndex]; + parent = (TripleShellParent*) GET_ACTOR(shell->parentIndex); if (parent->type != ACTOR_TRIPLE_RED_SHELL) { destroy_destructable_actor((struct Actor*) shell); } else { diff --git a/src/actors/falling_rock/update.inc.c b/src/actors/falling_rock/update.inc.c index 97d9a2a6b..f189aeaa1 100644 --- a/src/actors/falling_rock/update.inc.c +++ b/src/actors/falling_rock/update.inc.c @@ -53,7 +53,7 @@ void spawn_falling_rocks(struct ActorSpawnData* spawnData) { vec3f_set(startingVelocity, 0, 0, 0); vec3s_set(startingRot, 0, 0, 0); temp = add_actor_to_empty_slot(startingPos, startingRot, startingVelocity, ACTOR_FALLING_ROCK); - temp_v1 = (struct FallingRock*) &gActorList[temp]; + temp_v1 = (struct FallingRock*) GET_ACTOR(temp); temp_v1->unk_06 = temp_s0->someId; func_802AAAAC((Collision*) &temp_v1->unk30); diff --git a/src/actors/green_shell/update.inc.c b/src/actors/green_shell/update.inc.c index 157895844..546baee89 100644 --- a/src/actors/green_shell/update.inc.c +++ b/src/actors/green_shell/update.inc.c @@ -74,7 +74,7 @@ void update_actor_green_shell(struct ShellActor* shell) { func_800C9060(shell->playerId, SOUND_ARG_LOAD(0x19, 0x00, 0x80, 0x04)); func_800C90F4(shell->playerId, (player->characterId * 0x10) + SOUND_ARG_LOAD(0x29, 0x00, 0x80, 0x00)); - add_green_shell_in_unexpired_actor_list((struct Actor*) shell - gActorList); + add_green_shell_in_unexpired_actor_list(m_FindActorIndex(shell)); return; } else { shell->state = 1; @@ -97,7 +97,7 @@ void update_actor_green_shell(struct ShellActor* shell) { func_800C9060(shell->playerId, SOUND_ARG_LOAD(0x19, 0x00, 0x80, 0x04)); func_800C90F4(shell->playerId, (player->characterId * 0x10) + SOUND_ARG_LOAD(0x29, 0x00, 0x80, 0x00)); - add_green_shell_in_unexpired_actor_list((struct Actor*) shell - gActorList); + add_green_shell_in_unexpired_actor_list(m_FindActorIndex(shell)); } } else { shell->rotAngle += 0xE38; @@ -107,7 +107,7 @@ void update_actor_green_shell(struct ShellActor* shell) { func_800C9060(shell->playerId, SOUND_ARG_LOAD(0x19, 0x00, 0x80, 0x04)); func_800C90F4(shell->playerId, (player->characterId * 0x10) + SOUND_ARG_LOAD(0x29, 0x00, 0x80, 0x00)); - add_green_shell_in_unexpired_actor_list((struct Actor*) shell - gActorList); + add_green_shell_in_unexpired_actor_list(m_FindActorIndex(shell)); } } if (shell->state == 2) { @@ -160,7 +160,7 @@ void update_actor_green_shell(struct ShellActor* shell) { break; case TRIPLE_GREEN_SHELL: player = &gPlayers[shell->playerId]; - parent = (TripleShellParent*) &gActorList[shell->parentIndex]; + parent = (TripleShellParent*) GET_ACTOR(shell->parentIndex); if (parent->type != ACTOR_TRIPLE_GREEN_SHELL) { destroy_destructable_actor((struct Actor*) shell); } else { diff --git a/src/actors/trees/render.inc.c b/src/actors/trees/render.inc.c index 9ae645199..cb54275c6 100644 --- a/src/actors/trees/render.inc.c +++ b/src/actors/trees/render.inc.c @@ -204,8 +204,6 @@ void func_80299864(Camera* camera, Mat4 arg1, struct Actor* arg2) { // This comment can be removed when this is confirmed to work. if (GetCourse() == GetLuigiRaceway()) { gSPDisplayList(gDisplayListHead++, d_course_luigi_raceway_dl_FC70); - } else if (GetCourse() == GetMooMooFarm()) { - gSPDisplayList(gDisplayListHead++, d_course_moo_moo_farm_mole_tlut); } } } diff --git a/src/animation.c b/src/animation.c index 19204641e..6ccab044a 100644 --- a/src/animation.c +++ b/src/animation.c @@ -93,10 +93,12 @@ void render_limb_or_add_mtx(Armature* arg0, s16* arg1, AnimationLimbVector arg2, } mtxf_translate_rotate2(modelMatrix, pos, angle); - convert_to_fixed_point_matrix_animation(&gGfxPool->mtxHud[gMatrixHudCount], modelMatrix); + //convert_to_fixed_point_matrix_animation(&gGfxPool->mtxHud[gMatrixHudCount], modelMatrix); sMatrixStackSize += 1; - gSPMatrix(gDisplayListHead++, (&gGfxPool->mtxHud[gMatrixHudCount++]), - G_MTX_PUSH | G_MTX_MUL | G_MTX_MODELVIEW); + // gSPMatrix(gDisplayListHead++, (&gGfxPool->mtxHud[gMatrixHudCount++]), + // G_MTX_PUSH | G_MTX_MUL | G_MTX_MODELVIEW); + + AddHudMatrix(modelMatrix, G_MTX_PUSH | G_MTX_MUL | G_MTX_MODELVIEW); if (virtualModel != NULL) { model = (virtualModel); gSPDisplayList(gDisplayListHead++, model); @@ -111,8 +113,6 @@ void render_armature(Armature* animation, Animation* arg1, s16 timeCycle) { s32 animation_type; s32 someIndex; - printf("model: %d %d %d\n", animation->pos[0], animation->pos[1], animation->pos[2]); - angle_array = (arg1->angle_array); animation_cycle_list = (arg1->animation_cycle_spec_vector); sMatrixStackSize = 0; diff --git a/src/code_800029B0.c b/src/code_800029B0.c index aa00b5ca1..b6f5b1820 100644 --- a/src/code_800029B0.c +++ b/src/code_800029B0.c @@ -124,7 +124,7 @@ Vec3f D_8015F768; Vec3f D_8015F778; f32 gCourseDirection; // Extra mode, flips vertices. -s32 D_8015F788; +s32 gNumScreens; // Set to zero in single player mode s32 D_8015F790[64]; // Unknown data, potentially not used. u16 D_8015F890; u16 D_8015F892; @@ -149,7 +149,7 @@ s16 gPlayerPositionLUT[8]; // Player index at each position u16 gNumPermanentActors; s32 code_800029B0_bss_pad2[44]; -struct Actor gActorList[ACTOR_LIST_SIZE]; +struct Actor gActorList[100]; //! @warning todo: Is this apart of the actor array? UNUSED u8 D_80162578[sizeof(struct Actor)]; @@ -179,6 +179,8 @@ void setup_race(void) { struct Controller* controller; int i; + printf("Setup Race!\n"); + gPlayerCountSelection1 = gPlayerCount; if (gGamestate != RACING) { gIsMirrorMode = 0; @@ -191,7 +193,7 @@ void setup_race(void) { if (gModeSelection == GRAND_PRIX) { gCurrentCourseId = gCupCourseOrder[gCupSelection][gCourseIndexInCup]; // Skip for debug menu - if (gDebugMenuSelection < DEBUG_MENU) { + if (gMenuSelection != START_MENU) { SetCourseFromCup(); } } @@ -201,7 +203,7 @@ void setup_race(void) { gCurrentlyLoadedCourseId = gCurrentCourseId; gNextFreeMemoryAddress = gFreeMemoryResetAnchor; load_course(gCurrentCourseId); - func_80295D88(); + course_init(); D_8015F730 = gNextFreeMemoryAddress; } else { gNextFreeMemoryAddress = D_8015F730; @@ -221,18 +223,19 @@ void setup_race(void) { func_80091FA4(); init_actors_and_load_textures(); - if (gModeSelection != BATTLE) { - D_8015F8D0[1] = (f32) (D_80164490->posY - 15); - ; - D_8015F8D0[2] = D_80164490->posZ; - if (GetCourse() == GetToadsTurnpike()) { - D_8015F8D0[0] = (gIsMirrorMode != 0) ? D_80164490->posX + 138.0f : D_80164490->posX - 138.0f; - } else if (GetCourse() == GetWarioStadium()) { - D_8015F8D0[0] = (gIsMirrorMode != 0) ? D_80164490->posX + 12.0f : D_80164490->posX - 12.0f; - } else { - D_8015F8D0[0] = D_80164490->posX; - } - } + // Set finishline position. This is now done in files in src/engine/courses/* + // if (gModeSelection != BATTLE) { + // D_8015F8D0[1] = (f32) (D_80164490->posY - 15); + // D_8015F8D0[2] = D_80164490->posZ; + + // if (GetCourse() == GetToadsTurnpike()) { + // D_8015F8D0[0] = (gIsMirrorMode != 0) ? D_80164490->posX + 138.0f : D_80164490->posX - 138.0f; + // } else if (GetCourse() == GetWarioStadium()) { + // D_8015F8D0[0] = (gIsMirrorMode != 0) ? D_80164490->posX + 12.0f : D_80164490->posX - 12.0f; + // } else { + // D_8015F8D0[0] = D_80164490->posX; + // } + // } if (!gDemoMode) { func_800CA008(gPlayerCountSelection1 - 1, gCurrentCourseId + 4); func_800CB2C4(); @@ -299,7 +302,10 @@ void clear_nmi_buffer(void) { } } -void func_80003040(void) { +/** + * Also spawns water features + */ +void credits_spawn_actors(void) { Vec3f position; Vec3f velocity = { 0, 0, 0 }; Vec3s rotation = { 0, 0, 0 }; @@ -311,89 +317,14 @@ void func_80003040(void) { gCourseDirection = 1.0f; gPlayerCountSelection1 = 1; - set_segment_base_addr(0x3, (void*) (gNextFreeMemoryAddress + 0xFFFF7000)); + set_segment_base_addr_x64(3, (void*) gNextFreeMemoryAddress); + + // Stupid hack to sync segment 3 memory allocations with hard-coded address in data. + gNextFreeMemoryAddress += 0x9000; destroy_all_actors(); + m_ClearActors(); - CourseManager_SetCourseVtxColours(); + CourseManager_CreditsSpawnActors(); - // switch (gCurrentCourseId) { - // case COURSE_MARIO_RACEWAY: { - // dma_textures(gTextureTrees1, 0x35B, 0x800); - // spawn_foliage(d_course_mario_raceway_tree_spawns); - // break; - // } - // case COURSE_BOWSER_CASTLE: - // // d_course_bowsers_castle_packed_dl_1350 - // find_vtx_and_set_colours(segmented_gfx_to_virtual(0x07001350), 0x32, 0, 0, 0); - // break; - // case COURSE_BANSHEE_BOARDWALK: - // // d_course_banshee_boardwalk_packed_dl_878 - // find_vtx_and_set_colours(segmented_gfx_to_virtual(0x07000878), -0x80, 0, 0, 0); - // break; - // case COURSE_YOSHI_VALLEY: - // vec3f_set(position, -2300.0f, 0.0f, 634.0f); - // position[0] *= gCourseDirection; - // add_actor_to_empty_slot(position, rotation, velocity, ACTOR_YOSHI_EGG); - // break; - // case COURSE_MOO_MOO_FARM: - // dma_textures(gTextureTrees4Left, 0x3E8, 0x800); - // dma_textures(gTextureTrees4Right, 0x3E8, 0x800); - // dma_textures(gTextureCow01Left, 0x400, 0x800); - // dma_textures(gTextureCow01Right, 0x400, 0x800); - // dma_textures(gTextureCow02Left, 0x400, 0x800); - // dma_textures(gTextureCow02Right, 0x400, 0x800); - // dma_textures(gTextureCow03Left, 0x400, 0x800); - // dma_textures(gTextureCow03Right, 0x400, 0x800); - // dma_textures(gTextureCow04Left, 0x400, 0x800); - // dma_textures(gTextureCow04Right, 0x400, 0x800); - // dma_textures(gTextureCow05Left, 0x400, 0x800); - // dma_textures(gTextureCow05Right, 0x400, 0x800); - // spawn_foliage(d_course_moo_moo_farm_tree_spawn); - // break; - // case COURSE_SHERBET_LAND: - // // d_course_sherbet_land_packed_dl_1EB8 - // find_vtx_and_set_colours(segmented_gfx_to_virtual(0x07001EB8), -0x4C, 0xFF, 0xFF, 0xFF); - // // d_course_sherbet_land_packed_dl_2308 - // find_vtx_and_set_colours(segmented_gfx_to_virtual(0x07002308), -0x6A, 0xFF, 0xFF, 0xFF); - // break; - // case COURSE_RAINBOW_ROAD: - // // d_course_rainbow_road_packed_dl_2068 - // find_vtx_and_set_colours(segmented_gfx_to_virtual(0x07002068), -0x6A, 0xFF, 0xFF, 0xFF); - // // d_course_rainbow_road_packed_dl_1E18 - // find_vtx_and_set_colours(segmented_gfx_to_virtual(0x07001E18), -0x6A, 0xFF, 0xFF, 0xFF); - // // d_course_rainbow_road_packed_dl_1318 - // find_vtx_and_set_colours(segmented_gfx_to_virtual(0x07001318), -1, 0xFF, 0xFF, 0); - // break; - // case COURSE_WARIO_STADIUM: - // vec3f_set(position, -131.0f, 83.0f, 286.0f); - // add_actor_to_empty_slot(position, rotation, velocity, ACTOR_WARIO_SIGN); - // vec3f_set(position, -2353.0f, 72.0f, -1608.0f); - // add_actor_to_empty_slot(position, rotation, velocity, ACTOR_WARIO_SIGN); - // vec3f_set(position, -2622.0f, 79.0f, 739.0f); - // add_actor_to_empty_slot(position, rotation, velocity, ACTOR_WARIO_SIGN); - // // d_course_wario_stadium_packed_dl_C50 - // find_vtx_and_set_colours(segmented_gfx_to_virtual(0x07000C50), 0x64, 0xFF, 0xFF, 0xFF); - // // d_course_wario_stadium_packed_dl_BD8 - // find_vtx_and_set_colours(segmented_gfx_to_virtual(0x07000BD8), 0x64, 0xFF, 0xFF, 0xFF); - // // d_course_wario_stadium_packed_dl_B60 - // find_vtx_and_set_colours(segmented_gfx_to_virtual(0x07000B60), 0x64, 0xFF, 0xFF, 0xFF); - // // d_course_wario_stadium_packed_dl_AE8 - // find_vtx_and_set_colours(segmented_gfx_to_virtual(0x07000AE8), 0x64, 0xFF, 0xFF, 0xFF); - // // d_course_wario_stadium_packed_dl_CC8 - // find_vtx_and_set_colours(segmented_gfx_to_virtual(0x07000CC8), 0x64, 0xFF, 0xFF, 0xFF); - // // d_course_wario_stadium_packed_dl_D50 - // find_vtx_and_set_colours(segmented_gfx_to_virtual(0x07000D50), 0x64, 0xFF, 0xFF, 0xFF); - // // d_course_wario_stadium_packed_dl_DD0 - // find_vtx_and_set_colours(segmented_gfx_to_virtual(0x07000DD0), 0x64, 0xFF, 0xFF, 0xFF); - // // d_course_wario_stadium_packed_dl_E48 - // find_vtx_and_set_colours(segmented_gfx_to_virtual(0x07000E48), 0x64, 0xFF, 0xFF, 0xFF); - // break; - // case COURSE_DK_JUNGLE: - // // d_course_dks_jungle_parkway_packed_dl_3FA8 - // find_vtx_and_set_colours(segmented_gfx_to_virtual(0x07003FA8), 0x78, 0xFF, 0xFF, 0xFF); - // break; - // default: - // break; - // } gNumPermanentActors = gNumActors; } diff --git a/src/code_800029B0.h b/src/code_800029B0.h index 009d876ff..584b7af8c 100644 --- a/src/code_800029B0.h +++ b/src/code_800029B0.h @@ -32,7 +32,7 @@ void func_800029B0(void); void setup_race(void); void func_80002DAC(void); void clear_nmi_buffer(void); -void func_80003040(void); +void credits_spawn_actors(void); extern s16 gCurrentCourseId; // D_800DC5A0 extern s16 gCurrentlyLoadedCourseId; @@ -111,7 +111,7 @@ extern Vec3f D_8015F768; extern Vec3f D_8015F778; extern f32 gCourseDirection; -extern s32 D_8015F788; +extern s32 gNumScreens; extern s32 D_8015F790[]; extern u16 D_8015F890; diff --git a/src/code_80005FD0.c b/src/code_80005FD0.c index 1cc9c990a..735887971 100644 --- a/src/code_80005FD0.c +++ b/src/code_80005FD0.c @@ -156,7 +156,7 @@ VehicleStuff gTankerTruckList[NUM_RACE_TANKER_TRUCKS]; VehicleStuff gCarList[NUM_RACE_CARS]; s32 D_80163DD8[4]; BombKart gBombKarts[NUM_BOMB_KARTS_MAX]; -Collision D_80164038[NUM_BOMB_KARTS_MAX]; +Collision gBombKartCollision[NUM_BOMB_KARTS_MAX]; struct unexpiredActors gUnexpiredActorsList[8]; D_801642D8_entry D_801642D8[8]; s16 D_80164358; @@ -1539,22 +1539,8 @@ void update_vehicles(void) { generate_player_smoke(); D_8016337C++; - if (GetCourse() == GetPodiumCeremony()) { - for (i = 0; i < 7; i++) { - func_8000DF8C(i); - } - return; - } - - if (D_8016337C & 1) { - if (gModeSelection == VERSUS) { - for (i = 0; i < 7; i++) { - func_8000DF8C(i); - } - } - - CourseManager_VehiclesTick(); - } + CourseManager_TickBombKarts(); + CourseManager_VehiclesTick(); } void func_800098FC(s32 arg0, Player* player) { @@ -1743,7 +1729,7 @@ void func_80009B60(s32 playerId) { } D_801631F8[playerId] = D_801631E0[playerId]; - CourseManager_RenderTrucks(playerId); + CourseManager_DrawVehicles(playerId); if ((GetCourse() == GetYoshiValley()) || (GetCourse() == GetPodiumCeremony())) { D_801634F8[playerId].unk4 = 0.0f; @@ -1926,7 +1912,6 @@ void func_80009B60(s32 playerId) { } var_v1 = CourseManager_GetProps()->AISteeringSensitivity; - // var_v1 = gKartAISteeringSensitivity[gCurrentCourseId]; switch (D_801631D8[playerId]) { /* switch 4; irregular */ case 2: /* switch 4 */ @@ -2922,7 +2907,7 @@ void set_bomb_kart_spawn_positions(void) { BombKartSpawn* bombKartSpawn; for (var_s3 = 0; var_s3 < NUM_BOMB_KARTS_VERSUS; var_s3++) { - bombKartSpawn = &gBombKartSpawns[gCurrentCourseId][var_s3]; + //bombKartSpawn = &gBombKartSpawns[gCurrentCourseId][var_s3]; if (GetCourse() == GetYoshiValley()) { startingXPos = bombKartSpawn->startingXPos; startingZPos = bombKartSpawn->startingZPos; @@ -2962,7 +2947,7 @@ void set_bomb_kart_spawn_positions(void) { gBombKarts[var_s3].unk_4A = 0; gBombKarts[var_s3].unk_4C = 1; gBombKarts[var_s3].yPos = startingYPos; - check_bounding_collision(&D_80164038[var_s3], 2.0f, startingXPos, startingYPos, startingZPos); + check_bounding_collision(&gBombKartCollision[var_s3], 2.0f, startingXPos, startingYPos, startingZPos); } } @@ -3157,7 +3142,7 @@ void func_8000DF8C(s32 bombKartId) { var_f22 += temp_f14 / 5.0f; var_f24 += temp_f16 / 5.0f; } - temp_a0_4 = &D_80164038[bombKartId]; + temp_a0_4 = &gBombKartCollision[bombKartId]; var_f20 = calculate_surface_height(var_f22, 2000.0f, var_f24, temp_a0_4->meshIndexZX) + 3.5f; if (var_f20 < (-1000.0)) { var_f20 = bombKart->bombPos[1]; @@ -3255,7 +3240,7 @@ s32 add_actor_in_unexpired_actor_list(s32 actorIndex, s16 arg1) { } s32 add_red_shell_in_unexpired_actor_list(s32 actorIndex) { - struct Actor* actor = &gActorList[actorIndex]; + struct Actor* actor = m_GetActor(actorIndex); if (actor->type != ACTOR_RED_SHELL) { return -1; } @@ -3263,7 +3248,7 @@ s32 add_red_shell_in_unexpired_actor_list(s32 actorIndex) { } s32 add_green_shell_in_unexpired_actor_list(s32 actorIndex) { - struct Actor* actor = &gActorList[actorIndex]; + struct Actor* actor = m_GetActor(actorIndex); if (actor->type != ACTOR_GREEN_SHELL) { return -1; } @@ -3271,7 +3256,7 @@ s32 add_green_shell_in_unexpired_actor_list(s32 actorIndex) { } s32 add_blue_shell_in_unexpired_actor_list(s32 arg0) { - struct Actor* actor = &gActorList[arg0]; + struct Actor* actor = m_GetActor(arg0); if (actor->type != ACTOR_BLUE_SPINY_SHELL) { return -1; } @@ -3311,7 +3296,7 @@ void generate_player_smoke(void) { for (someIndex = 0; someIndex < NUM_PLAYERS; someIndex++) { var_s0 = &gUnexpiredActorsList[someIndex]; if (var_s0->unkC == 1) { - temp_s1 = &gActorList[var_s0->actorIndex]; + temp_s1 = GET_ACTOR(var_s0->actorIndex); var_s0->unk14++; switch (var_s0->unk10) { case 0: @@ -3460,12 +3445,11 @@ void func_8000F2DC(void) { D_80164430 = *gWaypointCountByPathIndex; - CourseManager_ResetVehicles(); + CourseManager_ClearVehicles(); CourseManager_SpawnVehicles(); - CourseManager_SpawnBombKarts(); - set_bomb_kart_spawn_positions(); + //set_bomb_kart_spawn_positions(); func_8000EEDC(); } @@ -4506,7 +4490,7 @@ void init_vehicles_trains(size_t i, size_t numCarriages, f32 speed) { void sync_train_components(TrainCarStuff* trainCar, s16 orientationY) { struct TrainCar* trainCarActor; - trainCarActor = (struct TrainCar*) &gActorList[trainCar->actorIndex]; + trainCarActor = (struct TrainCar*) GET_ACTOR(trainCar->actorIndex); trainCarActor->pos[0] = trainCar->position[0]; trainCarActor->pos[1] = trainCar->position[1]; trainCarActor->pos[2] = trainCar->position[2]; @@ -4823,7 +4807,7 @@ void update_vehicle_paddle_boats(void) { paddleBoat->velocity[0] = paddleBoat->position[0] - temp_f26; paddleBoat->velocity[1] = paddleBoat->position[1] - temp_f28; paddleBoat->velocity[2] = paddleBoat->position[2] - temp_f30; - paddleBoatActor = &gActorList[paddleBoat->actorIndex]; + paddleBoatActor = GET_ACTOR(paddleBoat->actorIndex); paddleBoatActor->pos[0] = paddleBoat->position[0]; paddleBoatActor->pos[1] = paddleBoat->position[1]; paddleBoatActor->pos[2] = paddleBoat->position[2]; @@ -5003,7 +4987,7 @@ void update_vehicle_follow_waypoint(VehicleStuff* vehicle) { vehicle->velocity[0] = vehicle->position[0] - sp5C; vehicle->velocity[1] = vehicle->position[1] - sp58; vehicle->velocity[2] = vehicle->position[2] - sp54; - vehicleActor = &gActorList[vehicle->actorIndex]; + vehicleActor = GET_ACTOR(vehicle->actorIndex); vehicleActor->pos[0] = vehicle->position[0]; vehicleActor->pos[1] = vehicle->position[1]; vehicleActor->pos[2] = vehicle->position[2]; @@ -7106,7 +7090,7 @@ void kart_ai_use_item_strategy(s32 playerId) { break; case 2: - banana = (struct BananaActor*) &gActorList[temp_s0->actorIndex]; + banana = (struct BananaActor*) GET_ACTOR(temp_s0->actorIndex); if ((!(banana->flags & 0x8000)) || (banana->type != 6) || (banana->state != 0) || (playerId != banana->playerId)) { temp_s0->unk_00 = 0; @@ -7118,7 +7102,7 @@ void kart_ai_use_item_strategy(s32 playerId) { break; case 3: - banana = (struct BananaActor*) &gActorList[temp_s0->actorIndex]; + banana = (struct BananaActor*) GET_ACTOR(temp_s0->actorIndex); if ((((!(banana->flags & 0x8000)) || (banana->type != 6)) || (banana->state != 0)) || (playerId != banana->playerId)) { if (playerId != banana->playerId) {} @@ -7141,7 +7125,7 @@ void kart_ai_use_item_strategy(s32 playerId) { case 34: temp_s0->actorIndex = use_banana_item(player); if ((temp_s0->actorIndex >= 0) && (temp_s0->actorIndex < 0x64)) { - banana = (struct BananaActor*) &gActorList[temp_s0->actorIndex]; + banana = (struct BananaActor*) GET_ACTOR(temp_s0->actorIndex); banana->state = 4; player->soundEffects |= HOLD_BANANA_SOUND_EFFECT; temp_s0->unk_00 = 0x0023; @@ -7163,7 +7147,7 @@ void kart_ai_use_item_strategy(s32 playerId) { break; case 35: - banana = (struct BananaActor*) &gActorList[temp_s0->actorIndex]; + banana = (struct BananaActor*) GET_ACTOR(temp_s0->actorIndex); if ((((!(banana->flags & 0x8000)) || (banana->type != 6)) || (banana->state != 4)) || (playerId != banana->playerId)) { temp_s0->unk_00 = 0; @@ -7181,7 +7165,7 @@ void kart_ai_use_item_strategy(s32 playerId) { break; case 36: - banana = (struct BananaActor*) &gActorList[temp_s0->actorIndex]; + banana = (struct BananaActor*) GET_ACTOR(temp_s0->actorIndex); if ((((!(banana->flags & 0x8000)) || (banana->type != 6)) || (banana->state != 4)) || (playerId != banana->playerId)) { if (playerId != banana->playerId) {} @@ -7216,7 +7200,7 @@ void kart_ai_use_item_strategy(s32 playerId) { break; case 5: - actor = &gActorList[temp_s0->actorIndex]; + actor = GET_ACTOR(temp_s0->actorIndex); if ((((!(actor->flags & 0x8000)) || (actor->type != 7)) || (actor->state != 0)) || (playerId != actor->rot[2])) { temp_s0->unk_00 = 0; @@ -7228,7 +7212,7 @@ void kart_ai_use_item_strategy(s32 playerId) { break; case 6: - actor = &gActorList[temp_s0->actorIndex]; + actor = GET_ACTOR(temp_s0->actorIndex); if ((((!(actor->flags & 0x8000)) || (actor->type != 7)) || (actor->state != 0)) || (playerId != actor->rot[2])) { temp_s0->unk_00 = 0; @@ -7257,7 +7241,7 @@ void kart_ai_use_item_strategy(s32 playerId) { break; case 8: - shell = (struct ShellActor*) &gActorList[temp_s0->actorIndex]; + shell = (struct ShellActor*) GET_ACTOR(temp_s0->actorIndex); if ((((!(shell->flags & 0x8000)) || (shell->type != 8)) || (shell->state != 0)) || (playerId != shell->playerId)) { temp_s0->unk_00 = 0; @@ -7269,7 +7253,7 @@ void kart_ai_use_item_strategy(s32 playerId) { case 9: func_8001ABEC((struct struct_801642D8*) temp_s0); - shell = (struct ShellActor*) &gActorList[temp_s0->actorIndex]; + shell = (struct ShellActor*) GET_ACTOR(temp_s0->actorIndex); if ((((!(shell->flags & 0x8000)) || (shell->type != 8)) || (shell->state != 0)) || (playerId != shell->playerId)) { temp_s0->unk_00 = 0; @@ -7298,7 +7282,7 @@ void kart_ai_use_item_strategy(s32 playerId) { break; case 11: - bananaBunchParent = (struct BananaBunchParent*) &gActorList[temp_s0->actorIndex]; + bananaBunchParent = (struct BananaBunchParent*) GET_ACTOR(temp_s0->actorIndex); if (bananaBunchParent->state == 6) { var_v0 = 0; if (bananaBunchParent->bananaIndices[4] != (-1)) { @@ -7330,7 +7314,7 @@ void kart_ai_use_item_strategy(s32 playerId) { case 12: if ((((s16) temp_s0->unk_04) % 10) == 0) { if (temp_s0->unk_08 < 5) { - bananaBunchParent = (struct BananaBunchParent*) &gActorList[temp_s0->actorIndex]; + bananaBunchParent = (struct BananaBunchParent*) GET_ACTOR(temp_s0->actorIndex); var_v0 = 0; switch (temp_s0->unk_08) { case 0: @@ -7388,7 +7372,7 @@ void kart_ai_use_item_strategy(s32 playerId) { break; case 14: - fakeItemBox = (struct FakeItemBox*) &gActorList[temp_s0->actorIndex]; + fakeItemBox = (struct FakeItemBox*) GET_ACTOR(temp_s0->actorIndex); if ((((!(fakeItemBox->flags & 0x8000)) || (fakeItemBox->type != 0x000D)) || (fakeItemBox->state != 0)) || (playerId != ((s32) fakeItemBox->playerId))) { @@ -7400,7 +7384,7 @@ void kart_ai_use_item_strategy(s32 playerId) { break; case 15: - fakeItemBox = (struct FakeItemBox*) &gActorList[temp_s0->actorIndex]; + fakeItemBox = (struct FakeItemBox*) GET_ACTOR(temp_s0->actorIndex); if ((((!(fakeItemBox->flags & 0x8000)) || (fakeItemBox->type != 0x000D)) || (fakeItemBox->state != 0)) || (playerId != ((s32) fakeItemBox->playerId))) { @@ -7585,7 +7569,7 @@ void func_8001C14C(void) { f32 temp_f0; f32 temp_f2; s32 var_s1; - Player* temp_s0; + Player* player; if (D_8016347C == 1) { D_80163480 += 1; @@ -7603,42 +7587,42 @@ void func_8001C14C(void) { break; } - temp_s0 = &gPlayerOne[var_s1]; + player = &gPlayerOne[var_s1]; func_80009B60(var_s1); - if (!(temp_s0->type & 0x2000)) { - temp_f0 = D_80163418[var_s1] - temp_s0->pos[0]; - temp_f2 = D_80163438[var_s1] - temp_s0->pos[2]; + if (!(player->type & 0x2000)) { + temp_f0 = D_80163418[var_s1] - player->pos[0]; + temp_f2 = D_80163438[var_s1] - player->pos[2]; if ((f64) ((temp_f0 * temp_f0) + (temp_f2 * temp_f2)) < 1.0) { if (var_s1 != 3) { if (1) {} // Why oh why is a ternary required here? Who does that? - (D_8016347C == 0) ? (temp_s0->type |= 0x2000) : (temp_s0->type &= ~0x2000); + (D_8016347C == 0) ? (player->type |= 0x2000) : (player->type &= ~0x2000); if ((gPlayerOne->type & 0x2000) && (gPlayerTwo->type & 0x2000) && (gPlayerThree->type & 0x2000)) { D_8016347C = 1; D_80163480 = 0; } } else if (D_8016347E == 0) { - if (!(temp_s0->effects & 0x01000000)) { - temp_s0->type |= 0x2000; + if (!(player->effects & 0x01000000)) { + player->type |= 0x2000; } D_8016347E = 1; D_80163484 = 0; - } else if (!(temp_s0->effects & 0x01000000)) { - temp_s0->type |= 0x2000; + } else if (!(player->effects & 0x01000000)) { + player->type |= 0x2000; } } } } } -void func_8001C3C4(s32 cameraId) { +void render_bomb_karts_wrap(s32 cameraId) { if (GetCourse() == GetPodiumCeremony()) { if (gBombKarts[0].waypointIndex >= 16) { - func_80057114(PLAYER_FOUR); + render_bomb_karts(PLAYER_FOUR); } } else { if (gModeSelection == VERSUS) { - func_80057114(cameraId); + render_bomb_karts(cameraId); } } } diff --git a/src/code_80005FD0.h b/src/code_80005FD0.h index 354cc2ec3..8fcf443b9 100644 --- a/src/code_80005FD0.h +++ b/src/code_80005FD0.h @@ -250,7 +250,7 @@ void func_8001BE78(void); void func_8001C05C(void); void func_8001C14C(void); -void func_8001C3C4(s32); +void render_bomb_karts_wrap(s32); void func_8001C42C(void); /* This is where I'd put my static data, if I had any */ diff --git a/src/code_80057C60.c b/src/code_80057C60.c index a359e1dcd..205e656d2 100644 --- a/src/code_80057C60.c +++ b/src/code_80057C60.c @@ -557,7 +557,8 @@ void render_object_p1(void) { gSPMatrix(gDisplayListHead++, VIRTUAL_TO_PHYSICAL(&gGfxPool->mtxLookAt[0]), G_MTX_NOPUSH | G_MTX_MUL | G_MTX_PROJECTION); - func_8001C3C4(PLAYER_ONE); + CourseManager_DrawBombKarts(PLAYER_ONE); + //render_bomb_karts_wrap(PLAYER_ONE); if (gGamestate == ENDING) { func_80055F48(PLAYER_ONE); func_80056160(PLAYER_ONE); @@ -578,7 +579,8 @@ void render_object_p2(void) { G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_PROJECTION); gSPMatrix(gDisplayListHead++, VIRTUAL_TO_PHYSICAL(&gGfxPool->mtxLookAt[1]), G_MTX_NOPUSH | G_MTX_MUL | G_MTX_PROJECTION); - func_8001C3C4(PLAYER_TWO); + CourseManager_DrawBombKarts(PLAYER_TWO); + //render_bomb_karts_wrap(PLAYER_TWO); if (!gDemoMode) { render_lakitu(PLAYER_TWO); } @@ -591,7 +593,8 @@ void render_object_p3(void) { G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_PROJECTION); gSPMatrix(gDisplayListHead++, VIRTUAL_TO_PHYSICAL(&gGfxPool->mtxLookAt[2]), G_MTX_NOPUSH | G_MTX_MUL | G_MTX_PROJECTION); - func_8001C3C4(PLAYER_THREE); + CourseManager_DrawBombKarts(PLAYER_THREE); + //render_bomb_karts_wrap(PLAYER_THREE); if (!gDemoMode) { render_lakitu(PLAYER_THREE); } @@ -605,7 +608,8 @@ void render_object_p4(void) { G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_PROJECTION); gSPMatrix(gDisplayListHead++, VIRTUAL_TO_PHYSICAL(&gGfxPool->mtxLookAt[3]), G_MTX_NOPUSH | G_MTX_MUL | G_MTX_PROJECTION); - func_8001C3C4(PLAYER_FOUR); + CourseManager_DrawBombKarts(PLAYER_FOUR); + //render_bomb_karts_wrap(PLAYER_FOUR); if ((!gDemoMode) && (gPlayerCountSelection1 == 4)) { render_lakitu(PLAYER_FOUR); } @@ -753,7 +757,7 @@ void render_object_for_player(s32 cameraId) { // break; // case COURSE_TOADS_TURNPIKE: // break; - // case COURSE_KALAMARI_DESERT: + // case COURSE_KALIMARI_DESERT: // render_object_trains_smoke_particles(cameraId); // break; // case COURSE_SHERBET_LAND: @@ -787,10 +791,11 @@ void render_object_for_player(s32 cameraId) { render_object_leaf_particle(cameraId); if (D_80165730 != 0) { - func_80053E6C(cameraId); + render_balloons_grand_prix(cameraId); } if (gModeSelection == BATTLE) { - render_object_bomb_kart(cameraId); + CourseManager_DrawBattleBombKarts(cameraId); + //render_battle_bomb_karts(cameraId); } } @@ -1622,7 +1627,7 @@ void update_object(void) { // update_moles(); // } // break; - // case COURSE_KALAMARI_DESERT: + // case COURSE_KALIMARI_DESERT: // update_train_smoke(); // break; // case COURSE_SHERBET_LAND: @@ -2715,29 +2720,31 @@ void func_8005D18C(void) { } } -void func_8005D1F4(s32 arg0) { - s32 playerWaypoint; - s32 bombWaypoint; - s32 var_a2; - s32 waypointDiff; +void func_8005D1F4(s32 cameraId) { - if (gModeSelection == 2) { - playerWaypoint = gNearestWaypointByPlayerId[arg0]; - playerHUD[arg0].unk_74 = 0; - for (var_a2 = 0; var_a2 < NUM_BOMB_KARTS_VERSUS; var_a2++) { - if ((gBombKarts[var_a2].state == BOMB_STATE_EXPLODED) || - (gBombKarts[var_a2].state == BOMB_STATE_INACTIVE)) { - continue; - } - bombWaypoint = gBombKarts[var_a2].waypointIndex; - waypointDiff = bombWaypoint - playerWaypoint; - if ((waypointDiff < -5) || (waypointDiff > 0x1E)) { - continue; - } - playerHUD[arg0].unk_74 = 1; - break; - } - } + CourseManager_BombKartsWaypoint(cameraId); + // s32 playerWaypoint; + // s32 bombWaypoint; + // s32 var_a2; + // s32 waypointDiff; + + // if (gModeSelection == 2) { + // playerWaypoint = gNearestWaypointByPlayerId[cameraId]; + // playerHUD[cameraId].unk_74 = 0; + // for (var_a2 = 0; var_a2 < NUM_BOMB_KARTS_VERSUS; var_a2++) { + // if ((gBombKarts[var_a2].state == BOMB_STATE_EXPLODED) || + // (gBombKarts[var_a2].state == BOMB_STATE_INACTIVE)) { + // continue; + // } + // bombWaypoint = gBombKarts[var_a2].waypointIndex; + // waypointDiff = bombWaypoint - playerWaypoint; + // if ((waypointDiff < -5) || (waypointDiff > 0x1E)) { + // continue; + // } + // playerHUD[cameraId].unk_74 = 1; + // break; + // } + // } } // Appears to load GP Mode race staging balloons and kart shadows. @@ -4972,13 +4979,15 @@ void func_800651F4(Player* player, UNUSED s8 arg1, UNUSED s8 arg2, s8 arg3) { } void func_800652D4(Vec3f arg0, Vec3s arg1, f32 arg2) { - Mat4 sp20; + Mat4 mtx; - mtxf_translate_rotate(sp20, arg0, arg1); - mtxf_scale2(sp20, arg2); - convert_to_fixed_point_matrix(&gGfxPool->mtxEffect[gMatrixEffectCount], sp20); - gSPMatrix(gDisplayListHead++, VIRTUAL_TO_PHYSICAL(&gGfxPool->mtxEffect[gMatrixEffectCount]), - G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + mtxf_translate_rotate(mtx, arg0, arg1); + mtxf_scale2(mtx, arg2); + // convert_to_fixed_point_matrix(&gGfxPool->mtxEffect[gMatrixEffectCount], mtx); + // gSPMatrix(gDisplayListHead++, VIRTUAL_TO_PHYSICAL(&gGfxPool->mtxEffect[gMatrixEffectCount]), + // G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + + AddEffectMatrix(mtx, G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); } void func_8006538C(Player* player, s8 arg1, s16 arg2, s8 arg3) { @@ -5600,10 +5609,16 @@ void func_80068AA4(Player* player, UNUSED s8 arg1, UNUSED f32 arg2, s8 arg3, s8 Vec3f sp64; Vec3s sp5C; + sp64[1] = player->pos[1]; + sp64[2] = player->pos[2]; + sp64[0] = player->pos[0]; + if ((player->unk_258[20 + arg4].unk_01C == 1) && (player->animFrameSelector[arg3] < 0xD)) { +if (gTickVisuals) { sp64[1] = player->pos[1] - 3.0f; sp64[2] = player->pos[2] + ((-2.5 * player->unk_258[20 + arg4].unk_01E) * coss(player->unk_048[arg3])); sp64[0] = player->pos[0] + ((-2.5 * player->unk_258[20 + arg4].unk_01E) * sins(player->unk_048[arg3])); +} sp5C[0] = 0; sp5C[1] = player->unk_048[arg3]; sp5C[2] = 0; @@ -5999,7 +6014,7 @@ void func_8006A7C0(Player* player, f32 arg1, f32 arg2, s8 arg3, s8 arg4) { } void render_battle_balloon(Player* player, s8 arg1, s16 arg2, s8 arg3) { - Mat4 sp140; + Mat4 mtx; Vec3f sp134; Vec3s sp12C; UNUSED s16 stackPadding; @@ -6055,23 +6070,24 @@ void render_battle_balloon(Player* player, s8 arg1, s16 arg2, s8 arg3) { sp12C[1] = player->unk_048[arg3]; sp12C[2] = D_8018D7D0[arg1][arg2] - (D_8018D860[arg1][arg2] * coss(temp_t1)) - ((D_8018D890[arg1][arg2] * 8) * sins(temp_t1)); - mtxf_translate_rotate(sp140, sp134, sp12C); - mtxf_scale2(sp140, var_f20); - convert_to_fixed_point_matrix(&gGfxPool->mtxEffect[gMatrixEffectCount], sp140); + mtxf_translate_rotate(mtx, sp134, sp12C); + mtxf_scale2(mtx, var_f20); + // convert_to_fixed_point_matrix(&gGfxPool->mtxEffect[gMatrixEffectCount], sp140); - gSPMatrix(gDisplayListHead++, VIRTUAL_TO_PHYSICAL(&gGfxPool->mtxEffect[gMatrixEffectCount]), - G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + // gSPMatrix(gDisplayListHead++, VIRTUAL_TO_PHYSICAL(&gGfxPool->mtxEffect[gMatrixEffectCount]), + // G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + AddEffectMatrix(mtx, G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); gSPDisplayList(gDisplayListHead++, D_0D008DB8); gDPLoadTLUT_pal256(gDisplayListHead++, gTLUTOnomatopoeia); gDPSetTextureLUT(gDisplayListHead++, G_TT_RGBA16); func_8004B614(primRed, primGreen, primBlue, envRed, envGreen, envBlue, 0x000000D8); - gDPSetRenderMode(gDisplayListHead++, - AA_EN | Z_CMP | Z_UPD | IM_RD | CVG_DST_WRAP | ZMODE_XLU | CVG_X_ALPHA | FORCE_BL | - GBL_c1(G_BL_CLR_IN, G_BL_A_IN, G_BL_CLR_MEM, G_BL_1MA), - 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)); + AA_EN | Z_CMP | Z_UPD | IM_RD | CVG_DST_WRAP | ZMODE_XLU | CVG_X_ALPHA | FORCE_BL | + GBL_c1(G_BL_CLR_IN, G_BL_A_IN, G_BL_CLR_MEM, G_BL_1MA), + 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, G_TX_NOMIRROR | G_TX_CLAMP, G_TX_NOMASK, G_TX_NOMASK, G_TX_NOLOD, G_TX_NOLOD); gSPVertex(gDisplayListHead++, gBalloonVertexPlane1, 4, 0); @@ -6147,7 +6163,7 @@ void func_8006BA94(Player* player, s8 playerIndex, s8 arg2) { * Used in podium ceremony. */ void render_balloon(Vec3f arg0, f32 arg1, s16 arg2, s16 arg3) { - Mat4 sp108; + Mat4 mtx; Vec3f spFC; Vec3s spF4; UNUSED s16 stackPadding; @@ -6178,20 +6194,22 @@ void render_balloon(Vec3f arg0, f32 arg1, s16 arg2, s16 arg3) { spF4[0] = 0; spF4[1] = camera1->rot[1]; spF4[2] = arg2; - mtxf_translate_rotate(sp108, spFC, spF4); - mtxf_scale2(sp108, arg1); - convert_to_fixed_point_matrix(&gGfxPool->mtxEffect[gMatrixEffectCount], sp108); - gSPMatrix(gDisplayListHead++, VIRTUAL_TO_PHYSICAL(&gGfxPool->mtxEffect[gMatrixEffectCount]), - G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + mtxf_translate_rotate(mtx, spFC, spF4); + mtxf_scale2(mtx, arg1); + // convert_to_fixed_point_matrix(&gGfxPool->mtxEffect[gMatrixEffectCount], sp108); + // gSPMatrix(gDisplayListHead++, VIRTUAL_TO_PHYSICAL(&gGfxPool->mtxEffect[gMatrixEffectCount]), + // G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + AddEffectMatrix(mtx, G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); gSPDisplayList(gDisplayListHead++, D_0D008DB8); gDPLoadTLUT_pal256(gDisplayListHead++, gTLUTOnomatopoeia); gDPSetTextureLUT(gDisplayListHead++, G_TT_RGBA16); func_8004B614(primRed, primGreen, primBlue, envRed, envGreen, envBlue, 0x000000D8); gDPSetRenderMode(gDisplayListHead++, - AA_EN | Z_CMP | Z_UPD | IM_RD | CVG_DST_WRAP | ZMODE_XLU | CVG_X_ALPHA | FORCE_BL | - GBL_c1(G_BL_CLR_IN, G_BL_A_IN, G_BL_CLR_MEM, G_BL_1MA), - 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)); + AA_EN | Z_CMP | Z_UPD | IM_RD | CVG_DST_WRAP | ZMODE_XLU | CVG_X_ALPHA | FORCE_BL | + GBL_c1(G_BL_CLR_IN, G_BL_A_IN, G_BL_CLR_MEM, G_BL_1MA), + 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, G_TX_NOMIRROR | G_TX_CLAMP, G_TX_NOMASK, G_TX_NOMASK, G_TX_NOLOD, G_TX_NOLOD); gSPVertex(gDisplayListHead++, gBalloonVertexPlane1, 4, 0); diff --git a/src/code_8006E9C0.c b/src/code_8006E9C0.c index 3a31a3ef2..e939ff8e8 100644 --- a/src/code_8006E9C0.c +++ b/src/code_8006E9C0.c @@ -286,7 +286,7 @@ void func_8006F008(void) { // D_8018D2E0 = 57; // D_8018D2E8 = 44; // break; - // case COURSE_KALAMARI_DESERT: + // case COURSE_KALIMARI_DESERT: // D_8018D2C0[0] = 263; // D_8018D2D8[0] = 165; // D_8018D220 = (void*) dma_textures(gTextureExhaust5, 0x443, 0x1000); @@ -624,9 +624,11 @@ void init_object_list_index(void) { find_unused_obj_index(&indexObjectList4[loopIndex]); } - for (loopIndex = 0; loopIndex < NUM_BOMB_KARTS_VERSUS; loopIndex++) { - find_unused_obj_index(&gIndexObjectBombKart[loopIndex]); - } + CourseManager_SpawnBombKarts(); + + // for (loopIndex = 0; loopIndex < NUM_BOMB_KARTS_VERSUS; loopIndex++) { + // find_unused_obj_index(&gIndexObjectBombKart[loopIndex]); + // } } void init_cloud_object(s32 objectIndex, s32 arg1, CloudData* arg2) { @@ -741,7 +743,7 @@ void func_8007055C(void) { // case COURSE_TOADS_TURNPIKE: // init_stars(gToadsTurnpikeRainbowRoadStars); // break; - // case COURSE_KALAMARI_DESERT: + // case COURSE_KALIMARI_DESERT: // init_clouds(gKalimariDesertClouds); // break; // case COURSE_SHERBET_LAND: @@ -990,7 +992,7 @@ void init_course_object(void) { // } // } // break; - // case COURSE_KALAMARI_DESERT: + // case COURSE_KALIMARI_DESERT: // if (gGamestate != CREDITS_SEQUENCE) { // find_unused_obj_index(&D_8018CF10); // init_object(D_8018CF10, 0); diff --git a/src/code_80091750.c b/src/code_80091750.c index 927572463..200a94398 100644 --- a/src/code_80091750.c +++ b/src/code_80091750.c @@ -46,6 +46,7 @@ #include "engine/Engine.h" #include "engine/courses/Course.h" +#include "engine/Matrix.h" const char* GetCupName(void); @@ -323,36 +324,9 @@ char* gCupNames[] = { "special cup", }; -// Displays at beginning of course -char* gCourseNames[] = { -#include "assets/course_metadata/gCourseNames.inc.c" -}; - -char* gCourseNamesDup[] = { -#include "assets/course_metadata/gCourseNames.inc.c" -}; - -char* gCourseNamesDup2[] = { -#include "assets/course_metadata/gCourseNames.inc.c" -}; - -// Used in debug menu at splash screen -char* gDebugCourseNames[] = { -#include "assets/course_metadata/gCourseDebugNames.inc.c" -}; - -const s8 gPerCupIndexByCourseId[] = { -#include "assets/course_metadata/gPerCupIndexByCourseId.inc.c" -}; - // @todo Increase this array for more than eight players const s8 D_800EFD64[] = { 0, 1, 4, 3, 5, 6, 2, 7 }; -// Maps course IDs (as defined in the COURSES enum) to the cup they belong to -s8 gCupSelectionByCourseId[] = { -#include "assets/course_metadata/gCupSelectionByCourseId.inc.c" -}; - char* D_800E7678[] = { "none", "bronze", @@ -448,10 +422,6 @@ char D_800E77B4[] = "a BUTTON*SEE DATA B BUTTON*EXIT"; // This is plain data, it should not end up in rodata char D_800E77D8[] = "distance"; -char* sCourseLengths[] = { -#include "assets/course_metadata/sCourseLengths.inc.c" -}; - char* D_800E7834[] = { "return to menu", "erase records for this course", @@ -1987,7 +1957,7 @@ void func_80093A30(s32 arg0) { } void func_80093A5C(u32 arg0) { - if (D_8015F788 == 0) { + if (gNumScreens == 0) { func_8009C918(); } switch (arg0) { @@ -1998,7 +1968,7 @@ void func_80093A5C(u32 arg0) { case RENDER_SCREEN_MODE_2P_HORIZONTAL_PLAYER_TWO: case RENDER_SCREEN_MODE_2P_VERTICAL_PLAYER_ONE: case RENDER_SCREEN_MODE_2P_VERTICAL_PLAYER_TWO: - if (D_8015F788 == 0) { + if (gNumScreens == 0) { func_80093C1C((s32) D_800F0B1C[arg0]); } else { func_800940EC((s32) D_800F0B1C[arg0]); @@ -2008,7 +1978,7 @@ void func_80093A5C(u32 arg0) { case RENDER_SCREEN_MODE_3P_4P_PLAYER_TWO: case RENDER_SCREEN_MODE_3P_4P_PLAYER_THREE: case RENDER_SCREEN_MODE_3P_4P_PLAYER_FOUR: - if (D_8015F788 == 3) { + if (gNumScreens == 3) { func_800940EC((s32) D_800F0B1C[arg0]); } else { func_80093C1C((s32) D_800F0B1C[arg0]); @@ -2063,9 +2033,10 @@ UNUSED void func_80093C90(void) { void func_80093C98(s32 arg0) { gSPViewport(gDisplayListHead++, VIRTUAL_TO_PHYSICAL(D_802B8880)); - guOrtho(&gGfxPool->mtxEffect[gMatrixEffectCount], 0.0f, 319.0f, 239.0f, 0.0f, -100.0f, 100.0f, 1.0f); - gSPMatrix(gDisplayListHead++, VIRTUAL_TO_PHYSICAL(&gGfxPool->mtxEffect[gMatrixEffectCount++]), - G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_PROJECTION); + // guOrtho(&gGfxPool->mtxEffect[gMatrixEffectCount], 0.0f, 319.0f, 239.0f, 0.0f, -100.0f, 100.0f, 1.0f); + // gSPMatrix(gDisplayListHead++, VIRTUAL_TO_PHYSICAL(&gGfxPool->mtxEffect[gMatrixEffectCount++]), + // G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_PROJECTION); + AddEffectMatrixOrtho(); gSPDisplayList(gDisplayListHead++, D_02007F18); gDPSetScissor(gDisplayListHead++, G_SC_NON_INTERLACE, 0, 0, SCREEN_WIDTH, SCREEN_HEIGHT); func_800A8250(); @@ -2074,6 +2045,7 @@ void func_80093C98(s32 arg0) { func_8009CA6C(4); D_80165754 = gMatrixEffectCount; gMatrixEffectCount = 0; + ClearEffectsMatrixPool(); } } @@ -2110,9 +2082,10 @@ void func_80093E60(void) { void func_80093F10(void) { gSPViewport(gDisplayListHead++, VIRTUAL_TO_PHYSICAL(D_802B8880)); - guOrtho(&gGfxPool->mtxEffect[gMatrixEffectCount], 0.0f, 319.0f, 239.0f, 0.0f, -100.0f, 100.0f, 1.0f); - gSPMatrix(gDisplayListHead++, VIRTUAL_TO_PHYSICAL(&gGfxPool->mtxEffect[gMatrixEffectCount++]), - G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_PROJECTION); + // guOrtho(&gGfxPool->mtxEffect[gMatrixEffectCount], 0.0f, 319.0f, 239.0f, 0.0f, -100.0f, 100.0f, 1.0f); + // gSPMatrix(gDisplayListHead++, VIRTUAL_TO_PHYSICAL(&gGfxPool->mtxEffect[gMatrixEffectCount++]), + // G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_PROJECTION); + AddEffectMatrixOrtho(); gSPDisplayList(gDisplayListHead++, D_02007F18); gDPSetScissor(gDisplayListHead++, G_SC_NON_INTERLACE, 0, 0, SCREEN_WIDTH, SCREEN_HEIGHT); func_80092290(4, D_8018E850, D_8018E858); @@ -2126,14 +2099,16 @@ void func_80093F10(void) { func_8009CA2C(); gSPDisplayList(gDisplayListHead++, D_02007F48); gMatrixEffectCount = 0; + ClearEffectsMatrixPool(); } void func_800940EC(s32 arg0) { gSPViewport(gDisplayListHead++, VIRTUAL_TO_PHYSICAL(D_802B8880)); gDPSetScissor(gDisplayListHead++, G_SC_NON_INTERLACE, 0, 0, SCREEN_WIDTH, SCREEN_HEIGHT); - guOrtho(&gGfxPool->mtxEffect[gMatrixEffectCount], 0.0f, 319.0f, 239.0f, 0.0f, -100.0f, 100.0f, 1.0f); - gSPMatrix(gDisplayListHead++, VIRTUAL_TO_PHYSICAL(&gGfxPool->mtxEffect[gMatrixEffectCount++]), - G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_PROJECTION); + // guOrtho(&gGfxPool->mtxEffect[gMatrixEffectCount], 0.0f, 319.0f, 239.0f, 0.0f, -100.0f, 100.0f, 1.0f); + // gSPMatrix(gDisplayListHead++, VIRTUAL_TO_PHYSICAL(&gGfxPool->mtxEffect[gMatrixEffectCount++]), + // G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_PROJECTION); + AddEffectMatrixOrtho(); gSPDisplayList(gDisplayListHead++, D_02007F18); func_80092290(4, D_8018E850, D_8018E858); func_80092290(5, (s32*) &D_8018E850[1], (s32*) &D_8018E858[1]); @@ -2223,6 +2198,8 @@ void render_checkered_flag(struct GfxPool* arg0, UNUSED s32 arg1) { } void func_80094A64(struct GfxPool* pool) { + ClearHudMatrixPool(); + ClearEffectsMatrixPool(); gMatrixHudCount = 0; gMatrixEffectCount = 0; gSPViewport(gDisplayListHead++, VIRTUAL_TO_PHYSICAL(D_802B8880)); @@ -2625,13 +2602,10 @@ void func_80095AE0(MTX_TYPE* arg0, f32 arg1, f32 arg2, f32 arg3, f32 arg4) { Gfx* func_80095BD0(Gfx* displayListHead, u8* arg1, f32 arg2, f32 arg3, u32 arg4, u32 arg5, f32 arg6, f32 arg7) { Vtx* var_a1; - Mtx* sp28; - // A match is a match, but why are goto's required here? if (gMatrixEffectCount >= 0x2F7) { goto func_80095BD0_label1; } - sp28 = &gGfxPool->mtxEffect[gMatrixEffectCount]; if (gMatrixEffectCount < 0) { rmonPrintf("effectcount < 0 !!!!!!(kawano)\n"); } @@ -2640,10 +2614,9 @@ func_80095BD0_label1: rmonPrintf("MAX effectcount(760) over!!!!(kawano)\n"); return displayListHead; func_80095BD0_label2: - func_80095AE0(sp28, arg2, arg3, arg6, arg7); - gSPMatrix(displayListHead++, VIRTUAL_TO_PHYSICAL(&gGfxPool->mtxEffect[gMatrixEffectCount]), - G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); - gMatrixEffectCount += 1; + 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, G_TX_NOMIRROR | G_TX_WRAP, G_TX_NOMASK, G_TX_NOMASK, G_TX_NOLOD, G_TX_NOLOD); switch (arg4) { @@ -3341,9 +3314,9 @@ Gfx* draw_box(Gfx* displayListHead, s32 ulx, s32 uly, s32 lrx, s32 lry, u32 red, } gSPDisplayList(displayListHead++, D_02008008); gDPSetPrimColor(displayListHead++, 0, 0, red, green, blue, alpha); - // gDPFillWideRectangle(displayListHead++, OTRGetRectDimensionFromLeftEdge(0), uly, - // OTRGetRectDimensionFromRightEdge(SCREEN_WIDTH), lry); - gDPFillRectangle(displayListHead++, ulx, uly, lrx, lry); + gDPFillWideRectangle(displayListHead++, OTRGetRectDimensionFromLeftEdge(ulx), uly, + OTRGetRectDimensionFromRightEdge(lrx), lry); + //gDPFillRectangle(displayListHead++, ulx, uly, lrx, lry); gDPPipeSync(displayListHead++); return displayListHead; } @@ -4805,7 +4778,7 @@ void func_8009CE64(s32 arg0) { func_8009CE64_label1: if (var_a1) { gGotoMenu = 9; - gCreditsCourseId = 8; + gCreditsCourseId = COURSE_LUIGI_RACEWAY; } else { gGotoMenu = 1; gMenuSelection = 0x0000000B; @@ -4945,6 +4918,7 @@ void func_8009CE64(s32 arg0) { case 0: /* switch 4 */ SetCourseByClass(GetMarioRaceway()); CourseManager_SetCup(GetFlowerCup()); + SetCupCursorPosition(COURSE_FOUR); gCurrentCourseId = 0; gScreenModeSelection = 0; gPlayerCountSelection1 = 1; @@ -4955,6 +4929,7 @@ void func_8009CE64(s32 arg0) { case 1: /* switch 4 */ SetCourseByClass(GetLuigiRaceway()); CourseManager_SetCup(GetMushroomCup()); + SetCupCursorPosition(COURSE_ONE); gCurrentCourseId = (s16) 1; gScreenModeSelection = (s32) 1; gPlayerCountSelection1 = 2; @@ -4966,7 +4941,8 @@ void func_8009CE64(s32 arg0) { case 2: /* switch 4 */ SetCourseByClass(GetKalimariDesert()); CourseManager_SetCup(GetMushroomCup()); - gCurrentCourseId = COURSE_KALAMARI_DESERT; + SetCupCursorPosition(COURSE_FOUR); + gCurrentCourseId = COURSE_KALIMARI_DESERT; gScreenModeSelection = 0; gPlayerCountSelection1 = (s32) 1; gPlayerCount = 1; @@ -4976,6 +4952,7 @@ void func_8009CE64(s32 arg0) { case 3: /* switch 4 */ SetCourseByClass(GetWarioStadium()); CourseManager_SetCup(GetStarCup()); + SetCupCursorPosition(COURSE_ONE); gCurrentCourseId = 0x000E; gScreenModeSelection = 3; gPlayerCountSelection1 = 3; @@ -4988,6 +4965,7 @@ void func_8009CE64(s32 arg0) { case 4: /* switch 4 */ SetCourseByClass(GetBowsersCastle()); CourseManager_SetCup(GetStarCup()); + SetCupCursorPosition(COURSE_FOUR); gCurrentCourseId = 2; gScreenModeSelection = 0; gPlayerCountSelection1 = (s32) 1; @@ -4998,6 +4976,7 @@ void func_8009CE64(s32 arg0) { case 5: /* switch 4 */ SetCourseByClass(GetSherbetLand()); CourseManager_SetCup(GetFlowerCup()); + SetCupCursorPosition(COURSE_TWO); gCurrentCourseId = 0x000C; gScreenModeSelection = 3; gPlayerCountSelection1 = 4; @@ -5011,6 +4990,7 @@ void func_8009CE64(s32 arg0) { default: break; } + SetCourseFromCup(); gNextDemoId += 1; if (gNextDemoId >= 6) { gNextDemoId = 0; @@ -5063,7 +5043,7 @@ void func_8009CE64(s32 arg0) { case 2: /* switch 5 */ case 3: /* switch 5 */ gGamestateNext = 9; - gCreditsCourseId = 8; + gCreditsCourseId = COURSE_LUIGI_RACEWAY; break; default: /* switch 5 */ gGamestateNext = 4; @@ -5100,9 +5080,9 @@ void func_8009CE64(s32 arg0) { } } - gCupSelection = gCupSelectionByCourseId[gCurrentCourseId]; + //gCupSelection = gCupSelectionByCourseId[gCurrentCourseId]; D_800DC540 = GetCupIndex(); - gCourseIndexInCup = gPerCupIndexByCourseId[gCurrentCourseId]; + gCourseIndexInCup = GetCupCursorPosition();; switch (gDebugGotoScene) { /* switch 6; irregular */ case 1: /* switch 6 */ @@ -5453,12 +5433,12 @@ void func_8009E2F0(s32 arg0) { temp_t0 = &D_8018E810[arg0]; temp_v0 = &D_800E7AC8[temp_t7]; if ((u32) D_8018E840[arg0] < 0x1BU) { - gDisplayListHead = draw_box(gDisplayListHead, temp_t1->x - (temp_t0->x / 2), temp_t1->y - (temp_t0->y / 2), + gDisplayListHead = draw_box_fill_wide(gDisplayListHead, temp_t1->x - (temp_t0->x / 2), temp_t1->y - (temp_t0->y / 2), temp_t1->x + (temp_t0->x / 2), temp_t1->y + (temp_t0->y / 2), temp_v0->red, temp_v0->green, temp_v0->blue, temp_v0->alpha); } else { temp_t7_2 = ((u32) (38 - D_8018E840[arg0])) / 11.0; - gDisplayListHead = draw_box(gDisplayListHead, temp_t1->x - (temp_t0->x / 2), temp_t1->y - (temp_t0->y / 2), + gDisplayListHead = draw_box_fill_wide(gDisplayListHead, temp_t1->x - (temp_t0->x / 2), temp_t1->y - (temp_t0->y / 2), temp_t1->x + (temp_t0->x / 2), temp_t1->y + (temp_t0->y / 2), temp_v0->red, temp_v0->green, temp_v0->blue, (u32) (temp_v0->alpha * temp_t7_2)); } @@ -6011,11 +5991,11 @@ void func_8009F5E0(struct_8018D9E0_entry* arg0) { } break; case 0x5: /* switch 6 */ - var_t0 = (s32) ((f32) (get_string_width(gCourseNamesDup[0]) + 5) * 0.9f) / 2; + var_t0 = (s32) ((f32) (get_string_width(CourseManager_GetProps()->Name) + 5) * 0.9f) / 2; gDisplayListHead = draw_box(gDisplayListHead, 0xA0 - var_t0, 0x0000007B, var_t0 + 0xA0, 0x000000A4, 0, 0, 0, 0x00000096); set_text_color(1); - draw_text(0x0000009B, 0x0000008C, gCourseNamesDup[0], 0, 0.9f, 0.9f); + draw_text(0x0000009B, 0x0000008C, CourseManager_GetProps()->Name, 0, 0.9f, 0.9f); temp_v1 = func_800B4EB4(0, 7) & 0xFFFFF; if (temp_v1 < 0x1EAA) { set_text_color((s32) gGlobalTimer % 2); @@ -6813,10 +6793,10 @@ void func_800A1A20(struct_8018D9E0_entry* arg0) { courseId = gCupCourseOrder[gTimeTrialDataCourseIndex / 4][gTimeTrialDataCourseIndex % 4]; arg0->column = 0x14; set_text_color(TEXT_BLUE_GREEN_RED_CYCLE_1); - draw_text(0x69, arg0->row + 0x19, gCourseNamesDup[courseId], 0, 0.75f, 0.75f); + draw_text(0x69, arg0->row + 0x19, CourseManager_GetProps()->Name, 0, 0.75f, 0.75f); set_text_color(TEXT_RED); func_80093324(0x2D, arg0->row + 0x28, (char*) &D_800E77D8, 0, 0.75f, 0.75f); - func_800936B8(0xA5, arg0->row + 0x28, sCourseLengths[courseId], 1, 0.75f, 0.75f); + func_800936B8(0xA5, arg0->row + 0x28, CourseManager_GetProps()->CourseLength, 1, 0.75f, 0.75f); set_text_color(TEXT_YELLOW); func_80093324(0xA0, arg0->row + 0x86, D_800E7728[0], 0, 0.75f, 0.75f); // Print the 3 Lap Time Trial records @@ -7072,7 +7052,7 @@ void func_800A1FB0(struct_8018D9E0_entry* arg0) { } else { func_80093324( 0x2A + (var_s1 * 0x89), 0x96 + (0x1E * var_s2), - gCourseNamesDup2[gCupCourseOrder[var_v1->courseIndex / 4][var_v1->courseIndex % 4]], 0, + CourseManager_GetProps()->Name, 0, 0.5f, 0.5f); } } @@ -7111,7 +7091,7 @@ void func_800A1FB0(struct_8018D9E0_entry* arg0) { } else { func_80093324( 0x2A + (var_s1 * 0x89), 0x96 + (0x1E * var_s2), - gCourseNamesDup2[gCupCourseOrder[var_v1->courseIndex / 4][var_v1->courseIndex % 4]], 0, + CourseManager_GetProps()->Name, 0, 0.5f, 0.5f); } } @@ -7163,7 +7143,7 @@ void func_800A1FB0(struct_8018D9E0_entry* arg0) { } else { func_80093324( 0x2A + (var_s1 * 0x89), 0x96 + (0x1E * var_s2), - gCourseNamesDup2[gCupCourseOrder[var_v1->courseIndex / 4][var_v1->courseIndex % 4]], 0, + CourseManager_GetProps()->Name, 0, 0.5f, 0.5f); } } @@ -7491,7 +7471,7 @@ void func_800A3E60(struct_8018D9E0_entry* arg0) { set_text_color(4); draw_text(arg0->column + 0x55, 0x19 - arg0->row, - gCourseNamesDup[gCupCourseOrder[GetCupIndex()][GetCupCursorPosition()]], 0, 0.6f, 0.6f); + CourseManager_GetProps()->Name, 0, 0.6f, 0.6f); set_text_color(3); draw_text(arg0->column + 0x55, 0x28 - arg0->row, D_800E7730, 0, 0.75f, 0.75f); for (var_s1 = 0; var_s1 < 4; var_s1++) { @@ -7558,8 +7538,7 @@ void func_800A3E60(struct_8018D9E0_entry* arg0) { func_80093324(0xBB - arg0->column, 0xAA + (0x1E * var_s1), D_800E7A44, 0, 0.45f, 0.45f); } else { func_80093324(0xBB - arg0->column, 0xAA + (0x1E * var_s1), - gCourseNamesDup2[gCupCourseOrder[D_8018EE10[var_s1].courseIndex / 4] - [D_8018EE10[var_s1].courseIndex % 4]], + CourseManager_GetProps()->Name, 0, 0.45f, 0.45f); } } @@ -7788,7 +7767,7 @@ void render_pause_menu_time_trials(struct_8018D9E0_entry* arg0) { gDisplayListHead = draw_box(gDisplayListHead, 0, 0, 0x0000013F, 0x000000EF, 0, 0, 0, 0x0000008C); set_text_color(TEXT_YELLOW); - draw_text(0x000000A0, 0x00000050, gCourseNamesDup[gCupCourseOrder[GetCupIndex()][GetCupCursorPosition()]], 0, 1.0f, + draw_text(0x000000A0, 0x00000050, CourseManager_GetProps()->Name, 0, 1.0f, 1.0f); set_text_color(TEXT_RED); draw_text(0x0000009D, 0x00000060, D_800E7728[0], 0, 0.8f, 0.8f); @@ -7876,7 +7855,7 @@ void render_pause_grand_prix(struct_8018D9E0_entry* arg0) { set_text_color(TEXT_YELLOW); draw_text(160 + temp_s0, temp_s3->row - 50, D_800E76CC[gCCSelection], 0, 1.0f, 1.0f); set_text_color(TEXT_YELLOW); - draw_text(160, temp_s3->row - 30, gCourseNamesDup[gCupCourseOrder[GetCupIndex()][GetCupCursorPosition()]], 0, 1.0f, + draw_text(160, temp_s3->row - 30, CourseManager_GetProps()->Name, 0, 1.0f, 1.0f); for (var_s0 = 0; var_s0 < 2; var_s0++) { text_rainbow_effect(arg0->cursor - 31, var_s0, TEXT_YELLOW); @@ -7929,9 +7908,10 @@ void func_800A54EC(void) { sp48 = find_8018D9E0_entry(0x000000C7); if (why) {} // ????? gSPViewport(gDisplayListHead++, VIRTUAL_TO_PHYSICAL(D_802B8880)); - guOrtho(&gGfxPool->mtxEffect[gMatrixEffectCount], 0.0f, 319.0f, 239.0f, 0.0f, -100.0f, 100.0f, 1.0f); - gSPMatrix(gDisplayListHead++, VIRTUAL_TO_PHYSICAL(&gGfxPool->mtxEffect[gMatrixEffectCount++]), - G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_PROJECTION); + // guOrtho(&gGfxPool->mtxEffect[gMatrixEffectCount], 0.0f, 319.0f, 239.0f, 0.0f, -100.0f, 100.0f, 1.0f); + // gSPMatrix(gDisplayListHead++, VIRTUAL_TO_PHYSICAL(&gGfxPool->mtxEffect[gMatrixEffectCount++]), + // G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_PROJECTION); + AddEffectMatrixOrtho(); switch (why) { /* irregular */ default: break; @@ -7991,7 +7971,7 @@ void func_800A5738(struct_8018D9E0_entry* arg0) { gDisplayListHead = draw_box(gDisplayListHead, 0, 0, 0x0000013F, 0x000000EF, 0, 0, 0, var_s1); gDPSetPrimColor(gDisplayListHead++, 0, 0, 0x00, 0x00, 0x00, var_s2); set_text_color(3); - func_80093754(0x000000A0, 0x00000050, gCourseNamesDup[gCupCourseOrder[GetCupIndex()][GetCupCursorPosition()]], + func_80093754(0x000000A0, 0x00000050, CourseManager_GetProps()->Name, 0, 1.0f, 1.0f); switch (arg0->cursor) { /* switch 1 */ case 1: /* switch 1 */ @@ -8056,8 +8036,7 @@ void func_800A5738(struct_8018D9E0_entry* arg0) { func_80093324(0x69 - arg0->column, (0x96 + (0x14 * var_s1)), D_800E7A44, 0, 0.75f, 0.75f); } else { func_80093324(0x69 - arg0->column, (0x96 + (0x14 * var_s1)), - gCourseNamesDup2[gCupCourseOrder[D_8018EE10[var_s1].courseIndex / 4] - [D_8018EE10[var_s1].courseIndex % 4]], + CourseManager_GetProps()->Name, 0, 0.75f, 0.75f); } } @@ -8220,12 +8199,12 @@ void func_800A638C(struct_8018D9E0_entry* arg0) { } void func_800A66A8(struct_8018D9E0_entry* arg0, Unk_D_800E70A0* arg1) { - Mtx* mtx; + Mtx *mtx; f32 tmp; static float x2, y2, z2; static float x1, y1, z1; - mtx = &gGfxPool->mtxEffect[gMatrixEffectCount]; + mtx = GetEffectMatrix(); // &gGfxPool->mtxEffect[gMatrixEffectCount]; if (arg0->unk24 > 1.5) { arg0->unk24 *= 0.95; } else { @@ -8256,8 +8235,9 @@ void func_800A66A8(struct_8018D9E0_entry* arg0, Unk_D_800E70A0* arg1) { guMtxCatL(mtx, mtx + 1, mtx); guTranslate(mtx + 1, arg1->column, arg1->row, 0.0f); guMtxCatL(mtx, mtx + 1, mtx); - gSPMatrix(gDisplayListHead++, VIRTUAL_TO_PHYSICAL(&gGfxPool->mtxEffect[gMatrixEffectCount++]), - (G_MTX_NOPUSH | G_MTX_LOAD) | G_MTX_MODELVIEW); + //gSPMatrix(gDisplayListHead++, VIRTUAL_TO_PHYSICAL(&gGfxPool->mtxEffect[gMatrixEffectCount++]), + // (G_MTX_NOPUSH | G_MTX_LOAD) | G_MTX_MODELVIEW); + AddEffectMatrixFixed(G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); gSPClearGeometryMode(gDisplayListHead++, G_LIGHTING); gDPSetCombineMode(gDisplayListHead++, G_CC_MODULATEIA, G_CC_MODULATEIA); gDPNoOp(gDisplayListHead++); @@ -8511,11 +8491,11 @@ void func_800A7790(struct_8018D9E0_entry* arg0) { slideDirection = D_802850C0[creditIndex].slideDirection; if ((slideDirection == SLIDE_RIGHT) || (slideDirection != SLIDE_LEFT)) { someScaling = D_802850C0[creditIndex].textScaling; - func_800936B8(arg0->column, arg0->row, D_802854B0[creditIndex], arg0->unk1C * someScaling, + func_800936B8(arg0->column, arg0->row, gCreditsText[creditIndex], arg0->unk1C * someScaling, arg0->unk24 * someScaling, someScaling); } else { someScaling = D_802850C0[creditIndex].textScaling; - func_80093324(arg0->column, arg0->row, D_802854B0[creditIndex], arg0->unk1C * someScaling, + func_80093324(arg0->column, arg0->row, gCreditsText[creditIndex], arg0->unk1C * someScaling, arg0->unk24 * someScaling, someScaling); } } @@ -12208,7 +12188,7 @@ void func_800AF4DC(struct_8018D9E0_entry* arg0) { case 0: arg0->column = temp_v1->startingColumn; arg0->cursor = 1; - arg0->unk20 = temp_v1->columnExtra + (get_string_width(D_802854B0[temp_v0]) * temp_v1->textScaling / 2); + arg0->unk20 = temp_v1->columnExtra + (get_string_width(gCreditsText[temp_v0]) * temp_v1->textScaling / 2); /* fallthrough */ case 1: func_800A9208(arg0, arg0->unk20); @@ -12260,7 +12240,7 @@ void func_800AF740(struct_8018D9E0_entry* arg0) { case 0: arg0->column = temp_v1->startingColumn; arg0->cursor = 1; - arg0->unk20 = temp_v1->columnExtra - (get_string_width(D_802854B0[temp_v0]) * temp_v1->textScaling / 2); + arg0->unk20 = temp_v1->columnExtra - (get_string_width(gCreditsText[temp_v0]) * temp_v1->textScaling / 2); /* fallthrough */ case 1: func_800A9208(arg0, arg0->unk20); diff --git a/src/code_80091750.h b/src/code_80091750.h index 4cc9a414f..8d9c74935 100644 --- a/src/code_80091750.h +++ b/src/code_80091750.h @@ -489,14 +489,7 @@ extern RGBA16 D_800E74D0[]; extern RGBA16 D_800E74E8[]; extern const s16 gGlyphDisplayWidth[]; extern char* gCupNames[]; -extern char* gCourseNames[]; -extern char* gCourseNamesDup[]; -extern char* gCourseNamesDup2[]; -extern char* gDebugCourseNames[]; -// Maps course IDs (as defined in the COURSES enum) to an index in a given cup's track order -extern const s8 gPerCupIndexByCourseId[]; // D_800EFD50 extern const s8 D_800EFD64[]; -extern s8 gCupSelectionByCourseId[]; extern char* D_800E7678[]; extern char* gDebugCharacterNames[]; extern char* D_800E76A8[]; @@ -517,7 +510,6 @@ extern char* D_800E77A0[]; extern char* D_800E77A8[]; extern char D_800E77B4[]; extern char D_800E77D8[]; -extern char* sCourseLengths[]; extern char* D_800E7834[]; extern char* D_800E7840[]; extern char* D_800E7848[]; diff --git a/src/code_800AF9B0.c b/src/code_800AF9B0.c index 29279035f..fdc1c32d2 100644 --- a/src/code_800AF9B0.c +++ b/src/code_800AF9B0.c @@ -197,8 +197,10 @@ void func_800B0004(void) { } } func_800AFF58(vtxs); - D_8018EDB0 += D_8018EDB2; - ++D_8018EDB4; + if (gTickVisuals) { + D_8018EDB0 += D_8018EDB2; + ++D_8018EDB4; + } gSPSetGeometryMode(gDisplayListHead++, G_CULL_BACK); gSPNumLights(gDisplayListHead++, NUMLIGHTS_1); gSPClearGeometryMode(gDisplayListHead++, G_LIGHTING); diff --git a/src/data/path_spawn_metadata.c b/src/data/path_spawn_metadata.c index 2157eae02..99450b12a 100644 --- a/src/data/path_spawn_metadata.c +++ b/src/data/path_spawn_metadata.c @@ -12,37 +12,8 @@ #include #include -// @warning Array contains an extra zero element at the end. -KartAIBehaviour* gKartAIBehaviourLUT[] = { -#include "assets/course_metadata/gKartAIBehaviourLUT.inc.c" - -}; - TrackWaypoint nullPath = { 0x8000, 0x0000, 0x0000, 0x0000 }; -TrackWaypoint* gCoursePathTable[][4] = { -#include "assets/course_metadata/gCoursePathTableUnknown.inc.c" -}; - -TrackWaypoint* gCoursePathTable2[][4] = { -#include "assets/course_metadata/gCoursePathTable.inc.c" -}; - -// @warning Array contains an extra zero element at the end. -s16 gKartAISteeringSensitivity[] = { -#include "assets/course_metadata/gCPUSteeringSensitivity.inc.c" -}; - -// Possibly maximum cpu separation -f32 gKartAICourseMaximumSeparation[] = { -#include "assets/course_metadata/gKartAICourseMaximumSeparation.inc.c" -}; - -// Possibly minimum cpu separation -f32 gKartAICourseMinimumSeparation[] = { -#include "assets/course_metadata/gKartAICourseMinimumSeparation.inc.c" -}; - // I think the types for D_800DCAF4, D_800DCB34, and D_800DCBB4 are all // wrong in some way based on their usage in func_800088D8 // But I cannot be bothered to figure it out @@ -62,18 +33,6 @@ s16 D_800DCB34[] = { 0x0005, 0x0005, 0x0005, 0x0005, 0x000a, 0x0005, 0x0005, 0x0005, 0x0005, 0x0005, 0x0005, 0x0005, }; -s16* D_800DCBB4[] = { -#include "assets/course_metadata/D_800DCBB4.inc.c" -}; - -BombKartSpawn gBombKartSpawns[][NUM_BOMB_KARTS_MAX] = { -#include "assets/course_metadata/gBombKartSpawns.inc.c" -}; - -_struct_gCoursePathSizes_0x10 gCoursePathSizes[] = { -#include "assets/course_metadata/gCoursePathSizes.inc.c" -}; - s32 D_800DDB20 = 0x00000000; s32 D_800DDB24 = 0x00000001; diff --git a/src/data/path_spawn_metadata.h b/src/data/path_spawn_metadata.h index d1fc5451f..df2d8c7b7 100644 --- a/src/data/path_spawn_metadata.h +++ b/src/data/path_spawn_metadata.h @@ -15,18 +15,9 @@ typedef struct { /* 0x0A */ char padA[6]; } _struct_gCoursePathSizes_0x10; // size 0x10 -extern KartAIBehaviour* gKartAIBehaviourLUT[]; extern TrackWaypoint nullPath; -extern TrackWaypoint* gCoursePathTable[][4]; -extern TrackWaypoint* gCoursePathTable2[][4]; -extern s16 gKartAISteeringSensitivity[]; -extern f32 gKartAICourseMaximumSeparation[]; -extern f32 gKartAICourseMinimumSeparation[]; extern s16 D_800DCAF4[]; extern s16 D_800DCB34[]; -extern s16* D_800DCBB4[]; -extern BombKartSpawn gBombKartSpawns[][NUM_BOMB_KARTS_MAX]; -extern _struct_gCoursePathSizes_0x10 gCoursePathSizes[]; extern s32 D_800DDB20; extern s32 D_800DDB24; diff --git a/src/ending/ceremony_and_credits.c b/src/ending/ceremony_and_credits.c index 8af800cae..d91f3ace8 100644 --- a/src/ending/ceremony_and_credits.c +++ b/src/ending/ceremony_and_credits.c @@ -1482,7 +1482,7 @@ void func_802847CC(CinematicCamera* camera) { if (gCutsceneShotTimer == sp2C) { if (D_80286A04[D_800DC5E4].unk0 != 2) { - func_80280268(D_80286A04[D_800DC5E4 + 1].unk1); + func_80280268(D_80286A04[D_800DC5E4 + 1].courseId); } } } diff --git a/src/ending/ceremony_and_credits.h b/src/ending/ceremony_and_credits.h index 2913c3ec3..c84d33691 100644 --- a/src/ending/ceremony_and_credits.h +++ b/src/ending/ceremony_and_credits.h @@ -86,7 +86,7 @@ struct struct_80285D80 { struct struct_80286A04 { u8 unk0; - u8 unk1; + u8 courseId; struct struct_80285D80* unk4; struct struct_80285D80* unk8; u16 unkC; diff --git a/src/ending/code_80280000.c b/src/ending/code_80280000.c index 002ba2285..9c2f654c9 100644 --- a/src/ending/code_80280000.c +++ b/src/ending/code_80280000.c @@ -27,6 +27,7 @@ #include "engine/Engine.h" #include "engine/courses/Course.h" +#include "engine/Matrix.h" s32 D_802874A0; // s32 D_802874A4[5]; @@ -44,6 +45,8 @@ void func_80280038(void) { UNUSED s32 pad; Mat4 matrix; + ClearMatrixPools(); + gMatrixObjectCount = 0; gMatrixEffectCount = 0; gMatrixHudCount = 0; @@ -62,6 +65,7 @@ void func_80280038(void) { gSPMatrix(gDisplayListHead++, VIRTUAL_TO_PHYSICAL(&gGfxPool->mtxLookAt[0]), G_MTX_NOPUSH | G_MTX_MUL | G_MTX_PROJECTION); gCurrentCourseId = gCreditsCourseId; + SetCourseById(gCreditsCourseId); mtxf_identity(matrix); render_set_position(matrix, 0); render_course(D_800DC5EC); @@ -75,14 +79,14 @@ void func_80280038(void) { init_rdp(); } -void func_80280268(s32 arg0) { +void func_80280268(s32 courseId) { gIsInQuitToMenuTransition = 1; gQuitToMenuTransitionCounter = 5; D_802874A0 = 1; - if ((arg0 < 0) || ((arg0 >= 20))) { - arg0 = 0; + if ((courseId < 0) || ((courseId >= NUM_COURSES - 1))) { + courseId = 0; } - gCreditsCourseId = arg0; + gCreditsCourseId = courseId; } void credits_loop(void) { @@ -128,6 +132,7 @@ void load_credits(void) { Camera* camera = &cameras[0]; gCurrentCourseId = gCreditsCourseId; + SetCourseById(gCreditsCourseId); D_800DC5B4 = 1; creditsRenderMode = 1; func_802A4D18(); @@ -171,7 +176,7 @@ void load_credits(void) { camera->up[1] = 1.0f; camera->up[2] = 0.0f; init_cinematic_camera(); - func_80003040(); + credits_spawn_actors(); init_hud(); func_80093E60(); func_80092688(); diff --git a/src/ending/credits.c b/src/ending/credits.c index 892583a02..8458842df 100644 --- a/src/ending/credits.c +++ b/src/ending/credits.c @@ -67,7 +67,7 @@ struct_802850C0_entry D_802850C0[] = { { 0.90f, 520, 130, 160, 130, SLIDE_LEFT, TEXT_YELLOW, 0 }, }; -char* D_802854B0[] = { +char* gCreditsText[] = { // English Credits "executive producer", "hiroshi yamauchi", "producer", "shigeru miyamoto", "director", "hideki konno", "assistant director", "yasuyuki oyagi", "programmer", "masato kimura", "kenji yamamoto", "yasuhiro kawaguchi", diff --git a/src/ending/credits.h b/src/ending/credits.h index bf6eaca88..7af30d018 100644 --- a/src/ending/credits.h +++ b/src/ending/credits.h @@ -22,6 +22,6 @@ typedef struct { } struct_802850C0_entry; // size = 0x10 extern struct_802850C0_entry D_802850C0[]; // D_802850C0 -extern char* D_802854B0[]; +extern char* gCreditsText[]; #endif diff --git a/src/ending/podium_ceremony_actors.c b/src/ending/podium_ceremony_actors.c index b3edd81d7..c7698893d 100644 --- a/src/ending/podium_ceremony_actors.c +++ b/src/ending/podium_ceremony_actors.c @@ -19,6 +19,8 @@ #include "math_util.h" #include +#include "engine/Matrix.h" + s32 fireworkConeColour[] = { 0x00FF4080, // pink 0x008040FF, // purple @@ -223,9 +225,10 @@ void func_80280A28(Vec3f arg0, Vec3s arg1, f32 arg2) { mtx[2][0] = D_80287500[0][2] * arg2; mtx[2][1] = D_80287500[1][2] * arg2; mtx[2][2] = D_80287500[2][2] * arg2; - convert_to_fixed_point_matrix(&gGfxPool->mtxEffect[gMatrixEffectCount], mtx); - gSPMatrix(gDisplayListHead++, VIRTUAL_TO_PHYSICAL(&gGfxPool->mtxEffect[gMatrixEffectCount]), - G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + // convert_to_fixed_point_matrix(&gGfxPool->mtxEffect[gMatrixEffectCount], mtx); + // gSPMatrix(gDisplayListHead++, VIRTUAL_TO_PHYSICAL(&gGfxPool->mtxEffect[gMatrixEffectCount]), + // G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + AddEffectMatrix(mtx, G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); } void render_fireworks(Vec3f arg0, f32 arg1, s32 rgb, s16 alpha) { @@ -448,6 +451,7 @@ void func_80281540(void) { } void podium_ceremony_loop(void) { + ClearMatrixPools(); gMatrixObjectCount = 0; D_802874FC = 0; update_camera_podium_ceremony(); diff --git a/src/engine/Actor.cpp b/src/engine/Actor.cpp index 1749d4600..b6b2520d0 100644 --- a/src/engine/Actor.cpp +++ b/src/engine/Actor.cpp @@ -9,5 +9,9 @@ AActor::AActor() {} // Virtual functions to be overridden by derived classes void AActor::Tick() { } void AActor::Draw(Camera *camera) { } -void AActor::Collision() {} -void AActor::Destroy() { } \ No newline at end of file +void AActor::Collision(Player* player, AActor* actor) {} +void AActor::Destroy() { + // Set uuid to zero. + memset(uuid, 0, sizeof(uuid)); +} +bool AActor::IsMod() { return false; } \ No newline at end of file diff --git a/src/engine/Actor.h b/src/engine/Actor.h index 53b5cfa4d..88f5b34a0 100644 --- a/src/engine/Actor.h +++ b/src/engine/Actor.h @@ -7,13 +7,12 @@ extern "C" { #include "main.h" #include "camera.h" #include "common_structs.h" -} + class AActor { public: - uint8_t uuid[16]; - /* 0x00 */ s16 Type; + /* 0x00 */ s16 Type = 0; /* 0x02 */ s16 Flags; /* 0x04 */ s16 Unk_04; /* 0x06 */ s16 State; @@ -24,6 +23,7 @@ public: /* 0x18 */ Vec3f Pos; /* 0x24 */ Vec3f Velocity = {0, 0, 0}; /* 0x30 */ Collision Unk30; + uint8_t uuid[16]; virtual ~AActor() = default; // Virtual destructor for proper cleanup in derived classes @@ -31,6 +31,9 @@ public: virtual void Tick(); virtual void Draw(Camera*); - virtual void Collision(); + virtual void Collision(Player* player, AActor* actor); virtual void Destroy(); + virtual bool IsMod(); }; + +} \ No newline at end of file diff --git a/src/engine/Matrix.cpp b/src/engine/Matrix.cpp new file mode 100644 index 000000000..7b8c3b1fb --- /dev/null +++ b/src/engine/Matrix.cpp @@ -0,0 +1,123 @@ +#include +#include +#include "engine/World.h" + +extern "C" { +#include "common_structs.h" +} + +void AddMatrix(std::vector& stack, Mat4 mtx, s32 flags) { + // Reserve space if needed to avoid reallocation overhead + stack.reserve(1000); + + // Push a new matrix to the stack + stack.emplace_back(); + + // Convert to a fixed-point matrix + guMtxF2L(mtx, &stack.back()); + + // Load the matrix + gSPMatrix(gDisplayListHead++, &stack.back(), flags); +} + +Mtx* GetMatrix(std::vector& stack) { + stack.emplace_back(); + return &stack.back(); +} + +/** + * Use GetMatrix first + */ +void AddMatrixFixed(std::vector& stack, s32 flags) { + // Load the matrix + gSPMatrix(gDisplayListHead++, &stack.back(), flags); +} + +// Used in func_80095BD0 +void SetTextMatrix(f32 arg1, f32 arg2, f32 arg3, f32 arg4) { + Mat4 mtx; + mtx[0][0] = arg3; + mtx[0][1] = 0.0f; + mtx[0][2] = 0.0f; + mtx[0][3] = 0.0f; + mtx[1][0] = 0.0f; + mtx[1][1] = arg4; + mtx[1][2] = 0.0f; + mtx[1][3] = 0.0f; + mtx[2][0] = 0.0f; + mtx[2][1] = 0.0f; + mtx[2][2] = 1.0f; + mtx[2][3] = 0.0f; + mtx[3][0] = arg1; + mtx[3][1] = arg2; + mtx[3][2] = 0.0f; + mtx[3][3] = 1.0f; + + AddMatrix(gWorldInstance.Mtx.Effects, mtx, G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); +} + + +// API +extern "C" { + + void AddHudMatrix(Mat4 mtx, s32 flags) { + AddMatrix(gWorldInstance.Mtx.Hud, mtx, flags); + } + + void AddObjectMatrix(Mat4 mtx, s32 flags) { + AddMatrix(gWorldInstance.Mtx.Objects, mtx, flags); + } + + void AddShadowMatrix(Mat4 mtx, s32 flags) { + AddMatrix(gWorldInstance.Mtx.Shadows, mtx, flags); + } + + void AddKartMatrix(Mat4 mtx, s32 flags) { + AddMatrix(gWorldInstance.Mtx.Karts, mtx, flags); + } + + void AddEffectMatrix(Mat4 mtx, s32 flags) { + AddMatrix(gWorldInstance.Mtx.Effects, mtx, flags); + } + + void AddEffectMatrixFixed(s32 flags) { + AddMatrixFixed(gWorldInstance.Mtx.Effects, flags); + } + + void AddEffectMatrixOrtho(void) { + auto& stack = gWorldInstance.Mtx.Effects; + stack.emplace_back(); + + guOrtho(&stack.back(), 0.0f, SCREEN_WIDTH - 1, SCREEN_HEIGHT - 1, 0.0f, -100.0f, 100.0f, 1.0f); + + gSPMatrix(gDisplayListHead++, &stack.back(), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_PROJECTION); + } + + Mtx* GetEffectMatrix(void) { + return GetMatrix(gWorldInstance.Mtx.Effects); + } + + + /** + * Note that the game doesn't seem to clear all of these at the beginning of a new frame. + * We might need to adjust which ones we clear. + */ + void ClearMatrixPools(void) { + gWorldInstance.Mtx.Hud.clear(); + gWorldInstance.Mtx.Objects.clear(); + gWorldInstance.Mtx.Shadows.clear(); + gWorldInstance.Mtx.Karts.clear(); + gWorldInstance.Mtx.Effects.clear(); + } + + void ClearHudMatrixPool(void) { + gWorldInstance.Mtx.Hud.clear(); + } + void ClearEffectsMatrixPool(void) { + gWorldInstance.Mtx.Effects.clear(); + } + + void ClearObjectsMatrixPool(void) { + gWorldInstance.Mtx.Objects.clear(); + } +} diff --git a/src/engine/Matrix.h b/src/engine/Matrix.h new file mode 100644 index 000000000..b0be2bf87 --- /dev/null +++ b/src/engine/Matrix.h @@ -0,0 +1,27 @@ +#ifndef _MATRIX_HEADER_ +#define _MATRIX_HEADER_ + +#include + +#include "common_structs.h" + +#ifdef __cplusplus +extern "C" { +#endif +void ClearMatrixPools(void); +void AddHudMatrix(Mat4 mtx, s32 flags); +void AddObjectMatrix(Mat4 mtx, s32 flags); +void AddEffectMatrix(Mat4 mtx, s32 flags); +void AddEffectMatrixOrtho(void); +void AddEffectMatrixFixed(s32 flags); +void SetTextMatrix(f32 arg1, f32 arg2, f32 arg3, f32 arg4); +Mtx* GetEffectMatrix(void); +void ClearHudMatrixPool(void); +void ClearEffectsMatrixPool(void); +void ClearObjectsMatrixPool(void); + +#ifdef __cplusplus +} +#endif + +#endif // _MATRIX_HEADER_ \ No newline at end of file diff --git a/src/engine/World.cpp b/src/engine/World.cpp index 01c6f13bd..a5bbd6cdf 100644 --- a/src/engine/World.cpp +++ b/src/engine/World.cpp @@ -9,6 +9,7 @@ #include "vehicles/Bus.h" #include "vehicles/TankerTruck.h" #include "vehicles/Car.h" +#include "vehicles/OBombKart.h" #include "TrainCrossing.h" #include @@ -75,7 +76,7 @@ void World::AddCar(f32 speedA, f32 speedB, TrackWaypoint* path, uint32_t waypoin cars++; } -void World::ResetVehicles(void) { +void World::ClearVehicles(void) { trains = trucks = busses = tankerTrucks = cars = boats = 0; Vehicles.clear(); } @@ -86,6 +87,10 @@ TrainCrossing* World::AddCrossing(Vec3f position, u32 waypointMin, u32 waypointM return crossing.get(); } +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)); +} + u32 World::GetCupIndex() { return this->CupIndex; } @@ -164,28 +169,52 @@ Object* World::AddObject(std::unique_ptr object) { return &rawPtr->o; } -AActor* World::AddActor(std::unique_ptr actor) { - AActor* rawPtr = actor.get(); - Actors.push_back(std::move(actor)); - return rawPtr; +AActor* World::AddActor(AActor* actor) { + Actors.push_back(actor); + return Actors.back(); +} + +struct Actor* World::AddBaseActor() { + Actors.push_back(new AActor()); + // Skip C++ vtable to access variables in C + return reinterpret_cast(reinterpret_cast(Actors.back()) + sizeof(void*)); +} + +/** + * Converts a C struct Actor* to its C++ AActor class + */ +AActor* World::ConvertActorToAActor(Actor* actor) { + // Move the ptr back so that it points at the vtable. + // Which is the initial item in the class, or in other words + // Point to the class. + return reinterpret_cast((char*)actor - sizeof(void*)); +} + +/** + * Converts a C++ AActor class to a C Actor* struct. + */ +Actor* World::ConvertAActorToActor(AActor* actor) { + // Move the ptr forward past the vtable. + // This allows C to access the class variables like a normal Actor* struct. + return reinterpret_cast((char*)actor + sizeof(void*)); +} + +AActor* World::GetActor(size_t index) { + return Actors[index]; } void World::TickActors() { - for (auto& actor : Actors) { - actor->Tick(); - } -} - -void World::DrawActors(Camera* camera) { - for (auto& actor : Actors) { - actor->Draw(camera); + for (AActor* actor : Actors) { + if (actor->IsMod()) { + actor->Tick(); + } } } void RemoveExpiredActors() { - //Actors.erase( + // Actors.erase( // std::remove_if(Actors.begin(), Actors.end(), - // [](const std::unique_ptr& actor) { return actor->uuid == 0; }), // Example condition + // [](const std::unique_ptr& actor) { return actor->uuid == 0; }), // Actors.end()); } diff --git a/src/engine/World.h b/src/engine/World.h index a2947499a..ee562118b 100644 --- a/src/engine/World.h +++ b/src/engine/World.h @@ -6,6 +6,7 @@ #include "vehicles/Vehicle.h" #include "vehicles/Train.h" #include "vehicles/Car.h" +#include "vehicles/OBombKart.h" #include "TrainCrossing.h" #include #include "Actor.h" @@ -64,15 +65,27 @@ class World { SkyboxColours Skybox; } Properties; + typedef struct { + std::vector Hud; + std::vector Objects; + std::vector Shadows; + std::vector Karts; + std::vector Effects; + } Matrix; + public: explicit World(); void AddCourse(Course* course); - AActor* AddActor(std::unique_ptr actor); + AActor* AddActor(AActor* actor); + struct Actor* AddBaseActor(); + AActor* GetActor(size_t index); + void TickActors(); - void DrawActors(Camera* camera); void RemoveExpiredActors(); + AActor* ConvertActorToAActor(Actor* actor); + Actor* ConvertAActorToActor(AActor* actor); Object* AddObject(std::unique_ptr object); @@ -99,6 +112,8 @@ public: void NextCourse(void); void PreviousCourse(void); + Matrix Mtx; + // Holds all available courses Course* CurrentCourse; @@ -108,8 +123,9 @@ public: size_t CupIndex = 1; std::vector> GameObjects; - std::vector> Actors; + std::vector Actors; + /** Actors */ void AddBoat(f32 speed, uint32_t waypoint); void AddTrain(size_t numCarriages, f32 speed, uint32_t waypoint); void AddTruck(f32 speedA, f32 speedB, TrackWaypoint* path, uint32_t waypoint); @@ -117,7 +133,11 @@ public: 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; - void ResetVehicles(void); + void ClearVehicles(void); + + /** Objects **/ + void AddBombKart(Vec3f pos, TrackWaypoint* waypoint, uint16_t waypointIndex, uint16_t state, f32 unk_3C); + std::vector> BombKarts; TrainCrossing* AddCrossing(Vec3f position, u32 waypointMin, u32 waypointMax, f32 approachRadius, f32 exitRadius); std::vector> Crossings; diff --git a/src/engine/actors/ABanana.cpp b/src/engine/actors/ABanana.cpp index c26efca24..d484ab983 100644 --- a/src/engine/actors/ABanana.cpp +++ b/src/engine/actors/ABanana.cpp @@ -54,7 +54,7 @@ void ABanana::Tick() { void ABanana::Draw(Camera *camera) { render_actor_banana(camera, NULL, (BananaActor*)this); } -void ABanana::Collision() { } +void ABanana::Collision(Player* player, AActor*) { } void ABanana::Destroy() { } //void ABanana::Held() {} diff --git a/src/engine/actors/ABanana.h b/src/engine/actors/ABanana.h index 5ef8900d6..0da9eb98f 100644 --- a/src/engine/actors/ABanana.h +++ b/src/engine/actors/ABanana.h @@ -16,6 +16,6 @@ public: // Virtual functions to be overridden by derived classes virtual void Tick() override; virtual void Draw(Camera*) override; - virtual void Collision() override; + virtual void Collision(Player*, AActor*) override; virtual void Destroy() override; }; diff --git a/src/engine/actors/ACloud.cpp b/src/engine/actors/ACloud.cpp new file mode 100644 index 000000000..d3eaad32d --- /dev/null +++ b/src/engine/actors/ACloud.cpp @@ -0,0 +1,136 @@ +#include + +#include "ACloud.h" +#include "engine/Actor.h" +#include "World.h" + +extern "C" { +#include "macros.h" +#include "common_structs.h" +#include "math_util.h" +#include "actor_types.h" +#include "actors.h" +extern f32 gKartHopInitialVelocityTable[]; +extern f32 gKartGravityTable[]; +} + +ACloud::ACloud(Vec3f pos) { + Pos[0] = pos[0]; + Pos[1] = pos[1]; + Pos[2] = pos[2]; + Rot[0] = 0; + Rot[1] = 0; + Rot[2] = 0; + + //Flags = -0x8000 | 0x4000; + + BoundingBoxSize = 2.0f; +} + +void ACloud::Tick() { + Rot[1] += 0x200; + + if (PickedUp) { + Timer++; // Increment timer + } + + if (Timer > 500) { // Time has expired, reset the actor and player + PickedUp = false; + if (_player) { + gKartHopInitialVelocityTable[_player->characterId] = OldHop; // reset back to normal + gKartGravityTable[_player->characterId] = OldGravity; + _player = NULL; // Reset + } + Timer = 0; + } +} + +extern Gfx cloud_mesh[]; + +void ACloud::Draw(Camera *camera) { + Mat4 mtx; + + if (PickedUp) { + return; // Skip drawing if the actor has been picked up + } + + mtxf_pos_rotation_xyz(mtx, Pos, Rot); + if (render_set_position(mtx, 0) != 0) { + gSPSetGeometryMode(gDisplayListHead++, G_SHADING_SMOOTH); + gSPDisplayList(gDisplayListHead++, (Gfx*)cloud_mesh); + } +} + +void ACloud::Collision(Player* player, AActor* actor) { + if (!PickedUp) { + if (query_collision_player_vs_actor_item(player, gWorldInstance.ConvertAActorToActor(actor))) { + // Player has picked up the actor, activate the cloud effect + _player = player; + PickedUp = true; + + OldHop = gKartHopInitialVelocityTable[player->characterId]; + OldGravity = gKartGravityTable[player->characterId]; + gKartHopInitialVelocityTable[player->characterId] = Hop; + gKartGravityTable[player->characterId] = Gravity; + } + } +} + +bool ACloud::IsMod() { return true; } + +Vtx cloud_mesh_vtx_cull[8] = { + {{ {0, -4, -4}, 0, {0, 0}, {0, 0, 0, 0} }}, + {{ {0, -4, 4}, 0, {0, 0}, {0, 0, 0, 0} }}, + {{ {0, 4, 4}, 0, {0, 0}, {0, 0, 0, 0} }}, + {{ {0, 4, -4}, 0, {0, 0}, {0, 0, 0, 0} }}, + {{ {0, -4, -4}, 0, {0, 0}, {0, 0, 0, 0} }}, + {{ {0, -4, 4}, 0, {0, 0}, {0, 0, 0, 0} }}, + {{ {0, 4, 4}, 0, {0, 0}, {0, 0, 0, 0} }}, + {{ {0, 4, -4}, 0, {0, 0}, {0, 0, 0, 0} }}, +}; + +Vtx cloud_mesh_vtx_0[4] = { + {{ {0, 4, 4}, 0, {-524, -530}, {255, 255, 255, 166} }}, + {{ {0, -4, 4}, 0, {-530, 1516}, {255, 255, 255, 201} }}, + {{ {0, -4, -4}, 0, {1516, 1522}, {255, 255, 255, 188} }}, + {{ {0, 4, -4}, 0, {1522, -524}, {255, 255, 255, 154} }}, +}; + +Gfx cloud_mesh_tri_0[] = { + gsSPVertex(cloud_mesh_vtx_0 + 0, 4, 0), + gsSP2Triangles(0, 1, 2, 0, 0, 2, 3, 0), + gsSPEndDisplayList(), +}; + +Gfx mat_cloud_cutout[] = { + gsSPSetGeometryMode(G_ZBUFFER | G_SHADE | G_FOG | G_SHADING_SMOOTH), + gsSPClearGeometryMode(G_CULL_FRONT | G_CULL_BACK | G_LIGHTING | G_TEXTURE_GEN | G_TEXTURE_GEN_LINEAR | G_LOD | G_CLIPPING), + gsDPPipeSync(), + gsDPSetCombineLERP(TEXEL0, PRIMITIVE, PRIMITIVE, TEXEL1, 0, 0, 0, TEXEL0, COMBINED, 0, PRIMITIVE, 0, 0, 0, 0, COMBINED), + gsSPSetOtherMode(G_SETOTHERMODE_H, 4, 20, G_AD_NOISE | G_CD_MAGICSQ | G_CK_NONE | G_TC_FILT | G_TF_BILERP | G_TT_NONE | G_TL_TILE | G_TD_CLAMP | G_TP_PERSP | G_CYC_2CYCLE | G_PM_NPRIMITIVE), + gsSPSetOtherMode(G_SETOTHERMODE_L, 0, 32, G_AC_NONE | G_ZS_PIXEL | G_RM_FOG_SHADE_A | G_RM_AA_ZB_TEX_EDGE2), + gsSPTexture(65535, 65535, 0, 0, 1), + gsDPSetPrimColor(0, 0, 255, 220, 203, 255), + gsDPSetTextureImage(G_IM_FMT_I, G_IM_SIZ_8b_LOAD_BLOCK, 1, gTexture69C4E4), + gsDPSetTile(G_IM_FMT_I, G_IM_SIZ_8b_LOAD_BLOCK, 0, 0, 7, 0, G_TX_WRAP | G_TX_NOMIRROR, 0, 0, G_TX_WRAP | G_TX_NOMIRROR, 0, 0), + gsDPLoadBlock(7, 0, 0, 511, 512), + gsDPSetTile(G_IM_FMT_I, G_IM_SIZ_8b, 4, 0, 0, 0, G_TX_WRAP | G_TX_NOMIRROR, 5, 1, G_TX_WRAP | G_TX_NOMIRROR, 5, 1), + gsDPSetTileSize(0, 98, 100, 124, 124), + gsDPSetTextureImage(G_IM_FMT_RGBA, G_IM_SIZ_16b_LOAD_BLOCK, 1, gTexture66C8F4), + gsDPSetTile(G_IM_FMT_RGBA, G_IM_SIZ_16b_LOAD_BLOCK, 0, 128, 6, 0, G_TX_WRAP | G_TX_NOMIRROR, 0, 0, G_TX_WRAP | G_TX_NOMIRROR, 0, 0), + gsDPLoadBlock(6, 0, 0, 1023, 256), + gsDPSetTile(G_IM_FMT_RGBA, G_IM_SIZ_16b, 8, 128, 1, 0, G_TX_CLAMP | G_TX_NOMIRROR, 5, 0, G_TX_CLAMP | G_TX_NOMIRROR, 5, 0), + gsDPSetTileSize(1, 0, 0, 124, 124), + gsSPEndDisplayList(), +}; + +Gfx cloud_mesh[] = { + //gsSPClearGeometryMode(G_LIGHTING), + //gsSPVertex(cloud_mesh_vtx_cull + 0, 8, 0), + gsSPSetGeometryMode(G_LIGHTING), + //gsSPCullDisplayList(0, 7), + gsSPDisplayList(mat_cloud_cutout), + gsSPDisplayList(cloud_mesh_tri_0), + gsSPEndDisplayList(), +}; + diff --git a/src/engine/actors/ACloud.h b/src/engine/actors/ACloud.h new file mode 100644 index 000000000..3d266243c --- /dev/null +++ b/src/engine/actors/ACloud.h @@ -0,0 +1,39 @@ +#pragma once + +#include +#include "engine/Actor.h" + +extern "C" { +#include "macros.h" +#include "main.h" +#include "camera.h" +#include "common_structs.h" +} + +class ACloud : public AActor { +public: + + + // Constructor + ACloud(Vec3f pos); + + virtual ~ACloud() override = default; + + // Virtual functions to be overridden by derived classes + virtual void Tick() override; + virtual void Draw(Camera*) override; + virtual void Collision(Player* player, AActor* actor) override; + virtual bool IsMod() override; + + bool PickedUp = false; + uint32_t Timer = 0; + + Player* _player = NULL; + + f32 Hop = 3.0f; + f32 Gravity = 200.0f; + + f32 OldHop = 0; + f32 OldGravity = 0; + +}; diff --git a/src/engine/actors/AFinishline.cpp b/src/engine/actors/AFinishline.cpp new file mode 100644 index 000000000..cc920f2bb --- /dev/null +++ b/src/engine/actors/AFinishline.cpp @@ -0,0 +1,80 @@ +#include +#include + +#include "AFinishline.h" +#include "engine/Actor.h" +#include "World.h" +#include "assets/common_data.h" + +extern "C" { +#include "macros.h" +#include "common_structs.h" +#include "math_util.h" +#include "actor_types.h" +#include "actors.h" +extern f32 gKartHopInitialVelocityTable[]; +extern f32 gKartGravityTable[]; +} + +AFinishline::AFinishline(Vec3f pos) { + if (pos != nullptr) { // Allow user to set their own values + Pos[0] = pos[0]; + Pos[1] = pos[1] - 15; + Pos[2] = pos[2]; + } else { // Default to first waypoint position + Pos[0] = D_80164490->posX; + Pos[1] = (f32) (D_80164490->posY - 15); + Pos[2] = D_80164490->posZ; + } + + Rot[0] = 0; + Rot[1] = 0; + Rot[2] = 0; + + + + Flags = -0x8000 | 0x4000; + + BoundingBoxSize = 0.0f; +} + +void AFinishline::Tick() {} + +extern Gfx cloud_mesh[]; + +void AFinishline::Draw(Camera *camera) { + Mat4 mtx; + s16 temp = Pos[2]; + s32 maxObjectsReached; + + + if (gGamestate == CREDITS_SEQUENCE) { + return; + } + + mtxf_pos_rotation_xyz(mtx, Pos, Rot); + + maxObjectsReached = render_set_position(mtx, 0) == 0; + if (maxObjectsReached) { + return; + } + + if (temp < camera->pos[2]) { + if (D_800DC5BC != 0) { + + gDPSetFogColor(gDisplayListHead++, D_801625EC, D_801625F4, D_801625F0, 0xFF); + gSPDisplayList(gDisplayListHead++, (Gfx*)D_0D001C20); + } else { + gSPDisplayList(gDisplayListHead++, (Gfx*)D_0D001B90); + } + } else if (D_800DC5BC != 0) { + gDPSetFogColor(gDisplayListHead++, D_801625EC, D_801625F4, D_801625F0, 0xFF); + gSPDisplayList(gDisplayListHead++, (Gfx*)D_0D001C88); + } else { + gSPDisplayList(gDisplayListHead++, (Gfx*)D_0D001BD8); + } +} + +void AFinishline::Collision(Player* player, AActor* actor) {} + +bool AFinishline::IsMod() { return true; } diff --git a/src/engine/actors/AFinishline.h b/src/engine/actors/AFinishline.h new file mode 100644 index 000000000..ea27f3b61 --- /dev/null +++ b/src/engine/actors/AFinishline.h @@ -0,0 +1,40 @@ +#pragma once + +#include +#include "engine/Actor.h" + +extern "C" { +#include "macros.h" +#include "main.h" +#include "camera.h" +#include "common_structs.h" +} + +class AFinishline : public AActor { +public: + /** + * Default behaviour places the finishline at the first waypoint. + * @arg pos, optional. Sets a custom position + */ + AFinishline(Vec3f pos = nullptr); + + virtual ~AFinishline() override = default; + + // Virtual functions to be overridden by derived classes + virtual void Tick() override; + virtual void Draw(Camera*) override; + virtual void Collision(Player* player, AActor* actor) override; + virtual bool IsMod() override; + + bool PickedUp = false; + uint32_t Timer = 0; + + Player* _player = NULL; + + f32 Hop = 3.0f; + f32 Gravity = 200.0f; + + f32 OldHop = 0; + f32 OldGravity = 0; + +}; diff --git a/src/engine/actors/ATree.cpp b/src/engine/actors/ATree.cpp new file mode 100644 index 000000000..fa1c7f580 --- /dev/null +++ b/src/engine/actors/ATree.cpp @@ -0,0 +1,66 @@ +#include "ATree.h" + +#include + +extern "C" { +#include "common_structs.h" +#include "math_util.h" +#include "main.h" +#include "actors.h" +} + +ATree::ATree(Vec3f pos, Gfx* displaylist, f32 drawDistance, f32 minDrawDistance, const char* tlut = nullptr) { + Pos[0] = pos[0]; + Pos[1] = pos[1]; + Pos[2] = pos[2]; + + Displaylist = displaylist; + Tlut = tlut; + DrawDistance = drawDistance; + MinDrawDistance = minDrawDistance; +} + +void ATree::Tick() { + if (((Flags & 0x800) == 0) && ((Flags & 0x400) != 0)) { + Pos[1] = Pos[1] + 4.0f; + if (Pos[1] > 800.0f) { + Flags |= 0x800; + } + } +} + +void ATree::Draw(Camera* camera) { + f32 dist; + + if ((Flags & 0x800) != 0) { + return; + } + + dist = is_within_render_distance(camera->pos, Pos, camera->rot[1], 0, gCameraZoom[camera - camera1], + DrawDistance); + + if (CVarGetInteger("gNoCulling", 0) == 1) { + dist = MAX(dist, 0.0f); + } + + if (dist < 0.0f) { + return; + } + + if (((Flags & 0x400) == 0) && (dist < MinDrawDistance)) { + func_8029794C(Pos, Rot, 3.0f); + } + sBillBoardMtx[3][0] = Pos[0]; + sBillBoardMtx[3][1] = Pos[1]; + sBillBoardMtx[3][2] = Pos[2]; + + if (render_set_position(sBillBoardMtx, 0) != 0) { + if (Tlut) { + gDPLoadTLUT_pal256(gDisplayListHead++, Tlut); + } + gSPDisplayList(gDisplayListHead++, Displaylist); + } +} + +void ATree::Collision(Player* player, AActor*) { } +void ATree::Destroy() { } diff --git a/src/engine/actors/ATree.h b/src/engine/actors/ATree.h new file mode 100644 index 000000000..eb51f6e7e --- /dev/null +++ b/src/engine/actors/ATree.h @@ -0,0 +1,35 @@ +#pragma once + +#include +#include "engine/Actor.h" + +extern "C" { +#include "common_structs.h" +} + + +// Note that this doesn't seem to work right +// Use add_actor_to_empty_slot(test, rot, vel, ACTOR_TREE_MARIO_RACEWAY); +// to spawn stock actors +class ATree : public AActor { +public: + + Gfx* Displaylist; + const char* Tlut; + f32 DrawDistance; + f32 MinDrawDistance; + s16 Flags = -0x8000 | 0x4000; + s16 State = 0x43; + f32 BoundingBoxSize = 3.0f; + f32 Unk_08 = 20.0f; + + virtual ~ATree() = default; + + // Set tlut to NULL if not using a tlut + explicit ATree(Vec3f pos, Gfx* displaylist, f32 drawDistance, f32 minDrawDistance, const char* tlut); + + virtual void Tick() override; + virtual void Draw(Camera* camera) override; + virtual void Collision(Player*, AActor*) override; + virtual void Destroy() override; +}; diff --git a/src/engine/actors/AWarioSign.cpp b/src/engine/actors/AWarioSign.cpp index 2dd8a5fc9..8e73a94f3 100644 --- a/src/engine/actors/AWarioSign.cpp +++ b/src/engine/actors/AWarioSign.cpp @@ -15,7 +15,6 @@ AWarioSign::AWarioSign(Vec3f pos) { Pos[2] = pos[2]; } - // Virtual functions to be overridden by derived classes void AWarioSign::Tick() { Rot[1] += 0xB6; } diff --git a/src/engine/courses/BansheeBoardwalk.cpp b/src/engine/courses/BansheeBoardwalk.cpp index 09517031d..2211b3294 100644 --- a/src/engine/courses/BansheeBoardwalk.cpp +++ b/src/engine/courses/BansheeBoardwalk.cpp @@ -6,7 +6,8 @@ #include "BansheeBoardwalk.h" #include "GameObject.h" #include "World.h" -#include "BombKart.h" +#include "engine/actors/AFinishline.h" +#include "engine/vehicles/OBombKart.h" #include "assets/banshee_boardwalk_data.h" #include "assets/boo_frames.h" @@ -102,13 +103,42 @@ BansheeBoardwalk::BansheeBoardwalk() { Props.Skybox.FloorTopLeft = {0, 0, 0}; } +void BansheeBoardwalk::Load() { + Course::Load(); + + D_800DC5BC = 1; + D_801625EC = 0; + D_801625F4 = 0; + D_801625F0 = 0; + parse_course_displaylists((TrackSectionsI*)LOAD_ASSET_RAW(d_course_banshee_boardwalk_track_sections)); + func_80295C6C(); + find_vtx_and_set_colours(segmented_gfx_to_virtual((void*)0x07000878), 128, 0, 0, 0); + D_8015F8E4 = -80.0f; +} + void BansheeBoardwalk::LoadTextures() { } void BansheeBoardwalk::SpawnActors() { + gWorldInstance.AddActor(new AFinishline()); + spawn_all_item_boxes((struct ActorSpawnData*)LOAD_ASSET_RAW(d_course_banshee_boardwalk_item_box_spawns)); } +void BansheeBoardwalk::SpawnVehicles() { + if (gModeSelection == VERSUS) { + Vec3f pos = {0, 0, 0}; + + gWorldInstance.AddBombKart(pos, &D_80164550[0][110], 110, 3, 0.8333333f); + gWorldInstance.AddBombKart(pos, &D_80164550[0][190], 190, 1, 0.8333333f); + gWorldInstance.AddBombKart(pos, &D_80164550[0][250], 250, 3, 0.8333333f); + gWorldInstance.AddBombKart(pos, &D_80164550[0][475], 475, 1, 0.8333333f); + gWorldInstance.AddBombKart(pos, &D_80164550[0][610], 610, 3, 0.8333333f); + gWorldInstance.AddBombKart(pos, &D_80164550[0][0], 0, 0, 0.8333333f); + gWorldInstance.AddBombKart(pos, &D_80164550[0][0], 0, 0, 0.8333333f); + } +} + // Likely sets minimap boundaries void BansheeBoardwalk::MinimapSettings() { D_80165880 = dma_textures((const char*)gTextureGhosts, 0x4CC2, 0xD980); @@ -188,27 +218,12 @@ void BansheeBoardwalk::WhatDoesThisDoAI(Player* player, int8_t playerId) { } } -void BansheeBoardwalk::SpawnBombKarts() { - gWorldInstance.AddObject(std::make_unique(140, 3, 0.8333333, 0, 0, 0, 0)); - gWorldInstance.AddObject(std::make_unique(165, 1, 0.8333333, 0, 0, 0, 0)); - gWorldInstance.AddObject(std::make_unique(330, 3, 0.8333333, 0, 0, 0, 0)); - gWorldInstance.AddObject(std::make_unique(550, 1, 0.8333333, 0, 0, 0, 0)); - gWorldInstance.AddObject(std::make_unique(595, 3, 0.8333333, 0, 0, 0, 0)); - gWorldInstance.AddObject(std::make_unique(0, 0, 0.8333333, 0, 0, 0, 0)); - gWorldInstance.AddObject(std::make_unique(0, 0, 0.8333333, 0, 0, 0, 0)); -} - // Positions the finishline on the minimap void BansheeBoardwalk::MinimapFinishlinePosition() { //! todo: Place hard-coded values here. draw_hud_2d_texture_8x8(this->Props.MinimapFinishlineX, this->Props.MinimapFinishlineY, (u8*) common_texture_minimap_finish_line); } -void BansheeBoardwalk::SetStaffGhost() { -} - -void BansheeBoardwalk::BeginPlay() { } - void BansheeBoardwalk::Render(struct UnkStruct_800DC5EC* arg0) { Camera* camera = arg0->camera; Mat4 spCC; @@ -274,18 +289,7 @@ void BansheeBoardwalk::RenderCredits() { void BansheeBoardwalk::Collision() {} -void BansheeBoardwalk::GenerateCollision() { - D_800DC5BC = 1; - D_801625EC = 0; - D_801625F4 = 0; - D_801625F0 = 0; - parse_course_displaylists((TrackSectionsI*)LOAD_ASSET_RAW(d_course_banshee_boardwalk_track_sections)); - func_80295C6C(); - find_vtx_and_set_colours(segmented_gfx_to_virtual(reinterpret_cast(0x07000878)), 128, 0, 0, 0); - D_8015F8E4 = -80.0f; -} - -void BansheeBoardwalk::Water() { +void BansheeBoardwalk::ScrollingTextures() { D_802B87BC++; if (D_802B87BC >= 0x100) { @@ -306,4 +310,21 @@ void BansheeBoardwalk::Waypoints(Player* player, int8_t playerId) { } } +void BansheeBoardwalk::DrawWater(struct UnkStruct_800DC5EC* screen, uint16_t pathCounter, uint16_t cameraRot, uint16_t playerDirection) { + gDPPipeSync(gDisplayListHead++); + gSPTexture(gDisplayListHead++, 0xFFFF, 0xFFFF, 0, G_TX_RENDERTILE, G_ON); + gSPClearGeometryMode(gDisplayListHead++, G_LIGHTING); + gDPSetRenderMode(gDisplayListHead++, G_RM_AA_ZB_XLU_INTER, G_RM_NOOP2); + gDPSetBlendMask(gDisplayListHead++, 0xFF); + gDPSetCombineMode(gDisplayListHead++, G_CC_MODULATEIA, G_CC_MODULATEIA); + // d_course_banshee_boardwalk_packed_dl_878 + gSPDisplayList(gDisplayListHead++, segmented_gfx_to_virtual((void*)0x07000878)); + gDPSetAlphaCompare(gDisplayListHead++, G_AC_NONE); + gDPPipeSync(gDisplayListHead++); +} + +void BansheeBoardwalk::CreditsSpawnActors() { + find_vtx_and_set_colours(segmented_gfx_to_virtual((void*)0x07000878), 0x32, 0, 0, 0); +} + void BansheeBoardwalk::Destroy() { } diff --git a/src/engine/courses/BansheeBoardwalk.h b/src/engine/courses/BansheeBoardwalk.h index c8ef58a6b..612597578 100644 --- a/src/engine/courses/BansheeBoardwalk.h +++ b/src/engine/courses/BansheeBoardwalk.h @@ -24,8 +24,10 @@ public: // virtual void Load(const char* courseVtx, // course_texture* textures, const char* displaylists, size_t dlSize); + virtual void Load() override; virtual void LoadTextures() override; virtual void SpawnActors() override; + virtual void SpawnVehicles() override; //virtual void InitClouds() override; virtual void MinimapSettings() override; virtual void InitCourseObjects() override; @@ -35,14 +37,12 @@ public: virtual void WhatDoesThisDo(Player* player, int8_t playerId) override; virtual void WhatDoesThisDoAI(Player* player, int8_t playerId) override; virtual void MinimapFinishlinePosition() override; - virtual void SetStaffGhost() override; - virtual void BeginPlay() override; virtual void Render(struct UnkStruct_800DC5EC*) override; virtual void RenderCredits() override; virtual void Collision() override; - virtual void SpawnBombKarts() override; - virtual void GenerateCollision() override; - virtual void Water() override; + virtual void ScrollingTextures() override; virtual void Waypoints(Player*, int8_t) override; + virtual void DrawWater(struct UnkStruct_800DC5EC* screen, uint16_t pathCounter, uint16_t cameraRot, uint16_t playerDirection) override; + virtual void CreditsSpawnActors() override; virtual void Destroy() override; }; diff --git a/src/engine/courses/BigDonut.cpp b/src/engine/courses/BigDonut.cpp index 18c8e65a4..f01930c7b 100644 --- a/src/engine/courses/BigDonut.cpp +++ b/src/engine/courses/BigDonut.cpp @@ -6,7 +6,7 @@ #include "BigDonut.h" #include "GameObject.h" #include "World.h" -#include "BombKart.h" +#include "engine/vehicles/OBombKart.h" #include "assets/big_donut_data.h" extern "C" { @@ -98,11 +98,42 @@ BigDonut::BigDonut() { Props.Skybox.FloorTopLeft = {0, 0, 0}; } +void BigDonut::Load() { + Course::Load(); + + // d_course_big_donut_packed_dl_1018 + generate_collision_mesh_with_default_section_id((Gfx*) segmented_gfx_to_virtual((void*)0x07001018), 6); + // d_course_big_donut_packed_dl_450 + generate_collision_mesh_with_default_section_id((Gfx*) segmented_gfx_to_virtual((void*)0x07000450), 6); + // d_course_big_donut_packed_dl_AC0 + generate_collision_mesh_with_default_section_id((Gfx*) segmented_gfx_to_virtual((void*)0x07000AC0), 6); + // d_course_big_donut_packed_dl_B58 + generate_collision_mesh_with_default_section_id((Gfx*) segmented_gfx_to_virtual((void*)0x07000B58), 6); + // d_course_big_donut_packed_dl_230 + generate_collision_mesh_with_default_section_id((Gfx*) segmented_gfx_to_virtual((void*)0x07000230), 6); + func_80295C6C(); + D_8015F8E4 = 100.0f; +} + void BigDonut::LoadTextures() { } void BigDonut::SpawnActors() {} +void BigDonut::SpawnVehicles() { + if (gModeSelection == VERSUS) { + Vec3f pos = {0, 0, 0}; + + gWorldInstance.AddBombKart(pos, &D_80164550[0][20], 20, 0, 1.0f); + gWorldInstance.AddBombKart(pos, &D_80164550[0][40], 40, 0, 1.0f); + gWorldInstance.AddBombKart(pos, &D_80164550[0][60], 60, 0, 1.0f); + gWorldInstance.AddBombKart(pos, &D_80164550[0][80], 80, 0, 1.0f); + gWorldInstance.AddBombKart(pos, &D_80164550[0][100], 100, 0, 1.0f); + gWorldInstance.AddBombKart(pos, &D_80164550[0][120], 120, 0, 1.0f); + gWorldInstance.AddBombKart(pos, &D_80164550[0][140], 140, 0, 1.0f); + } +} + // Likely sets minimap boundaries void BigDonut::MinimapSettings() { D_8018D2A0 = 0.0257f; @@ -118,17 +149,12 @@ void BigDonut::WhatDoesThisDo(Player* player, int8_t playerId) {} void BigDonut::WhatDoesThisDoAI(Player* player, int8_t playerId) {} -void BigDonut::SpawnBombKarts() {} - // Positions the finishline on the minimap void BigDonut::MinimapFinishlinePosition() { //! todo: Place hard-coded values here. draw_hud_2d_texture_8x8(this->Props.MinimapFinishlineX, this->Props.MinimapFinishlineY, (u8*) common_texture_minimap_finish_line); } -void BigDonut::SetStaffGhost() {} - -void BigDonut::BeginPlay() {} void BigDonut::Render(struct UnkStruct_800DC5EC* arg0) { gSPSetGeometryMode(gDisplayListHead++, G_SHADING_SMOOTH); gSPClearGeometryMode(gDisplayListHead++, G_LIGHTING); @@ -156,21 +182,6 @@ void BigDonut::RenderCredits() {} void BigDonut::Collision() {} -void BigDonut::GenerateCollision() { - // d_course_big_donut_packed_dl_1018 - generate_collision_mesh_with_default_section_id((Gfx*) segmented_gfx_to_virtual((void*)0x07001018), 6); - // d_course_big_donut_packed_dl_450 - generate_collision_mesh_with_default_section_id((Gfx*) segmented_gfx_to_virtual((void*)0x07000450), 6); - // d_course_big_donut_packed_dl_AC0 - generate_collision_mesh_with_default_section_id((Gfx*) segmented_gfx_to_virtual((void*)0x07000AC0), 6); - // d_course_big_donut_packed_dl_B58 - generate_collision_mesh_with_default_section_id((Gfx*) segmented_gfx_to_virtual((void*)0x07000B58), 6); - // d_course_big_donut_packed_dl_230 - generate_collision_mesh_with_default_section_id((Gfx*) segmented_gfx_to_virtual((void*)0x07000230), 6); - func_80295C6C(); - D_8015F8E4 = 100.0f; -} - void BigDonut::Waypoints(Player* player, int8_t playerId) { player->nearestWaypointId = 0; } diff --git a/src/engine/courses/BigDonut.h b/src/engine/courses/BigDonut.h index 41fd0457f..732a9a568 100644 --- a/src/engine/courses/BigDonut.h +++ b/src/engine/courses/BigDonut.h @@ -24,8 +24,10 @@ public: // virtual void Load(const char* courseVtx, // course_texture* textures, const char* displaylists, size_t dlSize); + virtual void Load() override; virtual void LoadTextures() override; virtual void SpawnActors() override; + virtual void SpawnVehicles() override; //virtual void InitClouds() override; virtual void MinimapSettings() override; virtual void InitCourseObjects() override; @@ -33,13 +35,9 @@ public: virtual void WhatDoesThisDo(Player* player, int8_t playerId) override; virtual void WhatDoesThisDoAI(Player* player, int8_t playerId) override; virtual void MinimapFinishlinePosition() override; - virtual void SetStaffGhost() override; - virtual void BeginPlay() override; virtual void Render(struct UnkStruct_800DC5EC*) override; virtual void RenderCredits() override; virtual void Collision() override; - virtual void SpawnBombKarts() override; - virtual void GenerateCollision() override; virtual void Waypoints(Player* player, int8_t playerId) override; virtual void Destroy() override; }; diff --git a/src/engine/courses/BlockFort.cpp b/src/engine/courses/BlockFort.cpp index e81550a64..d6ebf2263 100644 --- a/src/engine/courses/BlockFort.cpp +++ b/src/engine/courses/BlockFort.cpp @@ -6,7 +6,7 @@ #include "BlockFort.h" #include "GameObject.h" #include "World.h" -#include "BombKart.h" +#include "engine/vehicles/OBombKart.h" #include "assets/block_fort_data.h" extern "C" { @@ -101,10 +101,34 @@ BlockFort::BlockFort() { Props.Skybox.FloorTopLeft = {216, 232, 248}; } +void BlockFort::Load() { + Course::Load(); + + generate_collision_mesh_with_default_section_id((Gfx*) segmented_gfx_to_virtual((void*)0x070015C0), 1); + func_80295C6C(); + D_8015F8E4 = gCourseMinY - 10.0f; +} + void BlockFort::LoadTextures() { } -void BlockFort::SpawnActors() {} +void BlockFort::SpawnActors() { + spawn_all_item_boxes((ActorSpawnData*)LOAD_ASSET_RAW(d_course_block_fort_item_box_spawns)); +} + +void BlockFort::SpawnVehicles() { + if (gModeSelection == VERSUS) { + Vec3f pos = {0, 0, 0}; + + gWorldInstance.AddBombKart(pos, &D_80164550[0][20], 20, 0, 1.0f); + gWorldInstance.AddBombKart(pos, &D_80164550[0][40], 40, 0, 1.0f); + gWorldInstance.AddBombKart(pos, &D_80164550[0][60], 60, 0, 1.0f); + gWorldInstance.AddBombKart(pos, &D_80164550[0][80], 80, 0, 1.0f); + gWorldInstance.AddBombKart(pos, &D_80164550[0][100], 100, 0, 1.0f); + gWorldInstance.AddBombKart(pos, &D_80164550[0][120], 120, 0, 1.0f); + gWorldInstance.AddBombKart(pos, &D_80164550[0][140], 140, 0, 1.0f); + } +} // Likely sets minimap boundaries void BlockFort::MinimapSettings() { @@ -121,17 +145,12 @@ void BlockFort::WhatDoesThisDo(Player* player, int8_t playerId) {} void BlockFort::WhatDoesThisDoAI(Player* player, int8_t playerId) {} -void BlockFort::SpawnBombKarts() {} - // Positions the finishline on the minimap void BlockFort::MinimapFinishlinePosition() { //! todo: Place hard-coded values here. draw_hud_2d_texture_8x8(this->Props.MinimapFinishlineX, this->Props.MinimapFinishlineY, (u8*) common_texture_minimap_finish_line); } -void BlockFort::SetStaffGhost() {} - -void BlockFort::BeginPlay() { } void BlockFort::Render(struct UnkStruct_800DC5EC* arg0) { func_802B5D64(D_800DC610, D_802B87D4, 0, 1); gSPTexture(gDisplayListHead++, 0xFFFF, 0xFFFF, 0, G_TX_RENDERTILE, G_ON); @@ -145,12 +164,6 @@ void BlockFort::RenderCredits() {} void BlockFort::Collision() {} -void BlockFort::GenerateCollision() { - generate_collision_mesh_with_default_section_id((Gfx*) segmented_gfx_to_virtual((void*)0x070015C0), 1); - func_80295C6C(); - D_8015F8E4 = gCourseMinY - 10.0f; -} - void BlockFort::Waypoints(Player* player, int8_t playerId) { player->nearestWaypointId = 0; } diff --git a/src/engine/courses/BlockFort.h b/src/engine/courses/BlockFort.h index eba210234..b3d2fdc3c 100644 --- a/src/engine/courses/BlockFort.h +++ b/src/engine/courses/BlockFort.h @@ -24,8 +24,10 @@ public: // virtual void Load(const char* courseVtx, // course_texture* textures, const char* displaylists, size_t dlSize); + virtual void Load() override; virtual void LoadTextures() override; virtual void SpawnActors() override; + virtual void SpawnVehicles() override; //virtual void InitClouds() override; virtual void MinimapSettings() override; virtual void InitCourseObjects() override; @@ -33,13 +35,9 @@ public: virtual void WhatDoesThisDo(Player* player, int8_t playerId) override; virtual void WhatDoesThisDoAI(Player* player, int8_t playerId) override; virtual void MinimapFinishlinePosition() override; - virtual void SetStaffGhost() override; - virtual void BeginPlay() override; virtual void Render(struct UnkStruct_800DC5EC*) override; virtual void RenderCredits() override; virtual void Collision() override; - virtual void SpawnBombKarts() override; - virtual void GenerateCollision() override; virtual void Waypoints(Player*, int8_t) override; virtual void Destroy() override; }; diff --git a/src/engine/courses/BombKart.cpp b/src/engine/courses/BombKart.cpp deleted file mode 100644 index 1cbbd7477..000000000 --- a/src/engine/courses/BombKart.cpp +++ /dev/null @@ -1,28 +0,0 @@ -#include "BombKart.h" - -extern "C" { - #include "bomb_kart.h" -} - -/** - * BombKarts derive their Y position from the waypoint Y value or 'spawn_actor_on_surface' function - */ - -OBombKart::OBombKart(uint16_t waypoint, uint16_t state, float unk_04, float x, float z, float unk_10, float unk_14) {} - -void OBombKart::Init() { - // BombKarts.emplace_back(this); - //BombKarts.push_back(BombKarts(waypoint, state, unk_04, x, z, unk_10, unk_14)); -} - -void OBombKart::Update() { - -} - -void OBombKart::Render() { - -} - -void OBombKart::Explode() { - -} \ No newline at end of file diff --git a/src/engine/courses/BombKart.h b/src/engine/courses/BombKart.h deleted file mode 100644 index e11bf6820..000000000 --- a/src/engine/courses/BombKart.h +++ /dev/null @@ -1,38 +0,0 @@ -#ifndef BOMBKART_H -#define BOMBKART_H - -#include - - -#ifdef __cplusplus -#include "GameObject.h" -extern "C" { -#endif - - #include "bomb_kart.h" - #include "Engine.h" - -#ifdef __cplusplus -} -#endif - -#ifdef __cplusplus - -class OBombKart : public GameObject { - -public: - virtual ~OBombKart() = default; - - // Constructor - explicit OBombKart(uint16_t waypoint, uint16_t state, float unk_04, float x, float z, float unk_10, float unk_14); - - BombKart vehicle; - virtual void Init(); - virtual void Update(); - virtual void Render(); - virtual void Explode(); -}; - -#endif - -#endif // BOMBKART_H \ No newline at end of file diff --git a/src/engine/courses/BowsersCastle.cpp b/src/engine/courses/BowsersCastle.cpp index 58aab3456..5c1e97236 100644 --- a/src/engine/courses/BowsersCastle.cpp +++ b/src/engine/courses/BowsersCastle.cpp @@ -6,7 +6,8 @@ #include "BowsersCastle.h" #include "GameObject.h" #include "World.h" -#include "BombKart.h" +#include "engine/actors/AFinishline.h" +#include "engine/vehicles/OBombKart.h" #include "bowsers_castle_data.h" extern "C" { @@ -102,15 +103,40 @@ BowsersCastle::BowsersCastle() { Props.Skybox.FloorTopLeft = {0, 0, 0}; } +void BowsersCastle::Load() { + Course::Load(); + + parse_course_displaylists((TrackSectionsI*)LOAD_ASSET_RAW(d_course_bowsers_castle_addr)); + func_80295C6C(); + find_vtx_and_set_colours(segmented_gfx_to_virtual(reinterpret_cast(0x07001350)), 0x32, 0, 0, 0); + D_8015F8E4 = -50.0f; +} + void BowsersCastle::LoadTextures() { dma_textures(gTextureShrub, 0x000003FFU, 0x00000800U); } void BowsersCastle::SpawnActors() { + gWorldInstance.AddActor(new AFinishline()); + 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)); } +void BowsersCastle::SpawnVehicles() { + if (gModeSelection == VERSUS) { + Vec3f pos = {0, 0, 0}; + + gWorldInstance.AddBombKart(pos, &D_80164550[0][50], 50, 3, 0.8333333f); + gWorldInstance.AddBombKart(pos, &D_80164550[0][150], 150, 1, 0.8333333f); + gWorldInstance.AddBombKart(pos, &D_80164550[0][200], 200, 3, 0.8333333f); + gWorldInstance.AddBombKart(pos, &D_80164550[0][260], 260, 1, 0.8333333f); + gWorldInstance.AddBombKart(pos, &D_80164550[0][435], 435, 3, 0.8333333f); + gWorldInstance.AddBombKart(pos, &D_80164550[0][0], 0, 0, 0.8333333f); + gWorldInstance.AddBombKart(pos, &D_80164550[0][0], 0, 0, 0.8333333f); + } +} + // Likely sets minimap boundaries void BowsersCastle::MinimapSettings() { D_8018D2C0[0] = 265; @@ -212,26 +238,12 @@ void BowsersCastle::WhatDoesThisDoAI(Player* player, int8_t playerId) { } } -void BowsersCastle::SpawnBombKarts() { - gWorldInstance.AddObject(std::make_unique(140, 3, 0.8333333, 0, 0, 0, 0)); - gWorldInstance.AddObject(std::make_unique(165, 1, 0.8333333, 0, 0, 0, 0)); - gWorldInstance.AddObject(std::make_unique(330, 3, 0.8333333, 0, 0, 0, 0)); - gWorldInstance.AddObject(std::make_unique(550, 1, 0.8333333, 0, 0, 0, 0)); - gWorldInstance.AddObject(std::make_unique(595, 3, 0.8333333, 0, 0, 0, 0)); - gWorldInstance.AddObject(std::make_unique(0, 0, 0.8333333, 0, 0, 0, 0)); - gWorldInstance.AddObject(std::make_unique(0, 0, 0.8333333, 0, 0, 0, 0)); -} - // Positions the finishline on the minimap void BowsersCastle::MinimapFinishlinePosition() { //! todo: Place hard-coded values here. draw_hud_2d_texture_8x8(this->Props.MinimapFinishlineX, this->Props.MinimapFinishlineY, (u8*) common_texture_minimap_finish_line); } -void BowsersCastle::SetStaffGhost() { -} - -void BowsersCastle::BeginPlay() { } void BowsersCastle::Render(struct UnkStruct_800DC5EC* arg0) { gSPTexture(gDisplayListHead++, 0xFFFF, 0xFFFF, 0, G_TX_RENDERTILE, G_ON); gSPSetGeometryMode(gDisplayListHead++, G_SHADING_SMOOTH); @@ -269,13 +281,6 @@ void BowsersCastle::SomeCollisionThing(Player *player, Vec3f arg1, Vec3f arg2, V func_8003E6EC(player, arg1, arg2, arg3, arg4, arg5, arg6, arg7); } -void BowsersCastle::GenerateCollision() { - parse_course_displaylists((TrackSectionsI*)LOAD_ASSET_RAW(d_course_bowsers_castle_addr)); - func_80295C6C(); - find_vtx_and_set_colours(segmented_gfx_to_virtual(reinterpret_cast(0x07001350)), 0x32, 0, 0, 0); - D_8015F8E4 = -50.0f; -} - void BowsersCastle::Waypoints(Player* player, int8_t playerId) { s16 waypoint = gNearestWaypointByPlayerId[playerId]; if ((waypoint >= 0x235) && (waypoint < 0x247)) { @@ -290,4 +295,29 @@ void BowsersCastle::Waypoints(Player* player, int8_t playerId) { } } +void BowsersCastle::DrawWater(struct UnkStruct_800DC5EC* screen, uint16_t pathCounter, uint16_t cameraRot, uint16_t playerDirection) { + if (gActiveScreenMode != SCREEN_MODE_1P) { + return; + } + if (pathCounter < 6) { + return; + } + if (pathCounter > 9) { + return; + } + if (pathCounter == 9) { + if (cameraRot < 0xA000) { + return; + } + if (cameraRot > 0xE000) { + return; + } + } + gSPDisplayList(gDisplayListHead++, (Gfx*)d_course_bowsers_castle_dl_9228); +} + +void BowsersCastle::CreditsSpawnActors() { + find_vtx_and_set_colours(segmented_gfx_to_virtual((void*)0x07001350), 0x32, 0, 0, 0); +} + void BowsersCastle::Destroy() { } diff --git a/src/engine/courses/BowsersCastle.h b/src/engine/courses/BowsersCastle.h index e0ee8918d..bbbd4c75e 100644 --- a/src/engine/courses/BowsersCastle.h +++ b/src/engine/courses/BowsersCastle.h @@ -24,8 +24,10 @@ public: // virtual void Load(const char* courseVtx, // course_texture* textures, const char* displaylists, size_t dlSize); + virtual void Load() override; virtual void LoadTextures() override; virtual void SpawnActors() override; + virtual void SpawnVehicles() override; //virtual void InitClouds() override; virtual void MinimapSettings() override; virtual void InitCourseObjects() override; @@ -35,14 +37,12 @@ public: virtual void WhatDoesThisDo(Player* player, int8_t playerId) override; virtual void WhatDoesThisDoAI(Player* player, int8_t playerId) override; virtual void MinimapFinishlinePosition() override; - virtual void SetStaffGhost() override; - virtual void BeginPlay() override; virtual void Render(struct UnkStruct_800DC5EC*) override; virtual void RenderCredits() override; virtual void Collision() override; virtual void SomeCollisionThing(Player *player, Vec3f arg1, Vec3f arg2, Vec3f arg3, f32* arg4, f32* arg5, f32* arg6, f32* arg7) override; - virtual void SpawnBombKarts() override; - virtual void GenerateCollision() override; virtual void Waypoints(Player*, int8_t) override; + virtual void DrawWater(struct UnkStruct_800DC5EC* screen, uint16_t pathCounter, uint16_t cameraRot, uint16_t playerDirection); + virtual void CreditsSpawnActors() override; virtual void Destroy() override; }; diff --git a/src/engine/courses/ChocoMountain.cpp b/src/engine/courses/ChocoMountain.cpp index bfb1950c3..bc88bf645 100644 --- a/src/engine/courses/ChocoMountain.cpp +++ b/src/engine/courses/ChocoMountain.cpp @@ -6,8 +6,9 @@ #include "ChocoMountain.h" #include "GameObject.h" #include "World.h" -#include "BombKart.h" +#include "engine/vehicles/OBombKart.h" #include "choco_mountain_data.h" +#include "engine/actors/AFinishline.h" extern "C" { #include "main.h" @@ -102,14 +103,62 @@ ChocoMountain::ChocoMountain() { Props.Skybox.FloorTopLeft = {255, 255, 255}; } +void ChocoMountain::Load() { + Course::Load(); + D_800DC5BC = 1; + D_801625EC = 255; + D_801625F4 = 255; + D_801625F0 = 255; + D_802B87B0 = 0x3E3; + D_802B87B4 = 0x3E8; + D_802B87D4 = 0x71C; + D_802B87D0 = 0xE38; + + // Spawn guardrail only for CC_50 and time trials. + if ((gCCSelection != CC_50) && (gModeSelection != TIME_TRIALS)) { + // d_course_choco_mountain_packed_dl_0 + nullify_displaylist((uintptr_t) segmented_gfx_to_virtual(reinterpret_cast(0x07000000))); + // d_course_choco_mountain_packed_dl_98 + nullify_displaylist((uintptr_t) segmented_gfx_to_virtual(reinterpret_cast(0x07000098))); + // d_course_choco_mountain_packed_dl_178 + nullify_displaylist((uintptr_t) segmented_gfx_to_virtual(reinterpret_cast(0x07000178))); + // d_course_choco_mountain_packed_dl_280 + nullify_displaylist((uintptr_t) segmented_gfx_to_virtual(reinterpret_cast(0x07000280))); + // d_course_choco_mountain_packed_dl_340 + nullify_displaylist((uintptr_t) segmented_gfx_to_virtual(reinterpret_cast(0x07000340))); + // d_course_choco_mountain_packed_dl_3C8 + nullify_displaylist((uintptr_t) segmented_gfx_to_virtual(reinterpret_cast(0x070003C8))); + } + + parse_course_displaylists((TrackSectionsI*)LOAD_ASSET_RAW(d_course_choco_mountain_addr)); + func_802B5CAC(0x238E, 0x31C7, D_8015F590); + func_80295C6C(); + D_8015F8E4 = -80.0f; +} + void ChocoMountain::LoadTextures() { } void ChocoMountain::SpawnActors() { + gWorldInstance.AddActor(new AFinishline()); spawn_all_item_boxes((struct ActorSpawnData*)LOAD_ASSET_RAW(d_course_choco_mountain_item_box_spawns)); spawn_falling_rocks((struct ActorSpawnData*)LOAD_ASSET_RAW((const char*)d_course_choco_mountain_falling_rock_spawns)); } +void ChocoMountain::SpawnVehicles() { + if (gModeSelection == VERSUS) { + Vec3f pos = {0, 0, 0}; + + gWorldInstance.AddBombKart(pos, &D_80164550[0][140], 140, 3, 0.8333333f); + gWorldInstance.AddBombKart(pos, &D_80164550[0][165], 165, 1, 0.8333333f); + gWorldInstance.AddBombKart(pos, &D_80164550[0][330], 330, 3, 0.8333333f); + gWorldInstance.AddBombKart(pos, &D_80164550[0][550], 550, 1, 0.8333333f); + gWorldInstance.AddBombKart(pos, &D_80164550[0][595], 595, 3, 0.8333333f); + gWorldInstance.AddBombKart(pos, &D_80164550[0][0], 0, 0, 0.8333333f); + gWorldInstance.AddBombKart(pos, &D_80164550[0][0], 0, 0, 0.8333333f); + } +} + // Likely sets minimap boundaries void ChocoMountain::MinimapSettings() { D_8018D2A0 = 0.022f; @@ -165,26 +214,12 @@ void ChocoMountain::WhatDoesThisDoAI(Player* player, int8_t playerId) { } } -void ChocoMountain::SpawnBombKarts() { - gWorldInstance.AddObject(std::make_unique(140, 3, 0.8333333, 0, 0, 0, 0)); - gWorldInstance.AddObject(std::make_unique(165, 1, 0.8333333, 0, 0, 0, 0)); - gWorldInstance.AddObject(std::make_unique(330, 3, 0.8333333, 0, 0, 0, 0)); - gWorldInstance.AddObject(std::make_unique(550, 1, 0.8333333, 0, 0, 0, 0)); - gWorldInstance.AddObject(std::make_unique(595, 3, 0.8333333, 0, 0, 0, 0)); - gWorldInstance.AddObject(std::make_unique(0, 0, 0.8333333, 0, 0, 0, 0)); - gWorldInstance.AddObject(std::make_unique(0, 0, 0.8333333, 0, 0, 0, 0)); -} - // Positions the finishline on the minimap void ChocoMountain::MinimapFinishlinePosition() { //! todo: Place hard-coded values here. draw_hud_2d_texture_8x8(this->Props.MinimapFinishlineX, this->Props.MinimapFinishlineY, (u8*) common_texture_minimap_finish_line); } -void ChocoMountain::SetStaffGhost() { -} - -void ChocoMountain::BeginPlay() { } void ChocoMountain::Render(struct UnkStruct_800DC5EC* arg0) { gSPSetGeometryMode(gDisplayListHead++, G_SHADING_SMOOTH); gSPClearGeometryMode(gDisplayListHead++, G_LIGHTING); @@ -242,36 +277,4 @@ void ChocoMountain::SomeCollisionThing(Player *player, Vec3f arg1, Vec3f arg2, V func_8003E37C(player, arg1, arg2, arg3, arg4, arg5, arg6, arg7); } -void ChocoMountain::GenerateCollision() { - D_800DC5BC = 1; - D_801625EC = 255; - D_801625F4 = 255; - D_801625F0 = 255; - D_802B87B0 = 0x3E3; - D_802B87B4 = 0x3E8; - D_802B87D4 = 0x71C; - D_802B87D0 = 0xE38; - - // Spawn guardrail only for CC_50 and time trials. - if ((gCCSelection != CC_50) && (gModeSelection != TIME_TRIALS)) { - // d_course_choco_mountain_packed_dl_0 - nullify_displaylist((uintptr_t) segmented_gfx_to_virtual(reinterpret_cast(0x07000000))); - // d_course_choco_mountain_packed_dl_98 - nullify_displaylist((uintptr_t) segmented_gfx_to_virtual(reinterpret_cast(0x07000098))); - // d_course_choco_mountain_packed_dl_178 - nullify_displaylist((uintptr_t) segmented_gfx_to_virtual(reinterpret_cast(0x07000178))); - // d_course_choco_mountain_packed_dl_280 - nullify_displaylist((uintptr_t) segmented_gfx_to_virtual(reinterpret_cast(0x07000280))); - // d_course_choco_mountain_packed_dl_340 - nullify_displaylist((uintptr_t) segmented_gfx_to_virtual(reinterpret_cast(0x07000340))); - // d_course_choco_mountain_packed_dl_3C8 - nullify_displaylist((uintptr_t) segmented_gfx_to_virtual(reinterpret_cast(0x070003C8))); - } - - parse_course_displaylists((TrackSectionsI*)LOAD_ASSET_RAW(d_course_choco_mountain_addr)); - func_802B5CAC(0x238E, 0x31C7, D_8015F590); - func_80295C6C(); - D_8015F8E4 = -80.0f; -} - void ChocoMountain::Destroy() { } diff --git a/src/engine/courses/ChocoMountain.h b/src/engine/courses/ChocoMountain.h index c45d6ff1f..718b40202 100644 --- a/src/engine/courses/ChocoMountain.h +++ b/src/engine/courses/ChocoMountain.h @@ -24,22 +24,19 @@ public: // virtual void Load(const char* courseVtx, // course_texture* textures, const char* displaylists, size_t dlSize); + virtual void Load() override; virtual void LoadTextures() override; virtual void SpawnActors() override; - //virtual void InitClouds() override; + virtual void SpawnVehicles() override; virtual void MinimapSettings() override; virtual void InitCourseObjects() override; virtual void SomeSounds() override; virtual void WhatDoesThisDo(Player* player, int8_t playerId) override; virtual void WhatDoesThisDoAI(Player* player, int8_t playerId) override; virtual void MinimapFinishlinePosition() override; - virtual void SetStaffGhost() override; - virtual void BeginPlay() override; virtual void Render(struct UnkStruct_800DC5EC*) override; virtual void RenderCredits() override; virtual void Collision() override; virtual void SomeCollisionThing(Player *player, Vec3f arg1, Vec3f arg2, Vec3f arg3, f32* arg4, f32* arg5, f32* arg6, f32* arg7) override; - virtual void SpawnBombKarts() override; - virtual void GenerateCollision() override; virtual void Destroy() override; }; diff --git a/src/engine/courses/Course.cpp b/src/engine/courses/Course.cpp index f844adcdf..bdec26404 100644 --- a/src/engine/courses/Course.cpp +++ b/src/engine/courses/Course.cpp @@ -17,6 +17,8 @@ extern "C" { #include "save.h" #include "staff_ghosts.h" #include "Engine.h" + #include "code_800029B0.h" + #include "render_courses.h" extern StaffGhost* d_mario_raceway_staff_ghost; } @@ -76,6 +78,8 @@ Course::Course() { void Course::Load(Vtx* vtx, Gfx* gfx) { gSegmentTable[4] = reinterpret_cast(&vtx[0]); gSegmentTable[7] = reinterpret_cast(&gfx[0]); + + Course::Init(); } void Course::Load() { @@ -86,7 +90,6 @@ void Course::Load() { // Convert course vtx to vtx Vtx* vtx = reinterpret_cast(allocate_memory(vtxSize)); gSegmentTable[4] = reinterpret_cast(&vtx[0]); - printf("\nVtxsize: 0x%X\n\n",vtxSize); func_802A86A8(reinterpret_cast(LOAD_ASSET_RAW(this->vtx)), vtx, vtxSize / sizeof(Vtx)); // Load and allocate memory for course textures @@ -117,6 +120,28 @@ void Course::Load() { assert(gfx != NULL); gSegmentTable[7] = reinterpret_cast(&gfx[0]); displaylist_unpack(reinterpret_cast(gfx), reinterpret_cast(packed), 0); + + Course::Init(); +} + +void Course::Init() { + gNumActors = 0; + gCourseMinX = 0; + gCourseMinY = 0; + gCourseMinZ = 0; + + gCourseMaxX = 0; + gCourseMaxY = 0; + gCourseMaxZ = 0; + + D_8015F59C = 0; + D_8015F5A0 = 0; + func_80295D6C(); + D_8015F58C = 0; + gCollisionMeshCount = 0; + gCollisionMesh = (CollisionTriangle*) gNextFreeMemoryAddress; + D_800DC5BC = 0; + D_800DC5C8 = 0; } void Course::LoadTextures() { } @@ -172,7 +197,7 @@ void Course::SomeSounds() { } -void Course::SetCourseVtxColours() { +void Course::CreditsSpawnActors() { } @@ -195,9 +220,6 @@ void Course::SetStaffGhost() { D_80162DF4 = 1; } -void Course::SpawnBombKarts() { -} - void Course::Waypoints(Player* player, int8_t playerId) { player->nearestWaypointId = gNearestWaypointByPlayerId[playerId]; if (player->nearestWaypointId < 0) { @@ -208,12 +230,11 @@ void Course::Waypoints(Player* player, int8_t playerId) { void Course::SpawnVehicles() {} void Course::UpdateVehicles() {} -void Course::BeginPlay() {} void Course::Render(struct UnkStruct_800DC5EC* arg0) {} void Course::RenderCredits() {} void Course::Collision() {} -void Course::GenerateCollision() {} -void Course::Water() {} +void Course::ScrollingTextures() {} +void Course::DrawWater(struct UnkStruct_800DC5EC* screen, uint16_t pathCounter, uint16_t cameraRot, uint16_t playerDirection) {} void Course::Destroy() { } diff --git a/src/engine/courses/Course.h b/src/engine/courses/Course.h index 00eb54f46..20fd553c0 100644 --- a/src/engine/courses/Course.h +++ b/src/engine/courses/Course.h @@ -100,22 +100,22 @@ public: virtual void UpdateCourseObjects(); virtual void RenderCourseObjects(s32 cameraId); virtual void SomeSounds(); - virtual void SetCourseVtxColours(); + virtual void CreditsSpawnActors(); virtual void WhatDoesThisDo(Player*, int8_t); virtual void WhatDoesThisDoAI(Player*, int8_t); virtual void MinimapFinishlinePosition(); virtual void SetStaffGhost(); - virtual void SpawnBombKarts(); - virtual void BeginPlay(); virtual void Render(struct UnkStruct_800DC5EC*); virtual void RenderCredits(); virtual void SpawnVehicles(); virtual void UpdateVehicles(); virtual void Waypoints(Player* player, int8_t playerId); virtual void Collision(); - virtual void GenerateCollision(); - virtual void Water(); + virtual void ScrollingTextures(); + virtual void DrawWater(struct UnkStruct_800DC5EC* screen, uint16_t pathCounter, uint16_t cameraRot, uint16_t playerDirection); virtual void Destroy(); +private: + void Init(); }; #endif diff --git a/src/engine/courses/DKJungle.cpp b/src/engine/courses/DKJungle.cpp index bc8257548..4c3d6797c 100644 --- a/src/engine/courses/DKJungle.cpp +++ b/src/engine/courses/DKJungle.cpp @@ -6,7 +6,8 @@ #include "DKJungle.h" #include "GameObject.h" #include "World.h" -#include "BombKart.h" +#include "engine/actors/AFinishline.h" +#include "engine/vehicles/OBombKart.h" #include "assets/dks_jungle_parkway_data.h" #include "engine/vehicles/Utils.h" @@ -105,6 +106,16 @@ DKJungle::DKJungle() { Props.Skybox.FloorTopLeft = {22, 145, 22}; } +void DKJungle::Load() { + Course::Load(); + + parse_course_displaylists((TrackSectionsI*)LOAD_ASSET_RAW(d_course_dks_jungle_parkway_addr)); + func_80295C6C(); + D_8015F8E4 = -475.0f; + // d_course_dks_jungle_parkway_packed_dl_3FA8 + find_vtx_and_set_colours(segmented_gfx_to_virtual((void*)0x07003FA8), 120, 255, 255, 255); +} + void DKJungle::LoadTextures() { dma_textures(gTextureDksJungleParkwayKiwanoFruit1, 0x0000032FU, 0x00000400U); dma_textures(gTextureDksJungleParkwayKiwanoFruit2, 0x00000369U, 0x00000400U); @@ -112,6 +123,8 @@ void DKJungle::LoadTextures() { } void DKJungle::SpawnActors() { + gWorldInstance.AddActor(new AFinishline()); + spawn_all_item_boxes((struct ActorSpawnData*)LOAD_ASSET_RAW(d_course_dks_jungle_parkway_item_box_spawns)); init_kiwano_fruit(); func_80298D10(); @@ -193,25 +206,12 @@ void DKJungle::WhatDoesThisDoAI(Player* player, int8_t playerId) { } } -void DKJungle::SpawnBombKarts() { - gWorldInstance.AddObject(std::make_unique(40, 3, 0.8333333, 0, 0, 0, 0)); - gWorldInstance.AddObject(std::make_unique(100, 3, 0.8333333, 0, 0, 0, 0)); - gWorldInstance.AddObject(std::make_unique(265, 3, 0.8333333, 0, 0, 0, 0)); - gWorldInstance.AddObject(std::make_unique(285, 1, 0.8333333, 0, 0, 0, 0)); - gWorldInstance.AddObject(std::make_unique(420, 1, 0.8333333, 0, 0, 0, 0)); - gWorldInstance.AddObject(std::make_unique(0, 0, 0.8333333, 0, 0, 0, 0)); - gWorldInstance.AddObject(std::make_unique(0, 0, 0.8333333, 0, 0, 0, 0)); -} - // Positions the finishline on the minimap void DKJungle::MinimapFinishlinePosition() { //! todo: Place hard-coded values here. draw_hud_2d_texture_8x8(this->Props.MinimapFinishlineX, this->Props.MinimapFinishlineY, (u8*) common_texture_minimap_finish_line); } -void DKJungle::SetStaffGhost() {} - -void DKJungle::BeginPlay() { } void DKJungle::Render(struct UnkStruct_800DC5EC* arg0) { func_802B5D64(D_800DC610, D_802B87D4, 0, 1); func_802B5D64(&D_800DC610[1], D_802B87D4, D_802B87D0, 1); @@ -248,15 +248,21 @@ void DKJungle::SomeCollisionThing(Player *player, Vec3f arg1, Vec3f arg2, Vec3f void DKJungle::SpawnVehicles() { generate_ferry_waypoints(); - gWorldInstance.AddBoat(1.6666666f, 0); -} + // 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); -void DKJungle::GenerateCollision() { - parse_course_displaylists((TrackSectionsI*)LOAD_ASSET_RAW(d_course_dks_jungle_parkway_addr)); - func_80295C6C(); - D_8015F8E4 = -475.0f; - // d_course_dks_jungle_parkway_packed_dl_3FA8 - find_vtx_and_set_colours(segmented_gfx_to_virtual((void*)0x07003FA8), 120, 255, 255, 255); + if (gModeSelection == VERSUS) { + Vec3f pos = {0, 0, 0}; + + gWorldInstance.AddBombKart(pos, &D_80164550[0][50], 50, 3, 0.8333333f); + gWorldInstance.AddBombKart(pos, &D_80164550[0][100], 100, 1, 0.8333333f); + gWorldInstance.AddBombKart(pos, &D_80164550[0][150], 150, 3, 0.8333333f); + gWorldInstance.AddBombKart(pos, &D_80164550[0][190], 190, 1, 0.8333333f); + gWorldInstance.AddBombKart(pos, &D_80164550[0][250], 250, 3, 0.8333333f); + gWorldInstance.AddBombKart(pos, &D_80164550[0][0], 0, 0, 0.8333333f); + gWorldInstance.AddBombKart(pos, &D_80164550[0][0], 0, 0, 0.8333333f); + } } void DKJungle::Waypoints(Player* player, int8_t playerId) { @@ -271,4 +277,188 @@ void DKJungle::Waypoints(Player* player, int8_t playerId) { } } +void DKJungle::ScrollingTextures() { + D_802B87BC += 2; + if (D_802B87BC > 255) { + D_802B87BC = 0; + } + // d_course_dks_jungle_parkway_packed_dl_3DD0 + find_and_set_tile_size((uintptr_t) segmented_gfx_to_virtual((void*)0x07003DD0), 0, D_802B87BC); + // d_course_dks_jungle_parkway_packed_dl_3E40 + find_and_set_tile_size((uintptr_t) segmented_gfx_to_virtual((void*)0x07003E40), 0, D_802B87BC); + // d_course_dks_jungle_parkway_packed_dl_3EB0 + find_and_set_tile_size((uintptr_t) segmented_gfx_to_virtual((void*)0x07003EB0), 0, D_802B87BC); + // d_course_dks_jungle_parkway_packed_dl_3F30 + find_and_set_tile_size((uintptr_t) segmented_gfx_to_virtual((void*)0x07003F30), 0, D_802B87BC); + // d_course_dks_jungle_parkway_packed_dl_36A8 + find_and_set_tile_size((uintptr_t) segmented_gfx_to_virtual((void*)0x070036A8), 0, D_802B87BC); + D_802B87C4 -= 20; + if (D_802B87C4 < 0) { + D_802B87C4 = 0xFF; + } + // d_course_dks_jungle_parkway_packed_dl_9880 + find_and_set_tile_size((uintptr_t) segmented_gfx_to_virtual((void*)0x07009880), 0, D_802B87C4); + evaluate_collision_players_palm_trees(); +} + +void DKJungle::DrawWater(struct UnkStruct_800DC5EC* screen, uint16_t pathCounter, uint16_t cameraRot, uint16_t playerDirection) { + Mat4 matrix; + gDPPipeSync(gDisplayListHead++); + gSPClearGeometryMode(gDisplayListHead++, G_LIGHTING); + gSPTexture(gDisplayListHead++, 0xFFFF, 0xFFFF, 0, G_TX_RENDERTILE, G_ON); + gDPSetBlendMask(gDisplayListHead++, 0xFF); + gDPSetTextureFilter(gDisplayListHead++, G_TF_BILERP); + gDPSetTexturePersp(gDisplayListHead++, G_TP_PERSP); + + mtxf_identity(matrix); + render_set_position(matrix, 0); + + gDPSetCombineMode(gDisplayListHead++, G_CC_MODULATEIA, G_CC_MODULATEIA); + gDPSetRenderMode(gDisplayListHead++, G_RM_AA_ZB_XLU_INTER, G_RM_NOOP2); + + if (pathCounter < 17) { + gDPSetCombineMode(gDisplayListHead++, G_CC_MODULATEIA, G_CC_MODULATEIA); + // d_course_dks_jungle_parkway_packed_dl_3E40 + gSPDisplayList(gDisplayListHead++, segmented_gfx_to_virtual((void*)0x07003E40)); + // d_course_dks_jungle_parkway_packed_dl_3EB0 + gSPDisplayList(gDisplayListHead++, segmented_gfx_to_virtual((void*)0x07003EB0)); + if ((pathCounter >= 6) && (pathCounter < 13)) { + gDPSetCombineMode(gDisplayListHead++, G_CC_MODULATEIA, G_CC_MODULATEIA); + // d_course_dks_jungle_parkway_packed_dl_3DD0 + gSPDisplayList(gDisplayListHead++, segmented_gfx_to_virtual((void*)0x07003DD0)); + } + } else if ((pathCounter == 21) || (pathCounter == 22)) { + if (playerDirection == 3) { + gDPSetCombineMode(gDisplayListHead++, G_CC_MODULATEIDECALA, G_CC_MODULATEIDECALA); + // d_course_dks_jungle_parkway_packed_dl_36A8 + gSPDisplayList(gDisplayListHead++, segmented_gfx_to_virtual((void*)0x070036A8)); + } + if ((playerDirection == 1) || (playerDirection == 0)) { + gDPSetCombineMode(gDisplayListHead++, G_CC_MODULATEIDECALA, G_CC_MODULATEIDECALA); + // d_course_dks_jungle_parkway_packed_dl_36A8 + gSPDisplayList(gDisplayListHead++, segmented_gfx_to_virtual((void*)0x070036A8)); + } else { + gDPSetCombineMode(gDisplayListHead++, G_CC_MODULATEIA, G_CC_MODULATEIA); + // d_course_dks_jungle_parkway_packed_dl_3F30 + gSPDisplayList(gDisplayListHead++, segmented_gfx_to_virtual((void*)0x07003F30)); + // d_course_dks_jungle_parkway_packed_dl_36A8 + gSPDisplayList(gDisplayListHead++, segmented_gfx_to_virtual((void*)0x070036A8)); + } + } else if (pathCounter == 24) { + if ((playerDirection == 0) || (playerDirection == 3)) { + gDPSetCombineMode(gDisplayListHead++, G_CC_MODULATEIDECALA, G_CC_MODULATEIDECALA); + // d_course_dks_jungle_parkway_packed_dl_36A8 + gSPDisplayList(gDisplayListHead++, segmented_gfx_to_virtual((void*)0x070036A8)); + } + } else if (pathCounter == 23) { + if (playerDirection == 3) { + gDPSetCombineMode(gDisplayListHead++, G_CC_MODULATEIDECALA, G_CC_MODULATEIDECALA); + // d_course_dks_jungle_parkway_packed_dl_36A8 + gSPDisplayList(gDisplayListHead++, segmented_gfx_to_virtual((void*)0x070036A8)); + } else if (playerDirection == 0) { + gDPSetCombineMode(gDisplayListHead++, G_CC_MODULATEIDECALA, G_CC_MODULATEIDECALA); + // d_course_dks_jungle_parkway_packed_dl_36A8 + gSPDisplayList(gDisplayListHead++, segmented_gfx_to_virtual((void*)0x070036A8)); + } + } + gDPSetCombineMode(gDisplayListHead++, G_CC_MODULATEIA, G_CC_MODULATEIA); + switch (pathCounter) { + case 5: + if (playerDirection != 3) { + // d_course_dks_jungle_parkway_packed_dl_3DD0 + gSPDisplayList(gDisplayListHead++, segmented_gfx_to_virtual((void*)0x07003DD0)); + } + break; + case 17: + switch (playerDirection) { + case 0: + // d_course_dks_jungle_parkway_packed_dl_3E40 + gSPDisplayList(gDisplayListHead++, segmented_gfx_to_virtual((void*)0x07003E40)); + // d_course_dks_jungle_parkway_packed_dl_3EB0 + gSPDisplayList(gDisplayListHead++, segmented_gfx_to_virtual((void*)0x07003EB0)); + break; + case 1: + // d_course_dks_jungle_parkway_packed_dl_3DD0 + gSPDisplayList(gDisplayListHead++, segmented_gfx_to_virtual((void*)0x07003DD0)); + // d_course_dks_jungle_parkway_packed_dl_3E40 + gSPDisplayList(gDisplayListHead++, segmented_gfx_to_virtual((void*)0x07003E40)); + // d_course_dks_jungle_parkway_packed_dl_3EB0 + gSPDisplayList(gDisplayListHead++, segmented_gfx_to_virtual((void*)0x07003EB0)); + break; + case 2: + // d_course_dks_jungle_parkway_packed_dl_ + gSPDisplayList(gDisplayListHead++, segmented_gfx_to_virtual((void*)0x07003E40)); + // d_course_dks_jungle_parkway_packed_dl_3EB0 + gSPDisplayList(gDisplayListHead++, segmented_gfx_to_virtual((void*)0x07003EB0)); + // d_course_dks_jungle_parkway_packed_dl_3F30 + gSPDisplayList(gDisplayListHead++, segmented_gfx_to_virtual((void*)0x07003F30)); + break; + case 3: + // d_course_dks_jungle_parkway_packed_dl_3EB0 + gSPDisplayList(gDisplayListHead++, segmented_gfx_to_virtual((void*)0x07003EB0)); + // d_course_dks_jungle_parkway_packed_dl_3F30 + gSPDisplayList(gDisplayListHead++, segmented_gfx_to_virtual((void*)0x07003F30)); + break; + } + break; + case 18: + switch (playerDirection) { + case 0: + // d_course_dks_jungle_parkway_packed_dl_3E40 + gSPDisplayList(gDisplayListHead++, segmented_gfx_to_virtual((void*)0x07003E40)); + // d_course_dks_jungle_parkway_packed_dl_3EB0 + gSPDisplayList(gDisplayListHead++, segmented_gfx_to_virtual((void*)0x07003EB0)); + break; + case 1: + // d_course_dks_jungle_parkway_packed_dl_3DD0 + gSPDisplayList(gDisplayListHead++, segmented_gfx_to_virtual((void*)0x07003DD0)); + // d_course_dks_jungle_parkway_packed_dl_3E40 + gSPDisplayList(gDisplayListHead++, segmented_gfx_to_virtual((void*)0x07003E40)); + // d_course_dks_jungle_parkway_packed_dl_3EB0 + gSPDisplayList(gDisplayListHead++, segmented_gfx_to_virtual((void*)0x07003EB0)); + break; + case 2: + // d_course_dks_jungle_parkway_packed_dl_3E40 + gSPDisplayList(gDisplayListHead++, segmented_gfx_to_virtual((void*)0x07003E40)); + // d_course_dks_jungle_parkway_packed_dl_3EB0 + gSPDisplayList(gDisplayListHead++, segmented_gfx_to_virtual((void*)0x07003EB0)); + break; + } + break; + case 21: + if ((playerDirection == 0) || (playerDirection == 1)) { + // d_course_dks_jungle_parkway_packed_dl_3E40 + gSPDisplayList(gDisplayListHead++, segmented_gfx_to_virtual((void*)0x07003E40)); + // d_course_dks_jungle_parkway_packed_dl_3EB0 + gSPDisplayList(gDisplayListHead++, segmented_gfx_to_virtual((void*)0x07003EB0)); + // d_course_dks_jungle_parkway_packed_dl_3F30 + gSPDisplayList(gDisplayListHead++, segmented_gfx_to_virtual((void*)0x07003F30)); + } else { + // d_course_dks_jungle_parkway_packed_dl_3EB0 + gSPDisplayList(gDisplayListHead++, segmented_gfx_to_virtual((void*)0x07003EB0)); + } + break; + case 22: + if (playerDirection == 0) { + // d_course_dks_jungle_parkway_packed_dl_3F30 + gSPDisplayList(gDisplayListHead++, segmented_gfx_to_virtual((void*)0x07003F30)); + } + break; + case 23: + if (playerDirection != 1) { + // d_course_dks_jungle_parkway_packed_dl_3F30 + gSPDisplayList(gDisplayListHead++, segmented_gfx_to_virtual((void*)0x07003F30)); + } + break; + } + gSPTexture(gDisplayListHead++, 0xFFFF, 0xFFFF, 1, 1, G_OFF); + gDPSetAlphaCompare(gDisplayListHead++, G_AC_NONE); + gDPPipeSync(gDisplayListHead++); +} + +void DKJungle::CreditsSpawnActors() { + // d_course_dks_jungle_parkway_packed_dl_3FA8 + find_vtx_and_set_colours(segmented_gfx_to_virtual((void*)0x07003FA8), 0x78, 0xFF, 0xFF, 0xFF); +} + void DKJungle::Destroy() { } diff --git a/src/engine/courses/DKJungle.h b/src/engine/courses/DKJungle.h index bbe4e1cbf..389213c1f 100644 --- a/src/engine/courses/DKJungle.h +++ b/src/engine/courses/DKJungle.h @@ -24,6 +24,7 @@ public: // virtual void Load(const char* courseVtx, // course_texture* textures, const char* displaylists, size_t dlSize); + virtual void Load() override; virtual void LoadTextures() override; virtual void SpawnActors() override; //virtual void InitClouds() override; @@ -35,15 +36,14 @@ public: virtual void WhatDoesThisDo(Player* player, int8_t playerId) override; virtual void WhatDoesThisDoAI(Player* player, int8_t playerId) override; virtual void MinimapFinishlinePosition() override; - virtual void SetStaffGhost() override; - virtual void BeginPlay() override; virtual void Render(struct UnkStruct_800DC5EC*) override; virtual void RenderCredits() override; virtual void SpawnVehicles() override; virtual void Collision() override; virtual void SomeCollisionThing(Player *player, Vec3f arg1, Vec3f arg2, Vec3f arg3, f32* arg4, f32* arg5, f32* arg6, f32* arg7) override; - virtual void SpawnBombKarts() override; - virtual void GenerateCollision() override; virtual void Waypoints(Player* player, int8_t playerId) override; + virtual void ScrollingTextures() override; + virtual void DrawWater(struct UnkStruct_800DC5EC* screen, uint16_t pathCounter, uint16_t cameraRot, uint16_t playerDirection) override; + virtual void CreditsSpawnActors() override; virtual void Destroy() override; }; diff --git a/src/engine/courses/DoubleDeck.cpp b/src/engine/courses/DoubleDeck.cpp index 43b4b47c7..7d07cdc43 100644 --- a/src/engine/courses/DoubleDeck.cpp +++ b/src/engine/courses/DoubleDeck.cpp @@ -6,7 +6,7 @@ #include "DoubleDeck.h" #include "GameObject.h" #include "World.h" -#include "BombKart.h" +#include "engine/vehicles/OBombKart.h" #include "assets/double_deck_data.h" extern "C" { @@ -101,10 +101,34 @@ DoubleDeck::DoubleDeck() { Props.Skybox.FloorTopLeft = {255, 224, 240}; } +void DoubleDeck::Load() { + Course::Load(); + + generate_collision_mesh_with_default_section_id((Gfx*) segmented_gfx_to_virtual((void*)0x07000738), 1); + func_80295C6C(); + D_8015F8E4 = gCourseMinY - 10.0f; +} + void DoubleDeck::LoadTextures() { } -void DoubleDeck::SpawnActors() {} +void DoubleDeck::SpawnActors() { + spawn_all_item_boxes((ActorSpawnData*)LOAD_ASSET_RAW(d_course_double_deck_item_box_spawns)); +} + +void DoubleDeck::SpawnVehicles() { + if (gModeSelection == VERSUS) { + Vec3f pos = {0, 0, 0}; + + gWorldInstance.AddBombKart(pos, &D_80164550[0][20], 20, 0, 1.0f); + gWorldInstance.AddBombKart(pos, &D_80164550[0][40], 40, 0, 1.0f); + gWorldInstance.AddBombKart(pos, &D_80164550[0][60], 60, 0, 1.0f); + gWorldInstance.AddBombKart(pos, &D_80164550[0][80], 80, 0, 1.0f); + gWorldInstance.AddBombKart(pos, &D_80164550[0][100], 100, 0, 1.0f); + gWorldInstance.AddBombKart(pos, &D_80164550[0][120], 120, 0, 1.0f); + gWorldInstance.AddBombKart(pos, &D_80164550[0][140], 140, 0, 1.0f); + } +} // Likely sets minimap boundaries void DoubleDeck::MinimapSettings() { @@ -121,17 +145,12 @@ void DoubleDeck::WhatDoesThisDo(Player* player, int8_t playerId) {} void DoubleDeck::WhatDoesThisDoAI(Player* player, int8_t playerId) {} -void DoubleDeck::SpawnBombKarts() {} - // Positions the finishline on the minimap void DoubleDeck::MinimapFinishlinePosition() { //! todo: Place hard-coded values here. draw_hud_2d_texture_8x8(this->Props.MinimapFinishlineX, this->Props.MinimapFinishlineY, (u8*) common_texture_minimap_finish_line); } -void DoubleDeck::SetStaffGhost() {} - -void DoubleDeck::BeginPlay() { } void DoubleDeck::Render(struct UnkStruct_800DC5EC* arg0) { func_802B5D64(D_800DC610, D_802B87D4, 0, 1); gSPTexture(gDisplayListHead++, 0xFFFF, 0xFFFF, 0, G_TX_RENDERTILE, G_ON); @@ -147,12 +166,6 @@ void DoubleDeck::RenderCredits() {} void DoubleDeck::Collision() {} -void DoubleDeck::GenerateCollision() { - generate_collision_mesh_with_default_section_id((Gfx*) segmented_gfx_to_virtual((void*)0x07000738), 1); - func_80295C6C(); - D_8015F8E4 = gCourseMinY - 10.0f; -} - void DoubleDeck::Waypoints(Player* player, int8_t playerId) { player->nearestWaypointId = 0; } diff --git a/src/engine/courses/DoubleDeck.h b/src/engine/courses/DoubleDeck.h index 5d453742e..bb1a8f98c 100644 --- a/src/engine/courses/DoubleDeck.h +++ b/src/engine/courses/DoubleDeck.h @@ -24,8 +24,10 @@ public: // virtual void Load(const char* courseVtx, // course_texture* textures, const char* displaylists, size_t dlSize); + virtual void Load() override; virtual void LoadTextures() override; virtual void SpawnActors() override; + virtual void SpawnVehicles() override; //virtual void InitClouds() override; virtual void MinimapSettings() override; virtual void InitCourseObjects() override; @@ -33,13 +35,9 @@ public: virtual void WhatDoesThisDo(Player* player, int8_t playerId) override; virtual void WhatDoesThisDoAI(Player* player, int8_t playerId) override; virtual void MinimapFinishlinePosition() override; - virtual void SetStaffGhost() override; - virtual void BeginPlay() override; virtual void Render(struct UnkStruct_800DC5EC*) override; virtual void RenderCredits() override; virtual void Collision() override; - virtual void SpawnBombKarts() override; - virtual void GenerateCollision() override; virtual void Waypoints(Player* player, int8_t playerId) override; virtual void Destroy() override; }; diff --git a/src/engine/courses/FrappeSnowland.cpp b/src/engine/courses/FrappeSnowland.cpp index 8236c345a..90fa51e6c 100644 --- a/src/engine/courses/FrappeSnowland.cpp +++ b/src/engine/courses/FrappeSnowland.cpp @@ -6,7 +6,8 @@ #include "FrappeSnowland.h" #include "GameObject.h" #include "World.h" -#include "BombKart.h" +#include "engine/actors/AFinishline.h" +#include "engine/vehicles/OBombKart.h" #include "assets/frappe_snowland_data.h" #include "assets/boo_frames.h" @@ -103,16 +104,40 @@ FrappeSnowland::FrappeSnowland() { Props.Skybox.FloorTopLeft = {0, 99, 164}; } +void FrappeSnowland::Load() { + Course::Load(); + + parse_course_displaylists((TrackSectionsI*)LOAD_ASSET_RAW(d_course_frappe_snowland_addr)); + func_80295C6C(); + D_8015F8E4 = -50.0f; +} + void FrappeSnowland::LoadTextures() { dma_textures(gTextureFrappeSnowlandTreeLeft, 0x00000454U, 0x00000800U); dma_textures(gTextureFrappeSnowlandTreeRight, 0x00000432U, 0x00000800U); } void FrappeSnowland::SpawnActors() { + gWorldInstance.AddActor(new AFinishline()); + 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)); } +void FrappeSnowland::SpawnVehicles() { + if (gModeSelection == VERSUS) { + Vec3f pos = {0, 0, 0}; + + gWorldInstance.AddBombKart(pos, &D_80164550[0][50], 50, 3, 0.8333333f); + gWorldInstance.AddBombKart(pos, &D_80164550[0][100], 100, 1, 0.8333333f); + gWorldInstance.AddBombKart(pos, &D_80164550[0][150], 150, 3, 0.8333333f); + gWorldInstance.AddBombKart(pos, &D_80164550[0][290], 290, 1, 0.8333333f); + gWorldInstance.AddBombKart(pos, &D_80164550[0][350], 350, 3, 0.8333333f); + gWorldInstance.AddBombKart(pos, &D_80164550[0][0], 0, 0, 0.8333333f); + gWorldInstance.AddBombKart(pos, &D_80164550[0][0], 0, 0, 0.8333333f); + } +} + void FrappeSnowland::InitClouds() { s32 var_s0; s32 var_s4; @@ -187,27 +212,12 @@ void FrappeSnowland::WhatDoesThisDo(Player* player, int8_t playerId) {} void FrappeSnowland::WhatDoesThisDoAI(Player* player, int8_t playerId) {} -void FrappeSnowland::SpawnBombKarts() { - gWorldInstance.AddObject(std::make_unique(140, 3, 0.8333333, 0, 0, 0, 0)); - gWorldInstance.AddObject(std::make_unique(165, 1, 0.8333333, 0, 0, 0, 0)); - gWorldInstance.AddObject(std::make_unique(330, 3, 0.8333333, 0, 0, 0, 0)); - gWorldInstance.AddObject(std::make_unique(550, 1, 0.8333333, 0, 0, 0, 0)); - gWorldInstance.AddObject(std::make_unique(595, 3, 0.8333333, 0, 0, 0, 0)); - gWorldInstance.AddObject(std::make_unique(0, 0, 0.8333333, 0, 0, 0, 0)); - gWorldInstance.AddObject(std::make_unique(0, 0, 0.8333333, 0, 0, 0, 0)); -} - // Positions the finishline on the minimap void FrappeSnowland::MinimapFinishlinePosition() { //! todo: Place hard-coded values here. draw_hud_2d_texture_8x8(this->Props.MinimapFinishlineX, this->Props.MinimapFinishlineY, (u8*) common_texture_minimap_finish_line); } -void FrappeSnowland::SetStaffGhost() { -} - -void FrappeSnowland::BeginPlay() { } - void FrappeSnowland::Render(struct UnkStruct_800DC5EC* arg0) { gSPTexture(gDisplayListHead++, 0xFFFF, 0xFFFF, 0, G_TX_RENDERTILE, G_ON); gSPSetGeometryMode(gDisplayListHead++, G_SHADING_SMOOTH); @@ -231,12 +241,6 @@ void FrappeSnowland::RenderCredits() { void FrappeSnowland::Collision() {} -void FrappeSnowland::GenerateCollision() { - parse_course_displaylists((TrackSectionsI*)LOAD_ASSET_RAW(d_course_frappe_snowland_addr)); - func_80295C6C(); - D_8015F8E4 = -50.0f; -} - void FrappeSnowland::Waypoints(Player* player, int8_t playerId) { s16 waypoint = gNearestWaypointByPlayerId[playerId]; @@ -250,6 +254,6 @@ void FrappeSnowland::Waypoints(Player* player, int8_t playerId) { } } -void FrappeSnowland::Water() {} +void FrappeSnowland::ScrollingTextures() {} void FrappeSnowland::Destroy() {} diff --git a/src/engine/courses/FrappeSnowland.h b/src/engine/courses/FrappeSnowland.h index f01943015..5c53dafae 100644 --- a/src/engine/courses/FrappeSnowland.h +++ b/src/engine/courses/FrappeSnowland.h @@ -24,8 +24,10 @@ public: // virtual void Load(const char* courseVtx, // course_texture* textures, const char* displaylists, size_t dlSize); + virtual void Load() override; virtual void LoadTextures() override; virtual void SpawnActors() override; + virtual void SpawnVehicles() override; virtual void InitClouds() override; virtual void UpdateClouds(s32 sp1C, Camera* camera) override; virtual void MinimapSettings() override; @@ -36,14 +38,10 @@ public: virtual void WhatDoesThisDo(Player* player, int8_t playerId) override; virtual void WhatDoesThisDoAI(Player* player, int8_t playerId) override; virtual void MinimapFinishlinePosition() override; - virtual void SetStaffGhost() override; - virtual void BeginPlay() override; virtual void Render(struct UnkStruct_800DC5EC*) override; virtual void RenderCredits() override; virtual void Collision() override; - virtual void SpawnBombKarts() override; - virtual void GenerateCollision() override; - virtual void Water() override; + virtual void ScrollingTextures() override; virtual void Waypoints(Player* player, int8_t playerId) override; virtual void Destroy() override; }; diff --git a/src/engine/courses/KalimariDesert.cpp b/src/engine/courses/KalimariDesert.cpp index c88e52f9a..df6b4237d 100644 --- a/src/engine/courses/KalimariDesert.cpp +++ b/src/engine/courses/KalimariDesert.cpp @@ -6,7 +6,8 @@ #include "KalimariDesert.h" #include "GameObject.h" #include "World.h" -#include "BombKart.h" +#include "engine/actors/AFinishline.h" +#include "engine/vehicles/OBombKart.h" #include "kalimari_desert_data.h" #include "engine/vehicles/Utils.h" @@ -103,6 +104,14 @@ KalimariDesert::KalimariDesert() { Props.Skybox.FloorTopLeft = {255, 192, 0}; } +void KalimariDesert::Load() { + Course::Load(); + + parse_course_displaylists((TrackSectionsI*)LOAD_ASSET_RAW(d_course_kalimari_desert_addr)); + func_80295C6C(); + D_8015F8E4 = gCourseMinY - 10.0f; +} + void KalimariDesert::LoadTextures() { dma_textures(gTextureCactus1Left, 0x0000033EU, 0x00000800U); dma_textures(gTextureCactus1Right, 0x000002FBU, 0x00000800U); @@ -117,6 +126,8 @@ void KalimariDesert::SpawnActors() { Vec3f velocity = { 0.0f, 0.0f, 0.0f }; Vec3s rotation = { 0, 0, 0 }; + gWorldInstance.AddActor(new AFinishline()); + spawn_foliage((struct ActorSpawnData*)LOAD_ASSET_RAW(d_course_kalimari_desert_cactus_spawn)); spawn_all_item_boxes((struct ActorSpawnData*)LOAD_ASSET_RAW(d_course_kalimari_desert_item_box_spawns)); @@ -127,24 +138,24 @@ void KalimariDesert::SpawnActors() { vec3f_set(position, -1680.0f, 2.0f, 35.0f); position[0] *= gCourseDirection; - rrxing = (struct RailroadCrossing*) &gActorList[add_actor_to_empty_slot(position, rotation, velocity, - ACTOR_RAILROAD_CROSSING)]; + rrxing = (struct RailroadCrossing*) GET_ACTOR(add_actor_to_empty_slot(position, rotation, velocity, + ACTOR_RAILROAD_CROSSING)); rrxing->crossingTrigger = crossing2; vec3f_set(position, -1600.0f, 2.0f, 35.0f); position[0] *= gCourseDirection; - rrxing = (struct RailroadCrossing*) &gActorList[add_actor_to_empty_slot(position, rotation, velocity, - ACTOR_RAILROAD_CROSSING)]; + rrxing = (struct RailroadCrossing*) GET_ACTOR(add_actor_to_empty_slot(position, rotation, velocity, + ACTOR_RAILROAD_CROSSING)); rrxing->crossingTrigger = crossing2; vec3s_set(rotation, 0, -0x2000, 0); vec3f_set(position, -2459.0f, 2.0f, 2263.0f); position[0] *= gCourseDirection; - rrxing = (struct RailroadCrossing*) &gActorList[add_actor_to_empty_slot(position, rotation, velocity, - ACTOR_RAILROAD_CROSSING)]; + rrxing = (struct RailroadCrossing*) GET_ACTOR(add_actor_to_empty_slot(position, rotation, velocity, + ACTOR_RAILROAD_CROSSING)); rrxing->crossingTrigger = crossing1; vec3f_set(position, -2467.0f, 2.0f, 2375.0f); position[0] *= gCourseDirection; - rrxing = (struct RailroadCrossing*) &gActorList[add_actor_to_empty_slot(position, rotation, velocity, - ACTOR_RAILROAD_CROSSING)]; + rrxing = (struct RailroadCrossing*) GET_ACTOR(add_actor_to_empty_slot(position, rotation, velocity, + ACTOR_RAILROAD_CROSSING)); rrxing->crossingTrigger = crossing1; } @@ -181,24 +192,12 @@ void KalimariDesert::WhatDoesThisDo(Player* player, int8_t playerId) {} void KalimariDesert::WhatDoesThisDoAI(Player* player, int8_t playerId) {} -void KalimariDesert::SpawnBombKarts() { - gWorldInstance.AddObject(std::make_unique(140, 3, 0.8333333, 0, 0, 0, 0)); - gWorldInstance.AddObject(std::make_unique(165, 1, 0.8333333, 0, 0, 0, 0)); - gWorldInstance.AddObject(std::make_unique(330, 3, 0.8333333, 0, 0, 0, 0)); - gWorldInstance.AddObject(std::make_unique(550, 1, 0.8333333, 0, 0, 0, 0)); - gWorldInstance.AddObject(std::make_unique(595, 3, 0.8333333, 0, 0, 0, 0)); - gWorldInstance.AddObject(std::make_unique(0, 0, 0.8333333, 0, 0, 0, 0)); - gWorldInstance.AddObject(std::make_unique(0, 0, 0.8333333, 0, 0, 0, 0)); -} - // Positions the finishline on the minimap void KalimariDesert::MinimapFinishlinePosition() { //! todo: Place hard-coded values here. draw_hud_2d_texture_8x8(this->Props.MinimapFinishlineX, this->Props.MinimapFinishlineY, (u8*) common_texture_minimap_finish_line); } -void KalimariDesert::SetStaffGhost() {} - void KalimariDesert::SpawnVehicles() { generate_train_waypoints(); @@ -209,11 +208,22 @@ void KalimariDesert::SpawnVehicles() { for (size_t i = 0; i < numTrains; ++i) { uint32_t waypoint = CalculateWaypointDistribution(i, numTrains, gVehicle2DWaypointLength, centerWaypoint); - gWorldInstance.AddTrain(5, 5.0f, waypoint); + gWorldInstance.AddTrain(5, 2.5f, waypoint); + } + + if (gModeSelection == VERSUS) { + Vec3f pos = {0, 0, 0}; + + gWorldInstance.AddBombKart(pos, &D_80164550[0][50], 50, 3, 0.8333333f); + gWorldInstance.AddBombKart(pos, &D_80164550[0][138], 138, 1, 0.8333333f); + gWorldInstance.AddBombKart(pos, &D_80164550[0][280], 280, 3, 0.8333333f); + gWorldInstance.AddBombKart(pos, &D_80164550[0][404], 404, 1, 0.8333333f); + gWorldInstance.AddBombKart(pos, &D_80164550[0][510], 510, 3, 0.8333333f); + gWorldInstance.AddBombKart(pos, &D_80164550[0][0], 0, 0, 0.8333333f); + gWorldInstance.AddBombKart(pos, &D_80164550[0][0], 0, 0, 0.8333333f); } } -void KalimariDesert::BeginPlay() { } void KalimariDesert::Render(struct UnkStruct_800DC5EC* arg0) { func_802B5D64(D_800DC610, D_802B87D4, 0, 1); @@ -253,10 +263,4 @@ void KalimariDesert::RenderCredits() { void KalimariDesert::Collision() {} -void KalimariDesert::GenerateCollision() { - parse_course_displaylists((TrackSectionsI*)LOAD_ASSET_RAW(d_course_kalimari_desert_addr)); - func_80295C6C(); - D_8015F8E4 = gCourseMinY - 10.0f; -} - void KalimariDesert::Destroy() { } diff --git a/src/engine/courses/KalimariDesert.h b/src/engine/courses/KalimariDesert.h index 337be914e..8c2d9a4d8 100644 --- a/src/engine/courses/KalimariDesert.h +++ b/src/engine/courses/KalimariDesert.h @@ -24,6 +24,7 @@ public: // virtual void Load(const char* courseVtx, // course_texture* textures, const char* displaylists, size_t dlSize); + virtual void Load() override; virtual void LoadTextures() override; virtual void SpawnActors() override; virtual void MinimapSettings() override; @@ -32,13 +33,9 @@ public: virtual void WhatDoesThisDo(Player* player, int8_t playerId) override; virtual void WhatDoesThisDoAI(Player* player, int8_t playerId) override; virtual void MinimapFinishlinePosition() override; - virtual void SetStaffGhost() override; - virtual void BeginPlay() override; virtual void Render(struct UnkStruct_800DC5EC*) override; virtual void RenderCredits() override; virtual void SpawnVehicles() override; virtual void Collision() override; - virtual void SpawnBombKarts() override; - virtual void GenerateCollision() override; virtual void Destroy() override; }; diff --git a/src/engine/courses/KoopaTroopaBeach.cpp b/src/engine/courses/KoopaTroopaBeach.cpp index fc0419984..66bf99005 100644 --- a/src/engine/courses/KoopaTroopaBeach.cpp +++ b/src/engine/courses/KoopaTroopaBeach.cpp @@ -6,7 +6,8 @@ #include "KoopaTroopaBeach.h" #include "GameObject.h" #include "World.h" -#include "BombKart.h" +#include "engine/actors/AFinishline.h" +#include "engine/vehicles/OBombKart.h" #include "assets/koopa_troopa_beach_data.h" extern "C" { @@ -103,15 +104,42 @@ KoopaTroopaBeach::KoopaTroopaBeach() { Props.Skybox.FloorTopLeft = {48, 152, 120}; } +void KoopaTroopaBeach::Load() { + Course::Load(); + + parse_course_displaylists((TrackSectionsI*)LOAD_ASSET_RAW(d_course_koopa_troopa_beach_addr)); + func_80295C6C(); + find_vtx_and_set_colours(segmented_gfx_to_virtual((void*)0x0700ADE0), -0x6A, 255, 255, 255); + find_vtx_and_set_colours(segmented_gfx_to_virtual((void*)0x0700A540), -0x6A, 255, 255, 255); + find_vtx_and_set_colours(segmented_gfx_to_virtual((void*)0x07009E70), -0x6A, 255, 255, 255); + find_vtx_and_set_colours(segmented_gfx_to_virtual((void*)0x07000358), -0x6A, 255, 255, 255); +} + void KoopaTroopaBeach::LoadTextures() { } void KoopaTroopaBeach::SpawnActors() { + gWorldInstance.AddActor(new AFinishline()); + 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)); } +void KoopaTroopaBeach::SpawnVehicles() { + if (gModeSelection == VERSUS) { + Vec3f pos = {0, 0, 0}; + + gWorldInstance.AddBombKart(pos, &D_80164550[0][60], 60, 1, 0.8333333f); + gWorldInstance.AddBombKart(pos, &D_80164550[0][120], 120, 1, 0.8333333f); + gWorldInstance.AddBombKart(pos, &D_80164550[0][200], 200, 3, 0.8333333f); + gWorldInstance.AddBombKart(pos, &D_80164550[0][280], 280, 1, 0.8333333f); + gWorldInstance.AddBombKart(pos, &D_80164550[0][435], 435, 3, 0.8333333f); + gWorldInstance.AddBombKart(pos, &D_80164550[0][0], 0, 0, 0.8333333f); + gWorldInstance.AddBombKart(pos, &D_80164550[0][0], 0, 0, 0.8333333f); + } +} + // Likely sets minimap boundaries void KoopaTroopaBeach::MinimapSettings() { D_8018D220 = reinterpret_cast(dma_textures(gTextureExhaust3, 0x3C8U, 0x1000)); @@ -180,27 +208,12 @@ void KoopaTroopaBeach::WhatDoesThisDo(Player* player, int8_t playerId) {} void KoopaTroopaBeach::WhatDoesThisDoAI(Player* player, int8_t playerId) {} -void KoopaTroopaBeach::SpawnBombKarts() { - gWorldInstance.AddObject(std::make_unique(140, 3, 0.8333333, 0, 0, 0, 0)); - gWorldInstance.AddObject(std::make_unique(165, 1, 0.8333333, 0, 0, 0, 0)); - gWorldInstance.AddObject(std::make_unique(330, 3, 0.8333333, 0, 0, 0, 0)); - gWorldInstance.AddObject(std::make_unique(550, 1, 0.8333333, 0, 0, 0, 0)); - gWorldInstance.AddObject(std::make_unique(595, 3, 0.8333333, 0, 0, 0, 0)); - gWorldInstance.AddObject(std::make_unique(0, 0, 0.8333333, 0, 0, 0, 0)); - gWorldInstance.AddObject(std::make_unique(0, 0, 0.8333333, 0, 0, 0, 0)); -} - // Positions the finishline on the minimap void KoopaTroopaBeach::MinimapFinishlinePosition() { //! todo: Place hard-coded values here. draw_hud_2d_texture_8x8(this->Props.MinimapFinishlineX, this->Props.MinimapFinishlineY, (u8*) common_texture_minimap_finish_line); } -void KoopaTroopaBeach::SetStaffGhost() { -} - -void KoopaTroopaBeach::BeginPlay() { } - void KoopaTroopaBeach::Render(struct UnkStruct_800DC5EC* arg0) { gDPPipeSync(gDisplayListHead++); gSPTexture(gDisplayListHead++, 0xFFFF, 0xFFFF, 0, G_TX_RENDERTILE, G_ON); @@ -237,16 +250,7 @@ void KoopaTroopaBeach::SomeCollisionThing(Player *player, Vec3f arg1, Vec3f arg2 func_8003E37C(player, arg1, arg2, arg3, arg4, arg5, arg6, arg7); } -void KoopaTroopaBeach::GenerateCollision() { - parse_course_displaylists((TrackSectionsI*)LOAD_ASSET_RAW(d_course_koopa_troopa_beach_addr)); - func_80295C6C(); - find_vtx_and_set_colours(segmented_gfx_to_virtual(reinterpret_cast(0x0700ADE0)), -0x6A, 255, 255, 255); - find_vtx_and_set_colours(segmented_gfx_to_virtual(reinterpret_cast(0x0700A540)), -0x6A, 255, 255, 255); - find_vtx_and_set_colours(segmented_gfx_to_virtual(reinterpret_cast(0x07009E70)), -0x6A, 255, 255, 255); - find_vtx_and_set_colours(segmented_gfx_to_virtual((void*)0x07000358), -0x6A, 255, 255, 255); -} - -void KoopaTroopaBeach::Water() { +void KoopaTroopaBeach::ScrollingTextures() { // clang-format off if (D_8015F8E8 < 0.0f) { if (D_8015F8E4 < -20.0f) { D_8015F8E8 *= -1.0f; } @@ -281,4 +285,45 @@ void KoopaTroopaBeach::Water() { } +void KoopaTroopaBeach::DrawWater(struct UnkStruct_800DC5EC* screen, uint16_t pathCounter, uint16_t cameraRot, uint16_t playerDirection) { + Mat4 matrix; + Vec3f vector; + + gDPPipeSync(gDisplayListHead++); + gSPTexture(gDisplayListHead++, 0xFFFF, 0xFFFF, 0, G_TX_RENDERTILE, G_ON); + gSPClearGeometryMode(gDisplayListHead++, G_LIGHTING); + gDPSetRenderMode(gDisplayListHead++, G_RM_AA_ZB_XLU_INTER, G_RM_NOOP2); + gDPSetBlendMask(gDisplayListHead++, 0xFF); + gDPSetCombineMode(gDisplayListHead++, G_CC_MODULATEIA, G_CC_MODULATEIA); + + switch (pathCounter) { + case 22: + case 23: + case 29: + case 30: + case 31: + case 37: + gSPClearGeometryMode(gDisplayListHead++, G_CULL_BACK); + // d_course_koopa_troopa_beach_packed_dl_9E70 + gSPDisplayList(gDisplayListHead++, segmented_gfx_to_virtual((void*)0x07009E70)); + gSPSetGeometryMode(gDisplayListHead++, G_CULL_BACK); + break; + } + vector[0] = 0.0f; + vector[1] = D_8015F8E4; + vector[2] = 0.0f; + mtxf_translate(matrix, vector); + render_set_position(matrix, 0); + + gDPSetRenderMode(gDisplayListHead++, G_RM_AA_ZB_XLU_INTER, G_RM_NOOP2); + gDPSetBlendMask(gDisplayListHead++, 0xFF); + gDPSetCombineMode(gDisplayListHead++, G_CC_MODULATEIA, G_CC_MODULATEIA); + gSPClearGeometryMode(gDisplayListHead++, G_CULL_BACK); + render_course_segments((const char**)koopa_troopa_beach_dls2, screen); + gSPTexture(gDisplayListHead++, 0xFFFF, 0xFFFF, 1, 1, G_OFF); + gSPSetGeometryMode(gDisplayListHead++, G_CULL_BACK); + gDPSetAlphaCompare(gDisplayListHead++, G_AC_NONE); + gDPPipeSync(gDisplayListHead++); +} + void KoopaTroopaBeach::Destroy() {} diff --git a/src/engine/courses/KoopaTroopaBeach.h b/src/engine/courses/KoopaTroopaBeach.h index b930bbd95..4dc51313e 100644 --- a/src/engine/courses/KoopaTroopaBeach.h +++ b/src/engine/courses/KoopaTroopaBeach.h @@ -24,8 +24,10 @@ public: // virtual void Load(const char* courseVtx, // course_texture* textures, const char* displaylists, size_t dlSize); + virtual void Load() override; virtual void LoadTextures() override; virtual void SpawnActors() override; + virtual void SpawnVehicles() override; virtual void MinimapSettings() override; virtual void InitCourseObjects() override; virtual void UpdateCourseObjects() override; @@ -34,14 +36,11 @@ public: virtual void WhatDoesThisDo(Player* player, int8_t playerId) override; virtual void WhatDoesThisDoAI(Player* player, int8_t playerId) override; virtual void MinimapFinishlinePosition() override; - virtual void SetStaffGhost() override; - virtual void BeginPlay() override; virtual void Render(struct UnkStruct_800DC5EC*) override; virtual void RenderCredits() override; virtual void Collision() override; virtual void SomeCollisionThing(Player *player, Vec3f arg1, Vec3f arg2, Vec3f arg3, f32* arg4, f32* arg5, f32* arg6, f32* arg7) override; - virtual void SpawnBombKarts() override; - virtual void GenerateCollision() override; - virtual void Water() override; + virtual void ScrollingTextures() override; + virtual void DrawWater(struct UnkStruct_800DC5EC* screen, uint16_t pathCounter, uint16_t cameraRot, uint16_t playerDirection) override; virtual void Destroy() override; }; diff --git a/src/engine/courses/LuigiRaceway.cpp b/src/engine/courses/LuigiRaceway.cpp index 2f1ff2751..f9a9de13a 100644 --- a/src/engine/courses/LuigiRaceway.cpp +++ b/src/engine/courses/LuigiRaceway.cpp @@ -6,8 +6,9 @@ #include "LuigiRaceway.h" #include "GameObject.h" #include "World.h" -#include "BombKart.h" +#include "engine/vehicles/OBombKart.h" #include "assets/luigi_raceway_data.h" +#include "engine/actors/AFinishline.h" extern "C" { #include "main.h" @@ -30,6 +31,8 @@ extern "C" { #include "collision.h" #include "code_8003DC40.h" #include "memory.h" + #include "courses/staff_ghost_data.h" + #include "framebuffer_effects.h" extern const char *luigi_raceway_dls[]; extern s16 currentScreenSection; } @@ -103,16 +106,39 @@ LuigiRaceway::LuigiRaceway() { Props.Skybox.FloorTopLeft = {216, 232, 248}; } +void LuigiRaceway::Load() { + Course::Load(); + + parse_course_displaylists((TrackSectionsI*)LOAD_ASSET_RAW(d_course_luigi_raceway_addr)); + func_80295C6C(); + D_8015F8E4 = gCourseMinY - 10.0f; +} + void LuigiRaceway::LoadTextures() { dma_textures(gTextureTrees5Left, 0x000003E8U, 0x00000800U); dma_textures(gTextureTrees5Right, 0x000003E8U, 0x00000800U); } 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)); } +void LuigiRaceway::SpawnVehicles() { + if (gModeSelection == VERSUS) { + Vec3f pos = {0, 0, 0}; + + gWorldInstance.AddBombKart(pos, &D_80164550[0][50], 50, 1, 0.8333333f); + gWorldInstance.AddBombKart(pos, &D_80164550[0][200], 200, 3, 0.8333333f); + gWorldInstance.AddBombKart(pos, &D_80164550[0][305], 305, 1, 0.8333333f); + gWorldInstance.AddBombKart(pos, &D_80164550[0][440], 440, 3, 0.8333333f); + gWorldInstance.AddBombKart(pos, &D_80164550[0][515], 515, 3, 0.8333333f); + gWorldInstance.AddBombKart(pos, &D_80164550[0][0], 0, 0, 0.8333333f); + gWorldInstance.AddBombKart(pos, &D_80164550[0][0], 0, 0, 0.8333333f); + } +} + // Likely sets minimap boundaries void LuigiRaceway::MinimapSettings() { D_8018D220 = reinterpret_cast(dma_textures(gTextureExhaust2, 0x4F4U, 0xC00)); @@ -187,16 +213,6 @@ void LuigiRaceway::WhatDoesThisDoAI(Player* player, int8_t playerId) { } } -void LuigiRaceway::SpawnBombKarts() { - gWorldInstance.AddObject(std::make_unique(40, 3, 0.8333333, 0, 0, 0, 0)); - gWorldInstance.AddObject(std::make_unique(100, 3, 0.8333333, 0, 0, 0, 0)); - gWorldInstance.AddObject(std::make_unique(265, 3, 0.8333333, 0, 0, 0, 0)); - gWorldInstance.AddObject(std::make_unique(285, 1, 0.8333333, 0, 0, 0, 0)); - gWorldInstance.AddObject(std::make_unique(420, 1, 0.8333333, 0, 0, 0, 0)); - gWorldInstance.AddObject(std::make_unique(0, 0, 0.8333333, 0, 0, 0, 0)); - gWorldInstance.AddObject(std::make_unique(0, 0, 0.8333333, 0, 0, 0, 0)); -} - // Positions the finishline on the minimap void LuigiRaceway::MinimapFinishlinePosition() { //! todo: Place hard-coded values here. @@ -216,8 +232,6 @@ void LuigiRaceway::SetStaffGhost() { D_80162DE4 = 1; } -void LuigiRaceway::BeginPlay() {} - void LuigiRaceway::Render(struct UnkStruct_800DC5EC* arg0) { UNUSED s32 pad; u16 sp22 = (u16) arg0->pathCounter; @@ -264,9 +278,8 @@ void LuigiRaceway::Render(struct UnkStruct_800DC5EC* arg0) { currentScreenSection = 0; } - u16* fb = (u16*) gSegmentTable[5] + 0xF800; - - // FB_WriteFramebufferSliceToCPU(gDisplayListHead, fb, true); + uintptr_t fb = (uintptr_t) gSegmentTable[5] + 0xF800; + FB_WriteFramebufferSliceToCPU(gDisplayListHead, (void*)fb, true); // FB_DrawFromFramebuffer(gDisplayListHead, 0, fb, true); // FB_CopyToFramebuffer(gDisplayListHead, 0, fb, false, NULL); /** @@ -330,10 +343,4 @@ void LuigiRaceway::SomeCollisionThing(Player *player, Vec3f arg1, Vec3f arg2, Ve func_8003E9EC(player, arg1, arg2, arg3, arg4, arg5, arg6, arg7); } -void LuigiRaceway::GenerateCollision() { - parse_course_displaylists((TrackSectionsI*)LOAD_ASSET_RAW(d_course_luigi_raceway_addr)); - func_80295C6C(); - D_8015F8E4 = gCourseMinY - 10.0f; -} - void LuigiRaceway::Destroy() { } diff --git a/src/engine/courses/LuigiRaceway.h b/src/engine/courses/LuigiRaceway.h index 0f48c40ab..eb32e6c78 100644 --- a/src/engine/courses/LuigiRaceway.h +++ b/src/engine/courses/LuigiRaceway.h @@ -24,8 +24,10 @@ public: // virtual void Load(const char* courseVtx, // course_texture* textures, const char* displaylists, size_t dlSize); + virtual void Load() override; virtual void LoadTextures() override; virtual void SpawnActors() override; + virtual void SpawnVehicles() override; virtual void MinimapSettings() override; virtual void InitCourseObjects() override; virtual void UpdateCourseObjects() override; @@ -35,12 +37,9 @@ public: virtual void WhatDoesThisDoAI(Player* player, int8_t playerId) override; virtual void MinimapFinishlinePosition() override; virtual void SetStaffGhost() override; - virtual void BeginPlay() override; virtual void Render(struct UnkStruct_800DC5EC*) override; virtual void RenderCredits() override; virtual void Collision() override; virtual void SomeCollisionThing(Player *player, Vec3f arg1, Vec3f arg2, Vec3f arg3, f32* arg4, f32* arg5, f32* arg6, f32* arg7) override; - virtual void SpawnBombKarts() override; - virtual void GenerateCollision() override; virtual void Destroy() override; }; diff --git a/src/engine/courses/MarioRaceway.cpp b/src/engine/courses/MarioRaceway.cpp index 2900ad36e..f93b76762 100644 --- a/src/engine/courses/MarioRaceway.cpp +++ b/src/engine/courses/MarioRaceway.cpp @@ -6,7 +6,8 @@ #include "MarioRaceway.h" #include "GameObject.h" #include "World.h" -#include "BombKart.h" +#include "engine/actors/AFinishline.h" +#include "engine/vehicles/OBombKart.h" extern "C" { #include "main.h" @@ -29,6 +30,7 @@ extern "C" { #include "mario_raceway_data.h" #include "collision.h" #include "memory.h" + #include "courses/staff_ghost_data.h" extern const char *mario_raceway_dls[]; } @@ -102,6 +104,23 @@ MarioRaceway::MarioRaceway() { Props.Skybox.FloorTopLeft = {0, 0, 0}; } +void MarioRaceway::Load() { + Course::Load(); + + generate_collision_mesh_with_defaults(segmented_gfx_to_virtual(reinterpret_cast(0x07001140))); + if (gScreenModeSelection == SCREEN_MODE_1P) { + // d_course_mario_raceway_packed_dl_8E8 + generate_collision_mesh_with_defaults(segmented_gfx_to_virtual(reinterpret_cast(0x070008E8))); + } else { + // d_course_mario_raceway_packed_dl_2D68 + generate_collision_mesh_with_defaults(segmented_gfx_to_virtual(reinterpret_cast(0x07002D68))); + } + + parse_course_displaylists((TrackSectionsI*)LOAD_ASSET_RAW(d_course_mario_raceway_addr)); + func_80295C6C(); + D_8015F8E4 = gCourseMinY - 10.0f; +} + void MarioRaceway::LoadTextures() { dma_textures(gTextureTrees1, 0x0000035BU, 0x00000800U); D_802BA058 = dma_textures(gTexturePiranhaPlant1, 0x000003E8U, 0x00000800U); @@ -120,6 +139,9 @@ void MarioRaceway::SpawnActors() { Vec3f position; Vec3f velocity = { 0.0f, 0.0f, 0.0f }; Vec3s rotation = { 0, 0, 0 }; + + gWorldInstance.AddActor(new AFinishline()); + spawn_foliage((struct ActorSpawnData*)LOAD_ASSET_RAW(d_course_mario_raceway_tree_spawns)); spawn_piranha_plants((struct ActorSpawnData*)LOAD_ASSET_RAW(d_course_mario_raceway_piranha_plant_spawns)); spawn_all_item_boxes((struct ActorSpawnData*)LOAD_ASSET_RAW(d_course_mario_raceway_item_box_spawns)); @@ -128,8 +150,21 @@ void MarioRaceway::SpawnActors() { add_actor_to_empty_slot(position, rotation, velocity, ACTOR_MARIO_SIGN); vec3f_set(position, 2520.0f, 0.0f, 1240.0f); position[0] *= gCourseDirection; - actor = &gActorList[add_actor_to_empty_slot(position, rotation, velocity, ACTOR_MARIO_SIGN)]; - actor->flags |= 0x4000; + add_actor_to_empty_slot(position, rotation, velocity, ACTOR_MARIO_SIGN); +} + +void MarioRaceway::SpawnVehicles() { + if (gModeSelection == VERSUS) { + Vec3f pos = {0, 0, 0}; + + gWorldInstance.AddBombKart(pos, &D_80164550[0][40], 40, 3, 0.8333333f); + gWorldInstance.AddBombKart(pos, &D_80164550[0][100], 100, 3, 0.8333333f); + gWorldInstance.AddBombKart(pos, &D_80164550[0][265], 265, 3, 0.8333333f); + gWorldInstance.AddBombKart(pos, &D_80164550[0][285], 285, 1, 0.8333333f); + gWorldInstance.AddBombKart(pos, &D_80164550[0][420], 420, 1, 0.8333333f); + gWorldInstance.AddBombKart(pos, &D_80164550[0][0], 0, 0, 0.8333333f); + gWorldInstance.AddBombKart(pos, &D_80164550[0][0], 0, 0, 0.8333333f); + } } // Likely sets minimap boundaries @@ -192,16 +227,6 @@ void MarioRaceway::WhatDoesThisDoAI(Player* player, int8_t playerId) { } } -void MarioRaceway::SpawnBombKarts() { - gWorldInstance.AddObject(std::make_unique(40, 3, 0.8333333, 0, 0, 0, 0)); - gWorldInstance.AddObject(std::make_unique(100, 3, 0.8333333, 0, 0, 0, 0)); - gWorldInstance.AddObject(std::make_unique(265, 3, 0.8333333, 0, 0, 0, 0)); - gWorldInstance.AddObject(std::make_unique(285, 1, 0.8333333, 0, 0, 0, 0)); - gWorldInstance.AddObject(std::make_unique(420, 1, 0.8333333, 0, 0, 0, 0)); - gWorldInstance.AddObject(std::make_unique(0, 0, 0.8333333, 0, 0, 0, 0)); - gWorldInstance.AddObject(std::make_unique(0, 0, 0.8333333, 0, 0, 0, 0)); -} - // Positions the finishline on the minimap void MarioRaceway::MinimapFinishlinePosition() { //! todo: Place hard-coded values here. @@ -221,7 +246,6 @@ void MarioRaceway::SetStaffGhost() { D_80162DE4 = 0; } -void MarioRaceway::BeginPlay() { } void MarioRaceway::Render(struct UnkStruct_800DC5EC* arg0) { u16 sp22 = arg0->pathCounter; u16 temp_t0 = arg0->playerDirection; @@ -333,19 +357,9 @@ void MarioRaceway::RenderCredits() { void MarioRaceway::Collision() {} -void MarioRaceway::GenerateCollision() { - generate_collision_mesh_with_defaults(segmented_gfx_to_virtual(reinterpret_cast(0x07001140))); - if (gScreenModeSelection == SCREEN_MODE_1P) { - // d_course_mario_raceway_packed_dl_8E8 - generate_collision_mesh_with_defaults(segmented_gfx_to_virtual(reinterpret_cast(0x070008E8))); - } else { - // d_course_mario_raceway_packed_dl_2D68 - generate_collision_mesh_with_defaults(segmented_gfx_to_virtual(reinterpret_cast(0x07002D68))); - } - - parse_course_displaylists((TrackSectionsI*)LOAD_ASSET_RAW(d_course_mario_raceway_addr)); - func_80295C6C(); - D_8015F8E4 = gCourseMinY - 10.0f; +void MarioRaceway::CreditsSpawnActors() { + dma_textures(gTextureTrees1, 0x35B, 0x800); + spawn_foliage((struct ActorSpawnData*)LOAD_ASSET_RAW(d_course_mario_raceway_tree_spawns)); } void MarioRaceway::Destroy() { } diff --git a/src/engine/courses/MarioRaceway.h b/src/engine/courses/MarioRaceway.h index 6857c19a2..ef0fb904b 100644 --- a/src/engine/courses/MarioRaceway.h +++ b/src/engine/courses/MarioRaceway.h @@ -24,8 +24,10 @@ public: // virtual void Load(const char* courseVtx, // course_texture* textures, const char* displaylists, size_t dlSize); + virtual void Load() override; virtual void LoadTextures() override; virtual void SpawnActors() override; + virtual void SpawnVehicles() override; virtual void MinimapSettings() override; virtual void InitCourseObjects() override; virtual void SomeSounds() override; @@ -33,11 +35,9 @@ public: virtual void WhatDoesThisDoAI(Player* player, int8_t playerId) override; virtual void MinimapFinishlinePosition() override; virtual void SetStaffGhost() override; - virtual void BeginPlay() override; virtual void Render(struct UnkStruct_800DC5EC*) override; virtual void RenderCredits() override; virtual void Collision() override; - virtual void SpawnBombKarts() override; - virtual void GenerateCollision() override; + virtual void CreditsSpawnActors() override; virtual void Destroy() override; }; diff --git a/src/engine/courses/MooMooFarm.cpp b/src/engine/courses/MooMooFarm.cpp index f755dde39..6517eab82 100644 --- a/src/engine/courses/MooMooFarm.cpp +++ b/src/engine/courses/MooMooFarm.cpp @@ -6,7 +6,8 @@ #include "MooMooFarm.h" #include "GameObject.h" #include "World.h" -#include "BombKart.h" +#include "engine/actors/AFinishline.h" +#include "engine/vehicles/OBombKart.h" #include "assets/moo_moo_farm_data.h" extern "C" { @@ -103,6 +104,14 @@ MooMooFarm::MooMooFarm() { Props.Skybox.FloorTopLeft = {255, 184, 99}; } +void MooMooFarm::Load() { + Course::Load(); + + parse_course_displaylists((TrackSectionsI*)LOAD_ASSET_RAW(d_course_moo_moo_farm_addr)); + func_80295C6C(); + D_8015F8E4 = gCourseMinY - 10.0f; +} + void MooMooFarm::LoadTextures() { dma_textures(gTextureTrees4Left, 0x000003E8U, 0x00000800U); dma_textures(gTextureTrees4Right, 0x000003E8U, 0x00000800U); @@ -119,12 +128,28 @@ void MooMooFarm::LoadTextures() { } void MooMooFarm::SpawnActors() { + gWorldInstance.AddActor(new AFinishline()); + if (gPlayerCountSelection1 != 4) { spawn_foliage((struct ActorSpawnData*)LOAD_ASSET_RAW(d_course_moo_moo_farm_tree_spawn)); } spawn_all_item_boxes((struct ActorSpawnData*)LOAD_ASSET_RAW(d_course_moo_moo_farm_item_box_spawns)); } +void MooMooFarm::SpawnVehicles() { + if (gModeSelection == VERSUS) { + Vec3f pos = {0, 0, 0}; + + gWorldInstance.AddBombKart(pos, &D_80164550[0][50], 50, 3, 0.8333333f); + gWorldInstance.AddBombKart(pos, &D_80164550[0][140], 140, 3, 0.8333333f); + gWorldInstance.AddBombKart(pos, &D_80164550[0][225], 225, 3, 0.8333333f); + gWorldInstance.AddBombKart(pos, &D_80164550[0][316], 316, 3, 0.8333333f); + gWorldInstance.AddBombKart(pos, &D_80164550[0][434], 434, 3, 0.8333333f); + gWorldInstance.AddBombKart(pos, &D_80164550[0][0], 0, 0, 0.8333333f); + gWorldInstance.AddBombKart(pos, &D_80164550[0][0], 0, 0, 0.8333333f); + } +} + // Likely sets minimap boundaries void MooMooFarm::MinimapSettings() { D_8018D220 = reinterpret_cast(dma_textures(gTextureExhaust0, 0x479, 0xC00)); @@ -237,26 +262,12 @@ void MooMooFarm::WhatDoesThisDoAI(Player* player, int8_t playerId) { } } -void MooMooFarm::SpawnBombKarts() { - gWorldInstance.AddObject(std::make_unique(40, 3, 0.8333333, 0, 0, 0, 0)); - gWorldInstance.AddObject(std::make_unique(100, 3, 0.8333333, 0, 0, 0, 0)); - gWorldInstance.AddObject(std::make_unique(265, 3, 0.8333333, 0, 0, 0, 0)); - gWorldInstance.AddObject(std::make_unique(285, 1, 0.8333333, 0, 0, 0, 0)); - gWorldInstance.AddObject(std::make_unique(420, 1, 0.8333333, 0, 0, 0, 0)); - gWorldInstance.AddObject(std::make_unique(0, 0, 0.8333333, 0, 0, 0, 0)); - gWorldInstance.AddObject(std::make_unique(0, 0, 0.8333333, 0, 0, 0, 0)); -} - // Positions the finishline on the minimap void MooMooFarm::MinimapFinishlinePosition() { //! todo: Place hard-coded values here. draw_hud_2d_texture_8x8(this->Props.MinimapFinishlineX, this->Props.MinimapFinishlineY, (u8*) common_texture_minimap_finish_line); } -void MooMooFarm::SetStaffGhost() {} - -void MooMooFarm::BeginPlay() {} - void MooMooFarm::Render(struct UnkStruct_800DC5EC* arg0) { s16 temp_s0 = arg0->pathCounter; s16 temp_s1 = arg0->playerDirection; @@ -336,10 +347,20 @@ void MooMooFarm::RenderCredits() { void MooMooFarm::Collision() {} -void MooMooFarm::GenerateCollision() { - parse_course_displaylists((TrackSectionsI*)LOAD_ASSET_RAW(d_course_moo_moo_farm_addr)); - func_80295C6C(); - D_8015F8E4 = gCourseMinY - 10.0f; +void MooMooFarm::CreditsSpawnActors() { + dma_textures(gTextureTrees4Left, 0x3E8, 0x800); + dma_textures(gTextureTrees4Right, 0x3E8, 0x800); + dma_textures(gTextureCow01Left, 0x400, 0x800); + dma_textures(gTextureCow01Right, 0x400, 0x800); + dma_textures(gTextureCow02Left, 0x400, 0x800); + dma_textures(gTextureCow02Right, 0x400, 0x800); + dma_textures(gTextureCow03Left, 0x400, 0x800); + dma_textures(gTextureCow03Right, 0x400, 0x800); + dma_textures(gTextureCow04Left, 0x400, 0x800); + dma_textures(gTextureCow04Right, 0x400, 0x800); + dma_textures(gTextureCow05Left, 0x400, 0x800); + dma_textures(gTextureCow05Right, 0x400, 0x800); + spawn_foliage((struct ActorSpawnData*) LOAD_ASSET_RAW(d_course_moo_moo_farm_tree_spawn)); } void MooMooFarm::Destroy() { } diff --git a/src/engine/courses/MooMooFarm.h b/src/engine/courses/MooMooFarm.h index 71eff8913..fb27ef725 100644 --- a/src/engine/courses/MooMooFarm.h +++ b/src/engine/courses/MooMooFarm.h @@ -24,8 +24,10 @@ public: // virtual void Load(const char* courseVtx, // course_texture* textures, const char* displaylists, size_t dlSize); + virtual void Load() override; virtual void LoadTextures() override; virtual void SpawnActors() override; + virtual void SpawnVehicles() override; virtual void MinimapSettings() override; virtual void InitCourseObjects() override; virtual void UpdateCourseObjects() override; @@ -34,12 +36,9 @@ public: virtual void WhatDoesThisDo(Player* player, int8_t playerId) override; virtual void WhatDoesThisDoAI(Player* player, int8_t playerId) override; virtual void MinimapFinishlinePosition() override; - virtual void SetStaffGhost() override; - virtual void BeginPlay() override; virtual void Render(struct UnkStruct_800DC5EC*) override; virtual void RenderCredits() override; virtual void Collision() override; - virtual void SpawnBombKarts() override; - virtual void GenerateCollision() override; + virtual void CreditsSpawnActors() override; virtual void Destroy() override; }; diff --git a/src/engine/courses/PodiumCeremony.cpp b/src/engine/courses/PodiumCeremony.cpp index 08da45829..9488b8b21 100644 --- a/src/engine/courses/PodiumCeremony.cpp +++ b/src/engine/courses/PodiumCeremony.cpp @@ -6,8 +6,9 @@ #include "PodiumCeremony.h" #include "GameObject.h" #include "World.h" -#include "BombKart.h" +#include "engine/vehicles/OBombKart.h" #include "assets/royal_raceway_data.h" +#include "assets/ceremony_data.h" extern "C" { #include "main.h" @@ -29,6 +30,7 @@ extern "C" { #include "actors.h" #include "collision.h" #include "memory.h" + #include "courses/staff_ghost_data.h" extern const char *royal_raceway_dls[]; } @@ -49,7 +51,7 @@ PodiumCeremony::PodiumCeremony() { Props.SomePtr = D_800DCAF4; Props.AISteeringSensitivity = 53; - Props.PathSizes = {0x3E8, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0}; + Props.PathSizes = {500, 500, 500, 500, 1, 0, 0, 0, 0, 0, 0}; Props.D_0D009418[0] = 4.1666665f; Props.D_0D009418[1] = 5.5833334f; @@ -71,12 +73,12 @@ PodiumCeremony::PodiumCeremony() { Props.D_0D009808[2] = 5.75f; Props.D_0D009808[3] = 6.3333334f; - Props.PathTable[0] = (TrackWaypoint*)LOAD_ASSET_RAW(d_course_royal_raceway_unknown_waypoints); - Props.PathTable[1] = NULL; - Props.PathTable[2] = NULL; - Props.PathTable[3] = NULL; + Props.PathTable[0] = (TrackWaypoint*)LOAD_ASSET_RAW(podium_ceremony_path); + Props.PathTable[1] = (TrackWaypoint*)LOAD_ASSET_RAW(podium_ceremony_path_2); + Props.PathTable[2] = (TrackWaypoint*)LOAD_ASSET_RAW(podium_ceremony_path_3); + Props.PathTable[3] = (TrackWaypoint*)LOAD_ASSET_RAW(podium_ceremony_path_4); - Props.PathTable2[0] = (TrackWaypoint*)LOAD_ASSET_RAW(d_course_royal_raceway_track_waypoints); + Props.PathTable2[0] = NULL; Props.PathTable2[1] = NULL; Props.PathTable2[2] = NULL; Props.PathTable2[3] = NULL; @@ -96,6 +98,14 @@ PodiumCeremony::PodiumCeremony() { Props.Skybox.FloorTopLeft = {255, 224, 240}; } +void PodiumCeremony::Load() { + Course::Load(); + + parse_course_displaylists((TrackSectionsI*)LOAD_ASSET_RAW(d_course_royal_raceway_addr)); + func_80295C6C(); + D_8015F8E4 = -60.0f; +} + void PodiumCeremony::LoadTextures() { } @@ -105,6 +115,18 @@ void PodiumCeremony::SpawnActors() { spawn_piranha_plants((struct ActorSpawnData*)LOAD_ASSET_RAW(d_course_royal_raceway_piranha_plant_spawn)); } +void PodiumCeremony::SpawnVehicles() { + Vec3f pos = {0, 0, 0}; + + gWorldInstance.AddBombKart(pos, &D_80164550[3][3], 3, 5, 1.25f); + gWorldInstance.AddBombKart(pos, &D_80164550[3][40], 40, 0, 1.0f); + gWorldInstance.AddBombKart(pos, &D_80164550[3][60], 60, 0, 1.0f); + gWorldInstance.AddBombKart(pos, &D_80164550[3][80], 80, 0, 1.0f); + gWorldInstance.AddBombKart(pos, &D_80164550[3][100], 100, 0, 1.0f); + gWorldInstance.AddBombKart(pos, &D_80164550[3][120], 120, 0, 1.0f); + gWorldInstance.AddBombKart(pos, &D_80164550[3][140], 140, 0, 1.0f); +} + // Likely sets minimap boundaries void PodiumCeremony::MinimapSettings() { D_8018D220 = reinterpret_cast(dma_textures(gTextureExhaust4, 0x3F8, 0x1000)); @@ -163,36 +185,12 @@ void PodiumCeremony::WhatDoesThisDoAI(Player* player, int8_t playerId) { } } -void PodiumCeremony::SpawnBombKarts() { - gWorldInstance.AddObject(std::make_unique(40, 3, 0.8333333, 0, 0, 0, 0)); - gWorldInstance.AddObject(std::make_unique(100, 3, 0.8333333, 0, 0, 0, 0)); - gWorldInstance.AddObject(std::make_unique(265, 3, 0.8333333, 0, 0, 0, 0)); - gWorldInstance.AddObject(std::make_unique(285, 1, 0.8333333, 0, 0, 0, 0)); - gWorldInstance.AddObject(std::make_unique(420, 1, 0.8333333, 0, 0, 0, 0)); - gWorldInstance.AddObject(std::make_unique(0, 0, 0.8333333, 0, 0, 0, 0)); - gWorldInstance.AddObject(std::make_unique(0, 0, 0.8333333, 0, 0, 0, 0)); -} - // Positions the finishline on the minimap void PodiumCeremony::MinimapFinishlinePosition() { //! todo: Place hard-coded values here. draw_hud_2d_texture_8x8(this->Props.MinimapFinishlineX, this->Props.MinimapFinishlineY, (u8*) common_texture_minimap_finish_line); } -void PodiumCeremony::SetStaffGhost() { - u32 temp_v0 = func_800B4E24(0) & 0xfffff; - if (temp_v0 <= 16000) { - D_80162DD6 = 0; - D_80162DF4 = 0; - } else { - D_80162DD6 = 1; - D_80162DF4 = 1; - } - D_80162DC4 = d_royal_raceway_staff_ghost; - D_80162DE4 = 6; -} - -void PodiumCeremony::BeginPlay() { } void PodiumCeremony::Render(struct UnkStruct_800DC5EC* arg0) { gSPTexture(gDisplayListHead++, 0xFFFF, 0xFFFF, 0, G_TX_RENDERTILE, G_ON); gSPSetGeometryMode(gDisplayListHead++, G_SHADING_SMOOTH); @@ -228,10 +226,4 @@ void PodiumCeremony::RenderCredits() { void PodiumCeremony::Collision() {} -void PodiumCeremony::GenerateCollision() { - parse_course_displaylists((TrackSectionsI*)LOAD_ASSET_RAW(d_course_royal_raceway_addr)); - func_80295C6C(); - D_8015F8E4 = -60.0f; -} - void PodiumCeremony::Destroy() { } diff --git a/src/engine/courses/PodiumCeremony.h b/src/engine/courses/PodiumCeremony.h index c8f8b7c06..7f9de6b1d 100644 --- a/src/engine/courses/PodiumCeremony.h +++ b/src/engine/courses/PodiumCeremony.h @@ -24,8 +24,10 @@ public: // virtual void Load(const char* courseVtx, // course_texture* textures, const char* displaylists, size_t dlSize); + virtual void Load() override; virtual void LoadTextures() override; virtual void SpawnActors() override; + virtual void SpawnVehicles() override; //virtual void InitClouds() override; virtual void MinimapSettings() override; virtual void InitCourseObjects() override; @@ -33,12 +35,8 @@ public: virtual void WhatDoesThisDo(Player* player, int8_t playerId) override; virtual void WhatDoesThisDoAI(Player* player, int8_t playerId) override; virtual void MinimapFinishlinePosition() override; - virtual void SetStaffGhost() override; - virtual void BeginPlay() override; virtual void Render(struct UnkStruct_800DC5EC*) override; virtual void RenderCredits() override; virtual void Collision() override; - virtual void SpawnBombKarts() override; - virtual void GenerateCollision() override; virtual void Destroy() override; }; diff --git a/src/engine/courses/RainbowRoad.cpp b/src/engine/courses/RainbowRoad.cpp index 038a40541..4836611fb 100644 --- a/src/engine/courses/RainbowRoad.cpp +++ b/src/engine/courses/RainbowRoad.cpp @@ -6,7 +6,8 @@ #include "RainbowRoad.h" #include "GameObject.h" #include "World.h" -#include "BombKart.h" +#include "engine/actors/AFinishline.h" +#include "engine/vehicles/OBombKart.h" #include "assets/rainbow_road_data.h" extern "C" { @@ -100,13 +101,48 @@ RainbowRoad::RainbowRoad() { Props.Skybox.FloorTopLeft = {0, 0, 0}; } +void RainbowRoad::Load() { + Course::Load(); + + D_800DC5C8 = 1; + parse_course_displaylists((TrackSectionsI*)LOAD_ASSET_RAW(d_course_rainbow_road_addr)); + func_80295C6C(); + D_8015F8E4 = 0.0f; + // d_course_rainbow_road_packed_dl_2068 + find_vtx_and_set_colours(segmented_gfx_to_virtual((void*)0x07002068), -0x6A, 255, 255, 255); + // d_course_rainbow_road_packed_dl_1E18 + find_vtx_and_set_colours(segmented_gfx_to_virtual((void*)0x07001E18), -0x6A, 255, 255, 255); + // d_course_rainbow_road_packed_dl_1318 + find_vtx_and_set_colours(segmented_gfx_to_virtual((void*)0x07001318), 255, 255, 255, 0); + if (gGamestate != CREDITS_SEQUENCE) { + // d_course_rainbow_road_packed_dl_1FB8 + find_vtx_and_set_colours(segmented_gfx_to_virtual((void*)0x07001FB8), -0x6A, 255, 255, 255); + } +} + void RainbowRoad::LoadTextures() { } void RainbowRoad::SpawnActors() { + gWorldInstance.AddActor(new AFinishline()); + spawn_all_item_boxes((struct ActorSpawnData*)LOAD_ASSET_RAW(d_course_rainbow_road_item_box_spawns)); } +void RainbowRoad::SpawnVehicles() { + if (gModeSelection == VERSUS) { + Vec3f pos = {0, 0, 0}; + + gWorldInstance.AddBombKart(pos, &D_80164550[0][50], 50, 3, 0.8333333f); + gWorldInstance.AddBombKart(pos, &D_80164550[0][100], 100, 1, 0.8333333f); + gWorldInstance.AddBombKart(pos, &D_80164550[0][150], 150, 3, 0.8333333f); + gWorldInstance.AddBombKart(pos, &D_80164550[0][200], 200, 1, 0.8333333f); + gWorldInstance.AddBombKart(pos, &D_80164550[0][250], 250, 3, 0.8333333f); + gWorldInstance.AddBombKart(pos, &D_80164550[0][0], 0, 0, 0.8333333f); + gWorldInstance.AddBombKart(pos, &D_80164550[0][0], 0, 0, 0.8333333f); + } +} + void RainbowRoad::InitClouds() { init_stars(this->Props.Clouds); } @@ -157,25 +193,12 @@ void RainbowRoad::WhatDoesThisDo(Player* player, int8_t playerId) {} void RainbowRoad::WhatDoesThisDoAI(Player* player, int8_t playerId) {} -void RainbowRoad::SpawnBombKarts() { - gWorldInstance.AddObject(std::make_unique(40, 3, 0.8333333, 0, 0, 0, 0)); - gWorldInstance.AddObject(std::make_unique(100, 3, 0.8333333, 0, 0, 0, 0)); - gWorldInstance.AddObject(std::make_unique(265, 3, 0.8333333, 0, 0, 0, 0)); - gWorldInstance.AddObject(std::make_unique(285, 1, 0.8333333, 0, 0, 0, 0)); - gWorldInstance.AddObject(std::make_unique(420, 1, 0.8333333, 0, 0, 0, 0)); - gWorldInstance.AddObject(std::make_unique(0, 0, 0.8333333, 0, 0, 0, 0)); - gWorldInstance.AddObject(std::make_unique(0, 0, 0.8333333, 0, 0, 0, 0)); -} - // Positions the finishline on the minimap void RainbowRoad::MinimapFinishlinePosition() { //! todo: Place hard-coded values here. draw_hud_2d_texture_8x8(this->Props.MinimapFinishlineX, this->Props.MinimapFinishlineY, (u8*) common_texture_minimap_finish_line); } -void RainbowRoad::SetStaffGhost() {} - -void RainbowRoad::BeginPlay() {} void RainbowRoad::Render(struct UnkStruct_800DC5EC* arg0) { gSPTexture(gDisplayListHead++, 0xFFFF, 0xFFFF, 0, G_TX_RENDERTILE, G_ON); gSPSetGeometryMode(gDisplayListHead++, G_SHADING_SMOOTH); @@ -190,25 +213,30 @@ void RainbowRoad::RenderCredits() { void RainbowRoad::Collision() {} -void RainbowRoad::GenerateCollision() { - D_800DC5C8 = 1; - parse_course_displaylists((TrackSectionsI*)LOAD_ASSET_RAW(d_course_rainbow_road_addr)); - func_80295C6C(); - D_8015F8E4 = 0.0f; - // d_course_rainbow_road_packed_dl_2068 - find_vtx_and_set_colours(segmented_gfx_to_virtual((void*)0x07002068), -0x6A, 255, 255, 255); - // d_course_rainbow_road_packed_dl_1E18 - find_vtx_and_set_colours(segmented_gfx_to_virtual((void*)0x07001E18), -0x6A, 255, 255, 255); - // d_course_rainbow_road_packed_dl_1318 - find_vtx_and_set_colours(segmented_gfx_to_virtual((void*)0x07001318), 255, 255, 255, 0); - if (gGamestate != CREDITS_SEQUENCE) { - // d_course_rainbow_road_packed_dl_1FB8 - find_vtx_and_set_colours(segmented_gfx_to_virtual((void*)0x07001FB8), -0x6A, 255, 255, 255); - } -} - void RainbowRoad::Waypoints(Player* player, int8_t playerId) { player->nearestWaypointId = gCopyNearestWaypointByPlayerId[playerId]; } +void RainbowRoad::DrawWater(struct UnkStruct_800DC5EC* screen, uint16_t pathCounter, uint16_t cameraRot, uint16_t playerDirection) { + Mat4 matrix; + + gDPPipeSync(gDisplayListHead++); + mtxf_identity(matrix); + render_set_position(matrix, 0); + gSPClearGeometryMode(gDisplayListHead++, G_CULL_BACK); + render_course_segments(rainbow_road_dls, screen); + gSPSetGeometryMode(gDisplayListHead++, G_CULL_BACK); + gDPSetAlphaCompare(gDisplayListHead++, G_AC_NONE); + gDPPipeSync(gDisplayListHead++); +} + +void RainbowRoad::CreditsSpawnActors() { + // d_course_rainbow_road_packed_dl_2068 + find_vtx_and_set_colours(segmented_gfx_to_virtual((void*)0x07002068), -0x6A, 0xFF, 0xFF, 0xFF); + // d_course_rainbow_road_packed_dl_1E18 + find_vtx_and_set_colours(segmented_gfx_to_virtual((void*)0x07001E18), -0x6A, 0xFF, 0xFF, 0xFF); + // d_course_rainbow_road_packed_dl_1318 + find_vtx_and_set_colours(segmented_gfx_to_virtual((void*)0x07001318), -1, 0xFF, 0xFF, 0); +} + void RainbowRoad::Destroy() {} diff --git a/src/engine/courses/RainbowRoad.h b/src/engine/courses/RainbowRoad.h index 6c32adb51..5f6b0e5e7 100644 --- a/src/engine/courses/RainbowRoad.h +++ b/src/engine/courses/RainbowRoad.h @@ -24,8 +24,10 @@ public: // virtual void Load(const char* courseVtx, // course_texture* textures, const char* displaylists, size_t dlSize); + virtual void Load() override; virtual void LoadTextures() override; virtual void SpawnActors() override; + virtual void SpawnVehicles() override; virtual void InitClouds() override; virtual void UpdateClouds(s32, Camera*) override; virtual void MinimapSettings() override; @@ -36,13 +38,11 @@ public: virtual void WhatDoesThisDo(Player* player, int8_t playerId) override; virtual void WhatDoesThisDoAI(Player* player, int8_t playerId) override; virtual void MinimapFinishlinePosition() override; - virtual void SetStaffGhost() override; - virtual void BeginPlay() override; virtual void Render(struct UnkStruct_800DC5EC*) override; virtual void RenderCredits() override; virtual void Collision() override; - virtual void SpawnBombKarts() override; - virtual void GenerateCollision() override; virtual void Waypoints(Player* player, int8_t playerId) override; + virtual void DrawWater(struct UnkStruct_800DC5EC* screen, uint16_t pathCounter, uint16_t cameraRot, uint16_t playerDirection) override; + virtual void CreditsSpawnActors() override; virtual void Destroy() override; }; diff --git a/src/engine/courses/RoyalRaceway.cpp b/src/engine/courses/RoyalRaceway.cpp index e252d866f..ded9ec464 100644 --- a/src/engine/courses/RoyalRaceway.cpp +++ b/src/engine/courses/RoyalRaceway.cpp @@ -6,7 +6,8 @@ #include "RoyalRaceway.h" #include "GameObject.h" #include "World.h" -#include "BombKart.h" +#include "engine/actors/AFinishline.h" +#include "engine/vehicles/OBombKart.h" #include "assets/royal_raceway_data.h" extern "C" { @@ -29,6 +30,7 @@ extern "C" { #include "actors.h" #include "collision.h" #include "memory.h" + #include "courses/staff_ghost_data.h" extern const char *royal_raceway_dls[]; } @@ -100,6 +102,14 @@ RoyalRaceway::RoyalRaceway() { Props.Skybox.FloorTopLeft = {255, 224, 240}; } +void RoyalRaceway::Load() { + Course::Load(); + + parse_course_displaylists((TrackSectionsI*)LOAD_ASSET_RAW(d_course_royal_raceway_addr)); + func_80295C6C(); + D_8015F8E4 = -60.0f; +} + void RoyalRaceway::LoadTextures() { dma_textures(gTextureTrees3, 0x000003E8U, 0x00000800U); dma_textures(gTextureTrees7, 0x000003E8U, 0x00000800U); @@ -115,11 +125,27 @@ void RoyalRaceway::LoadTextures() { } void RoyalRaceway::SpawnActors() { + gWorldInstance.AddActor(new AFinishline()); + 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)); } +void RoyalRaceway::SpawnVehicles() { + if (gModeSelection == VERSUS) { + Vec3f pos = {0, 0, 0}; + + gWorldInstance.AddBombKart(pos, &D_80164550[0][50], 50, 3, 0.8333333f); + gWorldInstance.AddBombKart(pos, &D_80164550[0][100], 100, 3, 0.8333333f); + gWorldInstance.AddBombKart(pos, &D_80164550[0][296], 296, 3, 0.8333333f); + gWorldInstance.AddBombKart(pos, &D_80164550[0][400], 400, 1, 0.8333333f); + gWorldInstance.AddBombKart(pos, &D_80164550[0][746], 746, 3, 0.8333333f); + gWorldInstance.AddBombKart(pos, &D_80164550[0][0], 0, 0, 0.8333333f); + gWorldInstance.AddBombKart(pos, &D_80164550[0][0], 0, 0, 0.8333333f); + } +} + // Likely sets minimap boundaries void RoyalRaceway::MinimapSettings() { D_8018D220 = reinterpret_cast(dma_textures(gTextureExhaust4, 0x3F8, 0x1000)); @@ -178,16 +204,6 @@ void RoyalRaceway::WhatDoesThisDoAI(Player* player, int8_t playerId) { } } -void RoyalRaceway::SpawnBombKarts() { - gWorldInstance.AddObject(std::make_unique(40, 3, 0.8333333, 0, 0, 0, 0)); - gWorldInstance.AddObject(std::make_unique(100, 3, 0.8333333, 0, 0, 0, 0)); - gWorldInstance.AddObject(std::make_unique(265, 3, 0.8333333, 0, 0, 0, 0)); - gWorldInstance.AddObject(std::make_unique(285, 1, 0.8333333, 0, 0, 0, 0)); - gWorldInstance.AddObject(std::make_unique(420, 1, 0.8333333, 0, 0, 0, 0)); - gWorldInstance.AddObject(std::make_unique(0, 0, 0.8333333, 0, 0, 0, 0)); - gWorldInstance.AddObject(std::make_unique(0, 0, 0.8333333, 0, 0, 0, 0)); -} - // Positions the finishline on the minimap void RoyalRaceway::MinimapFinishlinePosition() { //! todo: Place hard-coded values here. @@ -207,7 +223,6 @@ void RoyalRaceway::SetStaffGhost() { D_80162DE4 = 6; } -void RoyalRaceway::BeginPlay() { } void RoyalRaceway::Render(struct UnkStruct_800DC5EC* arg0) { gSPTexture(gDisplayListHead++, 0xFFFF, 0xFFFF, 0, G_TX_RENDERTILE, G_ON); gSPSetGeometryMode(gDisplayListHead++, G_SHADING_SMOOTH); @@ -243,12 +258,6 @@ void RoyalRaceway::RenderCredits() { void RoyalRaceway::Collision() {} -void RoyalRaceway::GenerateCollision() { - parse_course_displaylists((TrackSectionsI*)LOAD_ASSET_RAW(d_course_royal_raceway_addr)); - func_80295C6C(); - D_8015F8E4 = -60.0f; -} - void RoyalRaceway::Waypoints(Player* player, int8_t playerId) { s16 waypoint = gNearestWaypointByPlayerId[playerId]; if ((waypoint >= 0x258) && (waypoint < 0x2A4)) { @@ -261,4 +270,15 @@ void RoyalRaceway::Waypoints(Player* player, int8_t playerId) { } } +void RoyalRaceway::ScrollingTextures() { + D_802B87BC -= 20; + if (D_802B87BC < 0) { + D_802B87BC = 0xFF; + } + // d_course_royal_raceway_packed_dl_A6A8 + find_and_set_tile_size((uintptr_t) segmented_gfx_to_virtual((void*)0x0700A6A8), 0, D_802B87BC); + // d_course_royal_raceway_packed_dl_A648 + find_and_set_tile_size((uintptr_t) segmented_gfx_to_virtual((void*)0x0700A648), 0, D_802B87BC); +} + void RoyalRaceway::Destroy() { } diff --git a/src/engine/courses/RoyalRaceway.h b/src/engine/courses/RoyalRaceway.h index 07498c6eb..0a7cd3e6a 100644 --- a/src/engine/courses/RoyalRaceway.h +++ b/src/engine/courses/RoyalRaceway.h @@ -24,8 +24,10 @@ public: // virtual void Load(const char* courseVtx, // course_texture* textures, const char* displaylists, size_t dlSize); + virtual void Load() override; virtual void LoadTextures() override; virtual void SpawnActors() override; + virtual void SpawnVehicles() override; virtual void MinimapSettings() override; virtual void InitCourseObjects() override; virtual void SomeSounds() override; @@ -33,12 +35,10 @@ public: virtual void WhatDoesThisDoAI(Player* player, int8_t playerId) override; virtual void MinimapFinishlinePosition() override; virtual void SetStaffGhost() override; - virtual void BeginPlay() override; virtual void Render(struct UnkStruct_800DC5EC*) override; virtual void RenderCredits() override; virtual void Collision() override; - virtual void SpawnBombKarts() override; - virtual void GenerateCollision() override; + virtual void ScrollingTextures() override; virtual void Waypoints(Player* player, int8_t playerId) override; virtual void Destroy() override; }; diff --git a/src/engine/courses/SherbetLand.cpp b/src/engine/courses/SherbetLand.cpp index 38439eb95..19bfa573e 100644 --- a/src/engine/courses/SherbetLand.cpp +++ b/src/engine/courses/SherbetLand.cpp @@ -6,7 +6,8 @@ #include "SherbetLand.h" #include "GameObject.h" #include "World.h" -#include "BombKart.h" +#include "engine/actors/AFinishline.h" +#include "engine/vehicles/OBombKart.h" #include "assets/sherbet_land_data.h" extern "C" { @@ -30,6 +31,7 @@ extern "C" { #include "collision.h" #include "memory.h" extern const char *sherbet_land_dls[]; + extern const char *sherbet_land_dls_2[]; } SherbetLand::SherbetLand() { @@ -100,13 +102,41 @@ SherbetLand::SherbetLand() { Props.Skybox.FloorTopLeft = {216, 232, 248}; } +void SherbetLand::Load() { + Course::Load(); + + parse_course_displaylists((TrackSectionsI*)LOAD_ASSET_RAW(d_course_sherbet_land_addr)); + func_80295C6C(); + D_8015F8E4 = -18.0f; + // d_course_sherbet_land_packed_dl_1EB8 + find_vtx_and_set_colours(segmented_gfx_to_virtual((void*)0x07001EB8), -0x4C, 255, 255, 255); + // d_course_sherbet_land_packed_dl_2308 + find_vtx_and_set_colours(segmented_gfx_to_virtual((void*)0x07002308), -0x6A, 255, 255, 255); +} + void SherbetLand::LoadTextures() { } void SherbetLand::SpawnActors() { + gWorldInstance.AddActor(new AFinishline()); + spawn_all_item_boxes((struct ActorSpawnData*)LOAD_ASSET_RAW(d_course_sherbet_land_item_box_spawns)); } +void SherbetLand::SpawnVehicles() { + if (gModeSelection == VERSUS) { + Vec3f pos = {0, 0, 0}; + + gWorldInstance.AddBombKart(pos, &D_80164550[0][50], 50, 3, 0.8333333f); + gWorldInstance.AddBombKart(pos, &D_80164550[0][100], 100, 1, 0.8333333f); + gWorldInstance.AddBombKart(pos, &D_80164550[0][150], 150, 3, 0.8333333f); + gWorldInstance.AddBombKart(pos, &D_80164550[0][200], 200, 1, 0.8333333f); + gWorldInstance.AddBombKart(pos, &D_80164550[0][250], 250, 3, 0.8333333f); + gWorldInstance.AddBombKart(pos, &D_80164550[0][0], 0, 0, 0.8333333f); + gWorldInstance.AddBombKart(pos, &D_80164550[0][0], 0, 0, 0.8333333f); + } +} + // Likely sets minimap boundaries void SherbetLand::MinimapSettings() { D_8018D220 = reinterpret_cast(dma_textures(gTextureExhaust1, 0x485, 0xC00)); @@ -146,25 +176,12 @@ void SherbetLand::WhatDoesThisDo(Player* player, int8_t playerId) {} void SherbetLand::WhatDoesThisDoAI(Player* player, int8_t playerId) {} -void SherbetLand::SpawnBombKarts() { - gWorldInstance.AddObject(std::make_unique(40, 3, 0.8333333, 0, 0, 0, 0)); - gWorldInstance.AddObject(std::make_unique(100, 3, 0.8333333, 0, 0, 0, 0)); - gWorldInstance.AddObject(std::make_unique(265, 3, 0.8333333, 0, 0, 0, 0)); - gWorldInstance.AddObject(std::make_unique(285, 1, 0.8333333, 0, 0, 0, 0)); - gWorldInstance.AddObject(std::make_unique(420, 1, 0.8333333, 0, 0, 0, 0)); - gWorldInstance.AddObject(std::make_unique(0, 0, 0.8333333, 0, 0, 0, 0)); - gWorldInstance.AddObject(std::make_unique(0, 0, 0.8333333, 0, 0, 0, 0)); -} - // Positions the finishline on the minimap void SherbetLand::MinimapFinishlinePosition() { //! todo: Place hard-coded values here. draw_hud_2d_texture_8x8(this->Props.MinimapFinishlineX, this->Props.MinimapFinishlineY, (u8*) common_texture_minimap_finish_line); } -void SherbetLand::SetStaffGhost() {} - -void SherbetLand::BeginPlay() { } void SherbetLand::Render(struct UnkStruct_800DC5EC* arg0) { gSPTexture(gDisplayListHead++, 0xFFFF, 0xFFFF, 0, G_TX_RENDERTILE, G_ON); gSPClearGeometryMode(gDisplayListHead++, G_LIGHTING); @@ -180,14 +197,37 @@ void SherbetLand::RenderCredits() { void SherbetLand::Collision() {} -void SherbetLand::GenerateCollision() { - parse_course_displaylists((TrackSectionsI*)LOAD_ASSET_RAW(d_course_sherbet_land_addr)); - func_80295C6C(); - D_8015F8E4 = -18.0f; +void SherbetLand::DrawWater(struct UnkStruct_800DC5EC* screen, uint16_t pathCounter, uint16_t cameraRot, uint16_t playerDirection) { + Mat4 matrix; + + gDPPipeSync(gDisplayListHead++); + gSPClearGeometryMode(gDisplayListHead++, G_LIGHTING); + gSPTexture(gDisplayListHead++, 0xFFFF, 0xFFFF, 0, G_TX_RENDERTILE, G_ON); + gDPSetBlendMask(gDisplayListHead++, 0xFF); + gDPSetCombineMode(gDisplayListHead++, G_CC_MODULATEIA, G_CC_MODULATEIA); + gDPSetTextureFilter(gDisplayListHead++, G_TF_BILERP); + gDPSetTexturePersp(gDisplayListHead++, G_TP_PERSP); + + mtxf_identity(matrix); + render_set_position(matrix, 0); + render_course_segments(sherbet_land_dls_2, screen); + + gDPSetAlphaCompare(gDisplayListHead++, G_AC_NONE); + if ((func_80290C20(screen->camera) == 1) && (func_802AAB4C(screen->player) < screen->player->pos[1])) { + gSPSetGeometryMode(gDisplayListHead++, G_ZBUFFER); + gDPSetCombineMode(gDisplayListHead++, G_CC_SHADE, G_CC_SHADE); + gDPSetRenderMode(gDisplayListHead++, G_RM_AA_ZB_OPA_SURF, G_RM_AA_ZB_OPA_SURF2); + // d_course_sherbet_land_packed_dl_2B48 + gSPDisplayList(gDisplayListHead++, segmented_gfx_to_virtual((void*)0x07002B48)); + } + gDPPipeSync(gDisplayListHead++); +} + +void SherbetLand::CreditsSpawnActors() { // d_course_sherbet_land_packed_dl_1EB8 - find_vtx_and_set_colours(segmented_gfx_to_virtual((void*)0x07001EB8), -0x4C, 255, 255, 255); + find_vtx_and_set_colours(segmented_gfx_to_virtual((void*)0x07001EB8), -0x4C, 0xFF, 0xFF, 0xFF); // d_course_sherbet_land_packed_dl_2308 - find_vtx_and_set_colours(segmented_gfx_to_virtual((void*)0x07002308), -0x6A, 255, 255, 255); + find_vtx_and_set_colours(segmented_gfx_to_virtual((void*)0x07002308), -0x6A, 0xFF, 0xFF, 0xFF); } void SherbetLand::Destroy() { } diff --git a/src/engine/courses/SherbetLand.h b/src/engine/courses/SherbetLand.h index 7ab4f9028..177410ca7 100644 --- a/src/engine/courses/SherbetLand.h +++ b/src/engine/courses/SherbetLand.h @@ -24,8 +24,10 @@ public: // virtual void Load(const char* courseVtx, // course_texture* textures, const char* displaylists, size_t dlSize); + virtual void Load() override; virtual void LoadTextures() override; virtual void SpawnActors() override; + virtual void SpawnVehicles() override; virtual void MinimapSettings() override; virtual void InitCourseObjects() override; virtual void UpdateCourseObjects() override; @@ -34,12 +36,10 @@ public: virtual void WhatDoesThisDo(Player* player, int8_t playerId) override; virtual void WhatDoesThisDoAI(Player* player, int8_t playerId) override; virtual void MinimapFinishlinePosition() override; - virtual void SetStaffGhost() override; - virtual void BeginPlay() override; virtual void Render(struct UnkStruct_800DC5EC*) override; virtual void RenderCredits() override; virtual void Collision() override; - virtual void SpawnBombKarts() override; - virtual void GenerateCollision() override; + virtual void DrawWater(struct UnkStruct_800DC5EC* screen, uint16_t pathCounter, uint16_t cameraRot, uint16_t playerDirection) override; + virtual void CreditsSpawnActors() override; virtual void Destroy() override; }; diff --git a/src/engine/courses/Skyscraper.cpp b/src/engine/courses/Skyscraper.cpp index 82a16ad93..df26ceccb 100644 --- a/src/engine/courses/Skyscraper.cpp +++ b/src/engine/courses/Skyscraper.cpp @@ -6,7 +6,7 @@ #include "Skyscraper.h" #include "GameObject.h" #include "World.h" -#include "BombKart.h" +#include "engine/vehicles/OBombKart.h" #include "assets/skyscraper_data.h" extern "C" { @@ -101,10 +101,38 @@ Skyscraper::Skyscraper() { Props.Skybox.FloorTopLeft = {0, 0, 0}; } +void Skyscraper::Load() { + Course::Load(); + + // d_course_skyscraper_packed_dl_1110 + generate_collision_mesh_with_default_section_id((Gfx*) segmented_gfx_to_virtual((void*)0x07001110), 1); + // d_course_skyscraper_packed_dl_258 + generate_collision_mesh_with_default_section_id((Gfx*) segmented_gfx_to_virtual((void*)0x07000258), 1); + func_80295C6C(); + + D_8015F8E4 = -480.0f; +} + void Skyscraper::LoadTextures() { } -void Skyscraper::SpawnActors() {} +void Skyscraper::SpawnActors() { + spawn_all_item_boxes((ActorSpawnData*)LOAD_ASSET_RAW(d_course_skyscraper_item_box_spawns)); +} + +void Skyscraper::SpawnVehicles() { + if (gModeSelection == VERSUS) { + Vec3f pos = {0, 0, 0}; + + gWorldInstance.AddBombKart(pos, &D_80164550[0][20], 20, 0, 1.0f); + gWorldInstance.AddBombKart(pos, &D_80164550[0][40], 40, 0, 1.0f); + gWorldInstance.AddBombKart(pos, &D_80164550[0][60], 60, 0, 1.0f); + gWorldInstance.AddBombKart(pos, &D_80164550[0][80], 80, 0, 1.0f); + gWorldInstance.AddBombKart(pos, &D_80164550[0][100], 100, 0, 1.0f); + gWorldInstance.AddBombKart(pos, &D_80164550[0][120], 120, 0, 1.0f); + gWorldInstance.AddBombKart(pos, &D_80164550[0][140], 140, 0, 1.0f); + } +} // Likely sets minimap boundaries void Skyscraper::MinimapSettings() { @@ -121,17 +149,12 @@ void Skyscraper::WhatDoesThisDo(Player* player, int8_t playerId) {} void Skyscraper::WhatDoesThisDoAI(Player* player, int8_t playerId) {} -void Skyscraper::SpawnBombKarts() {} - // Positions the finishline on the minimap void Skyscraper::MinimapFinishlinePosition() { //! todo: Place hard-coded values here. draw_hud_2d_texture_8x8(this->Props.MinimapFinishlineX, this->Props.MinimapFinishlineY, (u8*) common_texture_minimap_finish_line); } -void Skyscraper::SetStaffGhost() {} - -void Skyscraper::BeginPlay() { } void Skyscraper::Render(struct UnkStruct_800DC5EC* arg0) { func_802B5D64(D_800DC610, D_802B87D4, 0, 1); gSPTexture(gDisplayListHead++, 0xFFFF, 0xFFFF, 0, G_TX_RENDERTILE, G_ON); @@ -159,16 +182,6 @@ void Skyscraper::RenderCredits() {} void Skyscraper::Collision() {} -void Skyscraper::GenerateCollision() { - // d_course_skyscraper_packed_dl_1110 - generate_collision_mesh_with_default_section_id((Gfx*) segmented_gfx_to_virtual((void*)0x07001110), 1); - // d_course_skyscraper_packed_dl_258 - generate_collision_mesh_with_default_section_id((Gfx*) segmented_gfx_to_virtual((void*)0x07000258), 1); - func_80295C6C(); - - D_8015F8E4 = -480.0f; -} - void Skyscraper::Waypoints(Player* player, int8_t playerId) { player->nearestWaypointId = 0; } diff --git a/src/engine/courses/Skyscraper.h b/src/engine/courses/Skyscraper.h index a37c6e6ff..6658b43e6 100644 --- a/src/engine/courses/Skyscraper.h +++ b/src/engine/courses/Skyscraper.h @@ -24,8 +24,10 @@ public: // virtual void Load(const char* courseVtx, // course_texture* textures, const char* displaylists, size_t dlSize); + virtual void Load() override; virtual void LoadTextures() override; virtual void SpawnActors() override; + virtual void SpawnVehicles() override; //virtual void InitClouds() override; virtual void MinimapSettings() override; virtual void InitCourseObjects() override; @@ -33,13 +35,9 @@ public: virtual void WhatDoesThisDo(Player* player, int8_t playerId) override; virtual void WhatDoesThisDoAI(Player* player, int8_t playerId) override; virtual void MinimapFinishlinePosition() override; - virtual void SetStaffGhost() override; - virtual void BeginPlay() override; virtual void Render(struct UnkStruct_800DC5EC*) override; virtual void RenderCredits() override; virtual void Collision() override; - virtual void SpawnBombKarts() override; - virtual void GenerateCollision() override; virtual void Waypoints(Player* player, int8_t playerId) override; virtual void Destroy() override; }; diff --git a/src/engine/courses/TestCourse.cpp b/src/engine/courses/TestCourse.cpp index dcc64ec79..b3383a3b0 100644 --- a/src/engine/courses/TestCourse.cpp +++ b/src/engine/courses/TestCourse.cpp @@ -6,7 +6,14 @@ #include "TestCourse.h" #include "GameObject.h" #include "World.h" -#include "BombKart.h" +#include "engine/actors/AFinishline.h" +#include "engine/vehicles/OBombKart.h" +#include "assets/mario_raceway_data.h" +#include "assets/bowsers_castle_data.h" +#include "assets/bowsers_castle_displaylists.h" +#include "engine/actors/ATree.h" + +#include "engine/actors/ACloud.h" extern "C" { #include "main.h" @@ -29,10 +36,10 @@ extern "C" { #include "collision.h" #include "memory.h" typedef struct { - Gfx* addr; - u8 surfaceType; - u8 sectionId; - u16 flags; + Gfx* addr; + u8 surfaceType; + u8 sectionId; + u16 flags; } TrackSections; extern Gfx test_course_dls[]; extern Vtx mario_Plane_001_mesh_vtx_1[]; @@ -108,8 +115,13 @@ TestCourse::TestCourse() { } void TestCourse::Load() { - gSegmentTable[4] = reinterpret_cast(&mario_Plane_001_mesh_vtx_1[0]); - //gSegmentTable[7] = reinterpret_cast(&gfx[0]); + Course::Load(mario_Plane_001_mesh_vtx_1, NULL); + + generate_collision_mesh_with_defaults(mario_Plane_001_mesh); + + parse_course_displaylists((TrackSectionsI*)test_course_addr); + func_80295C6C(); + D_8015F8E4 = gCourseMinY - 10.0f; } void TestCourse::LoadTextures() { @@ -126,30 +138,39 @@ void TestCourse::LoadTextures() { } void TestCourse::SpawnActors() { -struct ActorSpawnData itemboxes[] = { - { 200, 1500, 200 , 0}, - { 350, 2500, 300 , 1}, - { 400, 2000, 350 , 2}, - { 40, 0, -800, 0}, - { -40, 0, -800, 0}, - { 0, 0, -800, 0}, - { 999, 6, 482, 0}, - { 1064, 8, 275, {0}}, - { 1028, 5, -39 , {0}}, - { 320, 0, 1020, {0}}, - { 293, 0, 950, {0}}, - {{ -32768, 0, 0 }, {0}}, -}; + struct ActorSpawnData itemboxes[] = { + { 200, 1500, 200 , 0}, + { 350, 2500, 300 , 1}, + { 400, 2000, 350 , 2}, + { 40, 0, -800, 0}, + { -40, 0, -800, 0}, + { 0, 0, -800, 0}, + { 999, 6, 482, 0}, + { 1064, 8, 275, {0}}, + { 1028, 5, -39 , {0}}, + { 320, 0, 1020, {0}}, + { 293, 0, 950, {0}}, + {{ -32768, 0, 0 }, {0}}, + }; + + struct ActorSpawnData rocks[] = { + {{ 200, 1500, 200 }, {0}}, + {{ 350, 2500, 300 }, {1}}, + {{ 400, 2000, 350 }, {2}}, + {{ -32768, 0, 0 }, {0}}, + }; + + gWorldInstance.AddActor(new AFinishline()); -struct ActorSpawnData rocks[] = { - {{ 200, 1500, 200 }, {0}}, - {{ 350, 2500, 300 }, {1}}, - {{ 400, 2000, 350 }, {2}}, - {{ -32768, 0, 0 }, {0}}, -}; spawn_all_item_boxes(itemboxes); spawn_falling_rocks(rocks); + Vec3f test = {-100, 0, -150}; + Vec3s rot = {0, 0, 0}; + Vec3f vel = {0, 0, 0}; + + add_actor_to_empty_slot(test, rot, vel, ACTOR_TREE_MARIO_RACEWAY); + struct RailroadCrossing* rrxing; Vec3f position; Vec3f velocity = { 0.0f, 0.0f, 0.0f }; @@ -160,9 +181,12 @@ struct ActorSpawnData rocks[] = { uintptr_t* crossing1 = (uintptr_t*) gWorldInstance.AddCrossing(crossingPos, 0, 2, 900.0f, 650.0f); position[0] *= gCourseDirection; - rrxing = (struct RailroadCrossing*) &gActorList[add_actor_to_empty_slot(position, rotation, velocity, - ACTOR_RAILROAD_CROSSING)]; + rrxing = (struct RailroadCrossing*) GET_ACTOR(add_actor_to_empty_slot(position, rotation, velocity, + ACTOR_RAILROAD_CROSSING)); rrxing->crossingTrigger = crossing1; + + Vec3f pos = {-80, 7, -20}; + gWorldInstance.AddActor(new ACloud(pos)); } // Likely sets minimap boundaries @@ -241,8 +265,14 @@ void TestCourse::SpawnVehicles() { gVehicle2DWaypointLength = 53; D_80162EB0 = spawn_actor_on_surface(test_course_path2D[0].x, 2000.0f, test_course_path2D[0].z); - gWorldInstance.AddTrain(5, 5.0f, 0); - gWorldInstance.AddTrain(5, 5.0f, 8); + gWorldInstance.AddTrain(5, 2.5f, 0); + gWorldInstance.AddTrain(5, 2.5f, 8); + + Vec3f pos = {0, 0, 0}; + + gWorldInstance.AddBombKart(pos, &D_80164550[0][25], 25, 2, 0.8333333f); + gWorldInstance.AddBombKart(pos, &D_80164550[0][45], 45, 3, 0.8333333f); + } void TestCourse::UpdateVehicles() { @@ -283,25 +313,12 @@ void TestCourse::WhatDoesThisDoAI(Player* player, int8_t playerId) { } } -void TestCourse::SpawnBombKarts() { - gWorldInstance.AddObject(std::make_unique(40, 3, 0.8333333, 0, 0, 0, 0)); - gWorldInstance.AddObject(std::make_unique(100, 3, 0.8333333, 0, 0, 0, 0)); - gWorldInstance.AddObject(std::make_unique(265, 3, 0.8333333, 0, 0, 0, 0)); - gWorldInstance.AddObject(std::make_unique(285, 1, 0.8333333, 0, 0, 0, 0)); - gWorldInstance.AddObject(std::make_unique(420, 1, 0.8333333, 0, 0, 0, 0)); - gWorldInstance.AddObject(std::make_unique(0, 0, 0.8333333, 0, 0, 0, 0)); - gWorldInstance.AddObject(std::make_unique(0, 0, 0.8333333, 0, 0, 0, 0)); -} - // Positions the finishline on the minimap void TestCourse::MinimapFinishlinePosition() { //! todo: Place hard-coded values here. draw_hud_2d_texture_8x8(this->Props.MinimapFinishlineX, this->Props.MinimapFinishlineY, (u8*) common_texture_minimap_finish_line); } -void TestCourse::SetStaffGhost() {} - -void TestCourse::BeginPlay() { } void TestCourse::Render(struct UnkStruct_800DC5EC* arg0) { gSPSetGeometryMode(gDisplayListHead++, G_SHADING_SMOOTH); gSPClearGeometryMode(gDisplayListHead++, G_LIGHTING); @@ -322,12 +339,4 @@ void TestCourse::RenderCredits() { void TestCourse::Collision() {} -void TestCourse::GenerateCollision() { - generate_collision_mesh_with_defaults(mario_Plane_001_mesh); - - parse_course_displaylists((TrackSectionsI*)test_course_addr); - func_80295C6C(); - D_8015F8E4 = gCourseMinY - 10.0f; -} - void TestCourse::Destroy() { } diff --git a/src/engine/courses/TestCourse.h b/src/engine/courses/TestCourse.h index 9d988e4c6..4f0e83b9c 100644 --- a/src/engine/courses/TestCourse.h +++ b/src/engine/courses/TestCourse.h @@ -33,14 +33,10 @@ public: virtual void WhatDoesThisDo(Player* player, int8_t playerId) override; virtual void WhatDoesThisDoAI(Player* player, int8_t playerId) override; virtual void MinimapFinishlinePosition() override; - virtual void SetStaffGhost() override; - virtual void BeginPlay() override; virtual void Render(struct UnkStruct_800DC5EC*) override; virtual void RenderCredits() override; virtual void Collision() override; virtual void SpawnVehicles() override; virtual void UpdateVehicles() override; - virtual void SpawnBombKarts() override; - virtual void GenerateCollision() override; virtual void Destroy() override; }; diff --git a/src/engine/courses/ToadsTurnpike.cpp b/src/engine/courses/ToadsTurnpike.cpp index d66faf571..e629b76ef 100644 --- a/src/engine/courses/ToadsTurnpike.cpp +++ b/src/engine/courses/ToadsTurnpike.cpp @@ -6,8 +6,9 @@ #include "ToadsTurnpike.h" #include "GameObject.h" #include "World.h" -#include "BombKart.h" +#include "engine/vehicles/OBombKart.h" #include "assets/toads_turnpike_data.h" +#include "engine/actors/AFinishline.h" #include "engine/vehicles/Utils.h" @@ -105,10 +106,30 @@ ToadsTurnpike::ToadsTurnpike() { Props.Skybox.FloorTopLeft = {209, 65, 23}; } +void ToadsTurnpike::Load() { + Course::Load(); + + D_801625EC = 43; + D_801625F4 = 13; + D_801625F0 = 4; + D_802B87B0 = 993; + D_802B87B4 = 1000; + parse_course_displaylists((TrackSectionsI*)LOAD_ASSET_RAW(d_course_toads_turnpike_addr)); + func_80295C6C(); + D_8015F8E4 = gCourseMinY - 10.0f; +} + void ToadsTurnpike::LoadTextures() { } void ToadsTurnpike::SpawnActors() { + Vec3f pos; + pos[0] = (gIsMirrorMode != 0) ? D_80164490->posX + 138.0f : D_80164490->posX - 138.0f; + pos[1] = (f32) (D_80164490->posY - 15); + pos[2] = D_80164490->posZ; + + gWorldInstance.AddActor(new AFinishline(pos)); + spawn_all_item_boxes((struct ActorSpawnData*)LOAD_ASSET_RAW(d_course_toads_turnpike_item_box_spawns)); } @@ -158,26 +179,12 @@ void ToadsTurnpike::WhatDoesThisDoAI(Player* player, int8_t playerId) { } } -void ToadsTurnpike::SpawnBombKarts() { - gWorldInstance.AddObject(std::make_unique(40, 3, 0.8333333, 0, 0, 0, 0)); - gWorldInstance.AddObject(std::make_unique(100, 3, 0.8333333, 0, 0, 0, 0)); - gWorldInstance.AddObject(std::make_unique(265, 3, 0.8333333, 0, 0, 0, 0)); - gWorldInstance.AddObject(std::make_unique(285, 1, 0.8333333, 0, 0, 0, 0)); - gWorldInstance.AddObject(std::make_unique(420, 1, 0.8333333, 0, 0, 0, 0)); - gWorldInstance.AddObject(std::make_unique(0, 0, 0.8333333, 0, 0, 0, 0)); - gWorldInstance.AddObject(std::make_unique(0, 0, 0.8333333, 0, 0, 0, 0)); -} - // Positions the finishline on the minimap void ToadsTurnpike::MinimapFinishlinePosition() { //! todo: Place hard-coded values here. draw_hud_2d_texture_8x8(this->Props.MinimapFinishlineX, this->Props.MinimapFinishlineY, (u8*) common_texture_minimap_finish_line); } -void ToadsTurnpike::SetStaffGhost() {} - -void ToadsTurnpike::BeginPlay() {} - void ToadsTurnpike::Render(struct UnkStruct_800DC5EC* arg0) { func_802B5D64(D_800DC610, D_802B87D4, 0, 1); gSPTexture(gDisplayListHead++, 0xFFFF, 0xFFFF, 0, G_TX_RENDERTILE, G_ON); @@ -213,6 +220,8 @@ void ToadsTurnpike::Collision() {} void ToadsTurnpike::SpawnVehicles() { f32 a = ((gCCSelection * 90.0) / 216.0f) + 4.583333333333333; f32 b = ((gCCSelection * 90.0) / 216.0f) + 2.9166666666666665; + a /= 2; // Normally vehicle logic is only ran every 2 frames. This slows the vehicles down to match. + b /= 2; uint32_t waypoint; if (gModeSelection == TIME_TRIALS) { @@ -256,17 +265,18 @@ void ToadsTurnpike::SpawnVehicles() { gWorldInstance.AddCar(a, b, &D_80164550[0][0], waypoint); } } -} -void ToadsTurnpike::GenerateCollision() { - D_801625EC = 43; - D_801625F4 = 13; - D_801625F0 = 4; - D_802B87B0 = 993; - D_802B87B4 = 1000; - parse_course_displaylists((TrackSectionsI*)LOAD_ASSET_RAW(d_course_toads_turnpike_addr)); - func_80295C6C(); - D_8015F8E4 = gCourseMinY - 10.0f; + if (gModeSelection == VERSUS) { + Vec3f pos = {0, 0, 0}; + + gWorldInstance.AddBombKart(pos, &D_80164550[0][50], 50, 3, 0.8333333f); + gWorldInstance.AddBombKart(pos, &D_80164550[0][100], 100, 1, 0.8333333f); + gWorldInstance.AddBombKart(pos, &D_80164550[0][150], 150, 3, 0.8333333f); + gWorldInstance.AddBombKart(pos, &D_80164550[0][200], 200, 1, 0.8333333f); + gWorldInstance.AddBombKart(pos, &D_80164550[0][250], 250, 3, 0.8333333f); + gWorldInstance.AddBombKart(pos, &D_80164550[0][0], 0, 0, 0.8333333f); + gWorldInstance.AddBombKart(pos, &D_80164550[0][0], 0, 0, 0.8333333f); + } } void ToadsTurnpike::Destroy() { } diff --git a/src/engine/courses/ToadsTurnpike.h b/src/engine/courses/ToadsTurnpike.h index 8bba69de5..7a097cce3 100644 --- a/src/engine/courses/ToadsTurnpike.h +++ b/src/engine/courses/ToadsTurnpike.h @@ -24,6 +24,7 @@ public: // virtual void Load(const char* courseVtx, // course_texture* textures, const char* displaylists, size_t dlSize); + virtual void Load() override; virtual void LoadTextures() override; virtual void SpawnActors() override; virtual void InitClouds() override; @@ -33,13 +34,9 @@ public: virtual void WhatDoesThisDo(Player* player, int8_t playerId) override; virtual void WhatDoesThisDoAI(Player* player, int8_t playerId) override; virtual void MinimapFinishlinePosition() override; - virtual void SetStaffGhost() override; - virtual void BeginPlay() override; virtual void Render(struct UnkStruct_800DC5EC*) override; virtual void RenderCredits() override; virtual void Collision() override; virtual void SpawnVehicles() override; - virtual void SpawnBombKarts() override; - virtual void GenerateCollision() override; virtual void Destroy() override; }; diff --git a/src/engine/courses/WarioStadium.cpp b/src/engine/courses/WarioStadium.cpp index bc90d15b6..39447b590 100644 --- a/src/engine/courses/WarioStadium.cpp +++ b/src/engine/courses/WarioStadium.cpp @@ -6,9 +6,10 @@ #include "WarioStadium.h" #include "GameObject.h" #include "World.h" -#include "BombKart.h" +#include "engine/vehicles/OBombKart.h" #include "assets/wario_stadium_data.h" #include "engine/actors/AWarioSign.h" +#include "engine/actors/AFinishline.h" extern "C" { #include "main.h" @@ -103,23 +104,68 @@ WarioStadium::WarioStadium() { Props.Skybox.FloorTopLeft = {0, 0, 0}; } +void WarioStadium::Load() { + Course::Load(); + + parse_course_displaylists((TrackSectionsI*)LOAD_ASSET_RAW(d_course_wario_stadium_addr)); + func_80295C6C(); + D_8015F8E4 = gCourseMinY - 10.0f; + // d_course_wario_stadium_packed_dl_C50 + find_vtx_and_set_colours(segmented_gfx_to_virtual((void*)0x07000C50), 100, 255, 255, 255); + // d_course_wario_stadium_packed_dl_BD8 + find_vtx_and_set_colours(segmented_gfx_to_virtual((void*)0x07000BD8), 100, 255, 255, 255); + // d_course_wario_stadium_packed_dl_B60 + find_vtx_and_set_colours(segmented_gfx_to_virtual((void*)0x07000B60), 100, 255, 255, 255); + // d_course_wario_stadium_packed_dl_AE8 + find_vtx_and_set_colours(segmented_gfx_to_virtual((void*)0x07000AE8), 100, 255, 255, 255); + // d_course_wario_stadium_packed_dl_CC8 + find_vtx_and_set_colours(segmented_gfx_to_virtual((void*)0x07000CC8), 100, 255, 255, 255); + // d_course_wario_stadium_packed_dl_D50 + find_vtx_and_set_colours(segmented_gfx_to_virtual((void*)0x07000D50), 100, 255, 255, 255); + // d_course_wario_stadium_packed_dl_DD0 + find_vtx_and_set_colours(segmented_gfx_to_virtual((void*)0x07000DD0), 100, 255, 255, 255); + // d_course_wario_stadium_packed_dl_E48 + find_vtx_and_set_colours(segmented_gfx_to_virtual((void*)0x07000E48), 100, 255, 255, 255); +} + void WarioStadium::LoadTextures() { } void WarioStadium::SpawnActors() { + Vec3f finish; + finish[0] = (gIsMirrorMode != 0) ? D_80164490->posX + 12.0f : D_80164490->posX - 12.0f;(gIsMirrorMode != 0) ? D_80164490->posX + 12.0f : D_80164490->posX - 12.0f; + finish[1] = D_8015F8D0[1] = (f32) (D_80164490->posY - 15); + finish[2] = D_8015F8D0[2] = D_80164490->posZ; + + gWorldInstance.AddActor(new AFinishline(finish)); + spawn_all_item_boxes((struct ActorSpawnData*)LOAD_ASSET_RAW(d_course_wario_stadium_item_box_spawns)); Vec3f pos = {-131.0f, 83.0f, 286.0f}; pos[0] *= gCourseDirection; - gWorldInstance.AddActor(std::make_unique(pos)); + gWorldInstance.AddActor(new AWarioSign(pos)); Vec3f pos2 = {-2353.0f, 72.0f, -1608.0f}; pos2[0] *= gCourseDirection; - gWorldInstance.AddActor(std::make_unique(pos2)); + gWorldInstance.AddActor(new AWarioSign(pos2)); Vec3f pos3 = {-2622.0f, 79.0f, 739.0f}; pos3[0] *= gCourseDirection; - gWorldInstance.AddActor(std::make_unique(pos3)); + gWorldInstance.AddActor(new AWarioSign(pos3)); +} + +void WarioStadium::SpawnVehicles() { + if (gModeSelection == VERSUS) { + Vec3f pos = {0, 0, 0}; + + gWorldInstance.AddBombKart(pos, &D_80164550[0][50], 50, 3, 0.8333333f); + gWorldInstance.AddBombKart(pos, &D_80164550[0][100], 100, 1, 0.8333333f); + gWorldInstance.AddBombKart(pos, &D_80164550[0][150], 150, 3, 0.8333333f); + gWorldInstance.AddBombKart(pos, &D_80164550[0][200], 200, 1, 0.8333333f); + gWorldInstance.AddBombKart(pos, &D_80164550[0][250], 250, 3, 0.8333333f); + gWorldInstance.AddBombKart(pos, &D_80164550[0][0], 0, 0, 0.8333333f); + gWorldInstance.AddBombKart(pos, &D_80164550[0][0], 0, 0, 0.8333333f); + } } void WarioStadium::InitClouds() { @@ -155,25 +201,12 @@ void WarioStadium::WhatDoesThisDo(Player* player, int8_t playerId) {} void WarioStadium::WhatDoesThisDoAI(Player* player, int8_t playerId) {} -void WarioStadium::SpawnBombKarts() { - gWorldInstance.AddObject(std::make_unique(40, 3, 0.8333333, 0, 0, 0, 0)); - gWorldInstance.AddObject(std::make_unique(100, 3, 0.8333333, 0, 0, 0, 0)); - gWorldInstance.AddObject(std::make_unique(265, 3, 0.8333333, 0, 0, 0, 0)); - gWorldInstance.AddObject(std::make_unique(285, 1, 0.8333333, 0, 0, 0, 0)); - gWorldInstance.AddObject(std::make_unique(420, 1, 0.8333333, 0, 0, 0, 0)); - gWorldInstance.AddObject(std::make_unique(0, 0, 0.8333333, 0, 0, 0, 0)); - gWorldInstance.AddObject(std::make_unique(0, 0, 0.8333333, 0, 0, 0, 0)); -} - // Positions the finishline on the minimap void WarioStadium::MinimapFinishlinePosition() { //! todo: Place hard-coded values here. draw_hud_2d_texture_8x8(this->Props.MinimapFinishlineX, this->Props.MinimapFinishlineY, (u8*) common_texture_minimap_finish_line); } -void WarioStadium::SetStaffGhost() {} - -void WarioStadium::BeginPlay() { } void WarioStadium::Render(struct UnkStruct_800DC5EC* arg0) { s16 prevFrame; @@ -272,26 +305,60 @@ void WarioStadium::SomeCollisionThing(Player *player, Vec3f arg1, Vec3f arg2, Ve func_8003EE2C(player, arg1, arg2, arg3, arg4, arg5, arg6, arg7); } -void WarioStadium::GenerateCollision() { - parse_course_displaylists((TrackSectionsI*)LOAD_ASSET_RAW(d_course_wario_stadium_addr)); - func_80295C6C(); - D_8015F8E4 = gCourseMinY - 10.0f; +void WarioStadium::DrawWater(struct UnkStruct_800DC5EC* screen, uint16_t pathCounter, uint16_t cameraRot, uint16_t playerDirection) { + Mat4 matrix; + + gDPPipeSync(gDisplayListHead++); + gSPTexture(gDisplayListHead++, 0xFFFF, 0xFFFF, 0, G_TX_RENDERTILE, G_ON); + gSPClearGeometryMode(gDisplayListHead++, G_LIGHTING); + gDPSetRenderMode(gDisplayListHead++, G_RM_AA_ZB_XLU_INTER, G_RM_NOOP2); + gDPSetBlendMask(gDisplayListHead++, 0xFF); + gDPSetCombineMode(gDisplayListHead++, G_CC_MODULATEIA, G_CC_MODULATEIA); + gDPSetTextureFilter(gDisplayListHead++, G_TF_BILERP); + gDPSetTexturePersp(gDisplayListHead++, G_TP_PERSP); + + mtxf_identity(matrix); + render_set_position(matrix, 0); + + gSPClearGeometryMode(gDisplayListHead++, G_CULL_BACK); + gDPSetCombineMode(gDisplayListHead++, G_CC_MODULATEIDECALA, G_CC_MODULATEIDECALA); + gDPSetRenderMode(gDisplayListHead++, G_RM_AA_ZB_XLU_SURF, G_RM_AA_ZB_XLU_SURF2); + gDPSetPrimColor(gDisplayListHead++, 0, 0, 0xFF, 0xFF, 0x00, 0xFF); + // d_course_wario_stadium_packed_dl_EC0 + gSPDisplayList(gDisplayListHead++, segmented_gfx_to_virtual((void*)0x07000EC0)); + gSPTexture(gDisplayListHead++, 0xFFFF, 0xFFFF, 1, 1, G_OFF); + gSPSetGeometryMode(gDisplayListHead++, G_CULL_BACK); + gDPSetAlphaCompare(gDisplayListHead++, G_AC_NONE); + gDPPipeSync(gDisplayListHead++); +} + +void WarioStadium::CreditsSpawnActors() { + Vec3f position; + Vec3f velocity = { 0, 0, 0 }; + Vec3s rotation = { 0, 0, 0 }; + + vec3f_set(position, -131.0f, 83.0f, 286.0f); + add_actor_to_empty_slot(position, rotation, velocity, ACTOR_WARIO_SIGN); + vec3f_set(position, -2353.0f, 72.0f, -1608.0f); + add_actor_to_empty_slot(position, rotation, velocity, ACTOR_WARIO_SIGN); + vec3f_set(position, -2622.0f, 79.0f, 739.0f); + add_actor_to_empty_slot(position, rotation, velocity, ACTOR_WARIO_SIGN); // d_course_wario_stadium_packed_dl_C50 - find_vtx_and_set_colours(segmented_gfx_to_virtual((void*)0x07000C50), 100, 255, 255, 255); + find_vtx_and_set_colours(segmented_gfx_to_virtual((void*)0x07000C50), 0x64, 0xFF, 0xFF, 0xFF); // d_course_wario_stadium_packed_dl_BD8 - find_vtx_and_set_colours(segmented_gfx_to_virtual((void*)0x07000BD8), 100, 255, 255, 255); + find_vtx_and_set_colours(segmented_gfx_to_virtual((void*)0x07000BD8), 0x64, 0xFF, 0xFF, 0xFF); // d_course_wario_stadium_packed_dl_B60 - find_vtx_and_set_colours(segmented_gfx_to_virtual((void*)0x07000B60), 100, 255, 255, 255); + find_vtx_and_set_colours(segmented_gfx_to_virtual((void*)0x07000B60), 0x64, 0xFF, 0xFF, 0xFF); // d_course_wario_stadium_packed_dl_AE8 - find_vtx_and_set_colours(segmented_gfx_to_virtual((void*)0x07000AE8), 100, 255, 255, 255); + find_vtx_and_set_colours(segmented_gfx_to_virtual((void*)0x07000AE8), 0x64, 0xFF, 0xFF, 0xFF); // d_course_wario_stadium_packed_dl_CC8 - find_vtx_and_set_colours(segmented_gfx_to_virtual((void*)0x07000CC8), 100, 255, 255, 255); + find_vtx_and_set_colours(segmented_gfx_to_virtual((void*)0x07000CC8), 0x64, 0xFF, 0xFF, 0xFF); // d_course_wario_stadium_packed_dl_D50 - find_vtx_and_set_colours(segmented_gfx_to_virtual((void*)0x07000D50), 100, 255, 255, 255); + find_vtx_and_set_colours(segmented_gfx_to_virtual((void*)0x07000D50), 0x64, 0xFF, 0xFF, 0xFF); // d_course_wario_stadium_packed_dl_DD0 - find_vtx_and_set_colours(segmented_gfx_to_virtual((void*)0x07000DD0), 100, 255, 255, 255); + find_vtx_and_set_colours(segmented_gfx_to_virtual((void*)0x07000DD0), 0x64, 0xFF, 0xFF, 0xFF); // d_course_wario_stadium_packed_dl_E48 - find_vtx_and_set_colours(segmented_gfx_to_virtual((void*)0x07000E48), 100, 255, 255, 255); + find_vtx_and_set_colours(segmented_gfx_to_virtual((void*)0x07000E48), 0x64, 0xFF, 0xFF, 0xFF); } void WarioStadium::Destroy() { } diff --git a/src/engine/courses/WarioStadium.h b/src/engine/courses/WarioStadium.h index f41535be1..14707876e 100644 --- a/src/engine/courses/WarioStadium.h +++ b/src/engine/courses/WarioStadium.h @@ -24,8 +24,10 @@ public: // virtual void Load(const char* courseVtx, // course_texture* textures, const char* displaylists, size_t dlSize); + virtual void Load() override; virtual void LoadTextures() override; virtual void SpawnActors() override; + virtual void SpawnVehicles() override; virtual void InitClouds() override; virtual void UpdateClouds(s32,Camera*) override; virtual void MinimapSettings() override; @@ -34,13 +36,11 @@ public: virtual void WhatDoesThisDo(Player* player, int8_t playerId) override; virtual void WhatDoesThisDoAI(Player* player, int8_t playerId) override; virtual void MinimapFinishlinePosition() override; - virtual void SetStaffGhost() override; - virtual void BeginPlay() override; virtual void Render(struct UnkStruct_800DC5EC*) override; virtual void RenderCredits() override; virtual void Collision() override; virtual void SomeCollisionThing(Player *player, Vec3f arg1, Vec3f arg2, Vec3f arg3, f32* arg4, f32* arg5, f32* arg6, f32* arg7) override; - virtual void SpawnBombKarts() override; - virtual void GenerateCollision() override; + virtual void DrawWater(struct UnkStruct_800DC5EC* screen, uint16_t pathCounter, uint16_t cameraRot, uint16_t playerDirection) override; + virtual void CreditsSpawnActors() override; virtual void Destroy() override; }; diff --git a/src/engine/courses/YoshiValley.cpp b/src/engine/courses/YoshiValley.cpp index fe7672d7e..3c0a195f4 100644 --- a/src/engine/courses/YoshiValley.cpp +++ b/src/engine/courses/YoshiValley.cpp @@ -6,7 +6,8 @@ #include "YoshiValley.h" #include "GameObject.h" #include "World.h" -#include "BombKart.h" +#include "engine/actors/AFinishline.h" +#include "engine/vehicles/OBombKart.h" #include "assets/yoshi_valley_data.h" #include "assets/boo_frames.h" @@ -101,6 +102,16 @@ YoshiValley::YoshiValley() { Props.Skybox.FloorTopLeft = {95, 40, 15}; } +void YoshiValley::Load() { + Course::Load(); + + Lights1 lights4 = gdSPDefLights1(100, 100, 100, 255, 254, 254, 0, 0, 120); + func_802B5D64(&lights4, -0x38F0, 0x1C70, 1); + parse_course_displaylists((TrackSectionsI*)LOAD_ASSET_RAW(d_course_yoshi_valley_addr)); + func_80295C6C(); + D_8015F8E4 = gCourseMinY - 10.0f; +} + void YoshiValley::LoadTextures() { dma_textures(gTextureTrees2, 0x000003E8U, 0x00000800U); } @@ -110,6 +121,8 @@ void YoshiValley::SpawnActors() { Vec3f velocity = { 0.0f, 0.0f, 0.0f }; Vec3s rotation = { 0, 0, 0 }; + gWorldInstance.AddActor(new AFinishline()); + spawn_foliage((struct ActorSpawnData*)LOAD_ASSET_RAW(d_course_yoshi_valley_tree_spawn)); spawn_all_item_boxes((struct ActorSpawnData*)LOAD_ASSET_RAW(d_course_yoshi_valley_item_box_spawns)); vec3f_set(position, -2300.0f, 0.0f, 634.0f); @@ -147,6 +160,30 @@ void YoshiValley::InitCourseObjects() { } } +void YoshiValley::SpawnVehicles() { + if (gModeSelection == VERSUS) { + + // Note that the waypoint values might be unused for Yoshi's Valley. Entered them because + // the original data has values here. + + // Note that the Y height is calculated automatically to place the kart on the surface + Vec3f pos = {-1533, 0, -682}; + gWorldInstance.AddBombKart(pos, NULL, 0, 0, 0.8333333f); + Vec3f pos2 = {-1565, 0, -619}; + gWorldInstance.AddBombKart(pos2, NULL, 10, 0, 0.8333333f); + Vec3f pos3 = {-1529, 0, -579}; + gWorldInstance.AddBombKart(pos3, NULL, 20, 0, 0.8333333f); + Vec3f pos4 = {-1588, 0, -534}; + gWorldInstance.AddBombKart(pos4, NULL, 30, 0, 0.8333333f); + Vec3f pos5 = {-1598, 0, -207}; + gWorldInstance.AddBombKart(pos5, NULL, 40, 0, 0.8333333f); + Vec3f pos6 = {-1646, 0, -147}; + gWorldInstance.AddBombKart(pos6, NULL, 50, 0, 0.8333333f); + Vec3f pos7 = {-2532, 0, -445}; + gWorldInstance.AddBombKart(pos7, NULL, 60, 0, 0.8333333f); + } +} + void YoshiValley::UpdateCourseObjects() { func_80083080(); if (gGamestate != CREDITS_SEQUENCE) { @@ -168,27 +205,12 @@ void YoshiValley::WhatDoesThisDo(Player* player, int8_t playerId) {} void YoshiValley::WhatDoesThisDoAI(Player* player, int8_t playerId) {} -void YoshiValley::SpawnBombKarts() { - gWorldInstance.AddObject(std::make_unique(140, 3, 0.8333333, 0, 0, 0, 0)); - gWorldInstance.AddObject(std::make_unique(165, 1, 0.8333333, 0, 0, 0, 0)); - gWorldInstance.AddObject(std::make_unique(330, 3, 0.8333333, 0, 0, 0, 0)); - gWorldInstance.AddObject(std::make_unique(550, 1, 0.8333333, 0, 0, 0, 0)); - gWorldInstance.AddObject(std::make_unique(595, 3, 0.8333333, 0, 0, 0, 0)); - gWorldInstance.AddObject(std::make_unique(0, 0, 0.8333333, 0, 0, 0, 0)); - gWorldInstance.AddObject(std::make_unique(0, 0, 0.8333333, 0, 0, 0, 0)); -} - // Positions the finishline on the minimap void YoshiValley::MinimapFinishlinePosition() { //! todo: Place hard-coded values here. draw_hud_2d_texture_8x8(this->Props.MinimapFinishlineX, this->Props.MinimapFinishlineY, (u8*) common_texture_minimap_finish_line); } -void YoshiValley::SetStaffGhost() { -} - -void YoshiValley::BeginPlay() { } - void YoshiValley::Render(struct UnkStruct_800DC5EC* arg0) { gDPPipeSync(gDisplayListHead++); gDPSetCombineMode(gDisplayListHead++, G_CC_MODULATEI, G_CC_MODULATEI); @@ -204,18 +226,20 @@ void YoshiValley::RenderCredits() { void YoshiValley::Collision() {} -void YoshiValley::GenerateCollision() { - Lights1 lights4 = gdSPDefLights1(100, 100, 100, 255, 254, 254, 0, 0, 120); - func_802B5D64(&lights4, -0x38F0, 0x1C70, 1); - parse_course_displaylists((TrackSectionsI*)LOAD_ASSET_RAW(d_course_yoshi_valley_addr)); - func_80295C6C(); - D_8015F8E4 = gCourseMinY - 10.0f; -} - void YoshiValley::Waypoints(Player* player, int8_t playerId) { player->nearestWaypointId = gCopyNearestWaypointByPlayerId[playerId]; } -void YoshiValley::Water() {} +void YoshiValley::ScrollingTextures() {} + +void YoshiValley::CreditsSpawnActors() { + Vec3f position; + Vec3f velocity = { 0, 0, 0 }; + Vec3s rotation = { 0, 0, 0 }; + + vec3f_set(position, -2300.0f, 0.0f, 634.0f); + position[0] *= gCourseDirection; + add_actor_to_empty_slot(position, rotation, velocity, ACTOR_YOSHI_EGG); +} void YoshiValley::Destroy() {} diff --git a/src/engine/courses/YoshiValley.h b/src/engine/courses/YoshiValley.h index 8fe294019..d0de64752 100644 --- a/src/engine/courses/YoshiValley.h +++ b/src/engine/courses/YoshiValley.h @@ -24,8 +24,10 @@ public: // virtual void Load(const char* courseVtx, // course_texture* textures, const char* displaylists, size_t dlSize); + virtual void Load() override; virtual void LoadTextures() override; virtual void SpawnActors() override; + virtual void SpawnVehicles() override; virtual void MinimapSettings() override; virtual void InitCourseObjects() override; virtual void UpdateCourseObjects() override; @@ -34,14 +36,11 @@ public: virtual void WhatDoesThisDo(Player* player, int8_t playerId) override; virtual void WhatDoesThisDoAI(Player* player, int8_t playerId) override; virtual void MinimapFinishlinePosition() override; - virtual void SetStaffGhost() override; - virtual void BeginPlay() override; virtual void Render(struct UnkStruct_800DC5EC*) override; virtual void RenderCredits() override; virtual void Collision() override; - virtual void SpawnBombKarts() override; - virtual void GenerateCollision() override; - virtual void Water() override; + virtual void ScrollingTextures() override; virtual void Waypoints(Player* player, int8_t playerId) override; + virtual void CreditsSpawnActors() override; virtual void Destroy() override; }; diff --git a/src/engine/readme.txt b/src/engine/readme.txt new file mode 100644 index 000000000..da0de518b --- /dev/null +++ b/src/engine/readme.txt @@ -0,0 +1,3 @@ +# Engine + +The replacement C++ engine which contains many code refactors for flexibility. \ No newline at end of file diff --git a/src/engine/vehicles/Boat.cpp b/src/engine/vehicles/Boat.cpp index bb2cda81d..1e7109e1d 100644 --- a/src/engine/vehicles/Boat.cpp +++ b/src/engine/vehicles/Boat.cpp @@ -143,7 +143,7 @@ void ABoat::Tick() { Velocity[0] = Position[0] - temp_f26; Velocity[1] = Position[1] - temp_f28; Velocity[2] = Position[2] - temp_f30; - paddleBoatActor = &gActorList[ActorIndex]; + paddleBoatActor = GET_ACTOR(ActorIndex); paddleBoatActor->pos[0] = Position[0]; paddleBoatActor->pos[1] = Position[1]; paddleBoatActor->pos[2] = Position[2]; diff --git a/src/engine/vehicles/Bus.cpp b/src/engine/vehicles/Bus.cpp index 2427cf77f..36bb576c6 100644 --- a/src/engine/vehicles/Bus.cpp +++ b/src/engine/vehicles/Bus.cpp @@ -133,7 +133,7 @@ void ABus::Tick() { Velocity[0] = Position[0] - sp5C; Velocity[1] = Position[1] - sp58; Velocity[2] = Position[2] - sp54; - struct Actor* vehicleActor = &gActorList[ActorIndex]; + struct Actor* vehicleActor = GET_ACTOR(ActorIndex); vehicleActor->pos[0] = Position[0]; vehicleActor->pos[1] = Position[1]; vehicleActor->pos[2] = Position[2]; diff --git a/src/engine/vehicles/Car.cpp b/src/engine/vehicles/Car.cpp index f742aaa75..604fe5f2f 100644 --- a/src/engine/vehicles/Car.cpp +++ b/src/engine/vehicles/Car.cpp @@ -115,7 +115,7 @@ void ACar::Tick() { Velocity[0] = Position[0] - sp5C; Velocity[1] = Position[1] - sp58; Velocity[2] = Position[2] - sp54; - struct Actor* vehicleActor = &gActorList[ActorIndex]; + struct Actor* vehicleActor = GET_ACTOR(ActorIndex); vehicleActor->pos[0] = Position[0]; vehicleActor->pos[1] = Position[1]; vehicleActor->pos[2] = Position[2]; diff --git a/src/engine/vehicles/OBombKart.cpp b/src/engine/vehicles/OBombKart.cpp new file mode 100644 index 000000000..907be2119 --- /dev/null +++ b/src/engine/vehicles/OBombKart.cpp @@ -0,0 +1,449 @@ +#include +#include "engine/vehicles/OBombKart.h" +#include + +#include "port/Game.h" +#include "engine/Matrix.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" +extern s8 gPlayerCount; +} + +OBombKart::OBombKart(Vec3f pos, TrackWaypoint* waypoint, uint16_t waypointIndex, uint16_t state, f32 unk_3C) { + + Vec3f _pos = {0, 0, 0}; + + if (waypoint) { // Spawn kart on waypoint + _pos[0] = waypoint->posX; + _pos[1] = waypoint->posY; + _pos[2] = waypoint->posZ; + } else { // Spawn kart on a surface with the provided position + + // Set height to the default value of 2000.0f unless Pos[1] is higher. + // This allows placing these on very high surfaces. + f32 height = (pos[1] > 2000.0f) ? pos[1] : 2000.0f; + _pos[0] = pos[0]; + _pos[1] = spawn_actor_on_surface(pos[0], height, pos[2]); + _pos[2] = pos[2]; + } + + WaypointIndex = waypointIndex; + Unk_3C = unk_3C; + State = static_cast(state); + + Pos[0] = _pos[0]; + Pos[1] = _pos[1]; + Pos[2] = _pos[2]; + CenterY = _pos[1]; + WheelPos[0][0] = _pos[0]; + WheelPos[0][1] = _pos[1]; + WheelPos[0][2] = _pos[2]; + WheelPos[1][0] = _pos[0]; + WheelPos[1][1] = _pos[1]; + WheelPos[1][2] = _pos[2]; + WheelPos[2][0] = _pos[0]; + WheelPos[2][1] = _pos[1]; + WheelPos[2][2] = _pos[2]; + WheelPos[3][0] = _pos[0]; + WheelPos[3][1] = _pos[1]; + WheelPos[3][2] = _pos[2]; + check_bounding_collision(&_Collision, 2.0f, _pos[0], _pos[1], _pos[2]); +} + +void OBombKart::Spawn() { + find_unused_obj_index(&ObjectIndex); +} + +void OBombKart::BeginPlay() { + +} + +void OBombKart::Tick() { + f32 sp118; + f32 var_f18; + TrackWaypoint* temp_v0_2; + f32 temp_f0_3; + f32 sp108; + f32 temp_f14; + f32 temp_f16; + f32 temp_f0; + f32 temp_f0_4; + u16 waypoint; + f32 unk_3C; + u16 someRot; + f32 temp_f12; + f32 temp_f12_3; + f32 temp_f12_4; + f32 temp_f14_2; + f32 spAC; + f32 temp_f16_2; + f32 spA0; + f32 temp_f2; + f32 temp_f2_4; + f32 sp94; + f32 var_f20; + f32 sp88; + f32 var_f22; + f32 var_f24; + States state; + u16 bounceTimer; + UNUSED u16 sp4C; + u16 temp_t6; + u16 temp_t7; + u16 circleTimer; + TrackWaypoint* temp_v0_4; + Player* player; + + state = State; + + if (state == States::DISABLED) { + return; + } + + if (((Unk_4A != 1) || (GetCourse() == GetPodiumCeremony()))) { + var_f22 = Pos[0]; + var_f20 = Pos[1]; + var_f24 = Pos[2]; + waypoint = WaypointIndex; + unk_3C = Unk_3C; + someRot = SomeRot; + bounceTimer = BounceTimer; + circleTimer = CircleTimer; + if ((state != States::DISABLED) && (state != States::EXPLODE)) { + if (GetCourse() == GetPodiumCeremony()) { + if (D_8016347E == 1) { + player = gPlayerFour; + temp_f0 = var_f22 - player->pos[0]; + temp_f2 = var_f20 - player->pos[1]; + temp_f12 = var_f24 - player->pos[2]; + if ((((temp_f0 * temp_f0) + (temp_f2 * temp_f2)) + (temp_f12 * temp_f12)) < 25.0f) { + circleTimer = 0; + state = States::EXPLODE; + player->soundEffects |= 0x400000; + player->type &= ~0x2000; + } + } + } else { + + for (size_t i = 0; i < gPlayerCount; i++) { + player = &gPlayers[i]; + if (!(player->effects & 0x80000000)) { + temp_f0 = var_f22 - player->pos[0]; + temp_f2 = var_f20 - player->pos[1]; + temp_f12 = var_f24 - player->pos[2]; + if ((((temp_f0 * temp_f0) + (temp_f2 * temp_f2)) + (temp_f12 * temp_f12)) < 25.0f) { + state = States::EXPLODE; + circleTimer = 0; + if (GetCourse() == GetFrappeSnowland()) { + player->soundEffects |= 0x01000000; + } else { + player->soundEffects |= 0x400000; + } + } + } + } + } + } + switch(state) { + case States::CCW: + circleTimer = (circleTimer + 356) % 360; + temp_t6 = (circleTimer * 0xFFFF) / 360; + sp118 = coss(temp_t6) * 25.0; + temp_f0_3 = sins(temp_t6) * 25.0; + temp_v0_2 = &D_80164550[0][waypoint]; + var_f22 = temp_v0_2->posX + sp118; + var_f20 = CenterY + 3.5f; + var_f24 = temp_v0_2->posZ + temp_f0_3; + D_80162FB0[0] = var_f22; + D_80162FB0[1] = var_f20; + D_80162FB0[2] = var_f24; + temp_t7 = (((circleTimer + 1) % 360) * 0xFFFF) / 360; + sp118 = coss(temp_t7) * 25.0; + temp_f0_3 = sins(temp_t7) * 25.0; + D_80162FC0[0] = temp_v0_2->posX + sp118; + D_80162FC0[1] = temp_v0_2->posY; + D_80162FC0[2] = temp_v0_2->posZ + temp_f0_3; + someRot = (get_angle_between_two_vectors(D_80162FB0, D_80162FC0) * 0xFFFF) / 65520; + break; + case States::CW: + circleTimer = (circleTimer + 4) % 360; + temp_t6 = (circleTimer * 0xFFFF) / 360; + sp118 = coss(temp_t6) * 25.0; + temp_f0_3 = sins(temp_t6) * 25.0; + temp_v0_2 = &D_80164550[0][waypoint]; + var_f22 = temp_v0_2->posX + sp118; + var_f20 = CenterY + 3.5f; + var_f24 = temp_v0_2->posZ + temp_f0_3; + D_80162FB0[0] = var_f22; + D_80162FB0[1] = var_f20; + D_80162FB0[2] = var_f24; + temp_t7 = (((circleTimer + 1) % 360) * 0xFFFF) / 360; + sp118 = coss(temp_t7) * 25.0; + temp_f0_3 = sins(temp_t7) * 25.0; + D_80162FC0[0] = temp_v0_2->posX + sp118; + D_80162FC0[1] = temp_v0_2->posY; + D_80162FC0[2] = temp_v0_2->posZ + temp_f0_3; + someRot = (get_angle_between_two_vectors(D_80162FB0, D_80162FC0) * 0xFFFF) / 65520; + break; + case States::STATIONARY: + var_f20 = CenterY + 3.5f; + someRot = 0; + break; + + case States::PODIUM_CEREMONY: + if ((D_8016347C == 0) || (gNearestWaypointByPlayerId[3] < 5)) { + break; + } else { + waypoint = func_8000D2B4(var_f22, var_f20, var_f24, waypoint, 3); + if ((waypoint < 0) || (gWaypointCountByPathIndex[3] < waypoint)) { + waypoint = 0; + } + if (((s32) waypoint) < 0x1A) { + temp_v0_2 = &D_80164550[3][(waypoint + 1) % gWaypointCountByPathIndex[3]]; + D_80162FB0[0] = temp_v0_2->posX; + D_80162FB0[1] = temp_v0_2->posY; + D_80162FB0[2] = temp_v0_2->posZ; + temp_v0_4 = &D_80164550[3][(waypoint + 2) % gWaypointCountByPathIndex[3]]; + D_80162FC0[0] = temp_v0_4->posX; + D_80162FC0[1] = temp_v0_4->posY; + D_80162FC0[2] = temp_v0_4->posZ; + someRot = (get_angle_between_two_vectors(D_80162FB0, D_80162FC0) * 0xFFFF) / 65520; + } else { + D_80162FB0[0] = var_f22; + D_80162FB0[1] = var_f20; + D_80162FB0[2] = var_f24; + D_80162FC0[0] = -2409.197f; + D_80162FC0[1] = 0.0f; + D_80162FC0[2] = -355.254f; + someRot = (get_angle_between_two_vectors(D_80162FB0, D_80162FC0) * 0xFFFF) / 65520; + } + temp_f14 = ((D_80162FB0[0] + D_80162FC0[0]) * 0.5f) - var_f22; + temp_f16 = ((D_80162FB0[2] + D_80162FC0[2]) * 0.5f) - var_f24; + temp_f0_4 = sqrtf((temp_f14 * temp_f14) + (temp_f16 * temp_f16)); + if (temp_f0_4 > 0.01f) { + var_f22 += (Unk_3C * temp_f14) / temp_f0_4; + var_f24 += (Unk_3C * temp_f16) / temp_f0_4; + } else { + var_f22 += temp_f14 / 5.0f; + var_f24 += temp_f16 / 5.0f; + } + var_f20 = calculate_surface_height(var_f22, 2000.0f, var_f24, _Collision.meshIndexZX) + 3.5f; + if (var_f20 < (-1000.0)) { + var_f20 = Pos[1]; + } + check_bounding_collision(&_Collision, 10.0f, var_f22, var_f20, var_f24); + } + break; + case States::EXPLODE: + temp_v0_2 = &D_80164550[0][waypoint]; + D_80162FB0[0] = temp_v0_2->posX; + D_80162FB0[1] = temp_v0_2->posY; + D_80162FB0[2] = temp_v0_2->posZ; + temp_v0_4 = &D_80164550[0][(waypoint + 1) % gWaypointCountByPathIndex[0]]; + D_80162FC0[0] = temp_v0_4->posX; + D_80162FC0[1] = temp_v0_4->posY; + D_80162FC0[2] = temp_v0_4->posZ; + var_f20 += 3.0f - (circleTimer * 0.3f); + someRot = (get_angle_between_two_vectors(D_80162FB0, D_80162FC0) * 0xFFFF) / 65520; + break; + default: + break; + } + + if (state == States::EXPLODE) { + sp108 = 2.0f * circleTimer; + sp118 = coss(0xFFFF - someRot) * circleTimer; + var_f18 = sins(0xFFFF - someRot) * circleTimer; + circleTimer++; + temp_f2_4 = (var_f20 - 2.3f) + (sp108 / 3.0f); + spAC = temp_f2_4; + spA0 = temp_f2_4; + sp94 = temp_f2_4; + sp88 = temp_f2_4; + if (circleTimer >= 31) { + state = States::DISABLED; + } + } else { + sp118 = coss(0xFFFF - someRot) * 1.5f; + var_f18 = sins(0xFFFF - someRot) * 1.5f; + temp_f16_2 = var_f20 - 2.3f; + temp_f12_3 = (bounceTimer % 3) * 0.15f; + temp_f14_2 = temp_f16_2 - temp_f12_3; + temp_f12_4 = temp_f16_2 + temp_f12_3; + spAC = temp_f14_2; + sp94 = temp_f14_2; + spA0 = temp_f12_4; + sp88 = temp_f12_4; + var_f20 += sins((bounceTimer * 0x13FFEC) / 360); + bounceTimer = (bounceTimer + 1) % 18; + } + + WheelPos[0][0] = (sp118 - var_f18) + var_f22; + WheelPos[0][1] = spAC; + WheelPos[0][2] = (var_f18 + sp118) + var_f24; + WheelPos[1][0] = (var_f18 + sp118) + var_f22; + WheelPos[1][1] = spA0; + WheelPos[1][2] = (var_f18 - sp118) + var_f24; + WheelPos[2][0] = ((-sp118) - var_f18) + var_f22; + WheelPos[2][1] = sp94; + WheelPos[2][2] = ((-var_f18) + sp118) + var_f24; + WheelPos[3][0] = ((-sp118) + var_f18) + var_f22; + WheelPos[3][1] = sp88; + WheelPos[3][2] = ((-var_f18) - sp118) + var_f24; + Pos[0] = var_f22; + Pos[1] = var_f20; + Pos[2] = var_f24; + WaypointIndex = waypoint; + Unk_3C = unk_3C; + SomeRot = someRot; + State = state; + BounceTimer = bounceTimer; + CircleTimer = circleTimer; + } +} + +void OBombKart::Draw(s32 cameraId) { + + if (gModeSelection == BATTLE) { + return; + } + + if (GetCourse() == GetPodiumCeremony()) { + // This isn't functionally equivallent. + // Technicaly it should be if (kart[0].WaypointIndex < 16) + if (WaypointIndex < 16) { + return; + } else { + cameraId = PLAYER_FOUR; + } + } + + Camera* camera; + s32 temp_s4; + s32 i; + s32 state; + + if (gGamestate == ENDING) { + cameraId = 0; + } + camera = &camera1[cameraId]; + if (cameraId == PLAYER_ONE) { + if (is_obj_flag_status_active(ObjectIndex, 0x00200000) != 0) { + Unk_4A = 0; + } else if (gGamestate != ENDING) { + Unk_4A = 1; + } + set_object_flag_status_false(ObjectIndex, 0x00200000); + } + + // huh??? + state = State; + if (State != States::DISABLED) { + gObjectList[ObjectIndex].pos[0] = Pos[0]; + gObjectList[ObjectIndex].pos[1] = Pos[1]; + 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); + D_80183E80[0] = 0; + D_80183E80[1] = func_800418AC(Pos[0], Pos[2], camera->pos); + D_80183E80[2] = 0x8000; + func_800563DC(ObjectIndex, cameraId, 0x000000FF); + OBombKart::SomeRender(camera->pos); + if (((u32) temp_s4 < 0x4E21U) && (state != BOMB_STATE_EXPLODED)) { + OBombKart::LoadMtx(); + } + } + } +} + +void OBombKart::DrawBattle(s32 cameraId) { + if (gModeSelection != BATTLE) { + return; + } + Player* temp_v0; + s32 temp_s1; + s32 playerId; + Object* object; + + for (playerId = 0; playerId < gPlayerCount; playerId++) { + object = &gObjectList[ObjectIndex]; + if (object->state != 0) { + temp_s1 = object->primAlpha; + temp_v0 = &gPlayerOne[playerId]; + object->pos[0] = temp_v0->pos[0]; + object->pos[1] = temp_v0->pos[1] - 2.0; + object->pos[2] = temp_v0->pos[2]; + object->surfaceHeight = temp_v0->unk_074; + func_800563DC(ObjectIndex, cameraId, temp_s1); + func_8005669C(ObjectIndex, cameraId, temp_s1); + func_800568A0(ObjectIndex, cameraId); + } + } +} + +void OBombKart::SomeRender(Vec3f arg1) { + D_80183E80[0] = 0; + D_80183E80[2] = 0x8000; + gSPDisplayList(gDisplayListHead++, (Gfx*)D_0D0079C8); + load_texture_block_rgba16_mirror((u8*) D_0D02AA58, 0x00000010, 0x00000010); + D_80183E80[1] = func_800418AC(WheelPos[0][0], WheelPos[0][2], arg1); + func_800431B0(WheelPos[0], D_80183E80, 0.15f, (Vtx*)common_vtx_rectangle); + D_80183E80[1] = func_800418AC(WheelPos[1][0], WheelPos[1][2], arg1); + func_800431B0(WheelPos[1], D_80183E80, 0.15f, (Vtx*)common_vtx_rectangle); + D_80183E80[1] = func_800418AC(WheelPos[2][0], WheelPos[2][2], arg1); + func_800431B0(WheelPos[2], D_80183E80, 0.15f, (Vtx*)common_vtx_rectangle); + D_80183E80[1] = func_800418AC(WheelPos[3][0], WheelPos[3][2], arg1); + func_800431B0(WheelPos[3], D_80183E80, 0.15f, (Vtx*)common_vtx_rectangle); + gSPTexture(gDisplayListHead++, 1, 1, 0, G_TX_RENDERTILE, G_OFF); +} + +void OBombKart::LoadMtx() { + Mat4 mat; + + D_80183E50[0] = Pos[0]; + D_80183E50[1] = CenterY + 1.0; + D_80183E50[2] = Pos[2]; + set_transform_matrix(mat, _Collision.orientationVector, D_80183E50, 0U, 0.5f); + //convert_to_fixed_point_matrix(&gGfxPool->mtxHud[gMatrixHudCount], mat); + + AddHudMatrix(mat, G_MTX_LOAD | G_MTX_NOPUSH | G_MTX_MODELVIEW); + + // gSPMatrix(gDisplayListHead++, VIRTUAL_TO_PHYSICAL(&gGfxPool->mtxHud[gMatrixHudCount++]), + // G_MTX_LOAD | G_MTX_NOPUSH | G_MTX_MODELVIEW); + gSPDisplayList(gDisplayListHead++, (Gfx*)D_0D007B98); +} + +void OBombKart::Waypoint(s32 screenId) { + s32 playerWaypoint; + s32 bombWaypoint; + s32 waypointDiff; + + playerWaypoint = gNearestWaypointByPlayerId[screenId]; + playerHUD[screenId].unk_74 = 0; + if ((State == States::EXPLODE) || (State == States::DISABLED)) { return; }; + bombWaypoint = WaypointIndex; + waypointDiff = bombWaypoint - playerWaypoint; + if ((waypointDiff < -5) || (waypointDiff > 0x1E)) { return; }; + playerHUD[screenId].unk_74 = 1; +} + +void OBombKart::Collision(s32 playerId, Player* player) { + +} diff --git a/src/engine/vehicles/OBombKart.h b/src/engine/vehicles/OBombKart.h new file mode 100644 index 000000000..a857b207b --- /dev/null +++ b/src/engine/vehicles/OBombKart.h @@ -0,0 +1,64 @@ +#pragma once + +#include +#include "Vehicle.h" +#include +#include "engine/Matrix.h" + +extern "C" { +#include "macros.h" +#include "main.h" +#include "vehicles.h" +#include "waypoints.h" +#include "common_structs.h" +#include "objects.h" +} + +/** + * Used in VS mode + * + * This differs from the other vehicle classes in that it does not get added to the standard actor list + * So this is sort of its own thing. Draw call in different place too. + */ +class OBombKart { +private: + enum States : uint16_t { // 0,1,3,5 + DISABLED, + CCW, + CW, + STATIONARY, + EXPLODE, + PODIUM_CEREMONY, + }; + +public: + + const char* Type; + + Vec3f Pos; + Vec3f WheelPos[4]; //! @todo Turn WheelPos into a struct + f32 Unk_3C; + u16 SomeRot; // Some angle + u16 WaypointIndex; // The waypoint the kart circles + States State = States::DISABLED; + u16 BounceTimer = 0; + u16 CircleTimer = 0; + u16 Unk_4A = 0; + s16 Unk_4C = 1; + f32 CenterY; // Center of the circle + s32 ObjectIndex = 0; // Index into gObjectList + Collision _Collision; + + // 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); + + void Spawn(); + void BeginPlay(); + void Tick(); + void Draw(s32 playerId); + void DrawBattle(s32 cameraId); + void Collision(s32 playerId, Player* player); + void SomeRender(Vec3f arg1); + void LoadMtx(); + void Waypoint(s32 screenId); +}; diff --git a/src/engine/vehicles/TankerTruck.cpp b/src/engine/vehicles/TankerTruck.cpp index 4d4de5016..8acd7984c 100644 --- a/src/engine/vehicles/TankerTruck.cpp +++ b/src/engine/vehicles/TankerTruck.cpp @@ -133,7 +133,7 @@ void ATankerTruck::Tick() { Velocity[0] = Position[0] - sp5C; Velocity[1] = Position[1] - sp58; Velocity[2] = Position[2] - sp54; - struct Actor* vehicleActor = &gActorList[ActorIndex]; + struct Actor* vehicleActor = GET_ACTOR(ActorIndex); vehicleActor->pos[0] = Position[0]; vehicleActor->pos[1] = Position[1]; vehicleActor->pos[2] = Position[2]; diff --git a/src/engine/vehicles/Train.cpp b/src/engine/vehicles/Train.cpp index e775563f7..a16b8b5f9 100644 --- a/src/engine/vehicles/Train.cpp +++ b/src/engine/vehicles/Train.cpp @@ -144,7 +144,7 @@ void ATrain::SyncComponents(TrainCarStuff* trainCar, s16 orientationY) { struct TrainCar* trainCarActor; //! @todo: Change actorIndex to ptr to TrainCar actor - trainCarActor = (struct TrainCar*) &gActorList[trainCar->actorIndex]; + trainCarActor = (struct TrainCar*) GET_ACTOR(trainCar->actorIndex); trainCarActor->pos[0] = trainCar->position[0]; trainCarActor->pos[1] = trainCar->position[1]; trainCarActor->pos[2] = trainCar->position[2]; diff --git a/src/engine/vehicles/Truck.cpp b/src/engine/vehicles/Truck.cpp index 06b0a5a45..139edc644 100644 --- a/src/engine/vehicles/Truck.cpp +++ b/src/engine/vehicles/Truck.cpp @@ -150,7 +150,7 @@ void ATruck::Tick() { Velocity[0] = Position[0] - sp5C; Velocity[1] = Position[1] - sp58; Velocity[2] = Position[2] - sp54; - struct Actor* vehicleActor = &gActorList[ActorIndex]; + struct Actor* vehicleActor = GET_ACTOR(ActorIndex); vehicleActor->pos[0] = Position[0]; vehicleActor->pos[1] = Position[1]; vehicleActor->pos[2] = Position[2]; diff --git a/src/engine/wasm.cpp b/src/engine/wasm.cpp index a0bd31b23..c94e7882b 100644 --- a/src/engine/wasm.cpp +++ b/src/engine/wasm.cpp @@ -1,247 +1,247 @@ -extern "C" { -#include -#include -#include -#include -#include -#include -#include -#include -#include -} +// extern "C" { +// #include +// #include +// #include +// #include +// #include +// #include +// #include +// #include +// #include +// } -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include +// #include +// #include +// #include +// #include +// #include +// #include +// #include +// #include +// #include +// #include -struct mod_instance { - wasm_exec_env_t exec_env; - char* name; -}; +// struct mod_instance { +// wasm_exec_env_t exec_env; +// char* name; +// }; -std::vector mods_instance = {}; +// std::vector mods_instance = {}; -std::vector> render_hook = {}; +// std::vector> render_hook = {}; -void hook_render(wasm_exec_env_t exec_env, uint32 func1) { - render_hook.push_back([exec_env, func1]() { wasm_runtime_call_indirect(exec_env, func1, 0, NULL); }); -} +// void hook_render(wasm_exec_env_t exec_env, uint32 func1) { +// render_hook.push_back([exec_env, func1]() { wasm_runtime_call_indirect(exec_env, func1, 0, NULL); }); +// } -extern "C" void call_render_hook() { - for (auto f : render_hook) { - f(); - } -} +// extern "C" void call_render_hook() { +// for (auto f : render_hook) { +// f(); +// } +// } -bool CreateDirectoryRecursive(std::string const& dirName, std::error_code& err) { - err.clear(); - if (!std::filesystem::create_directories(dirName, err)) { - if (std::filesystem::exists(dirName)) { - // The folder already exists: - err.clear(); - return true; - } - return false; - } - return true; -} +// bool CreateDirectoryRecursive(std::string const& dirName, std::error_code& err) { +// err.clear(); +// if (!std::filesystem::create_directories(dirName, err)) { +// if (std::filesystem::exists(dirName)) { +// // The folder already exists: +// err.clear(); +// return true; +// } +// return false; +// } +// return true; +// } -void load_mod_wasm_file(char* mod_name, char* buffer, size_t size) { - char error_buf[128]; - wasm_module_t module; - wasm_module_inst_t module_inst; - wasm_exec_env_t exec_env; - uint32_t stack_size = 8092 * 8092, heap_size = 8092 * 8; - /* parse the WASM file from buffer and create a WASM module */ - module = wasm_runtime_load((uint8_t*) buffer, size, error_buf, sizeof(error_buf)); - printf("error? %s\n", error_buf); +// void load_mod_wasm_file(char* mod_name, char* buffer, size_t size) { +// char error_buf[128]; +// wasm_module_t module; +// wasm_module_inst_t module_inst; +// wasm_exec_env_t exec_env; +// uint32_t stack_size = 8092 * 8092, heap_size = 8092 * 8; +// /* parse the WASM file from buffer and create a WASM module */ +// module = wasm_runtime_load((uint8_t*) buffer, size, error_buf, sizeof(error_buf)); +// printf("error? %s\n", error_buf); - if (module == NULL) { - printf("%s\n", error_buf); - exit(-1); - } +// if (module == NULL) { +// printf("%s\n", error_buf); +// exit(-1); +// } - /* create an instance of the WASM module (WASM linear memory is ready) */ - module_inst = wasm_runtime_instantiate(module, stack_size, heap_size, error_buf, sizeof(error_buf)); - if (module_inst == NULL) { - printf("%s\n", error_buf); - exit(-1); - } +// /* create an instance of the WASM module (WASM linear memory is ready) */ +// module_inst = wasm_runtime_instantiate(module, stack_size, heap_size, error_buf, sizeof(error_buf)); +// if (module_inst == NULL) { +// printf("%s\n", error_buf); +// exit(-1); +// } - /* lookup a WASM function by its name - The function signature can NULL here */ +// /* lookup a WASM function by its name +// The function signature can NULL here */ - /* creat an execution environment to execute the WASM functions */ - exec_env = wasm_runtime_create_exec_env(module_inst, stack_size); - mods_instance.push_back({ exec_env, mod_name }); -} +// /* creat an execution environment to execute the WASM functions */ +// exec_env = wasm_runtime_create_exec_env(module_inst, stack_size); +// mods_instance.push_back({ exec_env, mod_name }); +// } -mod_instance* find_mod(char* name) { - for (size_t i = 0; i < mods_instance.size(); i++) { - if (strcmp(mods_instance[i].name, name) == 0) { - return &mods_instance[i]; - } - } - return NULL; -} +// mod_instance* find_mod(char* name) { +// for (size_t i = 0; i < mods_instance.size(); i++) { +// if (strcmp(mods_instance[i].name, name) == 0) { +// return &mods_instance[i]; +// } +// } +// return NULL; +// } -wasm_module_inst_t get_mods_instance(char* mod_name) { - return wasm_exec_env_get_module_inst(find_mod(mod_name)->exec_env); -} +// wasm_module_inst_t get_mods_instance(char* mod_name) { +// return wasm_exec_env_get_module_inst(find_mod(mod_name)->exec_env); +// } -wasm_function_inst_t mod_lookup_function(char* mod_name, char* function_name) { - return wasm_runtime_lookup_function(get_mods_instance(mod_name), function_name); -} +// wasm_function_inst_t mod_lookup_function(char* mod_name, char* function_name) { +// return wasm_runtime_lookup_function(get_mods_instance(mod_name), function_name); +// } -bool mod_call_function_wasm(char* mod_name, char* function_name, uint32 argc, uint32 argv[]) { - wasm_function_inst_t func = mod_lookup_function(mod_name, function_name); - if (func == NULL) { - printf("error to find the function\n"); - return false; - } +// bool mod_call_function_wasm(char* mod_name, char* function_name, uint32 argc, uint32 argv[]) { +// wasm_function_inst_t func = mod_lookup_function(mod_name, function_name); +// if (func == NULL) { +// printf("error to find the function\n"); +// return false; +// } - return wasm_runtime_call_wasm(find_mod(mod_name)->exec_env, func, 1, argv); -} +// return wasm_runtime_call_wasm(find_mod(mod_name)->exec_env, func, 1, argv); +// } -void mod_print_exception(char* mod_name) { - printf("%s\n", wasm_runtime_get_exception(get_mods_instance(mod_name))); -} +// void mod_print_exception(char* mod_name) { +// printf("%s\n", wasm_runtime_get_exception(get_mods_instance(mod_name))); +// } -uint32 call_extern_function(wasm_exec_env_t exec_env, char* mod_name, char* function_name, uint32 argc, - uint32 argv_offset) { - if (!wasm_runtime_validate_app_addr(wasm_exec_env_get_module_inst(exec_env), (uint64) argv_offset, - (uint64) argc * 4)) { - return false; - } - uint32* argv = - (uint32*) wasm_runtime_addr_app_to_native(wasm_exec_env_get_module_inst(exec_env), (uint64) argv_offset); - return mod_call_function_wasm(mod_name, function_name, argc, argv); -} +// uint32 call_extern_function(wasm_exec_env_t exec_env, char* mod_name, char* function_name, uint32 argc, +// uint32 argv_offset) { +// if (!wasm_runtime_validate_app_addr(wasm_exec_env_get_module_inst(exec_env), (uint64) argv_offset, +// (uint64) argc * 4)) { +// return false; +// } +// uint32* argv = +// (uint32*) wasm_runtime_addr_app_to_native(wasm_exec_env_get_module_inst(exec_env), (uint64) argv_offset); +// return mod_call_function_wasm(mod_name, function_name, argc, argv); +// } -void post_debug_print(wasm_exec_env_t exec_env) { - gSPDisplayList(gDisplayListHead++, (Gfx*) D_0D007EB8); - gSPDisplayList(gDisplayListHead++, (Gfx*) D_020076E0); - func_80093C98(1); -} +// void post_debug_print(wasm_exec_env_t exec_env) { +// gSPDisplayList(gDisplayListHead++, (Gfx*) D_0D007EB8); +// gSPDisplayList(gDisplayListHead++, (Gfx*) D_020076E0); +// func_80093C98(1); +// } -void load_debug_font_wrapper(wasm_exec_env_t exec_env) { - load_debug_font(); -} +// void load_debug_font_wrapper(wasm_exec_env_t exec_env) { +// load_debug_font(); +// } -void debug_print_str2_wrapper(wasm_exec_env_t exec_env, uint32 x, uint32 y, char* str) { - debug_print_str2(x, y, str); -} +// void debug_print_str2_wrapper(wasm_exec_env_t exec_env, uint32 x, uint32 y, char* str) { +// debug_print_str2(x, y, str); +// } -/* the native functions that will be exported to WASM app */ -static NativeSymbol native_symbols[] = { - EXPORT_WASM_API_WITH_SIG(call_extern_function, "($$ii)i"), EXPORT_WASM_API_WITH_SIG(hook_render, "(i)"), - EXPORT_WASM_API_WITH_SIG(post_debug_print, "()"), EXPORT_WASM_API_WITH_SIG2(load_debug_font, "()"), - EXPORT_WASM_API_WITH_SIG2(debug_print_str2, "(ii$)"), - // EXPORT_WASM_API_WITH_SIG(display_input_read, "(*)i"), - // EXPORT_WASM_API_WITH_SIG(display_flush, "(iiii*)") -}; +// /* the native functions that will be exported to WASM app */ +// static NativeSymbol native_symbols[] = { +// EXPORT_WASM_API_WITH_SIG(call_extern_function, "($$ii)i"), EXPORT_WASM_API_WITH_SIG(hook_render, "(i)"), +// EXPORT_WASM_API_WITH_SIG(post_debug_print, "()"), EXPORT_WASM_API_WITH_SIG2(load_debug_font, "()"), +// EXPORT_WASM_API_WITH_SIG2(debug_print_str2, "(ii$)"), +// // EXPORT_WASM_API_WITH_SIG(display_input_read, "(*)i"), +// // EXPORT_WASM_API_WITH_SIG(display_flush, "(iiii*)") +// }; -/* all the runtime memory allocations are retricted in the global_heap_buf array */ -static char global_heap_buf[512 * 1024]; +// /* all the runtime memory allocations are retricted in the global_heap_buf array */ +// static char global_heap_buf[512 * 1024]; -char* read_wasm_binary_to_buffer(char* path, uint32_t* size) { - std::ifstream file; - file.open(path, std::ios::binary); - if (!file.is_open()) { - perror(path); - return NULL; - } +// char* read_wasm_binary_to_buffer(char* path, uint32_t* size) { +// std::ifstream file; +// file.open(path, std::ios::binary); +// if (!file.is_open()) { +// perror(path); +// return NULL; +// } - file.seekg(0, std::ios::end); +// file.seekg(0, std::ios::end); - *size = file.tellg(); +// *size = file.tellg(); - file.seekg(0); +// file.seekg(0); - char* c_buffer = (char*) malloc(*size); - file.read(c_buffer, *size); - return c_buffer; -} +// char* c_buffer = (char*) malloc(*size); +// file.read(c_buffer, *size); +// return c_buffer; +// } -extern "C" void load_wasm() { - printf("load wasm\n"); - char* buffer; +// extern "C" void load_wasm() { +// printf("load wasm\n"); +// char* buffer; - /* initialize the wasm runtime by default configurations */ - wasm_runtime_init(); +// /* initialize the wasm runtime by default configurations */ +// wasm_runtime_init(); - RuntimeInitArgs init_args; - memset(&init_args, 0, sizeof(RuntimeInitArgs)); +// RuntimeInitArgs init_args; +// memset(&init_args, 0, sizeof(RuntimeInitArgs)); - /* configure the memory allocator for the runtime */ - init_args.mem_alloc_type = Alloc_With_Pool; - init_args.mem_alloc_option.pool.heap_buf = global_heap_buf; - init_args.mem_alloc_option.pool.heap_size = sizeof(global_heap_buf); +// /* configure the memory allocator for the runtime */ +// init_args.mem_alloc_type = Alloc_With_Pool; +// init_args.mem_alloc_option.pool.heap_buf = global_heap_buf; +// init_args.mem_alloc_option.pool.heap_size = sizeof(global_heap_buf); - /* set maximum thread number if needed when multi-thread is enabled, - the default value is 4 */ - init_args.max_thread_num = 4; +// /* set maximum thread number if needed when multi-thread is enabled, +// the default value is 4 */ +// init_args.max_thread_num = 4; - /* initialize runtime environment with user configurations*/ - if (!wasm_runtime_full_init(&init_args)) { - exit(-1); - } +// /* initialize runtime environment with user configurations*/ +// if (!wasm_runtime_full_init(&init_args)) { +// exit(-1); +// } - int n_native_symbols = sizeof(native_symbols) / sizeof(NativeSymbol); - if (!wasm_runtime_register_natives("env", native_symbols, n_native_symbols)) { - exit(-1); - } - uint32_t size; +// int n_native_symbols = sizeof(native_symbols) / sizeof(NativeSymbol); +// if (!wasm_runtime_register_natives("env", native_symbols, n_native_symbols)) { +// exit(-1); +// } +// uint32_t size; - std::error_code err; - if (!CreateDirectoryRecursive("mods", err)) { - // Report the error: - std::cout << "CreateDirectoryRecursive FAILED, err: " << err.message() << std::endl; - } +// std::error_code err; +// if (!CreateDirectoryRecursive("mods", err)) { +// // Report the error: +// std::cout << "CreateDirectoryRecursive FAILED, err: " << err.message() << std::endl; +// } - /* read WASM file into a memory buffer */ - for (const auto& entry : std::filesystem::directory_iterator("mods")) { - if (std::filesystem::is_regular_file(entry) && entry.path().extension() == ".wasm") { - std::string path = entry.path().string(); - std::string name = entry.path().stem().string(); - printf("found %s\n", name.c_str()); - buffer = read_wasm_binary_to_buffer((char*) path.c_str(), &size); - if (buffer == NULL) { - printf("error read binary\n"); - } - load_mod_wasm_file((char*) name.c_str(), buffer, size); - mod_call_function_wasm((char*) name.c_str(), "init", 0, NULL); - } - } - // buffer = read_wasm_binary_to_buffer("test.wasm", &size); - // if (buffer == NULL) { - // printf("error read binary\n"); - // exit(-1); - // } +// /* read WASM file into a memory buffer */ +// for (const auto& entry : std::filesystem::directory_iterator("mods")) { +// if (std::filesystem::is_regular_file(entry) && entry.path().extension() == ".wasm") { +// std::string path = entry.path().string(); +// std::string name = entry.path().stem().string(); +// printf("found %s\n", name.c_str()); +// buffer = read_wasm_binary_to_buffer((char*) path.c_str(), &size); +// if (buffer == NULL) { +// printf("error read binary\n"); +// } +// load_mod_wasm_file((char*) name.c_str(), buffer, size); +// mod_call_function_wasm((char*) name.c_str(), "init", 0, NULL); +// } +// } +// // buffer = read_wasm_binary_to_buffer("test.wasm", &size); +// // if (buffer == NULL) { +// // printf("error read binary\n"); +// // exit(-1); +// // } - // load_mod_wasm_file("test", buffer, size); +// // load_mod_wasm_file("test", buffer, size); - // uint32_t argv[2]; +// // uint32_t argv[2]; - // /* arguments are always transferred in 32-bit element */ - // argv[0] = 8; - // printf("run fib function\n"); - // /* call the WASM function */ - // if (mod_call_function_wasm("test", "fib", 1, argv)) { - // /* the return value is stored in argv[0] */ - // printf("fib function return: %d\n", argv[0]); - // } else { - // /* exception is thrown if call fails */ - // // wasm_runtime_dump_call_stack(exec_env); - // mod_print_exception("test"); - // } - // mod_call_function_wasm("test", "init", 0, NULL); - // exit(-1); -} \ No newline at end of file +// // /* arguments are always transferred in 32-bit element */ +// // argv[0] = 8; +// // printf("run fib function\n"); +// // /* call the WASM function */ +// // if (mod_call_function_wasm("test", "fib", 1, argv)) { +// // /* the return value is stored in argv[0] */ +// // printf("fib function return: %d\n", argv[0]); +// // } else { +// // /* exception is thrown if call fails */ +// // // wasm_runtime_dump_call_stack(exec_env); +// // mod_print_exception("test"); +// // } +// // mod_call_function_wasm("test", "init", 0, NULL); +// // exit(-1); +// } \ No newline at end of file diff --git a/src/enhancements/moon_jump.c b/src/enhancements/moon_jump.c new file mode 100644 index 000000000..b3fc44f2a --- /dev/null +++ b/src/enhancements/moon_jump.c @@ -0,0 +1,12 @@ +#include +#include "main.h" +#include "code_800029B0.h" +#include "common_structs.h" + +void moon_jump(Player* player, struct Controller* controller) { + if (controller->button & L_TRIG) { + if (player->velocity[1] <= 3.2f) { + player->velocity[1] += 0.5f; + } + } +} diff --git a/src/enhancements/moon_jump.h b/src/enhancements/moon_jump.h new file mode 100644 index 000000000..d0c386739 --- /dev/null +++ b/src/enhancements/moon_jump.h @@ -0,0 +1,10 @@ +#ifndef _MOON_JUMP_H +#define _MOON_JUMP_H + +#include +#include "main.h" +#include "code_800029B0.h" + +void moon_jump(Player*, struct Controller*); + +#endif // _MOON_JUMP_H \ No newline at end of file diff --git a/src/kart_dma.c b/src/kart_dma.c index 4403ff4d1..b81b22c4d 100644 --- a/src/kart_dma.c +++ b/src/kart_dma.c @@ -1350,7 +1350,7 @@ void load_kart_palette(Player* player, s8 playerId, s8 screenId, s8 buffer) { #else size = ResourceGetTexSizeByName(gKartPalettes[player->characterId]); asset = (u8*) LOAD_ASSET(gKartPalettes[player->characterId]); - memcpy(&gPlayerPalettesList[buffer][screenId][playerId], asset, size); + memcpy(&gPlayerPalettesList[buffer][screenId][playerId].kart_palette[0], asset, size); #endif break; @@ -1366,7 +1366,7 @@ void load_kart_palette(Player* player, s8 playerId, s8 screenId, s8 buffer) { #else size = ResourceGetTexSizeByName(gKartPalettes[player->characterId]); asset = (u8*) LOAD_ASSET(gKartPalettes[player->characterId]); - memcpy(&gPlayerPalettesList[buffer][screenId][playerId], asset, size); + memcpy(&gPlayerPalettesList[buffer][screenId][playerId].kart_palette[0], asset, size); #endif break; @@ -1392,7 +1392,7 @@ void load_player_data(UNUSED Player* player, s32 arg1, void* vAddr, u16 size) { * @param vAddr Virtual address * @param size Size of data to read */ -void load_player_data_non_blocking(UNUSED Player* player, const char* texture, void* vAddr, u16 size) { +void load_wheel_palette_non_blocking(UNUSED Player* player, const char* texture, void* vAddr, u16 size) { osInvalDCache(vAddr, size); #ifdef TARGET_N64 @@ -1400,9 +1400,7 @@ void load_player_data_non_blocking(UNUSED Player* player, const char* texture, v (uintptr_t) &_kart_texturesSegmentRomStart[SEGMENT_OFFSET(arg1)], vAddr, size, &gDmaMesgQueue); #else u16* tex = (u16*) LOAD_ASSET(texture); - // printf("wheeltex: %s\n",texture); size_t textureSize = ResourceGetTexSizeByName(texture); - // vAddr = texture; memcpy(vAddr, tex, size); #endif } diff --git a/src/kart_dma.h b/src/kart_dma.h index af7d00014..f48dad359 100644 --- a/src/kart_dma.h +++ b/src/kart_dma.h @@ -10,7 +10,7 @@ void load_kart_texture(Player*, s8, s8, s8, s8); void load_kart_texture_non_blocking(Player*, s8, s8, s8, s8); void load_kart_palette(Player*, s8, s8, s8); void load_player_data(Player*, s32, void*, u16); -void load_player_data_non_blocking(Player*, const char*, void*, u16); +void load_wheel_palette_non_blocking(Player*, const char*, void*, u16); /* This is where I'd put my static data, if I had any */ diff --git a/src/main.c b/src/main.c index f2a2a21ff..1435944b0 100644 --- a/src/main.c +++ b/src/main.c @@ -117,7 +117,9 @@ u8 gControllerBits; CollisionGrid gCollisionGrid[1024]; u16 gNumActors; u16 gMatrixObjectCount; -s32 gTickSpeed; +s32 gTickLogic; // Tick game physics at 60fps +s32 gTickVisuals; // Tick animations at 30fps +s32 gTickGame; f32 D_80150118; u16 wasSoftReset; @@ -146,7 +148,7 @@ u16* gPhysicalFramebuffers[3]; uintptr_t gPhysicalZBuffer; UNUSED u32 D_801502B8; UNUSED u32 D_801502BC; -Mat4 D_801502C0; +Mat4 sBillBoardMtx; // Faces 2D actors at the camera s32 padding[2048]; @@ -483,7 +485,7 @@ void* clear_framebuffer(s32 color) { void rendering_init(void) { gGfxPool = &gGfxPools[0]; - set_segment_base_addr(1, gGfxPool); + set_segment_base_addr_x64(1, gGfxPool); gGfxSPTask = &gGfxPool->spTask; gDisplayListHead = gGfxPool->gfxPool; init_rcp(); @@ -496,7 +498,7 @@ void rendering_init(void) { void config_gfx_pool(void) { gGfxPool = &gGfxPools[gGlobalTimer & 1]; - set_segment_base_addr(1, gGfxPool); + set_segment_base_addr_x64(1, gGfxPool); gDisplayListHead = gGfxPool->gfxPool; gGfxSPTask = &gGfxPool->spTask; } @@ -526,7 +528,9 @@ void display_and_vsync(void) { if (++sRenderingFramebuffer == 3) { sRenderingFramebuffer = 0; } - gGlobalTimer++; + if (gTickVisuals) { + gGlobalTimer++; + } } void init_segment_ending_sequences(void) { @@ -625,12 +629,166 @@ void game_init_clear_framebuffer(void) { clear_framebuffer(0); } -void race_logic_loop(void) { - s16 i; - u16 rotY; +void calculate_updaterate(void) { + static u32 prevtime = 0; + static u32 remainder = 0; + static u32 logicAccumulator = 0; + static u32 visualsAccumulator = 0; + static u32 frameCounter = 0; // For tracking frames for logic updates + u32 now = SDL_GetTicks(); // Replaces osGetTime() + u32 frameRate = 0; + s32 total; + // Get target FPS from configuration variable + s32 targetFPS = CVarGetInteger("gInterpolationFPS", 30); + + if (targetFPS < 60) { + targetFPS = 30; + } + + // Detect frame rate based on time passed + if (now > prevtime) { + total = (now - prevtime) + remainder; + } else { + // Handle counter reset (shouldn't happen with SDL_GetTicks, but kept for logic parity) + total = (0xffffffff - prevtime) + 1 + now + remainder; + } + + prevtime = now; + + // Avoid division by zero + if (total > 0) { + // Calculate approximate frame rate (milliseconds per frame) + frameRate = 1000 / total; // Frame rate in frames per second + } else { + frameRate = targetFPS; // Fallback to target FPS + } + + // Default both to no updates + gTickLogic = 0; + gTickVisuals = 0; + + // Calculate the update rates based on target FPS + s32 logicUpdateInterval = 1000 / 60; // Time in ms between logic updates + s32 visualsUpdateInterval = 1000 / 30; // 30 FPS for visuals + + // Accumulate time for logic updates + logicAccumulator += total; + if (logicAccumulator >= logicUpdateInterval) { + logicAccumulator -= logicUpdateInterval; // Subtract full interval + if (targetFPS < 60) { + gTickLogic = 2; + } else { + gTickLogic = 1; // Perform logic update + } + } + + // Visual updates (based on 30 FPS equivalent) + visualsAccumulator += total; // Increment for each frame + if (visualsAccumulator >= visualsUpdateInterval) { // Check if it's time to update visuals + visualsAccumulator -= visualsUpdateInterval; + gTickVisuals = 1; // Perform visual update + } +} + + + + + +void display_debug_info(void) { + u16 rotY; + if (!gEnableDebugMode) { + D_800DC514 = false; + } else if (D_800DC514) { + if ((gControllerOne->buttonPressed & R_TRIG) && + (gControllerOne->button & A_BUTTON) && + (gControllerOne->button & B_BUTTON)) { + D_800DC514 = false; + } + rotY = camera1->rot[1]; + gDebugPathCount = D_800DC5EC->pathCounter; + + if (rotY < 0x2000) { + func_80057A50(40, 100, "SOUTH ", gDebugPathCount); + } else if (rotY < 0x6000) { + func_80057A50(40, 100, "EAST ", gDebugPathCount); + } else if (rotY < 0xA000) { + func_80057A50(40, 100, "NORTH ", gDebugPathCount); + } else if (rotY < 0xE000) { + func_80057A50(40, 100, "WEST ", gDebugPathCount); + } else { + func_80057A50(40, 100, "SOUTH ", gDebugPathCount); + } + + } else if ((gControllerOne->buttonPressed & L_TRIG) && + (gControllerOne->button & A_BUTTON) && + (gControllerOne->button & B_BUTTON)) { + D_800DC514 = true; + } + + if (!gEnableDebugMode) { + gEnableResourceMeters = 0; + } else { + if (gEnableResourceMeters) { + resource_display(); + if (!(gControllerOne->button & L_TRIG) && + (gControllerOne->button & R_TRIG) && + (gControllerOne->buttonPressed & B_BUTTON)) { + gEnableResourceMeters = 0; + } + } else if (!(gControllerOne->button & L_TRIG) && + (gControllerOne->button & R_TRIG) && + (gControllerOne->buttonPressed & B_BUTTON)) { + gEnableResourceMeters = 1; + } + } +} + +void process_game_tick(void) { + if (D_8015011E) { + gCourseTimer += COURSE_TIMER_ITER; + } + func_802909F0(); + evaluate_collision_for_players_and_actors(); + func_800382DC(); + func_8001EE98(gPlayerOneCopy, camera1, 0); + + switch(gActiveScreenMode) { + case SCREEN_MODE_1P: + func_80028F70(); + break; + case SCREEN_MODE_2P_SPLITSCREEN_VERTICAL: + case SCREEN_MODE_2P_SPLITSCREEN_HORIZONTAL: + func_80029060(); + func_8001EE98(gPlayerTwoCopy, camera2, 1); + func_80029150(); + break; + case SCREEN_MODE_3P_4P_SPLITSCREEN: + func_80029158(); + func_8001EE98(gPlayerTwo, camera2, 1); + func_800291E8(); + func_8001EE98(gPlayerThree, camera3, 2); + func_800291F0(); + func_8001EE98(gPlayerFour, camera4, 3); + func_800291F8(); + break; + } + + func_8028F474(); + func_80059AC8(); + update_course_actors(); + CourseManager_TickActors(); + func_802966A0(); + func_8028FCBC(); +} + +void race_logic_loop(void) { + ClearMatrixPools(); + ClearObjectsMatrixPool(); + ClearEffectsMatrixPool(); gMatrixObjectCount = 0; gMatrixEffectCount = 0; + if (gIsGamePaused != 0) { func_80290B14(); } @@ -645,276 +803,94 @@ void race_logic_loop(void) { if (sNumVBlanks < 0) { sNumVBlanks = 1; } + func_802A4EF4(); - switch (gActiveScreenMode) { - case SCREEN_MODE_1P: - gTickSpeed = 2; - staff_ghosts_loop(); - - // Wait for all racers to load - if (gNetwork.enabled) { - network_all_players_loaded(); - } - - if (gIsGamePaused == 0) { - for (i = 0; i < gTickSpeed; i++) { - if (D_8015011E) { - gCourseTimer += COURSE_TIMER_ITER; - } - func_802909F0(); - evaluate_collision_for_players_and_actors(); - func_800382DC(); - func_8001EE98(gPlayerOneCopy, camera1, 0); - func_80028F70(); - func_8028F474(); - func_80059AC8(); - update_course_actors(); - CourseManager_TickActors(); - func_802966A0(); - func_8028FCBC(); - } - func_80022744(); - } - func_8005A070(); - sNumVBlanks = 0; - profiler_log_thread5_time(LEVEL_SCRIPT_EXECUTE); - D_8015F788 = 0; - render_player_one_1p_screen(); - if (!gEnableDebugMode) { - D_800DC514 = false; - } else { - if (D_800DC514) { - - if ((gControllerOne->buttonPressed & R_TRIG) && (gControllerOne->button & A_BUTTON) && - (gControllerOne->button & B_BUTTON)) { - D_800DC514 = false; - } - - rotY = camera1->rot[1]; - gDebugPathCount = D_800DC5EC->pathCounter; - if (rotY < 0x2000) { - func_80057A50(40, 100, "SOUTH ", gDebugPathCount); - } else if (rotY < 0x6000) { - func_80057A50(40, 100, "EAST ", gDebugPathCount); - } else if (rotY < 0xA000) { - func_80057A50(40, 100, "NORTH ", gDebugPathCount); - } else if (rotY < 0xE000) { - func_80057A50(40, 100, "WEST ", gDebugPathCount); - } else { - func_80057A50(40, 100, "SOUTH ", gDebugPathCount); - } - - } else { - if ((gControllerOne->buttonPressed & L_TRIG) && (gControllerOne->button & A_BUTTON) && - (gControllerOne->button & B_BUTTON)) { - D_800DC514 = true; - } - } - } - break; - - case SCREEN_MODE_2P_SPLITSCREEN_VERTICAL: - if (GetCourse() == GetDkJungle()) { - gTickSpeed = 3; - } else { - gTickSpeed = 2; - } - if (gIsGamePaused == 0) { - for (i = 0; i < gTickSpeed; i++) { - if (D_8015011E != 0) { - gCourseTimer += COURSE_TIMER_ITER; - } - func_802909F0(); - evaluate_collision_for_players_and_actors(); - func_800382DC(); - func_8001EE98(gPlayerOneCopy, camera1, 0); - func_80029060(); - func_8001EE98(gPlayerTwoCopy, camera2, 1); - func_80029150(); - func_8028F474(); - func_80059AC8(); - update_course_actors(); - func_802966A0(); - func_8028FCBC(); - } - func_80022744(); - } - func_8005A070(); - profiler_log_thread5_time(LEVEL_SCRIPT_EXECUTE); - sNumVBlanks = 0; - move_segment_table_to_dmem(); - init_rdp(); - if (D_800DC5B0 != 0) { - select_framebuffer(); - } - D_8015F788 = 0; - if (gPlayerWinningIndex == 0) { - render_player_two_2p_screen_vertical(); - render_player_one_2p_screen_vertical(); - } else { - render_player_one_2p_screen_vertical(); - render_player_two_2p_screen_vertical(); - } - break; - - case SCREEN_MODE_2P_SPLITSCREEN_HORIZONTAL: - - if (GetCourse() == GetDkJungle()) { - gTickSpeed = 3; - } else { - gTickSpeed = 2; - } - - if (gIsGamePaused == 0) { - for (i = 0; i < gTickSpeed; i++) { - if (D_8015011E != 0) { - gCourseTimer += COURSE_TIMER_ITER; - } - func_802909F0(); - evaluate_collision_for_players_and_actors(); - func_800382DC(); - func_8001EE98(gPlayerOneCopy, camera1, 0); - func_80029060(); - func_8001EE98(gPlayerTwoCopy, camera2, 1); - func_80029150(); - func_8028F474(); - func_80059AC8(); - update_course_actors(); - func_802966A0(); - func_8028FCBC(); - } - func_80022744(); - } - profiler_log_thread5_time(LEVEL_SCRIPT_EXECUTE); - sNumVBlanks = (u16) 0; - func_8005A070(); - move_segment_table_to_dmem(); - init_rdp(); - if (D_800DC5B0 != 0) { - select_framebuffer(); - } - D_8015F788 = 0; - if (gPlayerWinningIndex == 0) { - render_player_two_2p_screen_horizontal(); - render_player_one_2p_screen_horizontal(); - } else { - render_player_one_2p_screen_horizontal(); - render_player_two_2p_screen_horizontal(); - } - - break; - - case SCREEN_MODE_3P_4P_SPLITSCREEN: - if (gPlayerCountSelection1 == 3) { - switch (gCurrentCourseId) { - case COURSE_BOWSER_CASTLE: - case COURSE_MOO_MOO_FARM: - case COURSE_SKYSCRAPER: - case COURSE_DK_JUNGLE: - gTickSpeed = 3; - break; - default: - gTickSpeed = 2; - break; - } - } else { - // Four players - switch (gCurrentCourseId) { - case COURSE_BLOCK_FORT: - case COURSE_DOUBLE_DECK: - case COURSE_BIG_DONUT: - gTickSpeed = 2; - break; - case COURSE_DK_JUNGLE: - gTickSpeed = 4; - break; - default: - gTickSpeed = 3; - break; - } - } - if (gIsGamePaused == 0) { - for (i = 0; i < gTickSpeed; i++) { - if (D_8015011E != 0) { - gCourseTimer += COURSE_TIMER_ITER; - } - func_802909F0(); - evaluate_collision_for_players_and_actors(); - func_800382DC(); - func_8001EE98(gPlayerOneCopy, camera1, 0); - func_80029158(); - func_8001EE98(gPlayerTwo, camera2, 1); - func_800291E8(); - func_8001EE98(gPlayerThree, camera3, 2); - func_800291F0(); - func_8001EE98(gPlayerFour, camera4, 3); - func_800291F8(); - func_8028F474(); - func_80059AC8(); - update_course_actors(); - func_802966A0(); - func_8028FCBC(); - } - func_80022744(); - } - func_8005A070(); - sNumVBlanks = 0; - profiler_log_thread5_time(LEVEL_SCRIPT_EXECUTE); - move_segment_table_to_dmem(); - init_rdp(); - if (D_800DC5B0 != 0) { - select_framebuffer(); - } - D_8015F788 = 0; - if (gPlayerWinningIndex == 0) { - render_player_two_3p_4p_screen(); - render_player_three_3p_4p_screen(); - render_player_four_3p_4p_screen(); - render_player_one_3p_4p_screen(); - } else if (gPlayerWinningIndex == 1) { - render_player_one_3p_4p_screen(); - render_player_three_3p_4p_screen(); - render_player_four_3p_4p_screen(); - render_player_two_3p_4p_screen(); - } else if (gPlayerWinningIndex == 2) { - render_player_one_3p_4p_screen(); - render_player_two_3p_4p_screen(); - render_player_four_3p_4p_screen(); - render_player_three_3p_4p_screen(); - } else { - render_player_one_3p_4p_screen(); - render_player_two_3p_4p_screen(); - render_player_three_3p_4p_screen(); - render_player_four_3p_4p_screen(); - } - break; + if (gModeSelection == TIME_TRIALS) { + staff_ghosts_loop(); } - if (!gEnableDebugMode) { - gEnableResourceMeters = 0; - } else { - if (gEnableResourceMeters) { - resource_display(); - if ((!(gControllerOne->button & L_TRIG)) && (gControllerOne->button & R_TRIG) && - (gControllerOne->buttonPressed & B_BUTTON)) { - gEnableResourceMeters = 0; - } - } else { - if ((!(gControllerOne->button & L_TRIG)) && (gControllerOne->button & R_TRIG) && - (gControllerOne->buttonPressed & B_BUTTON)) { - gEnableResourceMeters = 1; - } + // Wait for all racers to load + if (gNetwork.enabled) { + network_all_players_loaded(); + } + + if (gIsGamePaused == 0) { + for (size_t i = 0; i < gTickLogic; i++) { + process_game_tick(); } + func_80022744(); } + func_8005A070(); + profiler_log_thread5_time(LEVEL_SCRIPT_EXECUTE); + sNumVBlanks = 0; + gNumScreens = 0; + move_segment_table_to_dmem(); + init_rdp(); + if (D_800DC5B0 != 0) { + select_framebuffer(); + } + + switch(gActiveScreenMode) { + case SCREEN_MODE_1P: + render_screens(RENDER_SCREEN_MODE_1P_PLAYER_ONE, 0, 0); + break; + case SCREEN_MODE_2P_SPLITSCREEN_HORIZONTAL: + if (gPlayerWinningIndex == 0) { + // In VS Mode the winning player's viewport takes over the whole screen. + // Rendering the winning player last places their screen above the other screens + render_screens(RENDER_SCREEN_MODE_2P_HORIZONTAL_PLAYER_TWO, 1, 1); + render_screens(RENDER_SCREEN_MODE_2P_HORIZONTAL_PLAYER_ONE, 0, 0); + } else { + render_screens(RENDER_SCREEN_MODE_2P_HORIZONTAL_PLAYER_ONE, 0, 0); + render_screens(RENDER_SCREEN_MODE_2P_HORIZONTAL_PLAYER_TWO, 1, 1); + } + break; + case SCREEN_MODE_2P_SPLITSCREEN_VERTICAL: + if (gPlayerWinningIndex == 0) { + render_screens(RENDER_SCREEN_MODE_2P_VERTICAL_PLAYER_TWO, 1, 1); + render_screens(RENDER_SCREEN_MODE_2P_VERTICAL_PLAYER_ONE, 0, 0); + } else { + render_screens(RENDER_SCREEN_MODE_2P_VERTICAL_PLAYER_ONE, 0, 0); + render_screens(RENDER_SCREEN_MODE_2P_VERTICAL_PLAYER_TWO, 1, 1); + } + break; + case SCREEN_MODE_3P_4P_SPLITSCREEN: + if (gPlayerWinningIndex == 0) { + render_screens(RENDER_SCREEN_MODE_3P_4P_PLAYER_TWO, 1, 1); + render_screens(RENDER_SCREEN_MODE_3P_4P_PLAYER_THREE, 2, 2); + render_screens(RENDER_SCREEN_MODE_3P_4P_PLAYER_FOUR, 3, 3); + render_screens(RENDER_SCREEN_MODE_3P_4P_PLAYER_ONE, 0, 0); + } else if (gPlayerWinningIndex == 1) { + render_screens(RENDER_SCREEN_MODE_3P_4P_PLAYER_ONE, 0, 0); + render_screens(RENDER_SCREEN_MODE_3P_4P_PLAYER_THREE, 2, 2); + render_screens(RENDER_SCREEN_MODE_3P_4P_PLAYER_FOUR, 3, 3); + render_screens(RENDER_SCREEN_MODE_3P_4P_PLAYER_TWO, 1, 1); + } else if (gPlayerWinningIndex == 2) { + + render_screens(RENDER_SCREEN_MODE_3P_4P_PLAYER_ONE, 0, 0); + render_screens(RENDER_SCREEN_MODE_3P_4P_PLAYER_TWO, 1, 1); + render_screens(RENDER_SCREEN_MODE_3P_4P_PLAYER_FOUR, 3, 3); + render_screens(RENDER_SCREEN_MODE_3P_4P_PLAYER_THREE, 2, 2); + } else { + render_screens(RENDER_SCREEN_MODE_3P_4P_PLAYER_ONE, 0, 0); + render_screens(RENDER_SCREEN_MODE_3P_4P_PLAYER_TWO, 1, 1); + render_screens(RENDER_SCREEN_MODE_3P_4P_PLAYER_THREE, 2, 2); + render_screens(RENDER_SCREEN_MODE_3P_4P_PLAYER_FOUR, 3, 3); + } + break; + } + + display_debug_info(); + func_802A4300(); func_800591B4(); func_80093E20(); #if DVDL display_dvdl(); #endif - // gDPFullSync(gDisplayListHead++); - // gSPEndDisplayList(gDisplayListHead++); + gDPFullSync(gDisplayListHead++); + gSPEndDisplayList(gDisplayListHead++); } /** @@ -1265,6 +1241,7 @@ void thread5_iteration(void) { } #endif + calculate_updaterate(); if (GfxDebuggerIsDebugging()) { Graphics_PushFrame(gGfxPool->gfxPool); return; @@ -1280,7 +1257,7 @@ void thread5_iteration(void) { read_controllers(); game_state_handler(); - call_render_hook(); + //call_render_hook(); end_master_display_list(); display_and_vsync(); diff --git a/src/main.h b/src/main.h index 2faec36f6..fd313838d 100644 --- a/src/main.h +++ b/src/main.h @@ -162,7 +162,8 @@ extern u8 gControllerBits; extern CollisionGrid gCollisionGrid[]; extern u16 gNumActors; extern u16 gMatrixObjectCount; -extern s32 gTickSpeed; +extern s32 gTickLogic; +extern s32 gTickVisuals; extern f32 D_80150118; extern u16 wasSoftReset; extern u16 D_8015011E; @@ -183,7 +184,7 @@ extern s32 D_801502A0; extern s32 D_801502A4; extern u16* gPhysicalFramebuffers[]; extern uintptr_t gPhysicalZBuffer; -extern Mat4 D_801502C0; +extern Mat4 sBillBoardMtx; extern s32 padding[]; diff --git a/src/math_util_2.c b/src/math_util_2.c index 3e0346b80..7ea23aded 100644 --- a/src/math_util_2.c +++ b/src/math_util_2.c @@ -640,8 +640,6 @@ void set_matrix_hud_screen(void) { G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_PROJECTION); } -// void convert_to_fixed_point_matrix(Mtx*, Mat4); - UNUSED void func_80041F54(s32 x, s32 y) { Mat4 matrix; @@ -700,9 +698,11 @@ UNUSED void func_800421FC(s32 x, s32 y, f32 scale) { void func_80042330(s32 x, s32 y, u16 angle, f32 scale) { Mat4 matrix; mtxf_translation_x_y_rotate_z_scale_x_y(matrix, x, y, angle, scale); - convert_to_fixed_point_matrix(&gGfxPool->mtxHud[gMatrixHudCount], matrix); - gSPMatrix(gDisplayListHead++, VIRTUAL_TO_PHYSICAL(&gGfxPool->mtxHud[gMatrixHudCount++]), - G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + // convert_to_fixed_point_matrix(&gGfxPool->mtxHud[gMatrixHudCount], matrix); + // gSPMatrix(gDisplayListHead++, VIRTUAL_TO_PHYSICAL(&gGfxPool->mtxHud[gMatrixHudCount++]), + // G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + + AddHudMatrix(matrix, G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); } UNUSED void func_800423F0(Mat4 arg0, u16 arg1, u16 arg2, u16 arg3) { @@ -963,18 +963,22 @@ void rsp_set_matrix_transformation(Vec3f translate, Vec3su orientation, f32 scal Mat4 matrix; mtxf_set_matrix_transformation(matrix, translate, orientation, scale); - convert_to_fixed_point_matrix(&gGfxPool->mtxHud[gMatrixHudCount], matrix); - gSPMatrix(gDisplayListHead++, VIRTUAL_TO_PHYSICAL(&gGfxPool->mtxHud[gMatrixHudCount++]), - G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + // convert_to_fixed_point_matrix(&gGfxPool->mtxHud[gMatrixHudCount], matrix); + // gSPMatrix(gDisplayListHead++, VIRTUAL_TO_PHYSICAL(&gGfxPool->mtxHud[gMatrixHudCount++]), + // G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + + AddHudMatrix(matrix, G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); } UNUSED void rsp_set_matrix_diff_translation_scale(Vec3f pos1, Vec3f pos2, f32 scale) { Mat4 matrix; mtxf_set_matrix_scale_transl(matrix, pos1, pos2, scale); - convert_to_fixed_point_matrix(&gGfxPool->mtxHud[gMatrixHudCount], matrix); - gSPMatrix(gDisplayListHead++, VIRTUAL_TO_PHYSICAL(&gGfxPool->mtxHud[gMatrixHudCount++]), - G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + // convert_to_fixed_point_matrix(&gGfxPool->mtxHud[gMatrixHudCount], matrix); + // gSPMatrix(gDisplayListHead++, VIRTUAL_TO_PHYSICAL(&gGfxPool->mtxHud[gMatrixHudCount++]), + // G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + + AddHudMatrix(matrix, G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); } void rsp_set_matrix_transformation_inverted_x_y_orientation(Vec3f arg0, Vec3su arg1, f32 arg2) { @@ -985,27 +989,31 @@ void rsp_set_matrix_transformation_inverted_x_y_orientation(Vec3f arg0, Vec3su a orientation[1] = arg1[1] + 0x8000; // change the sign orientation[2] = arg1[2]; mtxf_set_matrix_transformation(matrix, arg0, orientation, arg2); - convert_to_fixed_point_matrix(&gGfxPool->mtxHud[gMatrixHudCount], matrix); + // convert_to_fixed_point_matrix(&gGfxPool->mtxHud[gMatrixHudCount], matrix); - gSPMatrix(gDisplayListHead++, VIRTUAL_TO_PHYSICAL(&gGfxPool->mtxHud[gMatrixHudCount++]), - G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + // gSPMatrix(gDisplayListHead++, VIRTUAL_TO_PHYSICAL(&gGfxPool->mtxHud[gMatrixHudCount++]), + // G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + AddHudMatrix(matrix, G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); } void rsp_set_matrix_transl_rot_scale(Vec3f arg0, Vec3f arg1, f32 arg2) { Mat4 matrix; set_transform_matrix(matrix, arg1, arg0, 0, arg2); - convert_to_fixed_point_matrix(&gGfxPool->mtxHud[gMatrixHudCount], matrix); - gSPMatrix(gDisplayListHead++, VIRTUAL_TO_PHYSICAL(&gGfxPool->mtxHud[gMatrixHudCount++]), - G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + // convert_to_fixed_point_matrix(&gGfxPool->mtxHud[gMatrixHudCount], matrix); + // gSPMatrix(gDisplayListHead++, VIRTUAL_TO_PHYSICAL(&gGfxPool->mtxHud[gMatrixHudCount++]), + // G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + AddHudMatrix(matrix, G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); } void rsp_set_matrix_gObjectList(s32 transformIndex) { Mat4 matrix; mtxf_set_matrix_gObjectList(transformIndex, matrix); - convert_to_fixed_point_matrix(&gGfxPool->mtxHud[gMatrixHudCount], matrix); + // convert_to_fixed_point_matrix(&gGfxPool->mtxHud[gMatrixHudCount], matrix); - gSPMatrix(gDisplayListHead++, VIRTUAL_TO_PHYSICAL(&gGfxPool->mtxHud[gMatrixHudCount++]), - G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + // gSPMatrix(gDisplayListHead++, VIRTUAL_TO_PHYSICAL(&gGfxPool->mtxHud[gMatrixHudCount++]), + // G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + + AddHudMatrix(matrix, G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); } diff --git a/src/menus.c b/src/menus.c index 676169ae6..9bbd14332 100644 --- a/src/menus.c +++ b/src/menus.c @@ -123,7 +123,7 @@ const s8 D_800F2BAC[] = { const s16 gCupCourseOrder[5][4] = { // mushroom cup - { COURSE_LUIGI_RACEWAY, COURSE_MOO_MOO_FARM, COURSE_KOOPA_BEACH, COURSE_KALAMARI_DESERT }, + { COURSE_LUIGI_RACEWAY, COURSE_MOO_MOO_FARM, COURSE_KOOPA_BEACH, COURSE_KALIMARI_DESERT }, // flower cup { COURSE_TOADS_TURNPIKE, COURSE_FRAPPE_SNOWLAND, COURSE_CHOCO_MOUNTAIN, COURSE_MARIO_RACEWAY }, // star cup @@ -1387,12 +1387,12 @@ void main_menu_act(struct Controller* controller, u16 arg1) { if (btnAndStick & D_JPAD) { sp24 = false; if (has_unlocked_extra_mode()) { - if (sp28 < gGameModePlayerColumnExtra[gPlayerCount - 1][D_800E86AC[gPlayerCount - 1] + 1]) { + if (sp28 < gGameModePlayerColumnExtra[gPlayerCount + 4][D_800E86AC[gPlayerCount - 1] + 1]) { sp24 = true; } } else { // L800B30D4 - if (sp28 < gGameModePlayerColumnDefault[gPlayerCount - 1][D_800E86AC[gPlayerCount - 1] + 1]) { + if (sp28 < gGameModePlayerColumnDefault[gPlayerCount][D_800E86AC[gPlayerCount - 1] + 1]) { sp24 = true; } } diff --git a/src/player_controller.c b/src/player_controller.c index 852e8ef5d..180a62290 100644 --- a/src/player_controller.c +++ b/src/player_controller.c @@ -21,6 +21,7 @@ #include "code_80005FD0.h" #include "sounds.h" #include "port/Game.h" +#include "src/enhancements/moon_jump.h" extern s32 D_8018D168; @@ -635,6 +636,7 @@ UNUSED void func_80028F5C(UNUSED s32 arg0, UNUSED s32 arg1, UNUSED s32 arg2, UNU } void func_80028F70(void) { + ClearEffectsMatrixPool(); gMatrixEffectCount = 0; func_80028E70(gPlayerOneCopy, camera1, 0, 0); func_80028E70(gPlayerTwo, camera1, 1, 0); @@ -647,6 +649,7 @@ void func_80028F70(void) { } void func_80029060(void) { + ClearEffectsMatrixPool(); gMatrixEffectCount = 0; func_80028E70(gPlayerOneCopy, camera1, 0, 0); func_80028E70(gPlayerTwo, camera1, 1, 0); @@ -662,6 +665,7 @@ void func_80029150(void) { } void func_80029158(void) { + ClearEffectsMatrixPool(); gMatrixEffectCount = 0; func_80028E70(gPlayerOneCopy, camera1, 0, 0); func_80028E70(gPlayerTwo, camera1, 1, 0); @@ -4478,6 +4482,11 @@ void func_80037BB4(Player* player, Vec3f arg1) { } void func_80037CFC(Player* player, struct Controller* controller, s8 arg2) { + + if (CVarGetInteger("gEnableMoonJump", 0)) { + moon_jump(player, controller); + } + if (((player->effects & 0x80) != 0x80) && ((player->effects & 0x40) != 0x40) && ((player->effects & 0x400) != 0x400) && ((player->effects & 0x4000) != 0x4000) && ((player->effects & 0x01000000) != 0x01000000) && diff --git a/src/port/Engine.cpp b/src/port/Engine.cpp index 22c14b38f..66b8cd2c3 100644 --- a/src/port/Engine.cpp +++ b/src/port/Engine.cpp @@ -156,7 +156,7 @@ void GameEngine::ProcessGfxCommands(Gfx* commands) { RunCommands(commands); auto wnd = std::dynamic_pointer_cast(Ship::Context::GetInstance()->GetWindow()); if (wnd != nullptr) { - wnd->SetTargetFps(30); + wnd->SetTargetFps(CVarGetInteger("gInterpolationFPS", 30)); wnd->SetMaximumFrameLatency(1); } } diff --git a/src/port/Game.cpp b/src/port/Game.cpp index 9787f4562..d9f9ee8d9 100644 --- a/src/port/Game.cpp +++ b/src/port/Game.cpp @@ -39,7 +39,7 @@ extern "C" { #include "audio/load.h" #include "audio/external.h" #include "networking/networking.h" -#include "engine/wasm.h" +//#include "engine/wasm.h" } extern "C" void Graphics_PushFrame(Gfx* data) { @@ -143,8 +143,9 @@ void CustomEngineInit() { /* Set default course; mario raceway */ gWorldInstance.CurrentCourse = gMarioRaceway; - gWorldInstance.CurrentCup = gFlowerCup; + gWorldInstance.CurrentCup = gMushroomCup; gWorldInstance.CurrentCup->CursorPosition = 3; + gWorldInstance.CupIndex = 0; } extern "C" { @@ -170,7 +171,6 @@ extern "C" { } u32 GetCupIndex(void) { - printf("Cup Index: %d\n", gWorldInstance.GetCupIndex()); return gWorldInstance.GetCupIndex(); } @@ -200,10 +200,19 @@ extern "C" { gWorldInstance.NextCourse(); } + void PreviousCourse() { gWorldInstance.PreviousCourse(); } + void SetCourseById(s32 course) { + if (course < 0 || course >= gWorldInstance.Courses.size()) { + return; + } + gWorldInstance.CourseIndex = course; + gWorldInstance.CurrentCourse = gWorldInstance.Courses[gWorldInstance.CourseIndex]; + } + void CourseManager_SpawnVehicles() { if (gWorldInstance.CurrentCourse) { gWorldInstance.CurrentCourse->SpawnVehicles(); @@ -234,7 +243,47 @@ extern "C" { } } - void CourseManager_RenderTrucks(s32 playerId) { + void CourseManager_SpawnBombKarts() { + for (auto& kart : gWorldInstance.BombKarts) { + if (kart) { + kart->Spawn(); + } + } + } + + void CourseManager_TickBombKarts() { + for (auto& kart : gWorldInstance.BombKarts) { + if (kart) { + kart->Tick(); + } + } + } + + void CourseManager_DrawBombKarts(s32 cameraId) { + for (auto& kart : gWorldInstance.BombKarts) { + if (kart) { + kart->Draw(cameraId); + } + } + } + + void CourseManager_DrawBattleBombKarts(s32 cameraId) { + for (auto& kart : gWorldInstance.BombKarts) { + if (kart) { + kart->DrawBattle(cameraId); + } + } + } + + void CourseManager_BombKartsWaypoint(s32 cameraId) { + for (auto& kart : gWorldInstance.BombKarts) { + if (kart) { + kart->Waypoint(cameraId); + } + } + } + + void CourseManager_DrawVehicles(s32 playerId) { for (auto& vehicle : gWorldInstance.Vehicles) { if (vehicle) { vehicle->Draw(playerId); @@ -242,8 +291,8 @@ extern "C" { } } - void CourseManager_ResetVehicles(void) { - gWorldInstance.ResetVehicles(); + void CourseManager_ClearVehicles(void) { + gWorldInstance.ClearVehicles(); } void CourseManager_CrossingTrigger() { @@ -301,9 +350,10 @@ extern "C" { } } - void CourseManager_DrawActors(Camera* camera) { - if (gWorldInstance.CurrentCourse) { - gWorldInstance.DrawActors(camera); + void CourseManager_DrawActor(Camera* camera, struct Actor* actor) { + AActor* a = gWorldInstance.ConvertActorToAActor(actor); + if (a->IsMod()) { + a->Draw(camera); } } @@ -331,12 +381,6 @@ extern "C" { } } - void CourseManager_GenerateCollision() { - if (gWorldInstance.CurrentCourse) { - gWorldInstance.CurrentCourse->GenerateCollision(); - } - } - void CourseManager_SomeCollisionThing(Player* player, Vec3f arg1, Vec3f arg2, Vec3f arg3, f32* arg4, f32* arg5, f32* arg6, f32* arg7) { if (gWorldInstance.CurrentCourse) { @@ -374,9 +418,9 @@ extern "C" { } } - void CourseManager_SetCourseVtxColours() { + void CourseManager_CreditsSpawnActors() { if (gWorldInstance.CurrentCourse) { - gWorldInstance.CurrentCourse->SetCourseVtxColours(); + gWorldInstance.CurrentCourse->CreditsSpawnActors(); } } @@ -410,15 +454,15 @@ extern "C" { } } - void CourseManager_SpawnBombKarts() { + void CourseManager_ScrollingTextures() { if (gWorldInstance.CurrentCourse) { - gWorldInstance.CurrentCourse->SpawnBombKarts(); + gWorldInstance.CurrentCourse->ScrollingTextures(); } } - void CourseManager_Water() { + void CourseManager_DrawWater(struct UnkStruct_800DC5EC* screen, uint16_t pathCounter, uint16_t cameraRot, uint16_t playerDirection) { if (gWorldInstance.CurrentCourse) { - gWorldInstance.CurrentCourse->Water(); + gWorldInstance.CurrentCourse->DrawWater(screen, pathCounter, cameraRot, playerDirection); } } @@ -447,6 +491,57 @@ extern "C" { gWorldInstance.CurrentCourse = (Course*) course; } + struct Actor* m_GetActor(size_t index) { + if (index < gWorldInstance.Actors.size()) { + AActor* actor = gWorldInstance.Actors[index]; + return reinterpret_cast(reinterpret_cast(actor) + sizeof(void*)); + } else { + //throw std::runtime_error("GetActor() index out of bounds"); + return NULL; + } + } + + size_t m_FindActorIndex(Actor* actor) { + // Move the ptr back to look at the vtable. + // This gets us the proper C++ class instead of just the variables used in C. + AActor* a = reinterpret_cast((char*)actor - sizeof(void*)); + auto actors = gWorldInstance.Actors; + + auto it = std::find(actors.begin(), actors.end(), static_cast(a)); + if (it != actors.end()) { + return std::distance(actors.begin(), it); + } + printf("FindActorIndex() actor not found\n"); + return 0; + } + + void m_DeleteActor(size_t index) { + std::vector actors = gWorldInstance.Actors; + if (index < actors.size()) { + actors.erase(actors.begin() + index); + } + } + + void m_ClearActors(void) { + gWorldInstance.Actors.clear(); + } + + struct Actor* m_AddBaseActor(void) { + return (struct Actor*) gWorldInstance.AddBaseActor(); + } + + size_t m_GetActorSize() { + return gWorldInstance.Actors.size(); + } + + void m_ActorCollision(Player* player, Actor* actor) { + AActor* a = gWorldInstance.ConvertActorToAActor(actor); + + if (a->IsMod()) { + a->Collision(player, a); + } + } + void* GetMarioRaceway(void) { return gMarioRaceway; } @@ -571,7 +666,7 @@ extern "C" int main(int argc, char* argv[]) { #endif - load_wasm(); + //load_wasm(); GameEngine::Create(); // audio_init(); // sound_init(); diff --git a/src/port/Game.h b/src/port/Game.h index 64fa0fb3a..1dbaaa519 100644 --- a/src/port/Game.h +++ b/src/port/Game.h @@ -8,6 +8,7 @@ extern "C" { #include "camera.h" #endif +#include "actor_types.h" u32 WorldNextCup(void); @@ -44,12 +45,12 @@ void CourseManager_SpawnActors(); void CourseManager_InitClouds(); +void CourseManager_DrawActor(Camera* camera, struct Actor* actor); + void CourseManager_UpdateClouds(s32 arg0, Camera* camera); void CourseManager_Waypoints(Player* player, int8_t playerId); -void CourseManager_GenerateCollision(); - void CourseManager_SomeCollisionThing(Player* player, Vec3f arg1, Vec3f arg2, Vec3f arg3, f32* arg4, f32* arg5, f32* arg6, f32* arg7); @@ -63,7 +64,7 @@ void CourseManager_RenderCourseObjects(s32 cameraId); void CourseManager_SomeSounds(); -void CourseManager_SetCourseVtxColours(); +void CourseManager_CreditsSpawnActors(); void CourseManager_WhatDoesThisDo(Player* player, int8_t playerId); @@ -77,7 +78,9 @@ CProperties* CourseManager_GetProps(); void CourseManager_SpawnBombKarts(); -void CourseManager_Water(); +void CourseManager_BombKartsWaypoint(s32 cameraId); + +void CourseManager_ScrollingTextures(); size_t GetCupCursorPosition(); @@ -91,6 +94,11 @@ void* GetCourse(void); void SetCourseByClass(void* course); +struct Actor* m_GetActor(size_t index); +void m_DeleteActor(size_t index); +struct Actor* m_AddBaseActor(void); +size_t m_GetActorSize(); + void* GetMarioRaceway(void); void* GetLuigiRaceway(void); diff --git a/src/port/ui/ImguiUI.cpp b/src/port/ui/ImguiUI.cpp index ed4575767..3ce6ed934 100644 --- a/src/port/ui/ImguiUI.cpp +++ b/src/port/ui/ImguiUI.cpp @@ -297,7 +297,7 @@ void DrawSettingsMenu() { currentFps = 60; } CVarSetInteger("gInterpolationFPS", currentFps); - Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesOnNextTick(); + Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesNextFrame(); #else bool matchingRefreshRate = CVarGetInteger("gMatchRefreshRate", 0) && @@ -326,7 +326,7 @@ void DrawSettingsMenu() { int hz = Ship::Context::GetInstance()->GetWindow()->GetCurrentRefreshRate(); if (hz >= 30 && hz <= 360) { CVarSetInteger("gInterpolationFPS", hz); - Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesOnNextTick(); + Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesNextFrame(); } } } else { @@ -491,6 +491,7 @@ void DrawEnhancementsMenu() { void DrawCheatsMenu() { if (UIWidgets::BeginMenu("Cheats")) { + UIWidgets::CVarCheckbox("Moon Jump", "gEnableMoonJump"); UIWidgets::CVarCheckbox("Enable Custom CC", "gEnableCustomCC"); UIWidgets::CVarSliderFloat("Custom CC", "gCustomCC", 0.0, 1000.0, 150.0, { .step = 10.0 }); UIWidgets::CVarCheckbox("Disable Wall Collision", "gNoWallColision", { .tooltip = "Disable wall collision." }); diff --git a/src/port/ui/MultiplayerWindow.cpp b/src/port/ui/MultiplayerWindow.cpp index bc1ba1a2e..098d277f1 100644 --- a/src/port/ui/MultiplayerWindow.cpp +++ b/src/port/ui/MultiplayerWindow.cpp @@ -14,7 +14,6 @@ extern "C" { #include "actor_types.h" #include "code_800029B0.h" extern struct Actor gActorList[]; -extern char* gCourseNames[]; extern char* gCupNames[]; extern char* D_800E76A8[]; extern Network gNetwork; diff --git a/src/port/ui/ResolutionEditor.cpp b/src/port/ui/ResolutionEditor.cpp index 54cc0c9c5..dbc9259d7 100644 --- a/src/port/ui/ResolutionEditor.cpp +++ b/src/port/ui/ResolutionEditor.cpp @@ -59,7 +59,7 @@ void AdvancedResolutionSettingsWindow::DrawElement() { for (unsigned short i = 0; i < sizeof(setting); i++) update[i] = false; static short updateCountdown = 0; - short countdownStartingValue = CVarGetInteger("gInterpolationFPS", 20) / 2; // half of a second, in frames. + short countdownStartingValue = CVarGetInteger("gInterpolationFPS", 30) / 2; // half of a second, in frames. // Initialise integer scale bounds. short max_integerScaleFactor = default_maxIntegerScaleFactor; // default value, which may or may not get @@ -408,7 +408,7 @@ void AdvancedResolutionSettingsWindow::UpdateElement() { bool AdvancedResolutionSettingsWindow::IsDroppingFrames() { // a rather imprecise way of checking for frame drops. // but it's mostly there to inform the player of large drops. - const short targetFPS = CVarGetInteger("gInterpolationFPS", 20); + const short targetFPS = CVarGetInteger("gInterpolationFPS", 30); const float threshold = targetFPS / 20.0f + 4.1f; return ImGui::GetIO().Framerate < targetFPS - threshold; } diff --git a/src/port/ui/UIWidgets.cpp b/src/port/ui/UIWidgets.cpp index f1e3badca..b97256765 100644 --- a/src/port/ui/UIWidgets.cpp +++ b/src/port/ui/UIWidgets.cpp @@ -216,7 +216,7 @@ bool EnhancementCheckbox(const char* text, const char* cvarName, bool disabled, bool val = (bool) CVarGetInteger(cvarName, defaultValue); if (CustomCheckbox(text, &val, disabled, disabledGraphic)) { CVarSetInteger(cvarName, val); - Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesOnNextTick(); + Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesNextFrame(); changed = true; } @@ -260,7 +260,7 @@ bool EnhancementCombobox(const char* cvarName, std::spanGetWindow()->GetGui()->SaveConsoleVariablesOnNextTick(); + Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesNextFrame(); } } } @@ -273,7 +273,7 @@ bool EnhancementCombobox(const char* cvarName, std::span= 0 && selected != disabledValue) { CVarSetInteger(cvarName, disabledValue); changed = true; - Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesOnNextTick(); + Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesNextFrame(); } } @@ -369,7 +369,7 @@ bool EnhancementSliderInt(const char* text, const char* id, const char* cvarName if (changed) { CVarSetInteger(cvarName, val); - Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesOnNextTick(); + Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesNextFrame(); } return changed; @@ -448,7 +448,7 @@ bool EnhancementSliderFloat(const char* text, const char* id, const char* cvarNa if (changed) { CVarSetFloat(cvarName, val); - Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesOnNextTick(); + Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesNextFrame(); } return changed; @@ -505,7 +505,7 @@ bool EnhancementRadioButton(const char* text, const char* cvarName, int id) { int val = CVarGetInteger(cvarName, 0); if (ImGui::RadioButton(make_invisible.c_str(), id == val)) { CVarSetInteger(cvarName, id); - Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesOnNextTick(); + Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesNextFrame(); ret = true; } ImGui::SameLine(); @@ -532,7 +532,7 @@ bool DrawResetColorButton(const char* cvarName, ImVec4* colors, ImVec4 defaultco CVarSetColor(cvarName, colorsRGBA); CVarSetInteger(Cvar_RBM.c_str(), 0); // On click disable rainbow mode. - Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesOnNextTick(); + Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesNextFrame(); changed = true; } Tooltip("Revert colors to the game's original colors (GameCube version)\nOverwrites previously chosen color"); @@ -805,7 +805,7 @@ bool CVarCheckbox(const char* label, const char* cvarName, const CheckboxOptions bool value = (bool) CVarGetInteger(cvarName, options.defaultValue); if (Checkbox(label, &value, options)) { CVarSetInteger(cvarName, value); - Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesOnNextTick(); + Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesNextFrame(); dirty = true; } return dirty; @@ -914,7 +914,7 @@ bool CVarCombobox(const char* label, const char* cvarName, std::spanGetWindow()->GetGui()->SaveConsoleVariablesOnNextTick(); + Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesNextFrame(); dirty = true; } return dirty; @@ -962,7 +962,7 @@ bool SliderInt(const char* label, int32_t* value, int32_t min, int32_t max, cons *value -= options.step; if (*value < min) *value = min; - Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesOnNextTick(); + Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesNextFrame(); dirty = true; } ImGui::SameLine(0, 3.0f); @@ -971,7 +971,7 @@ bool SliderInt(const char* label, int32_t* value, int32_t min, int32_t max, cons ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x); } if (ImGui::SliderScalar(invisibleLabel, ImGuiDataType_S32, value, &min, &max, options.format, options.flags)) { - Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesOnNextTick(); + Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesNextFrame(); dirty = true; } if (options.showButtons) { @@ -981,7 +981,7 @@ bool SliderInt(const char* label, int32_t* value, int32_t min, int32_t max, cons *value += options.step; if (*value > max) *value = max; - Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesOnNextTick(); + Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesNextFrame(); dirty = true; } } @@ -1004,7 +1004,7 @@ bool CVarSliderInt(const char* label, const char* cvarName, int32_t min, int32_t int32_t value = CVarGetInteger(cvarName, defaultValue); if (SliderInt(label, &value, min, max, options)) { CVarSetInteger(cvarName, value); - Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesOnNextTick(); + Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesNextFrame(); dirty = true; } return dirty; @@ -1037,7 +1037,7 @@ bool SliderFloat(const char* label, float* value, float min, float max, const Fl *value -= options.step; if (*value < min) *value = min; - Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesOnNextTick(); + Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesNextFrame(); dirty = true; } ImGui::SameLine(0, 3.0f); @@ -1048,7 +1048,7 @@ bool SliderFloat(const char* label, float* value, float min, float max, const Fl if (ImGui::SliderScalar(invisibleLabel, ImGuiDataType_Float, &valueToDisplay, &minToDisplay, &maxToDisplay, options.format, options.flags)) { *value = options.isPercentage ? valueToDisplay / 100.0f : valueToDisplay; - Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesOnNextTick(); + Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesNextFrame(); dirty = true; } if (options.showButtons) { @@ -1058,7 +1058,7 @@ bool SliderFloat(const char* label, float* value, float min, float max, const Fl *value += options.step; if (*value > max) *value = max; - Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesOnNextTick(); + Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesNextFrame(); dirty = true; } } @@ -1081,7 +1081,7 @@ bool CVarSliderFloat(const char* label, const char* cvarName, float min, float m float value = CVarGetFloat(cvarName, defaultValue); if (SliderFloat(label, &value, min, max, options)) { CVarSetFloat(cvarName, value); - Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesOnNextTick(); + Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesNextFrame(); dirty = true; } return dirty; diff --git a/src/racing/actors.c b/src/racing/actors.c index 075ed86c3..7ebdfd5f1 100644 --- a/src/racing/actors.c +++ b/src/racing/actors.c @@ -54,7 +54,7 @@ void cleanup_red_and_green_shells(struct ShellActor* shell) { // try finding the dead green shell for (actorIndex = gNumPermanentActors; actorIndex < ACTOR_LIST_SIZE; actorIndex++) { - compare = (struct ShellActor*) &gActorList[actorIndex]; + compare = (struct ShellActor*) m_GetActor(actorIndex); if ((shell != compare) && !(compare->flags & ACTOR_IS_NOT_EXPIRED) && (compare->type == ACTOR_GREEN_SHELL)) { if (compare->state == MOVING_SHELL) { delete_actor_in_unexpired_actor_list(actorIndex); @@ -67,7 +67,7 @@ void cleanup_red_and_green_shells(struct ShellActor* shell) { // try finding the dead red shell for (actorIndex = gNumPermanentActors; actorIndex < ACTOR_LIST_SIZE; actorIndex++) { - compare = (struct ShellActor*) &gActorList[actorIndex]; + compare = (struct ShellActor*) m_GetActor(actorIndex); if ((shell != compare) && !(compare->flags & ACTOR_IS_NOT_EXPIRED) && (compare->type == ACTOR_RED_SHELL)) { switch (compare->state) { case MOVING_SHELL: @@ -89,7 +89,7 @@ void cleanup_red_and_green_shells(struct ShellActor* shell) { // try finding the green shell for (actorIndex = gNumPermanentActors; actorIndex < ACTOR_LIST_SIZE; actorIndex++) { - compare = (struct ShellActor*) &gActorList[actorIndex]; + compare = (struct ShellActor*) m_GetActor(actorIndex); if ((shell != compare) && (compare->type == ACTOR_GREEN_SHELL)) { switch (compare->state) { case MOVING_SHELL: @@ -104,7 +104,7 @@ void cleanup_red_and_green_shells(struct ShellActor* shell) { // try finding the red or blue shell for (actorIndex = gNumPermanentActors; actorIndex < ACTOR_LIST_SIZE; actorIndex++) { - compare = (struct ShellActor*) &gActorList[actorIndex]; + compare = (struct ShellActor*) m_GetActor(actorIndex); if ((shell != compare) && (compare->type == ACTOR_RED_SHELL)) { switch (compare->state) { case MOVING_SHELL: @@ -194,6 +194,9 @@ void actor_init(struct Actor* actor, Vec3f startingPos, Vec3s startingRot, Vec3f actor->boundingBoxSize = 3.0f; actor->unk_08 = 20.0f; break; + case ACTOR_MARIO_SIGN: + actor->flags |= 0x4000; + break; case ACTOR_TREE_YOSHI_VALLEY: actor->flags |= 0x4000; actor->state = 0x0043; @@ -323,7 +326,7 @@ void actor_rendered(Camera* arg0, struct Actor* arg1) { } void func_80297340(Camera* arg0) { - Mat4 sp38; + Mat4 mtx; s16 temp = D_8015F8D0[2]; s32 maxObjectsReached; @@ -331,9 +334,9 @@ void func_80297340(Camera* arg0) { return; } - mtxf_translate(sp38, D_8015F8D0); + mtxf_translate(mtx, D_8015F8D0); - maxObjectsReached = render_set_position(sp38, 0) == 0; + maxObjectsReached = render_set_position(mtx, 0) == 0; if (maxObjectsReached) { return; } @@ -476,7 +479,7 @@ void update_actor_static_plant(struct Actor* arg0) { #include "actors/piranha_plant/render.inc.c" -void render_cows(Camera* camera, Mat4 arg1, UNUSED struct Actor* actor) { +void render_cows(Camera* camera, Mat4 arg1) { u16 temp_s1; f32 temp_f0; struct ActorSpawnData* var_t1; @@ -594,7 +597,7 @@ void func_80298D10(void) { } } -void render_palm_trees(Camera* camera, Mat4 arg1, UNUSED struct Actor* actor) { +void render_palm_trees(Camera* camera, Mat4 arg1) { struct UnkActorSpawnData* var_s1 = (struct UnkActorSpawnData*) LOAD_ASSET(d_course_dks_jungle_parkway_tree_spawn); UNUSED s32 pad; Vec3f spD4; @@ -754,7 +757,7 @@ UNUSED s16 D_802B8810[] = { 0x0fc0, 0x0000, 0xffff, 0xffff, 0x0014, 0x0000, 0x00 UNUSED void func_8029ABD4(f32* pos, s16 state) { gNumActors = 0; - gActorList[spawn_actor_at_pos(pos, ACTOR_UNKNOWN_0x14)].state = state; + GET_ACTOR(spawn_actor_at_pos(pos, ACTOR_UNKNOWN_0x14))->state = state; } void func_8029AC18(Camera* camera, Mat4 arg1, struct Actor* arg2) { @@ -834,7 +837,7 @@ void spawn_piranha_plants(struct ActorSpawnData* spawnData) { startingPos[1] = temp_s0->pos[1]; startingPos[2] = temp_s0->pos[2]; temp = add_actor_to_empty_slot(startingPos, startingRot, startingVelocity, ACTOR_PIRANHA_PLANT); - temp_v1 = (struct PiranhaPlant*) &gActorList[temp]; + temp_v1 = (struct PiranhaPlant*) m_GetActor(temp); temp_v1->visibilityStates[0] = 0; temp_v1->visibilityStates[1] = 0; temp_v1->visibilityStates[2] = 0; @@ -863,7 +866,7 @@ void spawn_palm_trees(const char* spawnData) { startingPos[1] = temp_s0->pos[1]; startingPos[2] = temp_s0->pos[2]; temp = add_actor_to_empty_slot(startingPos, startingRot, startingVelocity, ACTOR_PALM_TREE); - temp_v1 = (struct PalmTree*) &gActorList[temp]; + temp_v1 = (struct PalmTree*) m_GetActor(temp); temp_v1->variant = temp_s0->someId; check_bounding_collision((Collision*) &temp_v1->unk30, 5.0f, temp_v1->pos[0], temp_v1->pos[1], temp_v1->pos[2]); @@ -930,7 +933,7 @@ void spawn_foliage(struct ActorSpawnData* actor) { } } - temp_s0 = &gActorList[add_actor_to_empty_slot(position, rotation, velocity, actorType)]; + temp_s0 = m_GetActor(add_actor_to_empty_slot(position, rotation, velocity, actorType)); if (gGamestate == CREDITS_SEQUENCE) { func_802976D8(temp_s0->rot); } else { @@ -971,15 +974,15 @@ void spawn_all_item_boxes(struct ActorSpawnData* spawnData) { // Should be struct ItemBox but not enough space in the stack. // It's either the ItemBox or the SEGMENT/OFFSET variables. - // itemBox = (struct ItemBox *) &gActorList[temp_s1]; + // itemBox = (struct ItemBox *) GET_ACTOR(temp_s1); - gActorList[temp_s1].unk_08 = temp_f0; + m_GetActor(temp_s1)->unk_08 = temp_f0; // itemBox->resetDistance = temp_f0; - gActorList[temp_s1].velocity[0] = startingPos[1]; + m_GetActor(temp_s1)->velocity[0] = startingPos[1]; // itemBox->origY = startingPos[1]; - gActorList[temp_s1].pos[1] = temp_f0 - 20.0f; + m_GetActor(temp_s1)->pos[1] = temp_f0 - 20.0f; // itemBox->pos[1] = temp_f0 - 20.0f; temp_s0++; @@ -1007,7 +1010,7 @@ void init_kiwano_fruit(void) { } phi_s0 = add_actor_to_empty_slot(sp64, sp50, sp58, ACTOR_KIWANO_FRUIT); - actor = &gActorList[phi_s0]; + actor = m_GetActor(phi_s0); actor->unk_04 = i; } } @@ -1021,12 +1024,13 @@ void destroy_all_actors(void) { s32 i; gNumActors = 0; for (i = 0; i < ACTOR_LIST_SIZE; i++) { - gActorList[i].flags = 0; - gActorList[i].type = 0; - gActorList[i].unk_04 = 0; - gActorList[i].state = 0; - gActorList[i].unk_08 = 0.0f; - gActorList[i].boundingBoxSize = 0.0f; + struct Actor* actor = m_GetActor(i); + actor->flags = 0; + actor->type = 0; + actor->unk_04 = 0; + actor->state = 0; + actor->unk_08 = 0.0f; + actor->boundingBoxSize = 0.0f; } } @@ -1051,7 +1055,7 @@ void spawn_course_actors(void) { // // add_actor_to_empty_slot(position, rotation, velocity, ACTOR_MARIO_SIGN); // // vec3f_set(position, 2520.0f, 0.0f, 1240.0f); // // position[0] *= gCourseDirection; - // // actor = &gActorList[add_actor_to_empty_slot(position, rotation, velocity, ACTOR_MARIO_SIGN)]; + // // actor = GET_ACTOR(add_actor_to_empty_slot(position, rotation, velocity, ACTOR_MARIO_SIGN)); // // actor->flags |= 0x4000; // break; // case COURSE_CHOCO_MOUNTAIN: @@ -1099,7 +1103,7 @@ void spawn_course_actors(void) { // case COURSE_TOADS_TURNPIKE: // spawn_all_item_boxes(d_course_toads_turnpike_item_box_spawns); // break; - // case COURSE_KALAMARI_DESERT: + // case COURSE_KALIMARI_DESERT: // spawn_foliage(d_course_kalimari_desert_cactus_spawn); // spawn_all_item_boxes(d_course_kalimari_desert_item_box_spawns); // vec3f_set(position, -1680.0f, 2.0f, 35.0f); @@ -1201,6 +1205,7 @@ void init_actors_and_load_textures(void) { init_red_shell_texture(); destroy_all_actors(); + m_ClearActors(); spawn_course_actors(); CourseManager_VehiclesSpawn(); @@ -1250,7 +1255,7 @@ s16 try_remove_destructable_item(Vec3f pos, Vec3s rot, Vec3f velocity, s16 actor // try removing a red shell, green shell, banana, or a fake item box if the actor is expired for (actorIndex = gNumPermanentActors; actorIndex < ACTOR_LIST_SIZE; actorIndex++) { - compare = (struct ShellActor*) &gActorList[actorIndex]; + compare = (struct ShellActor*) m_GetActor(actorIndex); if (!(compare->flags & ACTOR_IS_NOT_EXPIRED)) { switch (compare->type) { case ACTOR_RED_SHELL: @@ -1307,7 +1312,7 @@ s16 try_remove_destructable_item(Vec3f pos, Vec3s rot, Vec3f velocity, s16 actor // will remove the oldest destructable actor in the list for (actorIndex = gNumPermanentActors; actorIndex < ACTOR_LIST_SIZE; actorIndex++) { - compare = (struct ShellActor*) &gActorList[actorIndex]; + compare = (struct ShellActor*) m_GetActor(actorIndex); switch (compare->type) { case ACTOR_RED_SHELL: switch (compare->state) { @@ -1365,19 +1370,24 @@ s16 try_remove_destructable_item(Vec3f pos, Vec3s rot, Vec3f velocity, s16 actor // returns actor index if any slot avaible returns -1 s16 add_actor_to_empty_slot(Vec3f pos, Vec3s rot, Vec3f velocity, s16 actorType) { - s32 index; + size_t index; - if (gNumActors >= ACTOR_LIST_SIZE) { - return try_remove_destructable_item(pos, rot, velocity, actorType); + // if (gNumActors >= m_GetActorSize()) { + // return try_remove_destructable_item(pos, rot, velocity, actorType); + // } + + // Cleanup unused actors + for (index = 0; index < m_GetActorSize(); index++) { + //if (m_GetActor(index)->flags == 0) { + //! @todo Commented out because deletes too soon. + //m_DeleteActor(index); + //gNumActors--; + //} } - for (index = 0; index < ACTOR_LIST_SIZE; index++) { - if (gActorList[index].flags == 0) { - gNumActors++; - actor_init(&gActorList[index], pos, rot, velocity, actorType); - return index; - } - } - return -1; + gNumActors++; + struct Actor* actor = m_AddBaseActor(); + actor_init(actor, pos, rot, velocity, actorType); + return (s16)m_GetActorSize() - 1; // Return current index; } UNUSED s16 spawn_actor_at_pos(Vec3f pos, s16 actorType) { @@ -1798,7 +1808,7 @@ void destroy_destructable_actor(struct Actor* actor) { if (shell->state != GREEN_SHELL_HIT_A_RACER) { switch (shell->state) { case MOVING_SHELL: - delete_actor_in_unexpired_actor_list(actor - gActorList); + delete_actor_in_unexpired_actor_list(m_FindActorIndex(actor)); /* fallthrough */ case HELD_SHELL: case RELEASED_SHELL: @@ -1827,7 +1837,7 @@ void destroy_destructable_actor(struct Actor* actor) { case BLUE_SHELL_LOCK_ON: case BLUE_SHELL_TARGET_ELIMINATED: func_800C9EF4(shell->pos, SOUND_ARG_LOAD(0x51, 0x01, 0x80, 0x08)); - delete_actor_in_unexpired_actor_list(actor - gActorList); + delete_actor_in_unexpired_actor_list(m_FindActorIndex(actor)); /* fallthrough */ case HELD_SHELL: case RELEASED_SHELL: @@ -1852,7 +1862,7 @@ void destroy_destructable_actor(struct Actor* actor) { case GREEN_SHELL_HIT_A_RACER: case BLUE_SHELL_LOCK_ON: case BLUE_SHELL_TARGET_ELIMINATED: - delete_actor_in_unexpired_actor_list(actor - gActorList); + delete_actor_in_unexpired_actor_list(m_FindActorIndex(actor)); /* fallthrough */ case HELD_SHELL: case RELEASED_SHELL: @@ -1986,6 +1996,8 @@ void evaluate_collision_between_player_actor(Player* player, struct Actor* actor f32 temp_f0; f32 temp_f2; + m_ActorCollision(player, actor); + temp_lo = player - gPlayerOne; switch (actor->type) { case ACTOR_YOSHI_EGG: @@ -2201,7 +2213,7 @@ void evaluate_collision_for_players_and_actors(void) { if (((phi_s1->type & 0x8000) != 0) && ((phi_s1->effects & 0x4000000) == 0)) { func_802977E4(phi_s1); for (j = 0; j < ACTOR_LIST_SIZE; j++) { - temp_a1 = &gActorList[j]; + temp_a1 = m_GetActor(j); if ((phi_s1->effects & 0x4000000) == 0) { // temp_v0 = temp_a1->unk2; @@ -2221,8 +2233,8 @@ void evaluate_collision_for_destructible_actors(void) { s32 i, j; UNUSED s32 pad; - for (i = gNumPermanentActors; i < (ACTOR_LIST_SIZE - 1); i++) { - actor1 = &gActorList[i]; + for (i = gNumPermanentActors; i < (ACTOR_LIST_SIZE); i++) { + actor1 = m_GetActor(i); if ((actor1->flags & 0x8000) == 0) { continue; @@ -2239,7 +2251,7 @@ void evaluate_collision_for_destructible_actors(void) { case ACTOR_FAKE_ITEM_BOX: for (j = i + 1; j < ACTOR_LIST_SIZE; j++) { - actor2 = &gActorList[j]; + actor2 = m_GetActor(j); if ((actor1->flags & 0x8000) == 0) { continue; @@ -2291,7 +2303,7 @@ void evaluate_collision_for_destructible_actors(void) { } void func_802A1064(struct FakeItemBox* fake_item_box) { - if ((u32) (fake_item_box - (struct FakeItemBox*) gActorList) <= (u32) ACTOR_LIST_SIZE) { + if ((u32) (m_FindActorIndex(fake_item_box)) <= (u32) ACTOR_LIST_SIZE) { if (((fake_item_box->flags & 0x8000) != 0) && (fake_item_box->type == ACTOR_FAKE_ITEM_BOX)) { fake_item_box->state = 1; fake_item_box->targetY = func_802ABEAC(&fake_item_box->unk30, fake_item_box->pos) + 8.66f; @@ -2318,7 +2330,7 @@ void init_actor_hot_air_balloon_item_box(f32 x, f32 y, f32 z) { pos[1] = y; pos[2] = z; id = add_actor_to_empty_slot(pos, rot, velocity, ACTOR_HOT_AIR_BALLOON_ITEM_BOX); - gActorHotAirBalloonItemBox = &gActorList[id]; + gActorHotAirBalloonItemBox = m_GetActor(id); } #include "actors/item_box/update.inc.c" @@ -2343,8 +2355,8 @@ void render_item_boxes(struct UnkStruct_800DC5EC* arg0) { s32 i; D_8015F8DC = 0; - for (i = 0; i < ACTOR_LIST_SIZE; i++) { - actor = &gActorList[i]; + for (i = 0; i < m_GetActorSize(); i++) { + actor = m_GetActor(i); if (actor->flags == 0) { continue; @@ -2375,91 +2387,93 @@ void render_course_actors(struct UnkStruct_800DC5EC* arg0) { f32 sp48 = sins(camera->rot[1] - 0x8000); // unk26; f32 temp_f0 = coss(camera->rot[1] - 0x8000); - D_801502C0[0][0] = temp_f0; - D_801502C0[0][2] = -sp48; - D_801502C0[2][2] = temp_f0; - D_801502C0[1][0] = 0.0f; - D_801502C0[0][1] = 0.0f; - D_801502C0[2][1] = 0.0f; - D_801502C0[1][2] = 0.0f; - D_801502C0[0][3] = 0.0f; - D_801502C0[1][3] = 0.0f; - D_801502C0[2][3] = 0.0f; // 2c - D_801502C0[2][0] = sp48; - D_801502C0[1][1] = 1.0f; - D_801502C0[3][3] = 1.0f; // unk3c + sBillBoardMtx[0][0] = temp_f0; + sBillBoardMtx[0][2] = -sp48; + sBillBoardMtx[2][2] = temp_f0; + sBillBoardMtx[1][0] = 0.0f; + sBillBoardMtx[0][1] = 0.0f; + sBillBoardMtx[2][1] = 0.0f; + sBillBoardMtx[1][2] = 0.0f; + sBillBoardMtx[0][3] = 0.0f; + sBillBoardMtx[1][3] = 0.0f; + sBillBoardMtx[2][3] = 0.0f; // 2c + sBillBoardMtx[2][0] = sp48; + sBillBoardMtx[1][1] = 1.0f; + sBillBoardMtx[3][3] = 1.0f; // unk3c gSPClearGeometryMode(gDisplayListHead++, G_LIGHTING); gSPSetLights1(gDisplayListHead++, D_800DC610[1]); gSPTexture(gDisplayListHead++, 0xFFFF, 0xFFFF, 0, G_TX_RENDERTILE, G_ON); - CourseManager_DrawActors(D_800DC5EC->camera); if (gModeSelection != BATTLE) { - func_80297340(camera); + //func_80297340(camera); } D_8015F8E0 = 0; - for (i = 0; i < ACTOR_LIST_SIZE; i++) { - actor = &gActorList[i]; + for (i = 0; i < m_GetActorSize(); i++) { + actor = m_GetActor(i); if (actor->flags == 0) { continue; } switch (actor->type) { + default: // Draw custom actor + CourseManager_DrawActor(D_800DC5EC->camera, actor); + break; case ACTOR_TREE_MARIO_RACEWAY: - render_actor_tree_mario_raceway(camera, D_801502C0, actor); + render_actor_tree_mario_raceway(camera, sBillBoardMtx, actor); break; case ACTOR_TREE_YOSHI_VALLEY: - render_actor_tree_yoshi_valley(camera, D_801502C0, actor); + render_actor_tree_yoshi_valley(camera, sBillBoardMtx, actor); break; case ACTOR_TREE_ROYAL_RACEWAY: - render_actor_tree_royal_raceway(camera, D_801502C0, actor); + render_actor_tree_royal_raceway(camera, sBillBoardMtx, actor); break; case ACTOR_TREE_MOO_MOO_FARM: - render_actor_tree_moo_moo_farm(camera, D_801502C0, actor); + render_actor_tree_moo_moo_farm(camera, sBillBoardMtx, actor); break; case ACTOR_UNKNOWN_0x1A: - func_80299864(camera, D_801502C0, actor); + func_80299864(camera, sBillBoardMtx, actor); break; case ACTOR_TREE_BOWSERS_CASTLE: - render_actor_tree_bowser_castle(camera, D_801502C0, actor); + render_actor_tree_bowser_castle(camera, sBillBoardMtx, actor); break; case ACTOR_BUSH_BOWSERS_CASTLE: - render_actor_bush_bowser_castle(camera, D_801502C0, actor); + render_actor_bush_bowser_castle(camera, sBillBoardMtx, actor); break; case ACTOR_TREE_FRAPPE_SNOWLAND: - render_actor_tree_frappe_snowland(camera, D_801502C0, actor); + render_actor_tree_frappe_snowland(camera, sBillBoardMtx, actor); break; case ACTOR_CACTUS1_KALAMARI_DESERT: - render_actor_tree_cactus1_kalimari_desert(camera, D_801502C0, actor); + render_actor_tree_cactus1_kalimari_desert(camera, sBillBoardMtx, actor); break; case ACTOR_CACTUS2_KALAMARI_DESERT: - render_actor_tree_cactus2_kalimari_desert(camera, D_801502C0, actor); + render_actor_tree_cactus2_kalimari_desert(camera, sBillBoardMtx, actor); break; case ACTOR_CACTUS3_KALAMARI_DESERT: - render_actor_tree_cactus3_kalimari_desert(camera, D_801502C0, actor); + render_actor_tree_cactus3_kalimari_desert(camera, sBillBoardMtx, actor); break; case ACTOR_FALLING_ROCK: render_actor_falling_rock(camera, (struct FallingRock*) actor); break; case ACTOR_KIWANO_FRUIT: - render_actor_kiwano_fruit(camera, D_801502C0, actor); + render_actor_kiwano_fruit(camera, sBillBoardMtx, actor); break; case ACTOR_BANANA: - render_actor_banana(camera, D_801502C0, (struct BananaActor*) actor); + render_actor_banana(camera, sBillBoardMtx, (struct BananaActor*) actor); break; case ACTOR_GREEN_SHELL: - render_actor_green_shell(camera, D_801502C0, (struct ShellActor*) actor); + render_actor_green_shell(camera, sBillBoardMtx, (struct ShellActor*) actor); break; case ACTOR_RED_SHELL: - render_actor_red_shell(camera, D_801502C0, (struct ShellActor*) actor); + render_actor_red_shell(camera, sBillBoardMtx, (struct ShellActor*) actor); break; case ACTOR_BLUE_SPINY_SHELL: - render_actor_blue_shell(camera, D_801502C0, (struct ShellActor*) actor); + render_actor_blue_shell(camera, sBillBoardMtx, (struct ShellActor*) actor); break; case ACTOR_PIRANHA_PLANT: - render_actor_piranha_plant(camera, D_801502C0, (struct PiranhaPlant*) actor); + render_actor_piranha_plant(camera, sBillBoardMtx, (struct PiranhaPlant*) actor); break; case ACTOR_TRAIN_ENGINE: render_actor_train_engine(camera, (struct TrainCar*) actor); @@ -2471,22 +2485,22 @@ void render_course_actors(struct UnkStruct_800DC5EC* arg0) { render_actor_train_passenger_car(camera, (struct TrainCar*) actor); break; case ACTOR_COW: - render_actor_cow(camera, D_801502C0, actor); + render_actor_cow(camera, sBillBoardMtx, actor); break; case ACTOR_UNKNOWN_0x14: - func_8029AC18(camera, D_801502C0, actor); + func_8029AC18(camera, sBillBoardMtx, actor); break; case ACTOR_MARIO_SIGN: - render_actor_mario_sign(camera, D_801502C0, actor); + render_actor_mario_sign(camera, sBillBoardMtx, actor); break; case ACTOR_WARIO_SIGN: render_actor_wario_sign(camera, actor); break; case ACTOR_PALM_TREE: - render_actor_palm_tree(camera, D_801502C0, (struct PalmTree*) actor); + render_actor_palm_tree(camera, sBillBoardMtx, (struct PalmTree*) actor); break; case ACTOR_PADDLE_BOAT: - render_actor_paddle_boat(camera, (struct PaddleWheelBoat*) actor, D_801502C0, pathCounter); + render_actor_paddle_boat(camera, (struct PaddleWheelBoat*) actor, sBillBoardMtx, pathCounter); break; case ACTOR_BOX_TRUCK: render_actor_box_truck(camera, actor); @@ -2504,23 +2518,23 @@ void render_course_actors(struct UnkStruct_800DC5EC* arg0) { render_actor_railroad_crossing(camera, (struct RailroadCrossing*) actor); break; case ACTOR_YOSHI_EGG: - render_actor_yoshi_egg(camera, D_801502C0, (struct YoshiValleyEgg*) actor, pathCounter); + render_actor_yoshi_egg(camera, sBillBoardMtx, (struct YoshiValleyEgg*) actor, pathCounter); break; } } if (GetCourse() == GetMooMooFarm()) { - render_cows(camera, D_801502C0, actor); + render_cows(camera, sBillBoardMtx); } else if (GetCourse() == GetDkJungle()) { - render_palm_trees(camera, D_801502C0, actor); + render_palm_trees(camera, sBillBoardMtx); } } void update_course_actors(void) { struct Actor* actor; s32 i; - for (i = 0; i < ACTOR_LIST_SIZE; i++) { + for (i = 0; i < m_GetActorSize(); i++) { - actor = &gActorList[i]; + actor = m_GetActor(i); if (actor->flags == 0) { continue; } diff --git a/src/racing/actors.h b/src/racing/actors.h index 968bf7264..fe32326af 100644 --- a/src/racing/actors.h +++ b/src/racing/actors.h @@ -32,11 +32,11 @@ void update_actor_train_tender(struct TrainCar*); void update_actor_train_passenger_car(struct TrainCar*); void update_actor_piranha_plant(struct PiranhaPlant*); void render_actor_piranha_plant(Camera*, Mat4, struct PiranhaPlant*); -void render_cows(Camera*, Mat4, struct Actor*); +void render_cows(Camera*, Mat4); void evaluate_collision_player_palm_trees(Player*); void evaluate_collision_players_palm_trees(void); void func_80298D10(void); -void render_palm_trees(Camera*, Mat4, struct Actor*); +void render_palm_trees(Camera*, Mat4); void render_actor_tree_mario_raceway(Camera*, Mat4, struct Actor*); void render_actor_tree_yoshi_valley(Camera*, Mat4, struct Actor*); void render_actor_tree_royal_raceway(Camera*, Mat4, struct Actor*); diff --git a/src/racing/actors_extended.c b/src/racing/actors_extended.c index de9d84932..b13609ef1 100644 --- a/src/racing/actors_extended.c +++ b/src/racing/actors_extended.c @@ -33,7 +33,7 @@ void copy_collision(Collision* src, Collision* dest) { } void triple_shell_actor_collide_with_player(struct ShellActor* shell, s32 shellType) { - TripleShellParent* parent = (TripleShellParent*) &gActorList[shell->parentIndex]; + TripleShellParent* parent = (TripleShellParent*) GET_ACTOR(shell->parentIndex); parent->shellsAvailable--; @@ -78,7 +78,7 @@ void func_802B0464(s16 bananaIndex) { struct BananaActor* banana; if (bananaIndex != -1) { - banana = (struct BananaActor*) &gActorList[bananaIndex]; + banana = (struct BananaActor*) GET_ACTOR(bananaIndex); func_802B039C(banana); func_802B0464(banana->youngerIndex); } @@ -88,7 +88,7 @@ void func_802B04E8(UNUSED struct BananaActor* arg0, s16 bananaIndex) { struct BananaActor* banana; if (bananaIndex != -1) { - banana = (struct BananaActor*) &gActorList[bananaIndex]; + banana = (struct BananaActor*) GET_ACTOR(bananaIndex); func_802B039C(banana); func_802B04E8(banana, banana->elderIndex); } @@ -107,7 +107,7 @@ void destroy_banana_in_banana_bunch(struct BananaActor* banana) { banana->unk_04 = 0x003C; banana->state = DESTROYED_BANANA; banana->velocity[1] = 3.0f; - temp_v0_2 = (struct BananaBunchParent*) &gActorList[banana->parentIndex]; + temp_v0_2 = (struct BananaBunchParent*) GET_ACTOR(banana->parentIndex); temp_v0_2->bananaIndices[0] = -1; temp_v0_2->bananaIndices[1] = -1; temp_v0_2->bananaIndices[2] = -1; @@ -122,19 +122,19 @@ void func_802B0648(struct BananaBunchParent* banana_bunch) { banana_bunch->bananasAvailable -= 1; if (banana_bunch->bananaIndices[4] != -1) { - banana = (struct BananaActor*) &gActorList[banana_bunch->bananaIndices[4]]; + banana = (struct BananaActor*) GET_ACTOR(banana_bunch->bananaIndices[4]); banana_bunch->bananaIndices[4] = -1; } else if (banana_bunch->bananaIndices[3] != -1) { - banana = (struct BananaActor*) &gActorList[banana_bunch->bananaIndices[3]]; + banana = (struct BananaActor*) GET_ACTOR(banana_bunch->bananaIndices[3]); banana_bunch->bananaIndices[3] = -1; } else if (banana_bunch->bananaIndices[2] != -1) { - banana = (struct BananaActor*) &gActorList[banana_bunch->bananaIndices[2]]; + banana = (struct BananaActor*) GET_ACTOR(banana_bunch->bananaIndices[2]); banana_bunch->bananaIndices[2] = -1; } else if (banana_bunch->bananaIndices[1] != -1) { - banana = (struct BananaActor*) &gActorList[banana_bunch->bananaIndices[1]]; + banana = (struct BananaActor*) GET_ACTOR(banana_bunch->bananaIndices[1]); banana_bunch->bananaIndices[1] = -1; } else if (banana_bunch->bananaIndices[0] != -1) { - banana = (struct BananaActor*) &gActorList[banana_bunch->bananaIndices[0]]; + banana = (struct BananaActor*) GET_ACTOR(banana_bunch->bananaIndices[0]); banana_bunch->bananaIndices[0] = -1; } else { return; @@ -147,7 +147,7 @@ void func_802B0648(struct BananaBunchParent* banana_bunch) { banana->velocity[2] = 0.0f; elderIndex = banana->elderIndex; if (elderIndex != -1) { - ((struct BananaActor*) &gActorList[elderIndex])->youngerIndex = -1; + ((struct BananaActor*) GET_ACTOR(elderIndex))->youngerIndex = -1; } } @@ -161,19 +161,19 @@ void func_802B0788(s16 rawStickY, struct BananaBunchParent* banana_bunch, Player banana_bunch->bananasAvailable -= 1; if (banana_bunch->bananaIndices[4] != -1) { - banana = (struct BananaActor*) &gActorList[banana_bunch->bananaIndices[4]]; + banana = (struct BananaActor*) GET_ACTOR(banana_bunch->bananaIndices[4]); banana_bunch->bananaIndices[4] = -1; } else if (banana_bunch->bananaIndices[3] != -1) { - banana = (struct BananaActor*) &gActorList[banana_bunch->bananaIndices[3]]; + banana = (struct BananaActor*) GET_ACTOR(banana_bunch->bananaIndices[3]); banana_bunch->bananaIndices[3] = -1; } else if (banana_bunch->bananaIndices[2] != -1) { - banana = (struct BananaActor*) &gActorList[banana_bunch->bananaIndices[2]]; + banana = (struct BananaActor*) GET_ACTOR(banana_bunch->bananaIndices[2]); banana_bunch->bananaIndices[2] = -1; } else if (banana_bunch->bananaIndices[1] != -1) { - banana = (struct BananaActor*) &gActorList[banana_bunch->bananaIndices[1]]; + banana = (struct BananaActor*) GET_ACTOR(banana_bunch->bananaIndices[1]); banana_bunch->bananaIndices[1] = -1; } else if (banana_bunch->bananaIndices[0] != -1) { - banana = (struct BananaActor*) &gActorList[banana_bunch->bananaIndices[0]]; + banana = (struct BananaActor*) GET_ACTOR(banana_bunch->bananaIndices[0]); banana_bunch->bananaIndices[0] = -1; } else { return; @@ -182,7 +182,7 @@ void func_802B0788(s16 rawStickY, struct BananaBunchParent* banana_bunch, Player banana->state = DROPPED_BANANA; banana->unk_04 = 0x001E; if (banana->elderIndex != -1) { - elderBanana = (struct BananaActor*) &gActorList[banana->elderIndex]; + elderBanana = (struct BananaActor*) GET_ACTOR(banana->elderIndex); elderBanana->youngerIndex = -1; } if (player->unk_094 < 2.0f) { @@ -204,7 +204,7 @@ s32 func_802B09C0(s16 bananaId) { if (bananaId == -1) { return 0; } - banana = (struct BananaActor*) &gActorList[bananaId]; + banana = (struct BananaActor*) GET_ACTOR(bananaId); if (banana->state == FIRST_BANANA_BUNCH_BANANA) { return 1; } @@ -268,11 +268,11 @@ void update_actor_banana_bunch(struct BananaBunchParent* banana_bunch) { banana_bunch->state = 6; // Unnecessary type-casting done here purely to help with understanding. // We're setting the ->flags of BananaActors, not plain Actors. - ((struct BananaActor*) &gActorList[banana_bunch->bananaIndices[0]])->flags |= 0x5000; - ((struct BananaActor*) &gActorList[banana_bunch->bananaIndices[1]])->flags |= 0x5000; - ((struct BananaActor*) &gActorList[banana_bunch->bananaIndices[2]])->flags |= 0x5000; - ((struct BananaActor*) &gActorList[banana_bunch->bananaIndices[3]])->flags |= 0x5000; - ((struct BananaActor*) &gActorList[banana_bunch->bananaIndices[4]])->flags |= 0x5000; + ((struct BananaActor*) GET_ACTOR(banana_bunch->bananaIndices[0]))->flags |= 0x5000; + ((struct BananaActor*) GET_ACTOR(banana_bunch->bananaIndices[1]))->flags |= 0x5000; + ((struct BananaActor*) GET_ACTOR(banana_bunch->bananaIndices[2]))->flags |= 0x5000; + ((struct BananaActor*) GET_ACTOR(banana_bunch->bananaIndices[3]))->flags |= 0x5000; + ((struct BananaActor*) GET_ACTOR(banana_bunch->bananaIndices[4]))->flags |= 0x5000; break; case 6: someCount = 0; @@ -318,7 +318,7 @@ bool is_shell_exist(s16 arg0) { if (arg0 < 0) { return false; } - actor = (struct ShellActor*) &gActorList[arg0]; + actor = (struct ShellActor*) GET_ACTOR(arg0); if (actor->type == ACTOR_GREEN_SHELL) { if (actor->state == TRIPLE_GREEN_SHELL) { return true; @@ -392,11 +392,11 @@ void update_actor_triple_shell(TripleShellParent* parent, s16 shellType) { break; case 3: parent->state = 4; - shell = (struct ShellActor*) &gActorList[(s16) parent->shellIndices[0]]; + shell = (struct ShellActor*) GET_ACTOR((s16) parent->shellIndices[0]); shell->flags |= 0x4000; - shell = (struct ShellActor*) &gActorList[(s16) parent->shellIndices[1]]; + shell = (struct ShellActor*) GET_ACTOR((s16) parent->shellIndices[1]); shell->flags |= 0x4000; - shell = (struct ShellActor*) &gActorList[(s16) parent->shellIndices[2]]; + shell = (struct ShellActor*) GET_ACTOR((s16) parent->shellIndices[2]); shell->flags |= 0x4000; break; case 4: @@ -426,7 +426,7 @@ void update_actor_triple_shell(TripleShellParent* parent, s16 shellType) { } if (parent->unk_08 > 0.0f) { if (parent->shellIndices[0] > 0.0f) { - shell = (struct ShellActor*) &gActorList[(s16) parent->shellIndices[0]]; + shell = (struct ShellActor*) GET_ACTOR((s16) parent->shellIndices[0]); if ((shell->rotAngle < 0x38E) || (shell->rotAngle >= -0x38D)) { someVelocity[0] = 0; someVelocity[1] = 0; @@ -452,7 +452,7 @@ void update_actor_triple_shell(TripleShellParent* parent, s16 shellType) { } } if (parent->shellIndices[1] > 0.0f) { - shell = (struct ShellActor*) &gActorList[(s16) parent->shellIndices[1]]; + shell = (struct ShellActor*) GET_ACTOR((s16) parent->shellIndices[1]); if ((shell->rotAngle < 0xAA1) || (shell->rotAngle >= 0x38F)) { someVelocity[0] = 0; someVelocity[1] = 0; @@ -478,7 +478,7 @@ void update_actor_triple_shell(TripleShellParent* parent, s16 shellType) { } } if (parent->shellIndices[2] > 0.0f) { - shell = (struct ShellActor*) &gActorList[(s16) parent->shellIndices[2]]; + shell = (struct ShellActor*) GET_ACTOR((s16) parent->shellIndices[2]); if ((shell->rotAngle < -0x38E) || (shell->rotAngle >= -0x71B)) { someVelocity[0] = 0; someVelocity[1] = 0; @@ -522,7 +522,7 @@ s32 use_banana_bunch_item(Player* player) { if (actorIndex < 0) { return actorIndex; } - bananaBunch = (struct BananaBunchParent*) &gActorList[actorIndex]; + bananaBunch = (struct BananaBunchParent*) GET_ACTOR(actorIndex); bananaBunch->state = 0; bananaBunch->playerId = player - gPlayerOne; player->soundEffects |= HOLD_BANANA_SOUND_EFFECT; @@ -541,7 +541,7 @@ s32 use_triple_shell_item(Player* player, s16 tripleShellType) { if (actorIndex < 0) { return actorIndex; } - parent = (TripleShellParent*) &gActorList[actorIndex]; + parent = (TripleShellParent*) GET_ACTOR(actorIndex); parent->state = 0; parent->rotVelocity = 0x05B0; parent->rotAngle = -0x8000; @@ -572,7 +572,7 @@ s32 init_triple_shell(TripleShellParent* parent, Player* player, s16 shellType, return -1; } - shell = (struct ShellActor*) &gActorList[actorIndex]; + shell = (struct ShellActor*) GET_ACTOR(actorIndex); startingPos[0] = player->pos[0]; startingPos[1] = player->pos[1]; startingPos[2] = player->pos[2]; @@ -591,9 +591,9 @@ s32 init_triple_shell(TripleShellParent* parent, Player* player, s16 shellType, shell->rotVelocity = 0; shell->rotAngle = -0x8000; shell->playerId = player - gPlayerOne; - shell->parentIndex = (struct Actor*) parent - gActorList; + shell->parentIndex = m_FindActorIndex(parent); shell->shellId = shellId; - parent->shellIndices[shellId] = (struct Actor*) shell - gActorList; + parent->shellIndices[shellId] = (f32) m_FindActorIndex(shell); return 1; } @@ -623,7 +623,7 @@ s32 use_green_shell_item(Player* player) { return actorIndex; } - shell = (struct ShellActor*) &gActorList[actorIndex]; + shell = (struct ShellActor*) GET_ACTOR(actorIndex); startingPos[0] = player->pos[0]; startingPos[1] = player->pos[1]; startingPos[2] = player->pos[2]; @@ -663,7 +663,7 @@ s32 use_red_shell_item(Player* player) { return actorIndex; } - shell = (struct ShellActor*) &gActorList[actorIndex]; + shell = (struct ShellActor*) GET_ACTOR(actorIndex); startingPos[0] = player->pos[0]; startingPos[1] = player->pos[1]; startingPos[2] = player->pos[2]; @@ -680,7 +680,7 @@ s32 use_red_shell_item(Player* player) { // Interestingly blue shells start their life as a red shell, // and then just change the type from red to blue shell void use_blue_shell_item(Player* player) { - gActorList[use_red_shell_item(player)].type = ACTOR_BLUE_SPINY_SHELL; + GET_ACTOR(use_red_shell_item(player))->type = ACTOR_BLUE_SPINY_SHELL; } #include "actors/banana/update.inc.c" @@ -711,7 +711,7 @@ void func_802B2914(struct BananaBunchParent* banana_bunch, Player* player, s16 b startingRot[2] = 0; actorIndex = add_actor_to_empty_slot(startingPos, startingRot, startingVelocity, ACTOR_BANANA); if (actorIndex >= 0) { - newBanana = (struct BananaActor*) &gActorList[actorIndex]; + newBanana = (struct BananaActor*) GET_ACTOR(actorIndex); startingPos[0] = player->pos[0]; startingPos[1] = player->pos[1]; startingPos[2] = player->pos[2]; @@ -720,7 +720,7 @@ void func_802B2914(struct BananaBunchParent* banana_bunch, Player* player, s16 b func_802B4E30((struct Actor*) newBanana); newBanana->flags = 0x9000; newBanana->playerId = player - gPlayerOne; - newBanana->parentIndex = (struct Actor*) banana_bunch - gActorList; + newBanana->parentIndex = (struct Actor*) m_FindActorIndex(banana_bunch); newBanana->youngerIndex = -1; newBanana->unk_04 = 0x0014; newBanana->bananaId = bananaId; @@ -734,28 +734,28 @@ void func_802B2914(struct BananaBunchParent* banana_bunch, Player* player, s16 b newBanana->state = 3; banana_bunch->bananaIndices[1] = actorIndex; newBanana->elderIndex = banana_bunch->bananaIndices[0]; - tempBanana = (struct BananaActor*) &gActorList[banana_bunch->bananaIndices[0]]; + tempBanana = (struct BananaActor*) GET_ACTOR(banana_bunch->bananaIndices[0]); tempBanana->youngerIndex = actorIndex; break; case 2: newBanana->state = 3; banana_bunch->bananaIndices[2] = actorIndex; newBanana->elderIndex = banana_bunch->bananaIndices[1]; - tempBanana = (struct BananaActor*) &gActorList[banana_bunch->bananaIndices[1]]; + tempBanana = (struct BananaActor*) GET_ACTOR(banana_bunch->bananaIndices[1]); tempBanana->youngerIndex = actorIndex; break; case 3: newBanana->state = 3; banana_bunch->bananaIndices[3] = actorIndex; newBanana->elderIndex = banana_bunch->bananaIndices[2]; - tempBanana = (struct BananaActor*) &gActorList[banana_bunch->bananaIndices[2]]; + tempBanana = (struct BananaActor*) GET_ACTOR(banana_bunch->bananaIndices[2]); tempBanana->youngerIndex = actorIndex; break; case 4: newBanana->state = 3; banana_bunch->bananaIndices[4] = actorIndex; newBanana->elderIndex = banana_bunch->bananaIndices[3]; - tempBanana = (struct BananaActor*) &gActorList[banana_bunch->bananaIndices[3]]; + tempBanana = (struct BananaActor*) GET_ACTOR(banana_bunch->bananaIndices[3]); tempBanana->youngerIndex = actorIndex; break; } @@ -800,7 +800,7 @@ s32 use_fake_itembox_item(Player* player) { if (actorIndex < 0) { return actorIndex; } - itemBox = (struct FakeItemBox*) &gActorList[actorIndex]; + itemBox = (struct FakeItemBox*) GET_ACTOR(actorIndex); itemBox->playerId = (player - gPlayerOne); itemBox->state = HELD_FAKE_ITEM_BOX; player->soundEffects |= HOLD_BANANA_SOUND_EFFECT; @@ -846,7 +846,7 @@ s32 use_banana_item(Player* player) { if (actorIndex < 0) { return actorIndex; } - banana = (struct BananaActor*) &gActorList[actorIndex]; + banana = (struct BananaActor*) GET_ACTOR(actorIndex); banana->playerId = playerId; banana->state = HELD_BANANA; banana->unk_04 = 0x0014; diff --git a/src/racing/math_util.c b/src/racing/math_util.c index a243a066e..a892066bc 100644 --- a/src/racing/math_util.c +++ b/src/racing/math_util.c @@ -43,27 +43,31 @@ UNUSED void func_802B4FF0() { * object already render Note that gMatrixObjectCount gets reset at the beginning of the game loop. So no cleanup needs * to be performed. */ -s32 render_set_position(Mat4 arg0, s32 arg1) { +s32 render_set_position(Mat4 mtx, s32 arg1) { if (gMatrixObjectCount >= MTX_OBJECT_POOL_SIZE) { return 0; } - mtxf_to_mtx(&gGfxPool->mtxObject[gMatrixObjectCount], arg0); + //mtxf_to_mtx(&gGfxPool->mtxObject[gMatrixObjectCount], arg0); switch (arg1) { /* irregular */ case 0: - gSPMatrix(gDisplayListHead++, VIRTUAL_TO_PHYSICAL(&gGfxPool->mtxObject[gMatrixObjectCount++]), - G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + AddObjectMatrix(mtx, G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + // gSPMatrix(gDisplayListHead++, VIRTUAL_TO_PHYSICAL(&gGfxPool->mtxObject[gMatrixObjectCount++]), + // G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); break; case 1: - gSPMatrix(gDisplayListHead++, VIRTUAL_TO_PHYSICAL(&gGfxPool->mtxObject[gMatrixObjectCount++]), - G_MTX_PUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + AddObjectMatrix(mtx, G_MTX_PUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + // gSPMatrix(gDisplayListHead++, VIRTUAL_TO_PHYSICAL(&gGfxPool->mtxObject[gMatrixObjectCount++]), + // G_MTX_PUSH | G_MTX_LOAD | G_MTX_MODELVIEW); break; case 3: - gSPMatrix(gDisplayListHead++, VIRTUAL_TO_PHYSICAL(&gGfxPool->mtxObject[gMatrixObjectCount++]), - G_MTX_PUSH | G_MTX_MUL | G_MTX_MODELVIEW); + AddObjectMatrix(mtx, G_MTX_PUSH | G_MTX_MUL | G_MTX_MODELVIEW); + // gSPMatrix(gDisplayListHead++, VIRTUAL_TO_PHYSICAL(&gGfxPool->mtxObject[gMatrixObjectCount++]), + // G_MTX_PUSH | G_MTX_MUL | G_MTX_MODELVIEW); break; case 2: - gSPMatrix(gDisplayListHead++, VIRTUAL_TO_PHYSICAL(&gGfxPool->mtxObject[gMatrixObjectCount++]), - G_MTX_NOPUSH | G_MTX_MUL | G_MTX_MODELVIEW); + AddObjectMatrix(mtx, G_MTX_NOPUSH | G_MTX_MUL | G_MTX_MODELVIEW); + // gSPMatrix(gDisplayListHead++, VIRTUAL_TO_PHYSICAL(&gGfxPool->mtxObject[gMatrixObjectCount++]), + // G_MTX_NOPUSH | G_MTX_MUL | G_MTX_MODELVIEW); break; } return 1; diff --git a/src/racing/memory.c b/src/racing/memory.c index a1da6d777..c51686e38 100644 --- a/src/racing/memory.c +++ b/src/racing/memory.c @@ -1647,5 +1647,7 @@ u8* load_lakitu_tlut_x64(const char** textureList, size_t length) { void load_course(s32 courseId) { printf("Loading Course %d\n", courseId); + gNextFreeMemoryAddress = gFreeMemoryResetAnchor; + m_ClearActors(); LoadCourse(); } diff --git a/src/racing/race_logic.c b/src/racing/race_logic.c index f69a50bdc..7565b4f5c 100644 --- a/src/racing/race_logic.c +++ b/src/racing/race_logic.c @@ -141,15 +141,14 @@ void func_8028E298(void) { func_800070F4(); } -void func_8028E3A0(void) { +void set_next_course(void) { if (D_80150120) { - if (GetCupCursorPosition() == GetCupSize()) { // CUP_COURSE_FOUR) { + if (GetCupCursorPosition() == GetCupSize() - 1) { // CUP_COURSE_FOUR) { gGotoMode = ENDING; } else { D_800DC544++; SetCupCursorPosition(GetCupCursorPosition() + 1); - SetCourseFromCup(); gCourseIndexInCup++; gGotoMode = RACING; } @@ -157,7 +156,6 @@ void func_8028E3A0(void) { D_800DC544++; gCourseIndexInCup++; SetCupCursorPosition(GetCupCursorPosition() + 1); - SetCourseFromCup(); gGotoMode = RACING; } } @@ -401,7 +399,7 @@ void func_8028E678(void) { gIsInQuitToMenuTransition = 1; gQuitToMenuTransitionCounter = 5; D_800DC510 = 7; - func_8028E3A0(); + set_next_course(); break; } } diff --git a/src/racing/race_logic.h b/src/racing/race_logic.h index 16b363e13..d2c3d7936 100644 --- a/src/racing/race_logic.h +++ b/src/racing/race_logic.h @@ -9,7 +9,7 @@ void func_8028DF38(void); void func_8028E028(void); void update_player_battle_status(void); void func_8028E298(void); -void func_8028E3A0(void); +void set_next_course(void); void func_8028E438(void); void func_8028E678(void); void func_8028EC38(s32); diff --git a/src/racing/render_courses.c b/src/racing/render_courses.c index 07ab94a11..7238a02e3 100644 --- a/src/racing/render_courses.c +++ b/src/racing/render_courses.c @@ -238,289 +238,289 @@ void func_8029122C(struct UnkStruct_800DC5EC* arg0, s32 playerId) { } mtxf_identity(matrix); render_set_position(matrix, 0); - switch (gCurrentCourseId) { - case COURSE_BOWSER_CASTLE: - if (gActiveScreenMode != SCREEN_MODE_1P) { - return; - } - if (pathCounter < 6) { - return; - } - if (pathCounter > 9) { - return; - } - if (pathCounter == 9) { - if (cameraRot < 0xA000) { - return; - } - if (cameraRot > 0xE000) { - return; - } - } - gSPDisplayList(gDisplayListHead++, d_course_bowsers_castle_dl_9228); - break; - case COURSE_BANSHEE_BOARDWALK: - gDPPipeSync(gDisplayListHead++); - gSPTexture(gDisplayListHead++, 0xFFFF, 0xFFFF, 0, G_TX_RENDERTILE, G_ON); - gSPClearGeometryMode(gDisplayListHead++, G_LIGHTING); - gDPSetRenderMode(gDisplayListHead++, G_RM_AA_ZB_XLU_INTER, G_RM_NOOP2); - gDPSetBlendMask(gDisplayListHead++, 0xFF); - gDPSetCombineMode(gDisplayListHead++, G_CC_MODULATEIA, G_CC_MODULATEIA); - // d_course_banshee_boardwalk_packed_dl_878 - gSPDisplayList(gDisplayListHead++, segmented_gfx_to_virtual(0x07000878)); - gDPSetAlphaCompare(gDisplayListHead++, G_AC_NONE); - gDPPipeSync(gDisplayListHead++); - break; - case COURSE_KOOPA_BEACH: + CourseManager_DrawWater(arg0, pathCounter, cameraRot, playerDirection); + // switch (gCurrentCourseId) { + // case COURSE_BOWSER_CASTLE: + // if (gActiveScreenMode != SCREEN_MODE_1P) { + // return; + // } + // if (pathCounter < 6) { + // return; + // } + // if (pathCounter > 9) { + // return; + // } + // if (pathCounter == 9) { + // if (cameraRot < 0xA000) { + // return; + // } + // if (cameraRot > 0xE000) { + // return; + // } + // } + // gSPDisplayList(gDisplayListHead++, d_course_bowsers_castle_dl_9228); + // break; + // case COURSE_BANSHEE_BOARDWALK: + // gDPPipeSync(gDisplayListHead++); + // gSPTexture(gDisplayListHead++, 0xFFFF, 0xFFFF, 0, G_TX_RENDERTILE, G_ON); + // gSPClearGeometryMode(gDisplayListHead++, G_LIGHTING); + // gDPSetRenderMode(gDisplayListHead++, G_RM_AA_ZB_XLU_INTER, G_RM_NOOP2); + // gDPSetBlendMask(gDisplayListHead++, 0xFF); + // gDPSetCombineMode(gDisplayListHead++, G_CC_MODULATEIA, G_CC_MODULATEIA); + // // d_course_banshee_boardwalk_packed_dl_878 + // gSPDisplayList(gDisplayListHead++, segmented_gfx_to_virtual(0x07000878)); + // gDPSetAlphaCompare(gDisplayListHead++, G_AC_NONE); + // gDPPipeSync(gDisplayListHead++); + // break; + // case COURSE_KOOPA_BEACH: - gDPPipeSync(gDisplayListHead++); - gSPTexture(gDisplayListHead++, 0xFFFF, 0xFFFF, 0, G_TX_RENDERTILE, G_ON); - gSPClearGeometryMode(gDisplayListHead++, G_LIGHTING); - gDPSetRenderMode(gDisplayListHead++, G_RM_AA_ZB_XLU_INTER, G_RM_NOOP2); - gDPSetBlendMask(gDisplayListHead++, 0xFF); - gDPSetCombineMode(gDisplayListHead++, G_CC_MODULATEIA, G_CC_MODULATEIA); + // gDPPipeSync(gDisplayListHead++); + // gSPTexture(gDisplayListHead++, 0xFFFF, 0xFFFF, 0, G_TX_RENDERTILE, G_ON); + // gSPClearGeometryMode(gDisplayListHead++, G_LIGHTING); + // gDPSetRenderMode(gDisplayListHead++, G_RM_AA_ZB_XLU_INTER, G_RM_NOOP2); + // gDPSetBlendMask(gDisplayListHead++, 0xFF); + // gDPSetCombineMode(gDisplayListHead++, G_CC_MODULATEIA, G_CC_MODULATEIA); - switch (pathCounter) { - case 22: - case 23: - case 29: - case 30: - case 31: - case 37: - gSPClearGeometryMode(gDisplayListHead++, G_CULL_BACK); - // d_course_koopa_troopa_beach_packed_dl_9E70 - gSPDisplayList(gDisplayListHead++, segmented_gfx_to_virtual(0x07009E70)); - gSPSetGeometryMode(gDisplayListHead++, G_CULL_BACK); - break; - } - vector[0] = 0.0f; - vector[1] = D_8015F8E4; - vector[2] = 0.0f; - mtxf_translate(matrix, vector); - render_set_position(matrix, 0); + // switch (pathCounter) { + // case 22: + // case 23: + // case 29: + // case 30: + // case 31: + // case 37: + // gSPClearGeometryMode(gDisplayListHead++, G_CULL_BACK); + // // d_course_koopa_troopa_beach_packed_dl_9E70 + // gSPDisplayList(gDisplayListHead++, segmented_gfx_to_virtual(0x07009E70)); + // gSPSetGeometryMode(gDisplayListHead++, G_CULL_BACK); + // break; + // } + // vector[0] = 0.0f; + // vector[1] = D_8015F8E4; + // vector[2] = 0.0f; + // mtxf_translate(matrix, vector); + // render_set_position(matrix, 0); - gDPSetRenderMode(gDisplayListHead++, G_RM_AA_ZB_XLU_INTER, G_RM_NOOP2); - gDPSetBlendMask(gDisplayListHead++, 0xFF); - gDPSetCombineMode(gDisplayListHead++, G_CC_MODULATEIA, G_CC_MODULATEIA); - gSPClearGeometryMode(gDisplayListHead++, G_CULL_BACK); - render_course_segments(koopa_troopa_beach_dls2, arg0); - gSPTexture(gDisplayListHead++, 0xFFFF, 0xFFFF, 1, 1, G_OFF); - gSPSetGeometryMode(gDisplayListHead++, G_CULL_BACK); - gDPSetAlphaCompare(gDisplayListHead++, G_AC_NONE); - gDPPipeSync(gDisplayListHead++); - break; - case COURSE_SHERBET_LAND: + // gDPSetRenderMode(gDisplayListHead++, G_RM_AA_ZB_XLU_INTER, G_RM_NOOP2); + // gDPSetBlendMask(gDisplayListHead++, 0xFF); + // gDPSetCombineMode(gDisplayListHead++, G_CC_MODULATEIA, G_CC_MODULATEIA); + // gSPClearGeometryMode(gDisplayListHead++, G_CULL_BACK); + // render_course_segments(koopa_troopa_beach_dls2, arg0); + // gSPTexture(gDisplayListHead++, 0xFFFF, 0xFFFF, 1, 1, G_OFF); + // gSPSetGeometryMode(gDisplayListHead++, G_CULL_BACK); + // gDPSetAlphaCompare(gDisplayListHead++, G_AC_NONE); + // gDPPipeSync(gDisplayListHead++); + // break; + // case COURSE_SHERBET_LAND: + // gDPPipeSync(gDisplayListHead++); + // gSPClearGeometryMode(gDisplayListHead++, G_LIGHTING); + // gSPTexture(gDisplayListHead++, 0xFFFF, 0xFFFF, 0, G_TX_RENDERTILE, G_ON); + // gDPSetBlendMask(gDisplayListHead++, 0xFF); + // gDPSetCombineMode(gDisplayListHead++, G_CC_MODULATEIA, G_CC_MODULATEIA); + // gDPSetTextureFilter(gDisplayListHead++, G_TF_BILERP); + // gDPSetTexturePersp(gDisplayListHead++, G_TP_PERSP); - gDPPipeSync(gDisplayListHead++); - gSPClearGeometryMode(gDisplayListHead++, G_LIGHTING); - gSPTexture(gDisplayListHead++, 0xFFFF, 0xFFFF, 0, G_TX_RENDERTILE, G_ON); - gDPSetBlendMask(gDisplayListHead++, 0xFF); - gDPSetCombineMode(gDisplayListHead++, G_CC_MODULATEIA, G_CC_MODULATEIA); - gDPSetTextureFilter(gDisplayListHead++, G_TF_BILERP); - gDPSetTexturePersp(gDisplayListHead++, G_TP_PERSP); + // mtxf_identity(matrix); + // render_set_position(matrix, 0); + // render_course_segments(sherbet_land_dls_2, arg0); - mtxf_identity(matrix); - render_set_position(matrix, 0); - render_course_segments(sherbet_land_dls_2, arg0); + // gDPSetAlphaCompare(gDisplayListHead++, G_AC_NONE); + // if ((func_80290C20(arg0->camera) == 1) && (func_802AAB4C(player) < player->pos[1])) { + // gSPSetGeometryMode(gDisplayListHead++, G_ZBUFFER); + // gDPSetCombineMode(gDisplayListHead++, G_CC_SHADE, G_CC_SHADE); + // gDPSetRenderMode(gDisplayListHead++, G_RM_AA_ZB_OPA_SURF, G_RM_AA_ZB_OPA_SURF2); + // // d_course_sherbet_land_packed_dl_2B48 + // gSPDisplayList(gDisplayListHead++, segmented_gfx_to_virtual(0x07002B48)); + // } + // gDPPipeSync(gDisplayListHead++); + // break; + // case COURSE_RAINBOW_ROAD: + // gDPPipeSync(gDisplayListHead++); + // mtxf_identity(matrix); + // render_set_position(matrix, 0); + // gSPClearGeometryMode(gDisplayListHead++, G_CULL_BACK); + // render_course_segments(rainbow_road_dls, arg0); + // gSPSetGeometryMode(gDisplayListHead++, G_CULL_BACK); + // gDPSetAlphaCompare(gDisplayListHead++, G_AC_NONE); + // gDPPipeSync(gDisplayListHead++); + // break; + // case COURSE_WARIO_STADIUM: + // gDPPipeSync(gDisplayListHead++); + // gSPTexture(gDisplayListHead++, 0xFFFF, 0xFFFF, 0, G_TX_RENDERTILE, G_ON); + // gSPClearGeometryMode(gDisplayListHead++, G_LIGHTING); + // gDPSetRenderMode(gDisplayListHead++, G_RM_AA_ZB_XLU_INTER, G_RM_NOOP2); + // gDPSetBlendMask(gDisplayListHead++, 0xFF); + // gDPSetCombineMode(gDisplayListHead++, G_CC_MODULATEIA, G_CC_MODULATEIA); + // gDPSetTextureFilter(gDisplayListHead++, G_TF_BILERP); + // gDPSetTexturePersp(gDisplayListHead++, G_TP_PERSP); - gDPSetAlphaCompare(gDisplayListHead++, G_AC_NONE); - if ((func_80290C20(arg0->camera) == 1) && (func_802AAB4C(player) < player->pos[1])) { - gSPSetGeometryMode(gDisplayListHead++, G_ZBUFFER); - gDPSetCombineMode(gDisplayListHead++, G_CC_SHADE, G_CC_SHADE); - gDPSetRenderMode(gDisplayListHead++, G_RM_AA_ZB_OPA_SURF, G_RM_AA_ZB_OPA_SURF2); - // d_course_sherbet_land_packed_dl_2B48 - gSPDisplayList(gDisplayListHead++, segmented_gfx_to_virtual(0x07002B48)); - } - gDPPipeSync(gDisplayListHead++); - break; - case COURSE_RAINBOW_ROAD: - gDPPipeSync(gDisplayListHead++); - mtxf_identity(matrix); - render_set_position(matrix, 0); - gSPClearGeometryMode(gDisplayListHead++, G_CULL_BACK); - render_course_segments(rainbow_road_dls, arg0); - gSPSetGeometryMode(gDisplayListHead++, G_CULL_BACK); - gDPSetAlphaCompare(gDisplayListHead++, G_AC_NONE); - gDPPipeSync(gDisplayListHead++); - break; - case COURSE_WARIO_STADIUM: - gDPPipeSync(gDisplayListHead++); - gSPTexture(gDisplayListHead++, 0xFFFF, 0xFFFF, 0, G_TX_RENDERTILE, G_ON); - gSPClearGeometryMode(gDisplayListHead++, G_LIGHTING); - gDPSetRenderMode(gDisplayListHead++, G_RM_AA_ZB_XLU_INTER, G_RM_NOOP2); - gDPSetBlendMask(gDisplayListHead++, 0xFF); - gDPSetCombineMode(gDisplayListHead++, G_CC_MODULATEIA, G_CC_MODULATEIA); - gDPSetTextureFilter(gDisplayListHead++, G_TF_BILERP); - gDPSetTexturePersp(gDisplayListHead++, G_TP_PERSP); + // mtxf_identity(matrix); + // render_set_position(matrix, 0); - mtxf_identity(matrix); - render_set_position(matrix, 0); + // gSPClearGeometryMode(gDisplayListHead++, G_CULL_BACK); + // gDPSetCombineMode(gDisplayListHead++, G_CC_MODULATEIDECALA, G_CC_MODULATEIDECALA); + // gDPSetRenderMode(gDisplayListHead++, G_RM_AA_ZB_XLU_SURF, G_RM_AA_ZB_XLU_SURF2); + // gDPSetPrimColor(gDisplayListHead++, 0, 0, 0xFF, 0xFF, 0x00, 0xFF); + // // d_course_wario_stadium_packed_dl_EC0 + // gSPDisplayList(gDisplayListHead++, segmented_gfx_to_virtual(0x07000EC0)); + // gSPTexture(gDisplayListHead++, 0xFFFF, 0xFFFF, 1, 1, G_OFF); + // gSPSetGeometryMode(gDisplayListHead++, G_CULL_BACK); + // gDPSetAlphaCompare(gDisplayListHead++, G_AC_NONE); + // gDPPipeSync(gDisplayListHead++); + // break; + // case COURSE_DK_JUNGLE: + // gDPPipeSync(gDisplayListHead++); + // gSPClearGeometryMode(gDisplayListHead++, G_LIGHTING); + // gSPTexture(gDisplayListHead++, 0xFFFF, 0xFFFF, 0, G_TX_RENDERTILE, G_ON); + // gDPSetBlendMask(gDisplayListHead++, 0xFF); + // gDPSetTextureFilter(gDisplayListHead++, G_TF_BILERP); + // gDPSetTexturePersp(gDisplayListHead++, G_TP_PERSP); - gSPClearGeometryMode(gDisplayListHead++, G_CULL_BACK); - gDPSetCombineMode(gDisplayListHead++, G_CC_MODULATEIDECALA, G_CC_MODULATEIDECALA); - gDPSetRenderMode(gDisplayListHead++, G_RM_AA_ZB_XLU_SURF, G_RM_AA_ZB_XLU_SURF2); - gDPSetPrimColor(gDisplayListHead++, 0, 0, 0xFF, 0xFF, 0x00, 0xFF); - // d_course_wario_stadium_packed_dl_EC0 - gSPDisplayList(gDisplayListHead++, segmented_gfx_to_virtual(0x07000EC0)); - gSPTexture(gDisplayListHead++, 0xFFFF, 0xFFFF, 1, 1, G_OFF); - gSPSetGeometryMode(gDisplayListHead++, G_CULL_BACK); - gDPSetAlphaCompare(gDisplayListHead++, G_AC_NONE); - gDPPipeSync(gDisplayListHead++); - break; - case COURSE_DK_JUNGLE: - gDPPipeSync(gDisplayListHead++); - gSPClearGeometryMode(gDisplayListHead++, G_LIGHTING); - gSPTexture(gDisplayListHead++, 0xFFFF, 0xFFFF, 0, G_TX_RENDERTILE, G_ON); - gDPSetBlendMask(gDisplayListHead++, 0xFF); - gDPSetTextureFilter(gDisplayListHead++, G_TF_BILERP); - gDPSetTexturePersp(gDisplayListHead++, G_TP_PERSP); + // mtxf_identity(matrix); + // render_set_position(matrix, 0); - mtxf_identity(matrix); - render_set_position(matrix, 0); + // gDPSetCombineMode(gDisplayListHead++, G_CC_MODULATEIA, G_CC_MODULATEIA); + // gDPSetRenderMode(gDisplayListHead++, G_RM_AA_ZB_XLU_INTER, G_RM_NOOP2); - gDPSetCombineMode(gDisplayListHead++, G_CC_MODULATEIA, G_CC_MODULATEIA); - gDPSetRenderMode(gDisplayListHead++, G_RM_AA_ZB_XLU_INTER, G_RM_NOOP2); - - if (pathCounter < 17) { - gDPSetCombineMode(gDisplayListHead++, G_CC_MODULATEIA, G_CC_MODULATEIA); - // d_course_dks_jungle_parkway_packed_dl_3E40 - gSPDisplayList(gDisplayListHead++, segmented_gfx_to_virtual(0x07003E40)); - // d_course_dks_jungle_parkway_packed_dl_3EB0 - gSPDisplayList(gDisplayListHead++, segmented_gfx_to_virtual(0x07003EB0)); - if ((pathCounter >= 6) && (pathCounter < 13)) { - gDPSetCombineMode(gDisplayListHead++, G_CC_MODULATEIA, G_CC_MODULATEIA); - // d_course_dks_jungle_parkway_packed_dl_3DD0 - gSPDisplayList(gDisplayListHead++, segmented_gfx_to_virtual(0x07003DD0)); - } - } else if ((pathCounter == 21) || (pathCounter == 22)) { - if (playerDirection == 3) { - gDPSetCombineMode(gDisplayListHead++, G_CC_MODULATEIDECALA, G_CC_MODULATEIDECALA); - // d_course_dks_jungle_parkway_packed_dl_36A8 - gSPDisplayList(gDisplayListHead++, segmented_gfx_to_virtual(0x070036A8)); - } - if ((playerDirection == 1) || (playerDirection == 0)) { - gDPSetCombineMode(gDisplayListHead++, G_CC_MODULATEIDECALA, G_CC_MODULATEIDECALA); - // d_course_dks_jungle_parkway_packed_dl_36A8 - gSPDisplayList(gDisplayListHead++, segmented_gfx_to_virtual(0x070036A8)); - } else { - gDPSetCombineMode(gDisplayListHead++, G_CC_MODULATEIA, G_CC_MODULATEIA); - // d_course_dks_jungle_parkway_packed_dl_3F30 - gSPDisplayList(gDisplayListHead++, segmented_gfx_to_virtual(0x07003F30)); - // d_course_dks_jungle_parkway_packed_dl_36A8 - gSPDisplayList(gDisplayListHead++, segmented_gfx_to_virtual(0x070036A8)); - } - } else if (pathCounter == 24) { - if ((playerDirection == 0) || (playerDirection == 3)) { - gDPSetCombineMode(gDisplayListHead++, G_CC_MODULATEIDECALA, G_CC_MODULATEIDECALA); - // d_course_dks_jungle_parkway_packed_dl_36A8 - gSPDisplayList(gDisplayListHead++, segmented_gfx_to_virtual(0x070036A8)); - } - } else if (pathCounter == 23) { - if (playerDirection == 3) { - gDPSetCombineMode(gDisplayListHead++, G_CC_MODULATEIDECALA, G_CC_MODULATEIDECALA); - // d_course_dks_jungle_parkway_packed_dl_36A8 - gSPDisplayList(gDisplayListHead++, segmented_gfx_to_virtual(0x070036A8)); - } else if (playerDirection == 0) { - gDPSetCombineMode(gDisplayListHead++, G_CC_MODULATEIDECALA, G_CC_MODULATEIDECALA); - // d_course_dks_jungle_parkway_packed_dl_36A8 - gSPDisplayList(gDisplayListHead++, segmented_gfx_to_virtual(0x070036A8)); - } - } - gDPSetCombineMode(gDisplayListHead++, G_CC_MODULATEIA, G_CC_MODULATEIA); - switch (pathCounter) { - case 5: - if (playerDirection != 3) { - // d_course_dks_jungle_parkway_packed_dl_3DD0 - gSPDisplayList(gDisplayListHead++, segmented_gfx_to_virtual(0x07003DD0)); - } - break; - case 17: - switch (playerDirection) { - case 0: - // d_course_dks_jungle_parkway_packed_dl_3E40 - gSPDisplayList(gDisplayListHead++, segmented_gfx_to_virtual(0x07003E40)); - // d_course_dks_jungle_parkway_packed_dl_3EB0 - gSPDisplayList(gDisplayListHead++, segmented_gfx_to_virtual(0x07003EB0)); - break; - case 1: - // d_course_dks_jungle_parkway_packed_dl_3DD0 - gSPDisplayList(gDisplayListHead++, segmented_gfx_to_virtual(0x07003DD0)); - // d_course_dks_jungle_parkway_packed_dl_3E40 - gSPDisplayList(gDisplayListHead++, segmented_gfx_to_virtual(0x07003E40)); - // d_course_dks_jungle_parkway_packed_dl_3EB0 - gSPDisplayList(gDisplayListHead++, segmented_gfx_to_virtual(0x07003EB0)); - break; - case 2: - // d_course_dks_jungle_parkway_packed_dl_ - gSPDisplayList(gDisplayListHead++, segmented_gfx_to_virtual(0x07003E40)); - // d_course_dks_jungle_parkway_packed_dl_3EB0 - gSPDisplayList(gDisplayListHead++, segmented_gfx_to_virtual(0x07003EB0)); - // d_course_dks_jungle_parkway_packed_dl_3F30 - gSPDisplayList(gDisplayListHead++, segmented_gfx_to_virtual(0x07003F30)); - break; - case 3: - // d_course_dks_jungle_parkway_packed_dl_3EB0 - gSPDisplayList(gDisplayListHead++, segmented_gfx_to_virtual(0x07003EB0)); - // d_course_dks_jungle_parkway_packed_dl_3F30 - gSPDisplayList(gDisplayListHead++, segmented_gfx_to_virtual(0x07003F30)); - break; - } - break; - case 18: - switch (playerDirection) { - case 0: - // d_course_dks_jungle_parkway_packed_dl_3E40 - gSPDisplayList(gDisplayListHead++, segmented_gfx_to_virtual(0x07003E40)); - // d_course_dks_jungle_parkway_packed_dl_3EB0 - gSPDisplayList(gDisplayListHead++, segmented_gfx_to_virtual(0x07003EB0)); - break; - case 1: - // d_course_dks_jungle_parkway_packed_dl_3DD0 - gSPDisplayList(gDisplayListHead++, segmented_gfx_to_virtual(0x07003DD0)); - // d_course_dks_jungle_parkway_packed_dl_3E40 - gSPDisplayList(gDisplayListHead++, segmented_gfx_to_virtual(0x07003E40)); - // d_course_dks_jungle_parkway_packed_dl_3EB0 - gSPDisplayList(gDisplayListHead++, segmented_gfx_to_virtual(0x07003EB0)); - break; - case 2: - // d_course_dks_jungle_parkway_packed_dl_3E40 - gSPDisplayList(gDisplayListHead++, segmented_gfx_to_virtual(0x07003E40)); - // d_course_dks_jungle_parkway_packed_dl_3EB0 - gSPDisplayList(gDisplayListHead++, segmented_gfx_to_virtual(0x07003EB0)); - break; - } - break; - case 21: - if ((playerDirection == 0) || (playerDirection == 1)) { - // d_course_dks_jungle_parkway_packed_dl_3E40 - gSPDisplayList(gDisplayListHead++, segmented_gfx_to_virtual(0x07003E40)); - // d_course_dks_jungle_parkway_packed_dl_3EB0 - gSPDisplayList(gDisplayListHead++, segmented_gfx_to_virtual(0x07003EB0)); - // d_course_dks_jungle_parkway_packed_dl_3F30 - gSPDisplayList(gDisplayListHead++, segmented_gfx_to_virtual(0x07003F30)); - } else { - // d_course_dks_jungle_parkway_packed_dl_3EB0 - gSPDisplayList(gDisplayListHead++, segmented_gfx_to_virtual(0x07003EB0)); - } - break; - case 22: - if (playerDirection == 0) { - // d_course_dks_jungle_parkway_packed_dl_3F30 - gSPDisplayList(gDisplayListHead++, segmented_gfx_to_virtual(0x07003F30)); - } - break; - case 23: - if (playerDirection != 1) { - // d_course_dks_jungle_parkway_packed_dl_3F30 - gSPDisplayList(gDisplayListHead++, segmented_gfx_to_virtual(0x07003F30)); - } - break; - } - gSPTexture(gDisplayListHead++, 0xFFFF, 0xFFFF, 1, 1, G_OFF); - gDPSetAlphaCompare(gDisplayListHead++, G_AC_NONE); - gDPPipeSync(gDisplayListHead++); - break; - } + // if (pathCounter < 17) { + // gDPSetCombineMode(gDisplayListHead++, G_CC_MODULATEIA, G_CC_MODULATEIA); + // // d_course_dks_jungle_parkway_packed_dl_3E40 + // gSPDisplayList(gDisplayListHead++, segmented_gfx_to_virtual(0x07003E40)); + // // d_course_dks_jungle_parkway_packed_dl_3EB0 + // gSPDisplayList(gDisplayListHead++, segmented_gfx_to_virtual(0x07003EB0)); + // if ((pathCounter >= 6) && (pathCounter < 13)) { + // gDPSetCombineMode(gDisplayListHead++, G_CC_MODULATEIA, G_CC_MODULATEIA); + // // d_course_dks_jungle_parkway_packed_dl_3DD0 + // gSPDisplayList(gDisplayListHead++, segmented_gfx_to_virtual(0x07003DD0)); + // } + // } else if ((pathCounter == 21) || (pathCounter == 22)) { + // if (playerDirection == 3) { + // gDPSetCombineMode(gDisplayListHead++, G_CC_MODULATEIDECALA, G_CC_MODULATEIDECALA); + // // d_course_dks_jungle_parkway_packed_dl_36A8 + // gSPDisplayList(gDisplayListHead++, segmented_gfx_to_virtual(0x070036A8)); + // } + // if ((playerDirection == 1) || (playerDirection == 0)) { + // gDPSetCombineMode(gDisplayListHead++, G_CC_MODULATEIDECALA, G_CC_MODULATEIDECALA); + // // d_course_dks_jungle_parkway_packed_dl_36A8 + // gSPDisplayList(gDisplayListHead++, segmented_gfx_to_virtual(0x070036A8)); + // } else { + // gDPSetCombineMode(gDisplayListHead++, G_CC_MODULATEIA, G_CC_MODULATEIA); + // // d_course_dks_jungle_parkway_packed_dl_3F30 + // gSPDisplayList(gDisplayListHead++, segmented_gfx_to_virtual(0x07003F30)); + // // d_course_dks_jungle_parkway_packed_dl_36A8 + // gSPDisplayList(gDisplayListHead++, segmented_gfx_to_virtual(0x070036A8)); + // } + // } else if (pathCounter == 24) { + // if ((playerDirection == 0) || (playerDirection == 3)) { + // gDPSetCombineMode(gDisplayListHead++, G_CC_MODULATEIDECALA, G_CC_MODULATEIDECALA); + // // d_course_dks_jungle_parkway_packed_dl_36A8 + // gSPDisplayList(gDisplayListHead++, segmented_gfx_to_virtual(0x070036A8)); + // } + // } else if (pathCounter == 23) { + // if (playerDirection == 3) { + // gDPSetCombineMode(gDisplayListHead++, G_CC_MODULATEIDECALA, G_CC_MODULATEIDECALA); + // // d_course_dks_jungle_parkway_packed_dl_36A8 + // gSPDisplayList(gDisplayListHead++, segmented_gfx_to_virtual(0x070036A8)); + // } else if (playerDirection == 0) { + // gDPSetCombineMode(gDisplayListHead++, G_CC_MODULATEIDECALA, G_CC_MODULATEIDECALA); + // // d_course_dks_jungle_parkway_packed_dl_36A8 + // gSPDisplayList(gDisplayListHead++, segmented_gfx_to_virtual(0x070036A8)); + // } + // } + // gDPSetCombineMode(gDisplayListHead++, G_CC_MODULATEIA, G_CC_MODULATEIA); + // switch (pathCounter) { + // case 5: + // if (playerDirection != 3) { + // // d_course_dks_jungle_parkway_packed_dl_3DD0 + // gSPDisplayList(gDisplayListHead++, segmented_gfx_to_virtual(0x07003DD0)); + // } + // break; + // case 17: + // switch (playerDirection) { + // case 0: + // // d_course_dks_jungle_parkway_packed_dl_3E40 + // gSPDisplayList(gDisplayListHead++, segmented_gfx_to_virtual(0x07003E40)); + // // d_course_dks_jungle_parkway_packed_dl_3EB0 + // gSPDisplayList(gDisplayListHead++, segmented_gfx_to_virtual(0x07003EB0)); + // break; + // case 1: + // // d_course_dks_jungle_parkway_packed_dl_3DD0 + // gSPDisplayList(gDisplayListHead++, segmented_gfx_to_virtual(0x07003DD0)); + // // d_course_dks_jungle_parkway_packed_dl_3E40 + // gSPDisplayList(gDisplayListHead++, segmented_gfx_to_virtual(0x07003E40)); + // // d_course_dks_jungle_parkway_packed_dl_3EB0 + // gSPDisplayList(gDisplayListHead++, segmented_gfx_to_virtual(0x07003EB0)); + // break; + // case 2: + // // d_course_dks_jungle_parkway_packed_dl_ + // gSPDisplayList(gDisplayListHead++, segmented_gfx_to_virtual(0x07003E40)); + // // d_course_dks_jungle_parkway_packed_dl_3EB0 + // gSPDisplayList(gDisplayListHead++, segmented_gfx_to_virtual(0x07003EB0)); + // // d_course_dks_jungle_parkway_packed_dl_3F30 + // gSPDisplayList(gDisplayListHead++, segmented_gfx_to_virtual(0x07003F30)); + // break; + // case 3: + // // d_course_dks_jungle_parkway_packed_dl_3EB0 + // gSPDisplayList(gDisplayListHead++, segmented_gfx_to_virtual(0x07003EB0)); + // // d_course_dks_jungle_parkway_packed_dl_3F30 + // gSPDisplayList(gDisplayListHead++, segmented_gfx_to_virtual(0x07003F30)); + // break; + // } + // break; + // case 18: + // switch (playerDirection) { + // case 0: + // // d_course_dks_jungle_parkway_packed_dl_3E40 + // gSPDisplayList(gDisplayListHead++, segmented_gfx_to_virtual(0x07003E40)); + // // d_course_dks_jungle_parkway_packed_dl_3EB0 + // gSPDisplayList(gDisplayListHead++, segmented_gfx_to_virtual(0x07003EB0)); + // break; + // case 1: + // // d_course_dks_jungle_parkway_packed_dl_3DD0 + // gSPDisplayList(gDisplayListHead++, segmented_gfx_to_virtual(0x07003DD0)); + // // d_course_dks_jungle_parkway_packed_dl_3E40 + // gSPDisplayList(gDisplayListHead++, segmented_gfx_to_virtual(0x07003E40)); + // // d_course_dks_jungle_parkway_packed_dl_3EB0 + // gSPDisplayList(gDisplayListHead++, segmented_gfx_to_virtual(0x07003EB0)); + // break; + // case 2: + // // d_course_dks_jungle_parkway_packed_dl_3E40 + // gSPDisplayList(gDisplayListHead++, segmented_gfx_to_virtual(0x07003E40)); + // // d_course_dks_jungle_parkway_packed_dl_3EB0 + // gSPDisplayList(gDisplayListHead++, segmented_gfx_to_virtual(0x07003EB0)); + // break; + // } + // break; + // case 21: + // if ((playerDirection == 0) || (playerDirection == 1)) { + // // d_course_dks_jungle_parkway_packed_dl_3E40 + // gSPDisplayList(gDisplayListHead++, segmented_gfx_to_virtual(0x07003E40)); + // // d_course_dks_jungle_parkway_packed_dl_3EB0 + // gSPDisplayList(gDisplayListHead++, segmented_gfx_to_virtual(0x07003EB0)); + // // d_course_dks_jungle_parkway_packed_dl_3F30 + // gSPDisplayList(gDisplayListHead++, segmented_gfx_to_virtual(0x07003F30)); + // } else { + // // d_course_dks_jungle_parkway_packed_dl_3EB0 + // gSPDisplayList(gDisplayListHead++, segmented_gfx_to_virtual(0x07003EB0)); + // } + // break; + // case 22: + // if (playerDirection == 0) { + // // d_course_dks_jungle_parkway_packed_dl_3F30 + // gSPDisplayList(gDisplayListHead++, segmented_gfx_to_virtual(0x07003F30)); + // } + // break; + // case 23: + // if (playerDirection != 1) { + // // d_course_dks_jungle_parkway_packed_dl_3F30 + // gSPDisplayList(gDisplayListHead++, segmented_gfx_to_virtual(0x07003F30)); + // } + // break; + // } + // gSPTexture(gDisplayListHead++, 0xFFFF, 0xFFFF, 1, 1, G_OFF); + // gDPSetAlphaCompare(gDisplayListHead++, G_AC_NONE); + // gDPPipeSync(gDisplayListHead++); + // break; + // } } void render_mario_raceway(struct UnkStruct_800DC5EC* arg0) { @@ -1334,7 +1334,7 @@ void func_8029569C(void) { // case COURSE_TOADS_TURNPIKE: // gSPDisplayList(gDisplayListHead++, d_course_toads_turnpike_dl_23930); // break; - // case COURSE_KALAMARI_DESERT: + // case COURSE_KALIMARI_DESERT: // gSPDisplayList(gDisplayListHead++, d_course_kalimari_desert_dl_22E00); // break; // case COURSE_SHERBET_LAND: @@ -1420,7 +1420,7 @@ void render_course(struct UnkStruct_800DC5EC* arg0) { // case COURSE_TOADS_TURNPIKE: // render_toads_turnpike(arg0); // break; - // case COURSE_KALAMARI_DESERT: + // case COURSE_KALIMARI_DESERT: // render_kalimari_desert(arg0); // break; // case COURSE_SHERBET_LAND: @@ -1487,27 +1487,7 @@ void func_80295D6C(void) { D_8015F6F6 = -3000; } -void func_80295D88(void) { - gNumActors = 0; - - gCourseMinX = 0; - gCourseMinY = 0; - gCourseMinZ = 0; - - gCourseMaxX = 0; - gCourseMaxY = 0; - gCourseMaxZ = 0; - - D_8015F59C = 0; - D_8015F5A0 = 0; - func_80295D6C(); - D_8015F58C = 0; - gCollisionMeshCount = 0; - gCollisionMesh = (CollisionTriangle*) gNextFreeMemoryAddress; - D_800DC5BC = 0; - D_800DC5C8 = 0; - - CourseManager_GenerateCollision(); +void course_init(void) { // switch (gCurrentCourseId) { // case COURSE_MARIO_RACEWAY: @@ -1618,7 +1598,7 @@ void func_80295D88(void) { // func_80295C6C(); // D_8015F8E4 = gCourseMinY - 10.0f; // break; - // case COURSE_KALAMARI_DESERT: + // case COURSE_KALIMARI_DESERT: // parse_course_displaylists(d_course_kalimari_desert_addr); // func_80295C6C(); // D_8015F8E4 = gCourseMinY - 10.0f; @@ -1716,7 +1696,7 @@ void func_80295D88(void) { void func_802966A0(void) { - CourseManager_Water(); + CourseManager_ScrollingTextures(); // switch (gCurrentCourseId) { // case COURSE_KOOPA_BEACH: diff --git a/src/racing/skybox_and_splitscreen.c b/src/racing/skybox_and_splitscreen.c index ad2d8fa81..f93394b0c 100644 --- a/src/racing/skybox_and_splitscreen.c +++ b/src/racing/skybox_and_splitscreen.c @@ -523,7 +523,7 @@ void func_802A4D18(void) { // D_8015014C = 4500.0f; // D_80150150 = 9.0f; // break; - // case COURSE_KALAMARI_DESERT: + // case COURSE_KALIMARI_DESERT: // D_8015014C = 7000.0f; // D_80150150 = 10.0f; // break; @@ -749,585 +749,153 @@ void func_802A5760(void) { } } -void render_player_one_1p_screen(void) { - Camera* camera = &cameras[0]; +void render_screens(s32 mode, s32 cameraId, s32 playerId) { UNUSED s32 pad[4]; u16 perspNorm; UNUSED s32 pad2[2]; -#ifdef VERSION_EU - f32 sp9C; -#endif UNUSED s32 pad3; Mat4 matrix; -#ifdef VERSION_EU - sp9C = gScreenAspect * 1.2f; -#endif - func_802A53A4(); + s32 screenId = 0; + s32 screenMode = SCREEN_MODE_1P; + + switch(mode) { + case RENDER_SCREEN_MODE_1P_PLAYER_ONE: + func_802A53A4(); + screenId = 0; + screenMode = SCREEN_MODE_1P; + break; + case RENDER_SCREEN_MODE_2P_HORIZONTAL_PLAYER_ONE: + func_802A51D4(); + screenId = 0; + screenMode = SCREEN_MODE_2P_SPLITSCREEN_HORIZONTAL; + break; + case RENDER_SCREEN_MODE_2P_HORIZONTAL_PLAYER_TWO: + func_802A52BC(); + screenId = 1; + screenMode = SCREEN_MODE_2P_SPLITSCREEN_HORIZONTAL; + break; + case RENDER_SCREEN_MODE_2P_VERTICAL_PLAYER_ONE: + func_802A50EC(); + screenId = 0; + screenMode = SCREEN_MODE_2P_SPLITSCREEN_VERTICAL; + break; + case RENDER_SCREEN_MODE_2P_VERTICAL_PLAYER_TWO: + func_802A5004(); + screenId = 1; + screenMode = SCREEN_MODE_2P_SPLITSCREEN_VERTICAL; + break; + case RENDER_SCREEN_MODE_3P_4P_PLAYER_ONE: + func_802A54A8(); + screenId = 0; + screenMode = SCREEN_MODE_3P_4P_SPLITSCREEN; + break; + case RENDER_SCREEN_MODE_3P_4P_PLAYER_TWO: + func_802A5590(); + screenId = 1; + screenMode = SCREEN_MODE_3P_4P_SPLITSCREEN; + break; + case RENDER_SCREEN_MODE_3P_4P_PLAYER_THREE: + func_802A5678(); + screenId = 2; + screenMode = SCREEN_MODE_3P_4P_SPLITSCREEN; + break; + case RENDER_SCREEN_MODE_3P_4P_PLAYER_FOUR: + func_802A5760(); + screenId = 3; + screenMode = SCREEN_MODE_3P_4P_SPLITSCREEN; + if (gPlayerCountSelection1 == 3) { + func_80093A5C(RENDER_SCREEN_MODE_3P_4P_PLAYER_FOUR); + if (D_800DC5B8 != 0) { + render_hud(RENDER_SCREEN_MODE_3P_4P_PLAYER_FOUR); + } + gNumScreens += 1; + return; + } + break; + } + + struct UnkStruct_800DC5EC *screen = &D_8015F480[screenId]; + Camera *camera = &cameras[cameraId]; + + if (screenMode == SCREEN_MODE_2P_SPLITSCREEN_HORIZONTAL) { + gSPSetGeometryMode(gDisplayListHead++, G_SHADE | G_CULL_BACK | G_LIGHTING | G_SHADING_SMOOTH); + } + init_rdp(); - func_802A3730(D_800DC5EC); + func_802A3730(screen); gSPSetGeometryMode(gDisplayListHead++, G_ZBUFFER | G_SHADE | G_CULL_BACK | G_LIGHTING | G_SHADING_SMOOTH); gDPSetRenderMode(gDisplayListHead++, G_RM_AA_ZB_OPA_SURF, G_RM_AA_ZB_OPA_SURF2); -#ifdef VERSION_EU - guPerspective(&gGfxPool->mtxPersp[0], &perspNorm, gCameraZoom[0], sp9C, CourseManager_GetProps()->NearPersp, - CourseManager_GetProps()->FarPersp, 1.0f); -#else - guPerspective(&gGfxPool->mtxPersp[0], &perspNorm, gCameraZoom[0], gScreenAspect, - CourseManager_GetProps()->NearPersp, CourseManager_GetProps()->FarPersp, 1.0f); -#endif - gSPPerspNormalize(gDisplayListHead++, perspNorm); - gSPMatrix(gDisplayListHead++, VIRTUAL_TO_PHYSICAL(&gGfxPool->mtxPersp[0]), - G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_PROJECTION); - guLookAt(&gGfxPool->mtxLookAt[0], camera->pos[0], camera->pos[1], camera->pos[2], camera->lookAt[0], - camera->lookAt[1], camera->lookAt[2], camera->up[0], camera->up[1], camera->up[2]); + guPerspective(&gGfxPool->mtxPersp[cameraId], &perspNorm, gCameraZoom[cameraId], gScreenAspect, CourseManager_GetProps()->NearPersp, CourseManager_GetProps()->FarPersp, 1.0f); + + gSPPerspNormalize(gDisplayListHead++, perspNorm); + gSPMatrix(gDisplayListHead++, VIRTUAL_TO_PHYSICAL(&gGfxPool->mtxPersp[cameraId]), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_PROJECTION); + + guLookAt(&gGfxPool->mtxLookAt[cameraId], camera->pos[0], camera->pos[1], camera->pos[2], + camera->lookAt[0], camera->lookAt[1], camera->lookAt[2], camera->up[0], + camera->up[1], camera->up[2]); if (D_800DC5C8 == 0) { - gSPMatrix(gDisplayListHead++, VIRTUAL_TO_PHYSICAL(&gGfxPool->mtxLookAt[0]), - G_MTX_NOPUSH | G_MTX_MUL | G_MTX_PROJECTION); + gSPMatrix(gDisplayListHead++, VIRTUAL_TO_PHYSICAL(&gGfxPool->mtxLookAt[cameraId]), G_MTX_NOPUSH | G_MTX_MUL | G_MTX_PROJECTION); mtxf_identity(matrix); render_set_position(matrix, 0); } else { - gSPMatrix(gDisplayListHead++, VIRTUAL_TO_PHYSICAL(&gGfxPool->mtxLookAt[0]), - G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + gSPMatrix(gDisplayListHead++, VIRTUAL_TO_PHYSICAL(&gGfxPool->mtxLookAt[cameraId]), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); } - render_course(D_800DC5EC); + render_course(screen); if (D_800DC5C8 == 1) { - gSPMatrix(gDisplayListHead++, VIRTUAL_TO_PHYSICAL(&gGfxPool->mtxLookAt[0]), - G_MTX_NOPUSH | G_MTX_MUL | G_MTX_PROJECTION); + gSPMatrix(gDisplayListHead++, VIRTUAL_TO_PHYSICAL(&gGfxPool->mtxLookAt[cameraId]), G_MTX_NOPUSH | G_MTX_MUL | G_MTX_PROJECTION); mtxf_identity(matrix); render_set_position(matrix, 0); } - render_course_actors(D_800DC5EC); - render_object(RENDER_SCREEN_MODE_1P_PLAYER_ONE); - render_players_on_screen_one(); - func_8029122C(D_800DC5EC, PLAYER_ONE); - func_80021B0C(); - render_item_boxes(D_800DC5EC); - render_player_snow_effect(RENDER_SCREEN_MODE_1P_PLAYER_ONE); + render_course_actors(screen); + render_object(mode); + switch(screenId) { + case 0: + render_players_on_screen_one(); + break; + case 1: + render_players_on_screen_two(); + break; + case 2: + render_players_on_screen_three(); + break; + case 3: + render_players_on_screen_four(); + break; + } + func_8029122C(screen, playerId); + + switch(playerId) { + case 0: + func_80021B0C(); + break; + case 1: + func_80021C78(); + break; + case 2: + func_80021D40(); + break; + case 3: + func_80021DA8(); + break; + }; + + render_item_boxes(screen); + render_player_snow_effect(mode); func_80058BF4(); if (D_800DC5B8 != 0) { - func_80058C20(RENDER_SCREEN_MODE_1P_PLAYER_ONE); + func_80058C20(mode); } - func_80093A5C(RENDER_SCREEN_MODE_1P_PLAYER_ONE); + func_80093A5C(mode); if (D_800DC5B8 != 0) { - render_hud(RENDER_SCREEN_MODE_1P_PLAYER_ONE); - } -} - -void render_player_one_2p_screen_vertical(void) { - Camera* camera = &cameras[0]; - UNUSED s32 pad[2]; - u16 perspNorm; - Mat4 matrix; -#ifdef VERSION_EU - f32 sp9C; -#else - UNUSED f32 sp9C; -#endif - - func_802A50EC(); -#ifdef VERSION_EU - sp9C = gScreenAspect * 1.2f; -#endif - init_rdp(); - func_802A3730(D_800DC5EC); - gSPSetGeometryMode(gDisplayListHead++, G_ZBUFFER | G_SHADE | G_CULL_BACK | G_SHADING_SMOOTH); -#ifdef VERSION_EU - guPerspective(&gGfxPool->mtxPersp[0], &perspNorm, gCameraZoom[0], sp9C, CourseManager_GetProps()->NearPersp, - CourseManager_GetProps()->FarPersp, 1.0f); -#else - guPerspective(&gGfxPool->mtxPersp[0], &perspNorm, gCameraZoom[0], gScreenAspect, - CourseManager_GetProps()->NearPersp, CourseManager_GetProps()->FarPersp, 1.0f); -#endif - gSPPerspNormalize(gDisplayListHead++, perspNorm); - gSPMatrix(gDisplayListHead++, VIRTUAL_TO_PHYSICAL(&gGfxPool->mtxPersp[0]), - G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_PROJECTION); - guLookAt(&gGfxPool->mtxLookAt[0], camera->pos[0], camera->pos[1], camera->pos[2], camera->lookAt[0], - camera->lookAt[1], camera->lookAt[2], camera->up[0], camera->up[1], camera->up[2]); - - if (D_800DC5C8 == 0) { - - gSPMatrix(gDisplayListHead++, VIRTUAL_TO_PHYSICAL(&gGfxPool->mtxLookAt[0]), - G_MTX_NOPUSH | G_MTX_MUL | G_MTX_PROJECTION); - mtxf_identity(matrix); - render_set_position(matrix, 0); - } else { - gSPMatrix(gDisplayListHead++, VIRTUAL_TO_PHYSICAL(&gGfxPool->mtxLookAt[0]), - G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); - } - render_course(D_800DC5EC); - if (D_800DC5C8 == 1) { - - gSPMatrix(gDisplayListHead++, VIRTUAL_TO_PHYSICAL(&gGfxPool->mtxLookAt[0]), - G_MTX_NOPUSH | G_MTX_MUL | G_MTX_PROJECTION); - - mtxf_identity(matrix); - render_set_position(matrix, 0); - } - render_course_actors(D_800DC5EC); - render_object(RENDER_SCREEN_MODE_2P_HORIZONTAL_PLAYER_ONE); - render_players_on_screen_one(); - func_8029122C(D_800DC5EC, PLAYER_ONE); - func_80021B0C(); - render_item_boxes(D_800DC5EC); - render_player_snow_effect(RENDER_SCREEN_MODE_2P_HORIZONTAL_PLAYER_ONE); - func_80058BF4(); - if (D_800DC5B8 != 0) { - func_80058C20(RENDER_SCREEN_MODE_2P_HORIZONTAL_PLAYER_ONE); - } - func_80093A5C(RENDER_SCREEN_MODE_2P_HORIZONTAL_PLAYER_ONE); - if (D_800DC5B8 != 0) { - render_hud(RENDER_SCREEN_MODE_2P_HORIZONTAL_PLAYER_ONE); - } - D_8015F788 += 1; -} - -void render_player_two_2p_screen_vertical(void) { - Camera* camera = &cameras[1]; - UNUSED s32 pad[2]; - u16 perspNorm; - Mat4 matrix; -#ifdef VERSION_EU - f32 sp9C; -#else - UNUSED f32 sp9C; -#endif - - func_802A5004(); - init_rdp(); - func_802A3730(D_800DC5F0); -#ifdef VERSION_EU - sp9C = gScreenAspect * 1.2f; -#endif - gSPSetGeometryMode(gDisplayListHead++, G_ZBUFFER | G_SHADE | G_CULL_BACK | G_SHADING_SMOOTH); -#ifdef VERSION_EU - guPerspective(&gGfxPool->mtxPersp[1], &perspNorm, gCameraZoom[1], sp9C, CourseManager_GetProps()->NearPersp, - CourseManager_GetProps()->FarPersp, 1.0f); -#else - guPerspective(&gGfxPool->mtxPersp[1], &perspNorm, gCameraZoom[1], gScreenAspect, - CourseManager_GetProps()->NearPersp, CourseManager_GetProps()->FarPersp, 1.0f); -#endif - gSPPerspNormalize(gDisplayListHead++, perspNorm); - gSPMatrix(gDisplayListHead++, VIRTUAL_TO_PHYSICAL(&gGfxPool->mtxPersp[1]), - G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_PROJECTION); - guLookAt(&gGfxPool->mtxLookAt[1], camera->pos[0], camera->pos[1], camera->pos[2], camera->lookAt[0], - camera->lookAt[1], camera->lookAt[2], camera->up[0], camera->up[1], camera->up[2]); - - if (D_800DC5C8 == 0) { - gSPMatrix(gDisplayListHead++, VIRTUAL_TO_PHYSICAL(&gGfxPool->mtxLookAt[1]), - G_MTX_NOPUSH | G_MTX_MUL | G_MTX_PROJECTION); - mtxf_identity(matrix); - render_set_position(matrix, 0); - } else { - gSPMatrix(gDisplayListHead++, VIRTUAL_TO_PHYSICAL(&gGfxPool->mtxLookAt[1]), - G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); - } - render_course(D_800DC5F0); - if (D_800DC5C8 == 1) { - gSPMatrix(gDisplayListHead++, VIRTUAL_TO_PHYSICAL(&gGfxPool->mtxLookAt[1]), - G_MTX_NOPUSH | G_MTX_MUL | G_MTX_PROJECTION); - mtxf_identity(matrix); - render_set_position(matrix, 0); - } - render_course_actors(D_800DC5F0); - render_object(RENDER_SCREEN_MODE_2P_HORIZONTAL_PLAYER_TWO); - render_players_on_screen_two(); - func_8029122C(D_800DC5F0, PLAYER_TWO); - func_80021C78(); - render_item_boxes(D_800DC5F0); - func_80058BF4(); - render_player_snow_effect(RENDER_SCREEN_MODE_2P_HORIZONTAL_PLAYER_TWO); - if (D_800DC5B8 != 0) { - func_80058C20(RENDER_SCREEN_MODE_2P_HORIZONTAL_PLAYER_TWO); - } - func_80093A5C(RENDER_SCREEN_MODE_2P_HORIZONTAL_PLAYER_TWO); - if (D_800DC5B8 != 0) { - render_hud(RENDER_SCREEN_MODE_2P_HORIZONTAL_PLAYER_TWO); - } - D_8015F788 += 1; -} - -void render_player_one_2p_screen_horizontal(void) { - Camera* camera = &cameras[0]; - UNUSED s32 pad[2]; - u16 perspNorm; - Mat4 matrix; -#ifdef VERSION_EU - f32 sp9C; -#endif - - func_802A51D4(); - gSPSetGeometryMode(gDisplayListHead++, G_SHADE | G_CULL_BACK | G_LIGHTING | G_SHADING_SMOOTH); - init_rdp(); - func_802A3730(D_800DC5EC); -#ifdef VERSION_EU - sp9C = gScreenAspect * 1.2f; -#endif - gSPSetGeometryMode(gDisplayListHead++, G_ZBUFFER | G_SHADE | G_CULL_BACK | G_SHADING_SMOOTH); -#ifdef VERSION_EU - guPerspective(&gGfxPool->mtxPersp[0], &perspNorm, gCameraZoom[0], sp9C, CourseManager_GetProps()->NearPersp, - CourseManager_GetProps()->FarPersp, 1.0f); -#else - guPerspective(&gGfxPool->mtxPersp[0], &perspNorm, gCameraZoom[0], gScreenAspect, - CourseManager_GetProps()->NearPersp, CourseManager_GetProps()->FarPersp, 1.0f); -#endif - gSPPerspNormalize(gDisplayListHead++, perspNorm); - gSPMatrix(gDisplayListHead++, VIRTUAL_TO_PHYSICAL(&gGfxPool->mtxPersp[0]), - G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_PROJECTION); - guLookAt(&gGfxPool->mtxLookAt[0], camera->pos[0], camera->pos[1], camera->pos[2], camera->lookAt[0], - camera->lookAt[1], camera->lookAt[2], camera->up[0], camera->up[1], camera->up[2]); - - if (D_800DC5C8 == 0) { - - gSPMatrix(gDisplayListHead++, VIRTUAL_TO_PHYSICAL(&gGfxPool->mtxLookAt[0]), - G_MTX_NOPUSH | G_MTX_MUL | G_MTX_PROJECTION); - mtxf_identity(matrix); - render_set_position(matrix, 0); - } else { - gSPMatrix(gDisplayListHead++, VIRTUAL_TO_PHYSICAL(&gGfxPool->mtxLookAt[0]), - G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); - } - render_course(D_800DC5EC); - if (D_800DC5C8 == 1) { - gSPMatrix(gDisplayListHead++, VIRTUAL_TO_PHYSICAL(&gGfxPool->mtxLookAt[0]), - G_MTX_NOPUSH | G_MTX_MUL | G_MTX_PROJECTION); - mtxf_identity(matrix); - render_set_position(matrix, 0); - } - render_course_actors(D_800DC5EC); - render_object(RENDER_SCREEN_MODE_2P_VERTICAL_PLAYER_ONE); - render_players_on_screen_one(); - func_8029122C(D_800DC5EC, PLAYER_ONE); - func_80021B0C(); - render_item_boxes(D_800DC5EC); - render_player_snow_effect(RENDER_SCREEN_MODE_2P_VERTICAL_PLAYER_ONE); - func_80058BF4(); - if (D_800DC5B8 != 0) { - func_80058C20(RENDER_SCREEN_MODE_2P_VERTICAL_PLAYER_ONE); - } - func_80093A5C(RENDER_SCREEN_MODE_2P_VERTICAL_PLAYER_ONE); - if (D_800DC5B8 != 0) { - render_hud(RENDER_SCREEN_MODE_2P_VERTICAL_PLAYER_ONE); - } - D_8015F788 += 1; -} - -void render_player_two_2p_screen_horizontal(void) { - Camera* camera = &cameras[1]; - UNUSED s32 pad[2]; - u16 perspNorm; - Mat4 matrix; -#ifdef VERSION_EU - f32 sp9C; -#endif - - func_802A52BC(); - gSPSetGeometryMode(gDisplayListHead++, G_SHADE | G_CULL_BACK | G_LIGHTING | G_SHADING_SMOOTH); - init_rdp(); - func_802A3730(D_800DC5F0); -#ifdef VERSION_EU - sp9C = gScreenAspect * 1.2f; -#endif - gSPSetGeometryMode(gDisplayListHead++, G_ZBUFFER | G_SHADE | G_CULL_BACK | G_SHADING_SMOOTH); -#ifdef VERSION_EU - guPerspective(&gGfxPool->mtxPersp[1], &perspNorm, gCameraZoom[1], sp9C, CourseManager_GetProps()->NearPersp, - CourseManager_GetProps()->FarPersp, 1.0f); -#else - guPerspective(&gGfxPool->mtxPersp[1], &perspNorm, gCameraZoom[1], gScreenAspect, - CourseManager_GetProps()->NearPersp, CourseManager_GetProps()->FarPersp, 1.0f); -#endif - gSPPerspNormalize(gDisplayListHead++, perspNorm); - gSPMatrix(gDisplayListHead++, VIRTUAL_TO_PHYSICAL(&gGfxPool->mtxPersp[1]), - G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_PROJECTION); - guLookAt(&gGfxPool->mtxLookAt[1], camera->pos[0], camera->pos[1], camera->pos[2], camera->lookAt[0], - camera->lookAt[1], camera->lookAt[2], camera->up[0], camera->up[1], camera->up[2]); - - if (D_800DC5C8 == 0) { - gSPMatrix(gDisplayListHead++, VIRTUAL_TO_PHYSICAL(&gGfxPool->mtxLookAt[1]), - G_MTX_NOPUSH | G_MTX_MUL | G_MTX_PROJECTION); - mtxf_identity(matrix); - render_set_position(matrix, 0); - } else { - gSPMatrix(gDisplayListHead++, VIRTUAL_TO_PHYSICAL(&gGfxPool->mtxLookAt[1]), - G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); - } - render_course(D_800DC5F0); - if (D_800DC5C8 == 1) { - gSPMatrix(gDisplayListHead++, VIRTUAL_TO_PHYSICAL(&gGfxPool->mtxLookAt[1]), - G_MTX_NOPUSH | G_MTX_MUL | G_MTX_PROJECTION); - mtxf_identity(matrix); - render_set_position(matrix, 0); - } - render_course_actors(D_800DC5F0); - render_object(RENDER_SCREEN_MODE_2P_VERTICAL_PLAYER_TWO); - render_players_on_screen_two(); - func_8029122C(D_800DC5F0, PLAYER_TWO); - func_80021C78(); - render_item_boxes(D_800DC5F0); - render_player_snow_effect(RENDER_SCREEN_MODE_2P_VERTICAL_PLAYER_TWO); - func_80058BF4(); - if (D_800DC5B8 != 0) { - func_80058C20(RENDER_SCREEN_MODE_2P_VERTICAL_PLAYER_TWO); - } - func_80093A5C(RENDER_SCREEN_MODE_2P_VERTICAL_PLAYER_TWO); - if (D_800DC5B8 != 0) { - render_hud(RENDER_SCREEN_MODE_2P_VERTICAL_PLAYER_TWO); - } - D_8015F788 += 1; -} - -void render_player_one_3p_4p_screen(void) { - Camera* camera = camera1; - UNUSED s32 pad[2]; - u16 perspNorm; - Mat4 matrix; -#ifdef VERSION_EU - f32 sp9C; - sp9C = gScreenAspect * 1.2f; -#endif - - func_802A54A8(); - init_rdp(); - func_802A3730(D_800DC5EC); - gSPSetGeometryMode(gDisplayListHead++, G_ZBUFFER | G_SHADE | G_CULL_BACK | G_SHADING_SMOOTH); -#ifdef VERSION_EU - guPerspective(&gGfxPool->mtxPersp[0], &perspNorm, gCameraZoom[0], sp9C, CourseManager_GetProps()->NearPersp, - CourseManager_GetProps()->FarPersp, 1.0f); -#else - guPerspective(&gGfxPool->mtxPersp[0], &perspNorm, gCameraZoom[0], gScreenAspect, - CourseManager_GetProps()->NearPersp, CourseManager_GetProps()->FarPersp, 1.0f); -#endif - gSPPerspNormalize(gDisplayListHead++, perspNorm); - gSPMatrix(gDisplayListHead++, VIRTUAL_TO_PHYSICAL(&gGfxPool->mtxPersp[0]), - G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_PROJECTION); - guLookAt(&gGfxPool->mtxLookAt[0], camera->pos[0], camera->pos[1], camera->pos[2], camera->lookAt[0], - camera->lookAt[1], camera->lookAt[2], camera->up[0], camera->up[1], camera->up[2]); - - if (D_800DC5C8 == 0) { - gSPMatrix(gDisplayListHead++, VIRTUAL_TO_PHYSICAL(&gGfxPool->mtxLookAt[0]), - G_MTX_NOPUSH | G_MTX_MUL | G_MTX_PROJECTION); - mtxf_identity(matrix); - render_set_position(matrix, 0); - } else { - gSPMatrix(gDisplayListHead++, VIRTUAL_TO_PHYSICAL(&gGfxPool->mtxLookAt[0]), - G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); - } - render_course(D_800DC5EC); - if (D_800DC5C8 == 1) { - gSPMatrix(gDisplayListHead++, VIRTUAL_TO_PHYSICAL(&gGfxPool->mtxLookAt[0]), - G_MTX_NOPUSH | G_MTX_MUL | G_MTX_PROJECTION); - mtxf_identity(matrix); - render_set_position(matrix, 0); - } - render_course_actors(D_800DC5EC); - render_object(RENDER_SCREEN_MODE_3P_4P_PLAYER_ONE); - render_players_on_screen_one(); - func_8029122C(D_800DC5EC, PLAYER_ONE); - func_80021B0C(); - render_item_boxes(D_800DC5EC); - render_player_snow_effect(RENDER_SCREEN_MODE_3P_4P_PLAYER_ONE); - func_80058BF4(); - if (D_800DC5B8 != 0) { - func_80058C20(RENDER_SCREEN_MODE_3P_4P_PLAYER_ONE); - } - func_80093A5C(RENDER_SCREEN_MODE_3P_4P_PLAYER_ONE); - if (D_800DC5B8 != 0) { - render_hud(RENDER_SCREEN_MODE_3P_4P_PLAYER_ONE); - } - D_8015F788 += 1; -} - -void render_player_two_3p_4p_screen(void) { - Camera* camera = camera2; - UNUSED s32 pad[2]; - u16 perspNorm; - Mat4 matrix; -#ifdef VERSION_EU - f32 sp9C; - sp9C = gScreenAspect * 1.2f; -#endif - - func_802A5590(); - init_rdp(); - func_802A3730(D_800DC5F0); - gSPSetGeometryMode(gDisplayListHead++, G_ZBUFFER | G_SHADE | G_CULL_BACK | G_SHADING_SMOOTH); -#ifdef VERSION_EU - guPerspective(&gGfxPool->mtxPersp[1], &perspNorm, gCameraZoom[1], sp9C, CourseManager_GetProps()->NearPersp, - CourseManager_GetProps()->FarPersp, 1.0f); -#else - guPerspective(&gGfxPool->mtxPersp[1], &perspNorm, gCameraZoom[1], gScreenAspect, - CourseManager_GetProps()->NearPersp, CourseManager_GetProps()->FarPersp, 1.0f); -#endif - gSPPerspNormalize(gDisplayListHead++, perspNorm); - gSPMatrix(gDisplayListHead++, VIRTUAL_TO_PHYSICAL(&gGfxPool->mtxPersp[1]), - G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_PROJECTION); - - guLookAt(&gGfxPool->mtxLookAt[1], camera->pos[0], camera->pos[1], camera->pos[2], camera->lookAt[0], - camera->lookAt[1], camera->lookAt[2], camera->up[0], camera->up[1], camera->up[2]); - if (D_800DC5C8 == 0) { - gSPMatrix(gDisplayListHead++, VIRTUAL_TO_PHYSICAL(&gGfxPool->mtxLookAt[1]), - G_MTX_NOPUSH | G_MTX_MUL | G_MTX_PROJECTION); - mtxf_identity(matrix); - render_set_position(matrix, 0); - } else { - gSPMatrix(gDisplayListHead++, VIRTUAL_TO_PHYSICAL(&gGfxPool->mtxLookAt[1]), - G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); - } - render_course(D_800DC5F0); - if (D_800DC5C8 == 1) { - gSPMatrix(gDisplayListHead++, VIRTUAL_TO_PHYSICAL(&gGfxPool->mtxLookAt[1]), - G_MTX_NOPUSH | G_MTX_MUL | G_MTX_PROJECTION); - mtxf_identity(matrix); - render_set_position(matrix, 0); - } - render_course_actors(D_800DC5F0); - render_object(RENDER_SCREEN_MODE_3P_4P_PLAYER_TWO); - render_players_on_screen_two(); - func_8029122C(D_800DC5F0, PLAYER_TWO); - func_80021C78(); - render_item_boxes(D_800DC5F0); - render_player_snow_effect(RENDER_SCREEN_MODE_3P_4P_PLAYER_TWO); - func_80058BF4(); - if (D_800DC5B8 != 0) { - func_80058C20(RENDER_SCREEN_MODE_3P_4P_PLAYER_TWO); - } - func_80093A5C(RENDER_SCREEN_MODE_3P_4P_PLAYER_TWO); - if (D_800DC5B8 != 0) { - render_hud(RENDER_SCREEN_MODE_3P_4P_PLAYER_TWO); - } - D_8015F788 += 1; -} - -void render_player_three_3p_4p_screen(void) { - Camera* camera = camera3; - UNUSED s32 pad[2]; - u16 perspNorm; - Mat4 matrix; -#ifdef VERSION_EU - f32 sp9C; - sp9C = gScreenAspect * 1.2f; -#endif - - func_802A5678(); - init_rdp(); - func_802A3730(D_800DC5F4); - - gSPSetGeometryMode(gDisplayListHead++, G_ZBUFFER | G_SHADE | G_CULL_BACK | G_SHADING_SMOOTH); -#ifdef VERSION_EU - guPerspective(&gGfxPool->mtxPersp[2], &perspNorm, gCameraZoom[2], sp9C, CourseManager_GetProps()->NearPersp, - CourseManager_GetProps()->FarPersp, 1.0f); -#else - guPerspective(&gGfxPool->mtxPersp[2], &perspNorm, gCameraZoom[2], gScreenAspect, - CourseManager_GetProps()->NearPersp, CourseManager_GetProps()->FarPersp, 1.0f); -#endif - gSPPerspNormalize(gDisplayListHead++, perspNorm); - gSPMatrix(gDisplayListHead++, VIRTUAL_TO_PHYSICAL(&gGfxPool->mtxPersp[2]), - G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_PROJECTION); - guLookAt(&gGfxPool->mtxLookAt[2], camera->pos[0], camera->pos[1], camera->pos[2], camera->lookAt[0], - camera->lookAt[1], camera->lookAt[2], camera->up[0], camera->up[1], camera->up[2]); - if (D_800DC5C8 == 0) { - gSPMatrix(gDisplayListHead++, VIRTUAL_TO_PHYSICAL(&gGfxPool->mtxLookAt[2]), - G_MTX_NOPUSH | G_MTX_MUL | G_MTX_PROJECTION); - - mtxf_identity(matrix); - render_set_position(matrix, 0); - } else { - gSPMatrix(gDisplayListHead++, VIRTUAL_TO_PHYSICAL(&gGfxPool->mtxLookAt[2]), - G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); - } - render_course(D_800DC5F4); - if (D_800DC5C8 == 1) { - gSPMatrix(gDisplayListHead++, VIRTUAL_TO_PHYSICAL(&gGfxPool->mtxLookAt[2]), - G_MTX_NOPUSH | G_MTX_MUL | G_MTX_PROJECTION); - mtxf_identity(matrix); - render_set_position(matrix, 0); - } - render_course_actors(D_800DC5F4); - render_object(RENDER_SCREEN_MODE_3P_4P_PLAYER_THREE); - render_players_on_screen_three(); - func_8029122C(D_800DC5F4, PLAYER_THREE); - func_80021D40(); - render_item_boxes(D_800DC5F4); - render_player_snow_effect(RENDER_SCREEN_MODE_3P_4P_PLAYER_THREE); - func_80058BF4(); - if (D_800DC5B8 != 0) { - func_80058C20(RENDER_SCREEN_MODE_3P_4P_PLAYER_THREE); - } - func_80093A5C(RENDER_SCREEN_MODE_3P_4P_PLAYER_THREE); - if (D_800DC5B8 != 0) { - render_hud(RENDER_SCREEN_MODE_3P_4P_PLAYER_THREE); - } - D_8015F788 += 1; -} - -void render_player_four_3p_4p_screen(void) { - Camera* camera = camera4; - UNUSED s32 pad[2]; - u16 perspNorm; - Mat4 matrix; -#ifdef VERSION_EU - f32 sp9C; - sp9C = gScreenAspect * 1.2f; -#endif - - func_802A5760(); - if (gPlayerCountSelection1 == 3) { - func_80093A5C(RENDER_SCREEN_MODE_3P_4P_PLAYER_FOUR); - if (D_800DC5B8 != 0) { - render_hud(RENDER_SCREEN_MODE_3P_4P_PLAYER_FOUR); - } - D_8015F788 += 1; - return; + render_hud(mode); } - init_rdp(); - func_802A3730(D_800DC5F8); - - gSPSetGeometryMode(gDisplayListHead++, G_ZBUFFER | G_SHADE | G_CULL_BACK | G_SHADING_SMOOTH); -#ifdef VERSION_EU - guPerspective(&gGfxPool->mtxPersp[3], &perspNorm, gCameraZoom[3], sp9C, CourseManager_GetProps()->NearPersp, - CourseManager_GetProps()->FarPersp, 1.0f); -#else - guPerspective(&gGfxPool->mtxPersp[3], &perspNorm, gCameraZoom[3], gScreenAspect, - CourseManager_GetProps()->NearPersp, CourseManager_GetProps()->FarPersp, 1.0f); -#endif - gSPPerspNormalize(gDisplayListHead++, perspNorm); - gSPMatrix(gDisplayListHead++, VIRTUAL_TO_PHYSICAL(&gGfxPool->mtxPersp[3]), - G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_PROJECTION); - guLookAt(&gGfxPool->mtxLookAt[3], camera->pos[0], camera->pos[1], camera->pos[2], camera->lookAt[0], - camera->lookAt[1], camera->lookAt[2], camera->up[0], camera->up[1], camera->up[2]); - if (D_800DC5C8 == 0) { - gSPMatrix(gDisplayListHead++, VIRTUAL_TO_PHYSICAL(&gGfxPool->mtxLookAt[3]), - G_MTX_NOPUSH | G_MTX_MUL | G_MTX_PROJECTION); - mtxf_identity(matrix); - render_set_position(matrix, 0); - } else { - gSPMatrix(gDisplayListHead++, VIRTUAL_TO_PHYSICAL(&gGfxPool->mtxLookAt[3]), - G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + // Do not increment in single player mode + if (mode != RENDER_SCREEN_MODE_1P_PLAYER_ONE) { + gNumScreens += 1; } - render_course(D_800DC5F8); - if (D_800DC5C8 == 1) { - gSPMatrix(gDisplayListHead++, VIRTUAL_TO_PHYSICAL(&gGfxPool->mtxLookAt[3]), - G_MTX_NOPUSH | G_MTX_MUL | G_MTX_PROJECTION); - mtxf_identity(matrix); - render_set_position(matrix, 0); - } - render_course_actors(D_800DC5F8); - render_object(RENDER_SCREEN_MODE_3P_4P_PLAYER_FOUR); - render_players_on_screen_four(); - func_8029122C(D_800DC5F8, PLAYER_FOUR); - func_80021DA8(); - render_item_boxes(D_800DC5F8); - render_player_snow_effect(RENDER_SCREEN_MODE_3P_4P_PLAYER_FOUR); - func_80058BF4(); - if (D_800DC5B8 != 0) { - func_80058C20(RENDER_SCREEN_MODE_3P_4P_PLAYER_FOUR); - } - func_80093A5C(RENDER_SCREEN_MODE_3P_4P_PLAYER_FOUR); - if (D_800DC5B8 != 0) { - render_hud(RENDER_SCREEN_MODE_3P_4P_PLAYER_FOUR); - } - D_8015F788 += 1; } void func_802A74BC(void) { @@ -1427,20 +995,20 @@ void func_802A7728(void) { } else if (temp_v0 > 2) { temp_v0 = 0; } - copy_framebuffer(D_800DC5DC, D_800DC5E0, 64, 32, (u16*) PHYSICAL_TO_VIRTUAL(gPhysicalFramebuffers[temp_v0]), - (u16*) PHYSICAL_TO_VIRTUAL(gSegmentTable[5] + 0x8800)); - copy_framebuffer(D_800DC5DC + 64, D_800DC5E0, 64, 32, (u16*) PHYSICAL_TO_VIRTUAL(gPhysicalFramebuffers[temp_v0]), - (u16*) PHYSICAL_TO_VIRTUAL(gSegmentTable[5] + 0x9800)); - copy_framebuffer(D_800DC5DC, D_800DC5E0 + 32, 64, 32, (u16*) PHYSICAL_TO_VIRTUAL(gPhysicalFramebuffers[temp_v0]), - (u16*) PHYSICAL_TO_VIRTUAL(gSegmentTable[5] + 0xA800)); - copy_framebuffer(D_800DC5DC + 64, D_800DC5E0 + 32, 64, 32, - (u16*) PHYSICAL_TO_VIRTUAL(gPhysicalFramebuffers[temp_v0]), - (u16*) PHYSICAL_TO_VIRTUAL(gSegmentTable[5] + 0xB800)); - copy_framebuffer(D_800DC5DC, D_800DC5E0 + 64, 64, 32, (u16*) PHYSICAL_TO_VIRTUAL(gPhysicalFramebuffers[temp_v0]), - (u16*) PHYSICAL_TO_VIRTUAL(gSegmentTable[5] + 0xC800)); - copy_framebuffer(D_800DC5DC + 64, D_800DC5E0 + 64, 64, 32, - (u16*) PHYSICAL_TO_VIRTUAL(gPhysicalFramebuffers[temp_v0]), - (u16*) PHYSICAL_TO_VIRTUAL(gSegmentTable[5] + 0xD800)); + // copy_framebuffer(D_800DC5DC, D_800DC5E0, 64, 32, (u16*) PHYSICAL_TO_VIRTUAL(gPhysicalFramebuffers[temp_v0]), + // (u16*) PHYSICAL_TO_VIRTUAL(gSegmentTable[5] + 0x8800)); + // copy_framebuffer(D_800DC5DC + 64, D_800DC5E0, 64, 32, (u16*) PHYSICAL_TO_VIRTUAL(gPhysicalFramebuffers[temp_v0]), + // (u16*) PHYSICAL_TO_VIRTUAL(gSegmentTable[5] + 0x9800)); + // copy_framebuffer(D_800DC5DC, D_800DC5E0 + 32, 64, 32, (u16*) PHYSICAL_TO_VIRTUAL(gPhysicalFramebuffers[temp_v0]), + // (u16*) PHYSICAL_TO_VIRTUAL(gSegmentTable[5] + 0xA800)); + // copy_framebuffer(D_800DC5DC + 64, D_800DC5E0 + 32, 64, 32, + // (u16*) PHYSICAL_TO_VIRTUAL(gPhysicalFramebuffers[temp_v0]), + // (u16*) PHYSICAL_TO_VIRTUAL(gSegmentTable[5] + 0xB800)); + // copy_framebuffer(D_800DC5DC, D_800DC5E0 + 64, 64, 32, (u16*) PHYSICAL_TO_VIRTUAL(gPhysicalFramebuffers[temp_v0]), + // (u16*) PHYSICAL_TO_VIRTUAL(gSegmentTable[5] + 0xC800)); + // copy_framebuffer(D_800DC5DC + 64, D_800DC5E0 + 64, 64, 32, + // (u16*) PHYSICAL_TO_VIRTUAL(gPhysicalFramebuffers[temp_v0]), + // (u16*) PHYSICAL_TO_VIRTUAL(gSegmentTable[5] + 0xD800)); } void func_802A7940(void) { @@ -1458,21 +1026,21 @@ void func_802A7940(void) { } else if (temp_v0 > 2) { temp_v0 = 0; } - copy_framebuffer(D_800DC5DC, D_800DC5E0, 0x40, 0x20, (u16*) PHYSICAL_TO_VIRTUAL(gPhysicalFramebuffers[temp_v0]), - (u16*) PHYSICAL_TO_VIRTUAL(gSegmentTable[5] + 0xF800)); - copy_framebuffer(D_800DC5DC + 0x40, D_800DC5E0, 0x40, 0x20, - (u16*) PHYSICAL_TO_VIRTUAL(gPhysicalFramebuffers[temp_v0]), - (u16*) PHYSICAL_TO_VIRTUAL(gSegmentTable[5] + 0x10800)); - copy_framebuffer(D_800DC5DC, D_800DC5E0 + 0x20, 0x40, 0x20, - (u16*) PHYSICAL_TO_VIRTUAL(gPhysicalFramebuffers[temp_v0]), - (u16*) PHYSICAL_TO_VIRTUAL(gSegmentTable[5] + 0x11800)); - copy_framebuffer(D_800DC5DC + 0x40, D_800DC5E0 + 0x20, 0x40, 0x20, - (u16*) PHYSICAL_TO_VIRTUAL(gPhysicalFramebuffers[temp_v0]), - (u16*) PHYSICAL_TO_VIRTUAL(gSegmentTable[5] + 0x12800)); - copy_framebuffer(D_800DC5DC, D_800DC5E0 + 0x40, 0x40, 0x20, - (u16*) PHYSICAL_TO_VIRTUAL(gPhysicalFramebuffers[temp_v0]), - (u16*) PHYSICAL_TO_VIRTUAL(gSegmentTable[5] + 0x13800)); - copy_framebuffer(D_800DC5DC + 0x40, D_800DC5E0 + 0x40, 0x40, 0x20, - (u16*) PHYSICAL_TO_VIRTUAL(gPhysicalFramebuffers[temp_v0]), - (u16*) PHYSICAL_TO_VIRTUAL(gSegmentTable[5] + 0x14800)); + // copy_framebuffer(D_800DC5DC, D_800DC5E0, 0x40, 0x20, (u16*) PHYSICAL_TO_VIRTUAL(gPhysicalFramebuffers[temp_v0]), + // (u16*) PHYSICAL_TO_VIRTUAL(gSegmentTable[5] + 0xF800)); + // copy_framebuffer(D_800DC5DC + 0x40, D_800DC5E0, 0x40, 0x20, + // (u16*) PHYSICAL_TO_VIRTUAL(gPhysicalFramebuffers[temp_v0]), + // (u16*) PHYSICAL_TO_VIRTUAL(gSegmentTable[5] + 0x10800)); + // copy_framebuffer(D_800DC5DC, D_800DC5E0 + 0x20, 0x40, 0x20, + // (u16*) PHYSICAL_TO_VIRTUAL(gPhysicalFramebuffers[temp_v0]), + // (u16*) PHYSICAL_TO_VIRTUAL(gSegmentTable[5] + 0x11800)); + // copy_framebuffer(D_800DC5DC + 0x40, D_800DC5E0 + 0x20, 0x40, 0x20, + // (u16*) PHYSICAL_TO_VIRTUAL(gPhysicalFramebuffers[temp_v0]), + // (u16*) PHYSICAL_TO_VIRTUAL(gSegmentTable[5] + 0x12800)); + // copy_framebuffer(D_800DC5DC, D_800DC5E0 + 0x40, 0x40, 0x20, + // (u16*) PHYSICAL_TO_VIRTUAL(gPhysicalFramebuffers[temp_v0]), + // (u16*) PHYSICAL_TO_VIRTUAL(gSegmentTable[5] + 0x13800)); + // copy_framebuffer(D_800DC5DC + 0x40, D_800DC5E0 + 0x40, 0x40, 0x20, + // (u16*) PHYSICAL_TO_VIRTUAL(gPhysicalFramebuffers[temp_v0]), + // (u16*) PHYSICAL_TO_VIRTUAL(gSegmentTable[5] + 0x14800)); } diff --git a/src/racing/skybox_and_splitscreen.h b/src/racing/skybox_and_splitscreen.h index 054a5adca..50f7d71e2 100644 --- a/src/racing/skybox_and_splitscreen.h +++ b/src/racing/skybox_and_splitscreen.h @@ -51,6 +51,7 @@ void render_player_one_3p_4p_screen(void); void render_player_two_3p_4p_screen(void); void render_player_three_3p_4p_screen(void); void render_player_four_3p_4p_screen(void); +void render_screens(s32 mode, s32 cameraId, s32 playerId); void func_802A74BC(void); void copy_framebuffer(s32, s32, s32, s32, u16*, u16*); void func_802A7728(void); diff --git a/src/render_objects.c b/src/render_objects.c index d32d08046..97d62f84e 100644 --- a/src/render_objects.c +++ b/src/render_objects.c @@ -44,6 +44,7 @@ #include "engine/Engine.h" #include "engine/courses/Course.h" +#include "engine/Matrix.h" Lights1 D_800E45C0[] = { gdSPDefLights1(100, 0, 0, 100, 0, 0, 0, -120, 0), @@ -1370,7 +1371,7 @@ void func_8004A7AC(s32 objectIndex, f32 arg1) { } void func_8004A870(s32 objectIndex, f32 arg1) { - Mat4 sp30; + Mat4 mtx; Object* object; if ((is_obj_flag_status_active(objectIndex, 0x00000020) != 0) && @@ -1379,10 +1380,12 @@ void func_8004A870(s32 objectIndex, f32 arg1) { D_80183E50[0] = object->pos[0]; D_80183E50[1] = object->surfaceHeight + 0.8; D_80183E50[2] = object->pos[2]; - set_transform_matrix(sp30, object->unk_01C, D_80183E50, 0U, arg1); - convert_to_fixed_point_matrix(&gGfxPool->mtxHud[gMatrixHudCount], sp30); - gSPMatrix(gDisplayListHead++, VIRTUAL_TO_PHYSICAL(&gGfxPool->mtxHud[gMatrixHudCount++]), - G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + 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); } } @@ -3794,13 +3797,18 @@ void func_80053D74(s32 objectIndex, UNUSED s32 arg1, s32 vertexIndex) { } } -void func_80053E6C(s32 arg0) { +void render_balloons_grand_prix(s32 arg0) { s32 var_s1; s32 objectIndex; gSPDisplayList(gDisplayListHead++, D_0D007E98); gDPLoadTLUT_pal256(gDisplayListHead++, gTLUTOnomatopoeia); func_8004B614(0, 0, 0, 0, 0, 0, 0); + gDPSetAlphaCompare(gDisplayListHead++, G_AC_THRESHOLD); + gDPSetRenderMode(gDisplayListHead++, AA_EN | Z_CMP | Z_UPD | IM_RD | CVG_DST_WRAP | ZMODE_XLU | FORCE_BL | + GBL_c1(G_BL_CLR_IN, G_BL_A_IN, G_BL_CLR_MEM, G_BL_1MA), + AA_EN | Z_CMP | Z_UPD | IM_RD | CVG_DST_WRAP | ZMODE_XLU | FORCE_BL | + GBL_c2(G_BL_CLR_IN, G_BL_A_IN, G_BL_CLR_MEM, G_BL_1MA)); D_80183E80[0] = 0; D_80183E80[1] = 0x8000; rsp_load_texture(gTextureBalloon1, 64, 32); @@ -3810,13 +3818,7 @@ void func_80053E6C(s32 arg0) { func_80053D74(objectIndex, arg0, 0); } } - //! @bug This part is not rendering. - - 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); - - // rsp_load_texture(gTextureBalloon2, 64, 32); + rsp_load_texture(gTextureBalloon2, 64, 32); for (var_s1 = 0; var_s1 < D_80165738; var_s1++) { objectIndex = gObjectParticle3[var_s1]; if ((objectIndex != NULL_OBJECT_ID) && (gObjectList[objectIndex].state >= 2)) { @@ -4199,8 +4201,8 @@ void draw_crabs(s32 objectIndex, s32 cameraId) { 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, common_vtx_hedgehog, 0x00000040, 0x00000040, - 0x00000040, 0x00000020); + gObjectList[objectIndex].activeTexture, vtx, 64, 64, + 64, 32); } } @@ -4447,9 +4449,12 @@ void func_80055FA0(s32 objectIndex, UNUSED s32 arg1) { 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); + //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]), @@ -4565,17 +4570,19 @@ void func_8005669C(s32 objectIndex, UNUSED s32 arg1, s32 arg2) { } void func_800568A0(s32 objectIndex, s32 playerId) { - Mat4 sp30; + Mat4 mtx; Player* player; player = &gPlayerOne[playerId]; D_80183E50[0] = gObjectList[objectIndex].pos[0]; D_80183E50[1] = gObjectList[objectIndex].surfaceHeight + 0.8; D_80183E50[2] = gObjectList[objectIndex].pos[2]; - set_transform_matrix(sp30, player->collision.orientationVector, D_80183E50, 0U, 0.5f); - convert_to_fixed_point_matrix(&gGfxPool->mtxHud[gMatrixHudCount], sp30); - gSPMatrix(gDisplayListHead++, VIRTUAL_TO_PHYSICAL(&gGfxPool->mtxHud[gMatrixHudCount++]), - G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + set_transform_matrix(mtx, player->collision.orientationVector, D_80183E50, 0U, 0.5f); + // 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_LOAD | G_MTX_NOPUSH | G_MTX_MODELVIEW); gSPDisplayList(gDisplayListHead++, D_0D007B98); } @@ -4599,7 +4606,7 @@ void func_80056A94(s32 playerIndex) { func_80072428(gIndexObjectBombKart[playerIndex]); } -void render_object_bomb_kart(s32 cameraId) { +void render_battle_bomb_karts(s32 cameraId) { Player* temp_v0; s32 temp_s1; s32 temp_s0; @@ -4680,14 +4687,15 @@ void func_80056FCC(s32 bombIndex) { D_80183E50[0] = temp_v0->bombPos[0]; D_80183E50[1] = temp_v0->yPos + 1.0; D_80183E50[2] = temp_v0->bombPos[2]; - set_transform_matrix(mat, D_80164038[bombIndex].orientationVector, D_80183E50, 0U, 0.5f); - convert_to_fixed_point_matrix(&gGfxPool->mtxHud[gMatrixHudCount], mat); - gSPMatrix(gDisplayListHead++, VIRTUAL_TO_PHYSICAL(&gGfxPool->mtxHud[gMatrixHudCount++]), - G_MTX_LOAD | G_MTX_NOPUSH | G_MTX_MODELVIEW); + set_transform_matrix(mat, gBombKartCollision[bombIndex].orientationVector, D_80183E50, 0U, 0.5f); + //convert_to_fixed_point_matrix(&gGfxPool->mtxHud[gMatrixHudCount], mat); + //gSPMatrix(gDisplayListHead++, VIRTUAL_TO_PHYSICAL(&gGfxPool->mtxHud[gMatrixHudCount++]), + // G_MTX_LOAD | G_MTX_NOPUSH | G_MTX_MODELVIEW); + AddHudMatrix(mat, G_MTX_LOAD | G_MTX_NOPUSH | G_MTX_MODELVIEW); gSPDisplayList(gDisplayListHead++, D_0D007B98); } -void func_80057114(s32 cameraId) { +void render_bomb_karts(s32 cameraId) { Camera* camera; s32 objectIndex; s32 temp_s4; @@ -4856,8 +4864,7 @@ UNUSED void func_80057708() { void load_debug_font(void) { gSPDisplayList(gDisplayListHead++, D_0D008108); gSPDisplayList(gDisplayListHead++, D_0D008080); - //! todo: Implement alpha compare - // gDPSetAlphaCompare(gDisplayListHead++, G_AC_THRESHOLD); + gDPSetAlphaCompare(gDisplayListHead++, G_AC_THRESHOLD); } void func_80057778(void) { diff --git a/src/render_objects.h b/src/render_objects.h index 1c6ff370f..8dfcb12e3 100644 --- a/src/render_objects.h +++ b/src/render_objects.h @@ -9,7 +9,7 @@ extern "C" { #endif void func_80045738(u8*, u8*, s32, s32); -void func_80057114(s32); +void render_bomb_karts(s32); void func_800431B0(Vec3f, Vec3su, f32, Vtx*); void func_80043220(Vec3f, Vec3su, f32, Gfx*); void func_80043328(Vec3f, Vec3su, f32, Gfx*); @@ -350,7 +350,7 @@ void func_800534E8(s32); void render_object_thwomps_model(s32); void render_object_thwomps(s32); void func_80053D74(s32, s32, s32); -void func_80053E6C(s32); +void render_balloons_grand_prix(s32); void render_object_train_smoke_particle(s32, s32); void render_object_trains_smoke_particles(s32); @@ -396,11 +396,11 @@ void func_8005669C(s32, s32, s32); void func_800569F4(s32); void func_80056A40(s32, s32); void func_80056A94(s32); -void render_object_bomb_kart(s32); +void render_battle_bomb_karts(s32); void func_80056E24(s32, Vec3f); void func_80056FCC(s32); -void func_80057114(s32); +void render_bomb_karts(s32); void func_8005762C(s32*, s32*, s32, u32); void func_80057330(void); void func_80057338(void); diff --git a/src/render_player.c b/src/render_player.c index 42f5e6d04..64e2fe9be 100644 --- a/src/render_player.c +++ b/src/render_player.c @@ -267,16 +267,7 @@ void load_kart_texture_and_render_kart_particle_on_screen_one(void) { load_kart_texture_non_blocking(gPlayersToRenderPlayer[0], gPlayersToRenderPlayerId[0], gPlayersToRenderScreenId[0], gPlayersToRenderScreenId[0], D_801651D0[gPlayersToRenderScreenId[0]][gPlayersToRenderPlayerId[0]]); - render_kart_particle_on_screen_one(gPlayerOneCopy, PLAYER_ONE, PLAYER_ONE); - render_kart_particle_on_screen_one(gPlayerTwo, PLAYER_TWO, PLAYER_ONE); - render_kart_particle_on_screen_one(gPlayerThree, PLAYER_THREE, PLAYER_ONE); - render_kart_particle_on_screen_one(gPlayerFour, PLAYER_FOUR, PLAYER_ONE); - if (gActiveScreenMode != SCREEN_MODE_3P_4P_SPLITSCREEN) { - render_kart_particle_on_screen_one(gPlayerFive, PLAYER_FIVE, PLAYER_ONE); - render_kart_particle_on_screen_one(gPlayerSix, PLAYER_SIX, PLAYER_ONE); - render_kart_particle_on_screen_one(gPlayerSeven, PLAYER_SEVEN, PLAYER_ONE); - render_kart_particle_on_screen_one(gPlayerEight, PLAYER_EIGHT, PLAYER_ONE); - } + osRecvMesg(&gDmaMesgQueue, &gMainReceivedMesg, OS_MESG_BLOCK); for (i = 1; i < gPlayersToRenderCount; i++) { @@ -338,16 +329,6 @@ void load_kart_texture_and_render_kart_particle_on_screen_two(void) { load_kart_texture_non_blocking(gPlayersToRenderPlayer[0], gPlayersToRenderPlayerId[0], gPlayersToRenderScreenId[0], gPlayersToRenderScreenId[0], D_801651D0[gPlayersToRenderScreenId[0]][gPlayersToRenderPlayerId[0]]); - render_kart_particle_on_screen_two(gPlayerOneCopy, PLAYER_ONE, PLAYER_TWO); - render_kart_particle_on_screen_two(gPlayerTwo, PLAYER_TWO, PLAYER_TWO); - render_kart_particle_on_screen_two(gPlayerThree, PLAYER_THREE, PLAYER_TWO); - render_kart_particle_on_screen_two(gPlayerFour, PLAYER_FOUR, PLAYER_TWO); - if (gActiveScreenMode != SCREEN_MODE_3P_4P_SPLITSCREEN) { - render_kart_particle_on_screen_two(gPlayerFive, PLAYER_FIVE, PLAYER_TWO); - render_kart_particle_on_screen_two(gPlayerSix, PLAYER_SIX, PLAYER_TWO); - render_kart_particle_on_screen_two(gPlayerSeven, PLAYER_SEVEN, PLAYER_TWO); - render_kart_particle_on_screen_two(gPlayerEight, PLAYER_EIGHT, PLAYER_TWO); - } osRecvMesg(&gDmaMesgQueue, &gMainReceivedMesg, OS_MESG_BLOCK); for (var_s0 = 1; var_s0 < gPlayersToRenderCount; var_s0++) { load_kart_texture_non_blocking(gPlayersToRenderPlayer[var_s0], gPlayersToRenderPlayerId[var_s0], @@ -408,10 +389,6 @@ void load_kart_texture_and_render_kart_particle_on_screen_three(void) { load_kart_texture_non_blocking(gPlayersToRenderPlayer[0], gPlayersToRenderPlayerId[0] + 4, gPlayersToRenderScreenId[0], gPlayersToRenderScreenId[0] - 2, D_801651D0[gPlayersToRenderScreenId[0]][gPlayersToRenderPlayerId[0]]); - render_kart_particle_on_screen_three(gPlayerOneCopy, PLAYER_ONE, PLAYER_THREE); - render_kart_particle_on_screen_three(gPlayerTwo, PLAYER_TWO, PLAYER_THREE); - render_kart_particle_on_screen_three(gPlayerThree, PLAYER_THREE, PLAYER_THREE); - render_kart_particle_on_screen_three(gPlayerFour, PLAYER_FOUR, PLAYER_THREE); osRecvMesg(&gDmaMesgQueue, &gMainReceivedMesg, OS_MESG_BLOCK); for (var_s0 = 1; var_s0 < gPlayersToRenderCount; var_s0++) { load_kart_texture_non_blocking(gPlayersToRenderPlayer[var_s0], gPlayersToRenderPlayerId[var_s0] + 4, @@ -472,10 +449,6 @@ void load_kart_texture_and_render_kart_particle_on_screen_four(void) { load_kart_texture_non_blocking(gPlayersToRenderPlayer[0], gPlayersToRenderPlayerId[0] + 4, gPlayersToRenderScreenId[0], gPlayersToRenderScreenId[0] - 2, D_801651D0[gPlayersToRenderScreenId[0]][gPlayersToRenderPlayerId[0]]); - render_kart_particle_on_screen_four(gPlayerOneCopy, PLAYER_ONE, PLAYER_FOUR); - render_kart_particle_on_screen_four(gPlayerTwo, PLAYER_TWO, PLAYER_FOUR); - render_kart_particle_on_screen_four(gPlayerThree, PLAYER_THREE, PLAYER_FOUR); - render_kart_particle_on_screen_four(gPlayerFour, PLAYER_FOUR, PLAYER_FOUR); osRecvMesg(&gDmaMesgQueue, &gMainReceivedMesg, OS_MESG_BLOCK); for (var_s0 = 1; var_s0 < gPlayersToRenderCount; var_s0++) { load_kart_texture_non_blocking(gPlayersToRenderPlayer[var_s0], gPlayersToRenderPlayerId[var_s0] + 4, @@ -559,6 +532,12 @@ void render_players_on_screen_one(void) { init_render_player(gPlayerSeven, camera1, PLAYER_SEVEN, PLAYER_ONE); init_render_player(gPlayerEight, camera1, PLAYER_EIGHT, PLAYER_ONE); } + + // This call moved here to sync kart texture and wheel texture tlut loading/rendering + if (gPlayersToRenderCount != 0) { + load_kart_texture_and_render_kart_particle_on_screen_one(); + } + try_rendering_player(gPlayerOne, PLAYER_ONE, PLAYER_ONE); try_rendering_player(gPlayerTwo, PLAYER_TWO, PLAYER_ONE); try_rendering_player(gPlayerThree, PLAYER_THREE, PLAYER_ONE); @@ -569,8 +548,20 @@ void render_players_on_screen_one(void) { try_rendering_player(gPlayerSeven, PLAYER_SEVEN, PLAYER_ONE); try_rendering_player(gPlayerEight, PLAYER_EIGHT, PLAYER_ONE); } + if (gPlayersToRenderCount != 0) { - load_kart_texture_and_render_kart_particle_on_screen_one(); + // Old call which is out of sync + // load_kart_texture_and_render_kart_particle_on_screen_one(); + render_kart_particle_on_screen_one(gPlayerOneCopy, PLAYER_ONE, PLAYER_ONE); + render_kart_particle_on_screen_one(gPlayerTwo, PLAYER_TWO, PLAYER_ONE); + render_kart_particle_on_screen_one(gPlayerThree, PLAYER_THREE, PLAYER_ONE); + render_kart_particle_on_screen_one(gPlayerFour, PLAYER_FOUR, PLAYER_ONE); + if (gActiveScreenMode != SCREEN_MODE_3P_4P_SPLITSCREEN) { + render_kart_particle_on_screen_one(gPlayerFive, PLAYER_FIVE, PLAYER_ONE); + render_kart_particle_on_screen_one(gPlayerSix, PLAYER_SIX, PLAYER_ONE); + render_kart_particle_on_screen_one(gPlayerSeven, PLAYER_SEVEN, PLAYER_ONE); + render_kart_particle_on_screen_one(gPlayerEight, PLAYER_EIGHT, PLAYER_ONE); + } } else { render_kart_particle_on_screen_one(gPlayerOneCopy, PLAYER_ONE, PLAYER_ONE); render_kart_particle_on_screen_one(gPlayerTwo, PLAYER_TWO, PLAYER_ONE); @@ -746,6 +737,10 @@ void render_players_on_screen_two(void) { init_render_player(gPlayerSeven, camera2, PLAYER_SEVEN, PLAYER_TWO); init_render_player(gPlayerEight, camera2, PLAYER_EIGHT, PLAYER_TWO); } + + // Call moved to sync kart and wheel tlut loading/rendering + load_kart_texture_and_render_kart_particle_on_screen_two(); + try_rendering_player(gPlayerOne, PLAYER_ONE, PLAYER_TWO); try_rendering_player(gPlayerTwo, PLAYER_TWO, PLAYER_TWO); try_rendering_player(gPlayerThree, PLAYER_THREE, PLAYER_TWO); @@ -757,7 +752,17 @@ void render_players_on_screen_two(void) { try_rendering_player(gPlayerEight, PLAYER_EIGHT, PLAYER_TWO); } if (gPlayersToRenderCount != 0) { - load_kart_texture_and_render_kart_particle_on_screen_two(); + // load_kart_texture_and_render_kart_particle_on_screen_two(); + render_kart_particle_on_screen_two(gPlayerOneCopy, PLAYER_ONE, PLAYER_TWO); + render_kart_particle_on_screen_two(gPlayerTwo, PLAYER_TWO, PLAYER_TWO); + render_kart_particle_on_screen_two(gPlayerThree, PLAYER_THREE, PLAYER_TWO); + render_kart_particle_on_screen_two(gPlayerFour, PLAYER_FOUR, PLAYER_TWO); + if (gActiveScreenMode != SCREEN_MODE_3P_4P_SPLITSCREEN) { + render_kart_particle_on_screen_two(gPlayerFive, PLAYER_FIVE, PLAYER_TWO); + render_kart_particle_on_screen_two(gPlayerSix, PLAYER_SIX, PLAYER_TWO); + render_kart_particle_on_screen_two(gPlayerSeven, PLAYER_SEVEN, PLAYER_TWO); + render_kart_particle_on_screen_two(gPlayerEight, PLAYER_EIGHT, PLAYER_TWO); + } } else { render_kart_particle_on_screen_two(gPlayerOneCopy, PLAYER_ONE, PLAYER_TWO); render_kart_particle_on_screen_two(gPlayerTwo, PLAYER_TWO, PLAYER_TWO); @@ -779,12 +784,19 @@ void render_players_on_screen_three(void) { init_render_player(gPlayerTwo, camera3, PLAYER_TWO, PLAYER_THREE); init_render_player(gPlayerThree, camera3, PLAYER_THREE, PLAYER_THREE); init_render_player(gPlayerFour, camera3, PLAYER_FOUR, PLAYER_THREE); + + load_kart_texture_and_render_kart_particle_on_screen_three(); + try_rendering_player(gPlayerOne, PLAYER_ONE, PLAYER_THREE); try_rendering_player(gPlayerTwo, PLAYER_TWO, PLAYER_THREE); try_rendering_player(gPlayerThree, PLAYER_THREE, PLAYER_THREE); try_rendering_player(gPlayerFour, PLAYER_FOUR, PLAYER_THREE); if (gPlayersToRenderCount != 0) { - load_kart_texture_and_render_kart_particle_on_screen_three(); + // load_kart_texture_and_render_kart_particle_on_screen_three(); + render_kart_particle_on_screen_three(gPlayerOneCopy, PLAYER_ONE, PLAYER_THREE); + render_kart_particle_on_screen_three(gPlayerTwo, PLAYER_TWO, PLAYER_THREE); + render_kart_particle_on_screen_three(gPlayerThree, PLAYER_THREE, PLAYER_THREE); + render_kart_particle_on_screen_three(gPlayerFour, PLAYER_FOUR, PLAYER_THREE); } else { render_kart_particle_on_screen_three(gPlayerOneCopy, PLAYER_ONE, PLAYER_THREE); render_kart_particle_on_screen_three(gPlayerTwo, PLAYER_TWO, PLAYER_THREE); @@ -800,12 +812,19 @@ void render_players_on_screen_four(void) { init_render_player(gPlayerTwo, camera4, PLAYER_TWO, PLAYER_FOUR); init_render_player(gPlayerThree, camera4, PLAYER_THREE, PLAYER_FOUR); init_render_player(gPlayerFour, camera4, PLAYER_FOUR, PLAYER_FOUR); + + load_kart_texture_and_render_kart_particle_on_screen_four(); + try_rendering_player(gPlayerOne, PLAYER_ONE, PLAYER_FOUR); try_rendering_player(gPlayerTwo, PLAYER_TWO, PLAYER_FOUR); try_rendering_player(gPlayerThree, PLAYER_THREE, PLAYER_FOUR); try_rendering_player(gPlayerFour, PLAYER_FOUR, PLAYER_FOUR); if (gPlayersToRenderCount != 0) { - load_kart_texture_and_render_kart_particle_on_screen_four(); + // load_kart_texture_and_render_kart_particle_on_screen_four(); + render_kart_particle_on_screen_four(gPlayerOneCopy, PLAYER_ONE, PLAYER_FOUR); + render_kart_particle_on_screen_four(gPlayerTwo, PLAYER_TWO, PLAYER_FOUR); + render_kart_particle_on_screen_four(gPlayerThree, PLAYER_THREE, PLAYER_FOUR); + render_kart_particle_on_screen_four(gPlayerFour, PLAYER_FOUR, PLAYER_FOUR); } else { render_kart_particle_on_screen_four(gPlayerOneCopy, PLAYER_ONE, PLAYER_FOUR); render_kart_particle_on_screen_four(gPlayerTwo, PLAYER_TWO, PLAYER_FOUR); @@ -1447,7 +1466,7 @@ void func_80023BF0(Player* player, s8 playerId, s8 screenId, s8 arg3) { } void render_player_shadow(Player* player, s8 playerId, s8 screenId) { - Mat4 sp118; + Mat4 mtx; UNUSED Mat4 pad; Vec3f spCC; Vec3s spC4; @@ -1485,7 +1504,7 @@ void render_player_shadow(Player* player, s8 playerId, s8 screenId) { spCC[0] = player->pos[0] + ((spB0 * sins(spC0)) + (spAC * coss(spC0))); spCC[1] = player->unk_074 + 1.0f; spCC[2] = player->pos[2] + ((spB0 * coss(spC0)) - (spAC * sins(spC0))); - set_transform_matrix(sp118, spB4, spCC, (spC0 + player->unk_042), + set_transform_matrix(mtx, spB4, spCC, (spC0 + player->unk_042), gCharacterSize[player->characterId] * player->size * var_f2); } else { spC4[0] = player->slopeAccel; @@ -1495,13 +1514,14 @@ void render_player_shadow(Player* player, s8 playerId, s8 screenId) { spCC[0] = player->pos[0] + ((spB0 * sins(spC0)) + (spAC * coss(spC0))); spCC[1] = player->unk_074 + 1.0f; spCC[2] = player->pos[2] + ((spB0 * coss(spC0)) - (spAC * sins(spC0))); - mtxf_translate_rotate(sp118, spCC, spC4); - mtxf_scale2(sp118, gCharacterSize[player->characterId] * player->size); + mtxf_translate_rotate(mtx, spCC, spC4); + mtxf_scale2(mtx, gCharacterSize[player->characterId] * player->size); } - convert_to_fixed_point_matrix(&gGfxPool->mtxShadow[playerId + (screenId * 8)], sp118); + // convert_to_fixed_point_matrix(&gGfxPool->mtxShadow[playerId + (screenId * 8)], mtx); - gSPMatrix(gDisplayListHead++, VIRTUAL_TO_PHYSICAL(&gGfxPool->mtxShadow[playerId + (screenId * 8)]), - G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + // gSPMatrix(gDisplayListHead++, VIRTUAL_TO_PHYSICAL(&gGfxPool->mtxShadow[playerId + (screenId * 8)]), + // G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + AddShadowMatrix(mtx, G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); gSPDisplayList(gDisplayListHead++, D_0D008D58); gDPSetTextureLUT(gDisplayListHead++, G_TT_NONE); @@ -1524,7 +1544,7 @@ void render_player_shadow(Player* player, s8 playerId, s8 screenId) { } void render_player_shadow_credits(Player* player, s8 playerId, s8 arg2) { - Mat4 sp118; + Mat4 mtx; UNUSED Mat4 pad; Vec3f spCC; Vec3s spC4; @@ -1550,12 +1570,14 @@ void render_player_shadow_credits(Player* player, s8 playerId, s8 arg2) { spCC[2] = player->pos[2] + ((spB0 * coss(spC0)) - (spAC * sins(spC0))); spCC[1] = gObjectList[indexObjectList1[playerId]].pos[1] + sp94[playerId]; - mtxf_translate_rotate(sp118, spCC, spC4); - mtxf_scale2(sp118, gCharacterSize[player->characterId] * player->size); - convert_to_fixed_point_matrix(&gGfxPool->mtxShadow[playerId + (arg2 * 8)], sp118); + mtxf_translate_rotate(mtx, spCC, spC4); + mtxf_scale2(mtx, gCharacterSize[player->characterId] * player->size); + // convert_to_fixed_point_matrix(&gGfxPool->mtxShadow[playerId + (arg2 * 8)], mtx); - gSPMatrix(gDisplayListHead++, VIRTUAL_TO_PHYSICAL(&gGfxPool->mtxShadow[playerId + (arg2 * 8)]), - G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + // gSPMatrix(gDisplayListHead++, VIRTUAL_TO_PHYSICAL(&gGfxPool->mtxShadow[playerId + (arg2 * 8)]), + // G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + + AddShadowMatrix(mtx, G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); gSPDisplayList(gDisplayListHead++, D_0D008D58); gDPSetTextureLUT(gDisplayListHead++, G_TT_NONE); @@ -1577,9 +1599,9 @@ void render_player_shadow_credits(Player* player, s8 playerId, s8 arg2) { gSPTexture(gDisplayListHead++, 1, 1, 0, G_TX_RENDERTILE, G_OFF); } -void render_kart(Player* player, s8 playerId, s8 arg2, s8 arg3) { +void render_kart(Player* player, s8 playerId, s8 screenId, s8 arg3) { UNUSED s32 pad; - Mat4 sp1A4; + Mat4 mtx; UNUSED s32 pad2[17]; Vec3f sp154; Vec3s sp14C; @@ -1591,60 +1613,59 @@ void render_kart(Player* player, s8 playerId, s8 arg2, s8 arg3) { if (player->unk_044 & 0x2000) { sp14C[0] = 0; - sp14C[1] = player->unk_048[arg2]; + sp14C[1] = player->unk_048[screenId]; sp14C[2] = 0; - func_80062B18(&sp148, &sp144, &sp140, 0.0f, 1.5f, 0.0f, -player->unk_048[arg2], player->unk_050[arg2]); + func_80062B18(&sp148, &sp144, &sp140, 0.0f, 1.5f, 0.0f, -player->unk_048[screenId], player->unk_050[screenId]); sp154[1] = (player->pos[1] - player->boundingBoxSize) + (sp144 - 2.0); sp154[0] = player->pos[0] + sp148; sp154[2] = player->pos[2] + sp140; } else { - thing = (u16) (player->unk_048[arg2] + player->rotation[1] + player->unk_0C0); - temp_v1 = player->unk_0CC[arg2] * sins(thing); + thing = (u16) (player->unk_048[screenId] + player->rotation[1] + player->unk_0C0); + temp_v1 = player->unk_0CC[screenId] * sins(thing); if ((player->effects & 8) == 8) { - sp14C[0] = cameras[arg2].rot[0] - 0x4000; + sp14C[0] = cameras[screenId].rot[0] - 0x4000; } else { sp14C[0] = -temp_v1 * 0.8; } - sp14C[1] = player->unk_048[arg2]; - sp14C[2] = player->unk_050[arg2]; + sp14C[1] = player->unk_048[screenId]; + sp14C[2] = player->unk_050[screenId]; if (((s32) player->effects & HIT_EFFECT) == HIT_EFFECT) { - func_80062B18(&sp148, &sp144, &sp140, 0.0f, 8.0f, 0.0f, -player->unk_048[arg2], player->unk_050[arg2]); + func_80062B18(&sp148, &sp144, &sp140, 0.0f, 8.0f, 0.0f, -player->unk_048[screenId], player->unk_050[screenId]); sp154[1] = (player->pos[1] - player->boundingBoxSize) + player->unk_108; sp154[0] = player->pos[0] + sp148; sp154[2] = player->pos[2] + sp140; } else { - func_80062B18(&sp148, &sp144, &sp140, 0.0f, 1.5f, 0.0f, -player->unk_048[arg2], player->unk_050[arg2]); + func_80062B18(&sp148, &sp144, &sp140, 0.0f, 1.5f, 0.0f, -player->unk_048[screenId], player->unk_050[screenId]); sp154[1] = (player->pos[1] - player->boundingBoxSize) + player->unk_108 + (sp144 - 2.0); sp154[0] = player->pos[0] + sp148; sp154[2] = player->pos[2] + sp140; } } #ifdef AVOID_UB - gPlayerPalette = &gPlayerPalettesList[D_801651D0[arg2][playerId]][arg2][playerId]; + gPlayerPalette = &gPlayerPalettesList[D_801651D0[screenId][playerId]][screenId][playerId]; #else - gPlayerPalette = (struct_D_802F1F80*) &gPlayerPalettesList[D_801651D0[arg2][playerId]][arg2][playerId * 0x100]; + gPlayerPalette = (struct_D_802F1F80*) &gPlayerPalettesList[D_801651D0[screenId][playerId]][screenId][playerId * 0x100]; #endif - if ((arg2 == 0) || (arg2 == 1)) { - sKartUpperTexture = &D_802BFB80.arraySize8[D_801651D0[arg2][playerId]][arg2][playerId].pixel_index_array[0]; + if ((screenId == 0) || (screenId == 1)) { + sKartUpperTexture = &D_802BFB80.arraySize8[D_801651D0[screenId][playerId]][screenId][playerId].pixel_index_array[0]; #ifdef TARGET_N64 - sKartLowerTexture = &D_802BFB80.arraySize8[D_801651D0[arg2][playerId]][arg2][playerId].pixel_index_array[0x7C0]; + sKartLowerTexture = &D_802BFB80.arraySize8[D_801651D0[screenId][playerId]][screenId][playerId].pixel_index_array[0x7C0]; #endif } else { sKartUpperTexture = - &D_802BFB80.arraySize8[D_801651D0[arg2][playerId]][arg2 - 1][playerId - 4].pixel_index_array[0]; + &D_802BFB80.arraySize8[D_801651D0[screenId][playerId]][screenId - 1][playerId - 4].pixel_index_array[0]; #ifdef TARGET_N64 sKartLowerTexture = - &D_802BFB80.arraySize8[D_801651D0[arg2][playerId]][arg2 - 1][playerId - 4].pixel_index_array[0x7C0]; + &D_802BFB80.arraySize8[D_801651D0[screenId][playerId]][screenId - 1][playerId - 4].pixel_index_array[0x7C0]; #endif } - mtxf_translate_rotate(sp1A4, sp154, sp14C); - mtxf_scale2(sp1A4, gCharacterSize[player->characterId] * player->size); - convert_to_fixed_point_matrix(&gGfxPool->mtxKart[playerId + (arg2 * 8)], sp1A4); + mtxf_translate_rotate(mtx, sp154, sp14C); + mtxf_scale2(mtx, gCharacterSize[player->characterId] * player->size); + //convert_to_fixed_point_matrix(&gGfxPool->mtxKart[playerId + (screenId * 8)], mtx); if ((player->effects & BOO_EFFECT) == BOO_EFFECT) { - if (arg2 == playerId) { - gSPMatrix(gDisplayListHead++, VIRTUAL_TO_PHYSICAL(&gGfxPool->mtxKart[playerId + (arg2 * 8)]), - G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + if (screenId == playerId) { + AddKartMatrix(mtx, G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); gSPDisplayList(gDisplayListHead++, common_setting_render_character); gDPLoadTLUT_pal256(gDisplayListHead++, gPlayerPalette); gDPSetTextureLUT(gDisplayListHead++, G_TT_RGBA16); @@ -1652,13 +1673,14 @@ void render_kart(Player* player, s8 playerId, s8 arg2, s8 arg3) { gPlayerCyanEffect[playerId], gPlayerMagentaEffect[playerId], gPlayerYellowEffect[playerId], (s32) player->unk_0C6); gDPSetRenderMode(gDisplayListHead++, - AA_EN | Z_CMP | Z_UPD | IM_RD | CVG_DST_WRAP | ZMODE_XLU | CVG_X_ALPHA | FORCE_BL | - GBL_c1(G_BL_CLR_IN, G_BL_A_IN, G_BL_CLR_MEM, G_BL_1MA), - 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)); + AA_EN | Z_CMP | Z_UPD | IM_RD | CVG_DST_WRAP | ZMODE_XLU | CVG_X_ALPHA | FORCE_BL | + GBL_c1(G_BL_CLR_IN, G_BL_A_IN, G_BL_CLR_MEM, G_BL_1MA), + 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)); } else { - gSPMatrix(gDisplayListHead++, VIRTUAL_TO_PHYSICAL(&gGfxPool->mtxKart[playerId + (arg2 * 8)]), - G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + // gSPMatrix(gDisplayListHead++, VIRTUAL_TO_PHYSICAL(&gGfxPool->mtxKart[playerId + (screenId * 8)]), + // G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + AddKartMatrix(mtx, G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); gSPDisplayList(gDisplayListHead++, common_setting_render_character); gDPLoadTLUT_pal256(gDisplayListHead++, gPlayerPalette); gDPSetTextureLUT(gDisplayListHead++, G_TT_RGBA16); @@ -1666,15 +1688,16 @@ void render_kart(Player* player, s8 playerId, s8 arg2, s8 arg3) { gPlayerCyanEffect[playerId], gPlayerMagentaEffect[playerId], gPlayerYellowEffect[playerId], D_8018D970[playerId]); gDPSetRenderMode(gDisplayListHead++, - AA_EN | Z_CMP | Z_UPD | IM_RD | CVG_DST_WRAP | ZMODE_XLU | CVG_X_ALPHA | FORCE_BL | - GBL_c1(G_BL_CLR_IN, G_BL_A_IN, G_BL_CLR_MEM, G_BL_1MA), - 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)); + AA_EN | Z_CMP | Z_UPD | IM_RD | CVG_DST_WRAP | ZMODE_XLU | CVG_X_ALPHA | FORCE_BL | + GBL_c1(G_BL_CLR_IN, G_BL_A_IN, G_BL_CLR_MEM, G_BL_1MA), + 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)); } } else if (((player->unk_0CA & 4) == 4) || (player->soundEffects & 0x08000000) || (player->soundEffects & 0x04000000)) { - gSPMatrix(gDisplayListHead++, VIRTUAL_TO_PHYSICAL(&gGfxPool->mtxKart[playerId + (arg2 * 8)]), - G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + // gSPMatrix(gDisplayListHead++, VIRTUAL_TO_PHYSICAL(&gGfxPool->mtxKart[playerId + (screenId * 8)]), + // G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + AddKartMatrix(mtx, G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); gSPDisplayList(gDisplayListHead++, common_setting_render_character); gDPLoadTLUT_pal256(gDisplayListHead++, gPlayerPalette); gDPSetTextureLUT(gDisplayListHead++, G_TT_RGBA16); @@ -1684,8 +1707,9 @@ void render_kart(Player* player, s8 playerId, s8 arg2, s8 arg3) { gDPSetAlphaCompare(gDisplayListHead++, G_AC_DITHER); gDPSetRenderMode(gDisplayListHead++, G_RM_ZB_XLU_SURF, G_RM_ZB_XLU_SURF2); } else { - gSPMatrix(gDisplayListHead++, VIRTUAL_TO_PHYSICAL(&gGfxPool->mtxKart[playerId + (arg2 * 8)]), - G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + // gSPMatrix(gDisplayListHead++, VIRTUAL_TO_PHYSICAL(&gGfxPool->mtxKart[playerId + (screenId * 8)]), + // G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + AddKartMatrix(mtx, G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); gSPDisplayList(gDisplayListHead++, common_setting_render_character); gDPLoadTLUT_pal256(gDisplayListHead++, gPlayerPalette); gDPSetTextureLUT(gDisplayListHead++, G_TT_RGBA16); @@ -1704,7 +1728,7 @@ void render_kart(Player* player, s8 playerId, s8 arg2, s8 arg3) { // Render karts u8* test = (u8*) LOAD_ASSET(sKartUpperTexture); - gDPLoadTextureBlock(gDisplayListHead++, test + 0x800, G_IM_FMT_CI, G_IM_SIZ_8b, 64, 32, 0, + gDPLoadTextureBlock(gDisplayListHead++, test + 0x7C0, 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++, &D_800DDBB4[playerId][arg3 + 4], 4, 0); @@ -1715,7 +1739,7 @@ void render_kart(Player* player, s8 playerId, s8 arg2, s8 arg3) { void render_ghost(Player* player, s8 playerId, s8 screenId, s8 arg3) { UNUSED s32 pad; - Mat4 sp12C; + Mat4 mtx; UNUSED s32 pad2[17]; Vec3f spDC; Vec3s spD4; @@ -1758,23 +1782,24 @@ void render_ghost(Player* player, s8 playerId, s8 screenId, s8 arg3) { // 4].pixel_index_array[0x7C0]; } - mtxf_translate_rotate(sp12C, spDC, spD4); - mtxf_scale2(sp12C, gCharacterSize[player->characterId] * player->size); - convert_to_fixed_point_matrix(&gGfxPool->mtxKart[playerId + (screenId * 8)], sp12C); + mtxf_translate_rotate(mtx, spDC, spD4); + mtxf_scale2(mtx, gCharacterSize[player->characterId] * player->size); + // convert_to_fixed_point_matrix(&gGfxPool->mtxKart[playerId + (screenId * 8)], mtx); + + // gSPMatrix(gDisplayListHead++, VIRTUAL_TO_PHYSICAL(&gGfxPool->mtxKart[playerId + (screenId * 8)]), + // G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + AddKartMatrix(mtx, G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); - gSPMatrix(gDisplayListHead++, VIRTUAL_TO_PHYSICAL(&gGfxPool->mtxKart[playerId + (screenId * 8)]), - G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); gSPDisplayList(gDisplayListHead++, common_setting_render_character); gDPLoadTLUT_pal256(gDisplayListHead++, gPlayerPalette); gDPSetTextureLUT(gDisplayListHead++, G_TT_RGBA16); func_8004B614(gPlayerRedEffect[playerId], gPlayerGreenEffect[playerId], gPlayerBlueEffect[playerId], gPlayerCyanEffect[playerId], gPlayerMagentaEffect[playerId], gPlayerYellowEffect[playerId], spC2); gDPSetRenderMode(gDisplayListHead++, - AA_EN | Z_CMP | Z_UPD | IM_RD | CVG_DST_WRAP | ZMODE_XLU | CVG_X_ALPHA | FORCE_BL | - GBL_c1(G_BL_CLR_IN, G_BL_A_IN, G_BL_CLR_MEM, G_BL_1MA), - 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)); - + AA_EN | Z_CMP | Z_UPD | IM_RD | CVG_DST_WRAP | ZMODE_XLU | CVG_X_ALPHA | FORCE_BL | + GBL_c1(G_BL_CLR_IN, G_BL_A_IN, G_BL_CLR_MEM, G_BL_1MA), + 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++, sKartUpperTexture, 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); @@ -1782,7 +1807,7 @@ void render_ghost(Player* player, s8 playerId, s8 screenId, s8 arg3) { gSPDisplayList(gDisplayListHead++, common_square_plain_render); u8* test = (u8*) LOAD_ASSET(sKartUpperTexture); - gDPLoadTextureBlock(gDisplayListHead++, test + 0x800, G_IM_FMT_CI, G_IM_SIZ_8b, 64, 32, 0, + gDPLoadTextureBlock(gDisplayListHead++, test + 0x7C0, 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++, &D_800DDBB4[playerId][arg3 + 4], 4, 0); @@ -1792,7 +1817,7 @@ void render_ghost(Player* player, s8 playerId, s8 screenId, s8 arg3) { } void func_80025DE8(Player* player, s8 playerId, s8 screenId, s8 arg3) { - Mat4 spA8; + Mat4 mtx; Vec3f sp9C; Vec3s sp94; @@ -1803,23 +1828,23 @@ void func_80025DE8(Player* player, s8 playerId, s8 screenId, s8 arg3) { sp94[1] = player->unk_048[screenId]; sp94[2] = player->unk_050[screenId]; - mtxf_translate_rotate(spA8, sp9C, sp94); - mtxf_scale2(spA8, gCharacterSize[player->characterId] * player->size); - convert_to_fixed_point_matrix(&gGfxPool->mtxEffect[gMatrixEffectCount], spA8); + mtxf_translate_rotate(mtx, sp9C, sp94); + mtxf_scale2(mtx, gCharacterSize[player->characterId] * player->size); + // convert_to_fixed_point_matrix(&gGfxPool->mtxEffect[gMatrixEffectCount], mtx); - gSPMatrix(gDisplayListHead++, VIRTUAL_TO_PHYSICAL(&gGfxPool->mtxEffect[gMatrixEffectCount]), - G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + // gSPMatrix(gDisplayListHead++, VIRTUAL_TO_PHYSICAL(&gGfxPool->mtxEffect[gMatrixEffectCount]), + // G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + AddEffectMatrix(mtx, G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); gSPDisplayList(gDisplayListHead++, D_0D008D10); gDPSetTextureLUT(gDisplayListHead++, G_TT_RGBA16); func_8004B614(gPlayerRedEffect[playerId], gPlayerGreenEffect[playerId], gPlayerBlueEffect[playerId], gPlayerCyanEffect[playerId], gPlayerMagentaEffect[playerId], gPlayerYellowEffect[playerId], 0x00000040); gDPSetRenderMode(gDisplayListHead++, - AA_EN | Z_CMP | Z_UPD | IM_RD | CVG_DST_WRAP | ZMODE_XLU | CVG_X_ALPHA | FORCE_BL | - GBL_c1(G_BL_CLR_IN, G_BL_A_IN, G_BL_CLR_MEM, G_BL_1MA), - 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)); - + AA_EN | Z_CMP | Z_UPD | IM_RD | CVG_DST_WRAP | ZMODE_XLU | CVG_X_ALPHA | FORCE_BL | + GBL_c1(G_BL_CLR_IN, G_BL_A_IN, G_BL_CLR_MEM, G_BL_1MA), + 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++, sKartUpperTexture, 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); @@ -1827,7 +1852,7 @@ void func_80025DE8(Player* player, s8 playerId, s8 screenId, s8 arg3) { gSPDisplayList(gDisplayListHead++, common_square_plain_render); u8* test = (u8*) LOAD_ASSET(sKartUpperTexture); - gDPLoadTextureBlock(gDisplayListHead++, test + 0x800, G_IM_FMT_CI, G_IM_SIZ_8b, 64, 32, 0, + gDPLoadTextureBlock(gDisplayListHead++, test + 0x7C0, 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++, &D_800DDBB4[playerId][arg3 + 4], 4, 0); @@ -1837,7 +1862,7 @@ void func_80025DE8(Player* player, s8 playerId, s8 screenId, s8 arg3) { } void render_player_ice_reflection(Player* player, s8 playerId, s8 screenId, s8 arg3) { - Mat4 spA8; + Mat4 mtx; Vec3f sp9C; Vec3s sp94; @@ -1853,12 +1878,13 @@ void render_player_ice_reflection(Player* player, s8 playerId, s8 screenId, s8 a arg3 = 0; } - mtxf_translate_rotate(spA8, sp9C, sp94); - mtxf_scale2(spA8, gCharacterSize[player->characterId] * player->size); - convert_to_fixed_point_matrix(&gGfxPool->mtxEffect[gMatrixEffectCount], spA8); + mtxf_translate_rotate(mtx, sp9C, sp94); + mtxf_scale2(mtx, gCharacterSize[player->characterId] * player->size); + // convert_to_fixed_point_matrix(&gGfxPool->mtxEffect[gMatrixEffectCount], mtx); - gSPMatrix(gDisplayListHead++, VIRTUAL_TO_PHYSICAL(&gGfxPool->mtxEffect[gMatrixEffectCount]), - G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + // gSPMatrix(gDisplayListHead++, VIRTUAL_TO_PHYSICAL(&gGfxPool->mtxEffect[gMatrixEffectCount]), + // G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + AddEffectMatrix(mtx, G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); gSPDisplayList(gDisplayListHead++, common_setting_render_character); gDPSetTextureLUT(gDisplayListHead++, G_TT_RGBA16); func_8004B614(gPlayerRedEffect[playerId], gPlayerGreenEffect[playerId], gPlayerBlueEffect[playerId], @@ -1872,7 +1898,7 @@ void render_player_ice_reflection(Player* player, s8 playerId, s8 screenId, s8 a gSPDisplayList(gDisplayListHead++, common_square_plain_render); u8* test = (u8*) LOAD_ASSET(sKartUpperTexture); - gDPLoadTextureBlock(gDisplayListHead++, test + 0x800, G_IM_FMT_CI, G_IM_SIZ_8b, 64, 32, 0, + gDPLoadTextureBlock(gDisplayListHead++, test + 0x7C0, 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++, &D_800DDBB4[playerId][arg3 + 4], 4, 0); @@ -1918,6 +1944,8 @@ void render_player(Player* player, s8 playerId, s8 screenId) { if (player->boostPower >= 2.0f) { func_80025DE8(player, playerId, screenId, var_v1); } + // Allows wheels to spin + gSPInvalidateTexCache(gDisplayListHead++, sKartLowerTexture); } void func_80026A48(Player* player, s8 arg1) { @@ -1944,9 +1972,9 @@ void func_80026A48(Player* player, s8 arg1) { // Properly define struct pointers, see buffers.h comment for more information. #ifdef AVOID_UB -#define D_802F1F80_WHEEL(a, b, c) &gPlayerPalettesList[a][b][c].wheel_palette +#define D_802F1F80_WHEEL(a, screenId, playerId) &gPlayerPalettesList[a][screenId][playerId].wheel_palette #else -#define D_802F1F80_WHEEL(a, b, c) &gPlayerPalettesList[a][b][(c * 0x100) + 0xC0] +#define D_802F1F80_WHEEL(a, screenId, playerId) &gPlayerPalettesList[a][screenId][(PlayerId * 0x100) + 0xC0] #endif void update_wheel_palette(Player* player, s8 playerId, s8 screenId, s8 arg3) { @@ -1966,21 +1994,21 @@ void update_wheel_palette(Player* player, s8 playerId, s8 screenId, s8 arg3) { if (frameId <= 20) { int32_t offset = (((frameId * temp_num * 4) + ((temp_t2 >> 8) * 0x40)) * 2) / 0x80; - load_player_data_non_blocking(player, wheelPtr[character][wheel0 + offset], + load_wheel_palette_non_blocking(player, wheelPtr[character][wheel0 + offset], D_802F1F80_WHEEL(arg3, screenId, playerId), 0x80); } else { int32_t offset = (((((frameId - 21) * (temp_num * 4) + ((temp_t2 >> 8) * 0x40)) + 0x600)) * 2) / 0x80; - load_player_data_non_blocking(player, wheelPtr[character][wheel1 + offset], + load_wheel_palette_non_blocking(player, wheelPtr[character][wheel1 + offset], D_802F1F80_WHEEL(arg3, screenId, playerId), 0x80); } } else { if (frameId == 0) { int32_t offset = (((frameId * temp_num * 4) + ((temp_t2 >> 8) * 0x40)) * 2) / 0x80; - load_player_data_non_blocking(player, wheelPtr[character][wheel0 + offset], + load_wheel_palette_non_blocking(player, wheelPtr[character][wheel0 + offset], D_802F1F80_WHEEL(arg3, screenId, playerId), 0x80); } else { int32_t offset = (((frameId * temp_num * 4) + ((temp_t2 >> 8) * 0x40)) * 2) / 0x80; - load_player_data_non_blocking(player, wheelPtr[character][wheel1 + offset], + load_wheel_palette_non_blocking(player, wheelPtr[character][wheel1 + offset], D_802F1F80_WHEEL(arg3, screenId, playerId), 0x80); } } @@ -1989,49 +2017,27 @@ void update_wheel_palette(Player* player, s8 playerId, s8 screenId, s8 arg3) { ((player->effects & 0x80000) != 0x80000) && ((player->effects & 0x800000) != 0x800000) && ((player->effects & 0x20000) != 0x20000) && ((player->unk_044 & 0x800) == 0)) { - // printf("---start---\n"); - if (frameId <= 20) { int32_t offset = (((frameId * temp_num * 4) + ((temp_t2 >> 8) * 0x40)) * 2) / 0x80; - // printf("OFFSET VAL 0x%X\n", ((frameId * temp_num * 4) + ((temp_t2 >> 8) * 0x40))); - // printf("OFFSET IDX %d\n", offset); - load_player_data_non_blocking(player, wheelPtr[character][wheel0 + offset], + load_wheel_palette_non_blocking(player, wheelPtr[character][wheel0 + offset], D_802F1F80_WHEEL(arg3, screenId, playerId), 0x80); } else { - // printf("wheel1\n"); - // printf("OFFSET: 0x%X, t0: 0x%X, temp_num: 0x%X t2: 0x%X, t2_8: 0x%X\n", (((frameId - 21) * (temp_num - // * 4) + ((temp_t2 >> 8) * 0x40) + 0x600)), frameId, temp_num, temp_t2, (temp_t2 >> 8)); printf("wheel - // offset: 0x%X, w0: 0x%X, t0: 0x%X\n", wheel1 + (((frameId - 21) * (temp_num * 4) + ((temp_t2 >> 8) * - // 0x40) + 0x600)), wheel1, frameId); printf("wheel: 0x%X, char: 0x%X, t1: 0x%X\n", wheel1, - // player->characterId, temp_t1); - int32_t offset = (((((frameId - 21) * (temp_num * 4) + ((temp_t2 >> 8) * 0x40)) + 0x600)) * 2) / 0x80; - load_player_data_non_blocking(player, wheelPtr[character][wheel1 + offset], + load_wheel_palette_non_blocking(player, wheelPtr[character][wheel1 + offset], D_802F1F80_WHEEL(arg3, screenId, playerId), 0x80); } } else { if (frameId == 0) { - // printf("wheel0\n"); - // printf("OFFSET: 0x%X, t0: 0x%X, temp_num: 0x%X t2: 0x%X, t2_8: 0x%X\n", (frameId * temp_num * 4) + - // ((temp_t2 >> 8) * 0x40), frameId, temp_num, temp_t2, (temp_t2 >> 8)); printf("wheel offset: 0x%X, w0: - // 0x%X, t0: 0x%X\n", wheel0 + ((frameId * temp_num * 4) + ((temp_t2 >> 8) * 0x40)), wheel0, frameId); - // printf("wheel: 0x%X, char: 0x%X, t1: 0x%X\n", wheel0, player->characterId, temp_t1); int32_t offset = (((frameId * temp_num * 4) + ((temp_t2 >> 8) * 0x40)) * 2) / 0x80; - load_player_data_non_blocking(player, wheelPtr[character][wheel0 + offset], + load_wheel_palette_non_blocking(player, wheelPtr[character][wheel0 + offset], D_802F1F80_WHEEL(arg3, screenId, playerId), 0x80); } else { - // printf("wheel1_2\n"); - // printf("OFFSET: 0x%X, t0: 0x%X, temp_num: 0x%X t2: 0x%X, t2_8: 0x%X\n", (frameId * temp_num * 4) + - // ((temp_t2 >> 8) * 0x40), frameId, temp_num, temp_t2, (temp_t2 >> 8)); printf("wheel offset: 0x%X, w0: - // 0x%X, t0: 0x%X\n", wheel1 + ((frameId * temp_num * 4) + ((temp_t2 >> 8) * 0x40)), wheel1, frameId); - // printf("wheel: 0x%X, char: 0x%X, t1: 0x%X\n", wheel1, player->characterId, temp_t1); int32_t offset = (((frameId * temp_num * 4) + ((temp_t2 >> 8) * 0x40)) * 2) / 0x80; - load_player_data_non_blocking(player, wheelPtr[character][wheel1 + offset], + load_wheel_palette_non_blocking(player, wheelPtr[character][wheel1 + offset], D_802F1F80_WHEEL(arg3, screenId, playerId), 0x80); } } - // printf("---end---\n"); } } diff --git a/src/staff_ghosts.c b/src/staff_ghosts.c index f85c87ae9..e04525e81 100644 --- a/src/staff_ghosts.c +++ b/src/staff_ghosts.c @@ -15,6 +15,7 @@ #include "code_80057C60.h" #include "kart_dma.h" #include "port/Game.h" +#include "courses/staff_ghost_data.h" u8* D_80162D80; s16 D_80162D84; @@ -68,7 +69,7 @@ void func_80004EF0(void) { u8* dest = (u8*) D_80162DA4; osInvalDCache(&D_80162DA4[0], 0x4000); - u8* ghost = (u8*) LOAD_ASSET(D_80162DC4); + u8* ghost = (u8*) D_80162DC4; // Manual memcpy required for byte swap for (int i = 0; i < 0x4000; i += 4) { diff --git a/src/staff_ghosts.h b/src/staff_ghosts.h index a58bb3291..9e7e316a6 100644 --- a/src/staff_ghosts.h +++ b/src/staff_ghosts.h @@ -21,10 +21,6 @@ void func_80005AE8(Player*); void func_80005E6C(void); void staff_ghosts_loop(void); -extern StaffGhost* d_mario_raceway_staff_ghost; -extern StaffGhost* d_royal_raceway_staff_ghost; -extern StaffGhost* d_luigi_raceway_staff_ghost; - // mi0decode extern s32 mio0encode(s32 input, s32, s32); diff --git a/src/update_objects.c b/src/update_objects.c index 61ceb6492..308149b36 100644 --- a/src/update_objects.c +++ b/src/update_objects.c @@ -2908,7 +2908,7 @@ void func_80078C70(s32 arg0) { // case COURSE_TOADS_TURNPIKE: /* switch 2 */ // update_stars(sp1C, camera, gToadsTurnpikeRainbowRoadStars); // break; - // case COURSE_KALAMARI_DESERT: /* switch 2 */ + // case COURSE_KALIMARI_DESERT: /* switch 2 */ // update_clouds(sp1C, camera, gKalimariDesertClouds); // break; // case COURSE_SHERBET_LAND: /* switch 2 */ @@ -7199,7 +7199,7 @@ 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, 0x40U, (u16) 0x00000040); + (u8*) d_course_koopa_troopa_beach_crab_frames, 64, (u16) 64); object = &gObjectList[objectIndex]; object->sizeScaling = 0.15f; object->textureListIndex = 0; diff --git a/torch b/torch index 298578677..ff8c2d13c 160000 --- a/torch +++ b/torch @@ -1 +1 @@ -Subproject commit 298578677e28ef1fe0d3a425f2856930c6cc4ef1 +Subproject commit ff8c2d13c71069f3117faf42ed25f0816229a872 diff --git a/yamls/us/credits_text.yml b/yamls/us/credits_text.yml new file mode 100644 index 000000000..4395d8224 --- /dev/null +++ b/yamls/us/credits_text.yml @@ -0,0 +1,14 @@ +:config: + vram: + addr: 0x802854B0 + offset: 0x3F0 + header: + code: + - '#include ' + header: + - '#include ' + - '#include ' +gCreditsText: + symbol: gCreditsText + type: text + offset: 0x802854B0