diff options
| author | MegaMech <MegaMech@users.noreply.github.com> | 2024-11-14 23:32:55 -0700 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2024-11-14 23:32:55 -0700 |
| commit | 475f167bb2803999c5116bc285601d1f9a05d7de (patch) | |
| tree | 859fec292c5c9807cc9690ebf4f0600f558b6063 /src/engine | |
| parent | 4fbb031dd95f2a84e73fbca269f517e98808d293 (diff) | |
[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>
Diffstat (limited to 'src/engine')
73 files changed, 2636 insertions, 1014 deletions
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 <libultraship.h> +#include <libultra/gbi.h> +#include "engine/World.h" + +extern "C" { +#include "common_structs.h" +} + +void AddMatrix(std::vector<Mtx>& 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<Mtx>& stack) { + stack.emplace_back(); + return &stack.back(); +} + +/** + * Use GetMatrix first + */ +void AddMatrixFixed(std::vector<Mtx>& 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 <libultraship.h> + +#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 <memory> @@ -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<OBombKart>(pos, waypoint, waypointIndex, state, unk_3C)); +} + u32 World::GetCupIndex() { return this->CupIndex; } @@ -164,28 +169,52 @@ Object* World::AddObject(std::unique_ptr<GameObject> object) { return &rawPtr->o; } -AActor* World::AddActor(std::unique_ptr<AActor> 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(); } -void World::TickActors() { - for (auto& actor : Actors) { - actor->Tick(); - } +struct Actor* World::AddBaseActor() { + Actors.push_back(new AActor()); + // Skip C++ vtable to access variables in C + return reinterpret_cast<struct Actor*>(reinterpret_cast<char*>(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<AActor*>((char*)actor - sizeof(void*)); } -void World::DrawActors(Camera* camera) { - for (auto& actor : Actors) { - actor->Draw(camera); +/** + * 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<Actor*>((char*)actor + sizeof(void*)); +} + +AActor* World::GetActor(size_t index) { + return Actors[index]; +} + +void World::TickActors() { + 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<AActor>& actor) { return actor->uuid == 0; }), // Example condition + // [](const std::unique_ptr<AActor>& 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 <memory> #include "Actor.h" @@ -64,15 +65,27 @@ class World { SkyboxColours Skybox; } Properties; + typedef struct { + std::vector<Mtx> Hud; + std::vector<Mtx> Objects; + std::vector<Mtx> Shadows; + std::vector<Mtx> Karts; + std::vector<Mtx> Effects; + } Matrix; + public: explicit World(); void AddCourse(Course* course); - AActor* AddActor(std::unique_ptr<AActor> 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<GameObject> 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<std::unique_ptr<GameObject>> GameObjects; - std::vector<std::unique_ptr<AActor>> Actors; + std::vector<AActor*> 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<std::unique_ptr<AVehicle>> 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<std::unique_ptr<OBombKart>> BombKarts; TrainCrossing* AddCrossing(Vec3f position, u32 waypointMin, u32 waypointMax, f32 approachRadius, f32 exitRadius); std::vector<std::shared_ptr<TrainCrossing>> 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 <libultraship.h> + +#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 <libultraship.h> +#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 <libultraship.h> +#include <libultra/gbi.h> + +#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 <libultraship.h> +#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 <libultra/gbi.h> + +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 <libultraship.h> +#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<OBombKart>(140, 3, 0.8333333, 0, 0, 0, 0)); - gWorldInstance.AddObject(std::make_unique<OBombKart>(165, 1, 0.8333333, 0, 0, 0, 0)); - gWorldInstance.AddObject(std::make_unique<OBombKart>(330, 3, 0.8333333, 0, 0, 0, 0)); - gWorldInstance.AddObject(std::make_unique<OBombKart>(550, 1, 0.8333333, 0, 0, 0, 0)); - gWorldInstance.AddObject(std::make_unique<OBombKart>(595, 3, 0.8333333, 0, 0, 0, 0)); - gWorldInstance.AddObject(std::make_unique<OBombKart>(0, 0, 0.8333333, 0, 0, 0, 0)); - gWorldInstance.AddObject(std::make_unique<OBombKart>(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<void*>(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 <libultraship.h> - - -#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<void*>(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<OBombKart>(140, 3, 0.8333333, 0, 0, 0, 0)); - gWorldInstance.AddObject(std::make_unique<OBombKart>(165, 1, 0.8333333, 0, 0, 0, 0)); - gWorldInstance.AddObject(std::make_unique<OBombKart>(330, 3, 0.8333333, 0, 0, 0, 0)); - gWorldInstance.AddObject(std::make_unique<OBombKart>(550, 1, 0.8333333, 0, 0, 0, 0)); - gWorldInstance.AddObject(std::make_unique<OBombKart>(595, 3, 0.8333333, 0, 0, 0, 0)); - gWorldInstance.AddObject(std::make_unique<OBombKart>(0, 0, 0.8333333, 0, 0, 0, 0)); - gWorldInstance.AddObject(std::make_unique<OBombKart>(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<void*>(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<void*>(0x07000000))); + // d_course_choco_mountain_packed_dl_98 + nullify_displaylist((uintptr_t) segmented_gfx_to_virtual(reinterpret_cast<void*>(0x07000098))); + // d_course_choco_mountain_packed_dl_178 + nullify_displaylist((uintptr_t) segmented_gfx_to_virtual(reinterpret_cast<void*>(0x07000178))); + // d_course_choco_mountain_packed_dl_280 + nullify_displaylist((uintptr_t) segmented_gfx_to_virtual(reinterpret_cast<void*>(0x07000280))); + // d_course_choco_mountain_packed_dl_340 + nullify_displaylist((uintptr_t) segmented_gfx_to_virtual(reinterpret_cast<void*>(0x07000340))); + // d_course_choco_mountain_packed_dl_3C8 + nullify_displaylist((uintptr_t) segmented_gfx_to_virtual(reinterpret_cast<void*>(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<OBombKart>(140, 3, 0.8333333, 0, 0, 0, 0)); - gWorldInstance.AddObject(std::make_unique<OBombKart>(165, 1, 0.8333333, 0, 0, 0, 0)); - gWorldInstance.AddObject(std::make_unique<OBombKart>(330, 3, 0.8333333, 0, 0, 0, 0)); - gWorldInstance.AddObject(std::make_unique<OBombKart>(550, 1, 0.8333333, 0, 0, 0, 0)); - gWorldInstance.AddObject(std::make_unique<OBombKart>(595, 3, 0.8333333, 0, 0, 0, 0)); - gWorldInstance.AddObject(std::make_unique<OBombKart>(0, 0, 0.8333333, 0, 0, 0, 0)); - gWorldInstance.AddObject(std::make_unique<OBombKart>(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<void*>(0x07000000))); - // d_course_choco_mountain_packed_dl_98 - nullify_displaylist((uintptr_t) segmented_gfx_to_virtual(reinterpret_cast<void*>(0x07000098))); - // d_course_choco_mountain_packed_dl_178 - nullify_displaylist((uintptr_t) segmented_gfx_to_virtual(reinterpret_cast<void*>(0x07000178))); - // d_course_choco_mountain_packed_dl_280 - nullify_displaylist((uintptr_t) segmented_gfx_to_virtual(reinterpret_cast<void*>(0x07000280))); - // d_course_choco_mountain_packed_dl_340 - nullify_displaylist((uintptr_t) segmented_gfx_to_virtual(reinterpret_cast<void*>(0x07000340))); - // d_course_choco_mountain_packed_dl_3C8 - nullify_displaylist((uintptr_t) segmented_gfx_to_virtual(reinterpret_cast<void*>(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<uintptr_t>(&vtx[0]); gSegmentTable[7] = reinterpret_cast<uintptr_t>(&gfx[0]); + + Course::Init(); } void Course::Load() { @@ -86,7 +90,6 @@ void Course::Load() { // Convert course vtx to vtx Vtx* vtx = reinterpret_cast<Vtx*>(allocate_memory(vtxSize)); gSegmentTable[4] = reinterpret_cast<uintptr_t>(&vtx[0]); - printf("\nVtxsize: 0x%X\n\n",vtxSize); func_802A86A8(reinterpret_cast<CourseVtx*>(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<uintptr_t>(&gfx[0]); displaylist_unpack(reinterpret_cast<uintptr_t *>(gfx), reinterpret_cast<uintptr_t>(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<OBombKart>(40, 3, 0.8333333, 0, 0, 0, 0)); - gWorldInstance.AddObject(std::make_unique<OBombKart>(100, 3, 0.8333333, 0, 0, 0, 0)); - gWorldInstance.AddObject(std::make_unique<OBombKart>(265, 3, 0.8333333, 0, 0, 0, 0)); - gWorldInstance.AddObject(std::make_unique<OBombKart>(285, 1, 0.8333333, 0, 0, 0, 0)); - gWorldInstance.AddObject(std::make_unique<OBombKart>(420, 1, 0.8333333, 0, 0, 0, 0)); - gWorldInstance.AddObject(std::make_unique<OBombKart>(0, 0, 0.8333333, 0, 0, 0, 0)); - gWorldInstance.AddObject(std::make_unique<OBombKart>(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<OBombKart>(140, 3, 0.8333333, 0, 0, 0, 0)); - gWorldInstance.AddObject(std::make_unique<OBombKart>(165, 1, 0.8333333, 0, 0, 0, 0)); - gWorldInstance.AddObject(std::make_unique<OBombKart>(330, 3, 0.8333333, 0, 0, 0, 0)); - gWorldInstance.AddObject(std::make_unique<OBombKart>(550, 1, 0.8333333, 0, 0, 0, 0)); - gWorldInstance.AddObject(std::make_unique<OBombKart>(595, 3, 0.8333333, 0, 0, 0, 0)); - gWorldInstance.AddObject(std::make_unique<OBombKart>(0, 0, 0.8333333, 0, 0, 0, 0)); - gWorldInstance.AddObject(std::make_unique<OBombKart>(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<OBombKart>(140, 3, 0.8333333, 0, 0, 0, 0)); - gWorldInstance.AddObject(std::make_unique<OBombKart>(165, 1, 0.8333333, 0, 0, 0, 0)); - gWorldInstance.AddObject(std::make_unique<OBombKart>(330, 3, 0.8333333, 0, 0, 0, 0)); - gWorldInstance.AddObject(std::make_unique<OBombKart>(550, 1, 0.8333333, 0, 0, 0, 0)); - gWorldInstance.AddObject(std::make_unique<OBombKart>(595, 3, 0.8333333, 0, 0, 0, 0)); - gWorldInstance.AddObject(std::make_unique<OBombKart>(0, 0, 0.8333333, 0, 0, 0, 0)); - gWorldInstance.AddObject(std::make_unique<OBombKart>(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<uint8_t (*)[1024]>(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<OBombKart>(140, 3, 0.8333333, 0, 0, 0, 0)); - gWorldInstance.AddObject(std::make_unique<OBombKart>(165, 1, 0.8333333, 0, 0, 0, 0)); - gWorldInstance.AddObject(std::make_unique<OBombKart>(330, 3, 0.8333333, 0, 0, 0, 0)); - gWorldInstance.AddObject(std::make_unique<OBombKart>(550, 1, 0.8333333, 0, 0, 0, 0)); - gWorldInstance.AddObject(std::make_unique<OBombKart>(595, 3, 0.8333333, 0, 0, 0, 0)); - gWorldInstance.AddObject(std::make_unique<OBombKart>(0, 0, 0.8333333, 0, 0, 0, 0)); - gWorldInstance.AddObject(std::make_unique<OBombKart>(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<void*>(0x0700ADE0)), -0x6A, 255, 255, 255); - find_vtx_and_set_colours(segmented_gfx_to_virtual(reinterpret_cast<void*>(0x0700A540)), -0x6A, 255, 255, 255); - find_vtx_and_set_colours(segmented_gfx_to_virtual(reinterpret_cast<void*>(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<uint8_t (*)[1024]>(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<OBombKart>(40, 3, 0.8333333, 0, 0, 0, 0)); - gWorldInstance.AddObject(std::make_unique<OBombKart>(100, 3, 0.8333333, 0, 0, 0, 0)); - gWorldInstance.AddObject(std::make_unique<OBombKart>(265, 3, 0.8333333, 0, 0, 0, 0)); - gWorldInstance.AddObject(std::make_unique<OBombKart>(285, 1, 0.8333333, 0, 0, 0, 0)); - gWorldInstance.AddObject(std::make_unique<OBombKart>(420, 1, 0.8333333, 0, 0, 0, 0)); - gWorldInstance.AddObject(std::make_unique<OBombKart>(0, 0, 0.8333333, 0, 0, 0, 0)); - gWorldInstance.AddObject(std::make_unique<OBombKart>(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<void*>(0x07001140))); + if (gScreenModeSelection == SCREEN_MODE_1P) { + // d_course_mario_raceway_packed_dl_8E8 + generate_collision_mesh_with_defaults(segmented_gfx_to_virtual(reinterpret_cast<void*>(0x070008E8))); + } else { + // d_course_mario_raceway_packed_dl_2D68 + generate_collision_mesh_with_defaults(segmented_gfx_to_virtual(reinterpret_cast<void*>(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<OBombKart>(40, 3, 0.8333333, 0, 0, 0, 0)); - gWorldInstance.AddObject(std::make_unique<OBombKart>(100, 3, 0.8333333, 0, 0, 0, 0)); - gWorldInstance.AddObject(std::make_unique<OBombKart>(265, 3, 0.8333333, 0, 0, 0, 0)); - gWorldInstance.AddObject(std::make_unique<OBombKart>(285, 1, 0.8333333, 0, 0, 0, 0)); - gWorldInstance.AddObject(std::make_unique<OBombKart>(420, 1, 0.8333333, 0, 0, 0, 0)); - gWorldInstance.AddObject(std::make_unique<OBombKart>(0, 0, 0.8333333, 0, 0, 0, 0)); - gWorldInstance.AddObject(std::make_unique<OBombKart>(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<void*>(0x07001140))); - if (gScreenModeSelection == SCREEN_MODE_1P) { - // d_course_mario_raceway_packed_dl_8E8 - generate_collision_mesh_with_defaults(segmented_gfx_to_virtual(reinterpret_cast<void*>(0x070008E8))); - } else { - // d_course_mario_raceway_packed_dl_2D68 - generate_collision_mesh_with_defaults(segmented_gfx_to_virtual(reinterpret_cast<void*>(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<uint8_t (*)[1024]>(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<OBombKart>(40, 3, 0.8333333, 0, 0, 0, 0)); - gWorldInstance.AddObject(std::make_unique<OBombKart>(100, 3, 0.8333333, 0, 0, 0, 0)); - gWorldInstance.AddObject(std::make_unique<OBombKart>(265, 3, 0.8333333, 0, 0, 0, 0)); - gWorldInstance.AddObject(std::make_unique<OBombKart>(285, 1, 0.8333333, 0, 0, 0, 0)); - gWorldInstance.AddObject(std::make_unique<OBombKart>(420, 1, 0.8333333, 0, 0, 0, 0)); - gWorldInstance.AddObject(std::make_unique<OBombKart>(0, 0, 0.8333333, 0, 0, 0, 0)); - gWorldInstance.AddObject(std::make_unique<OBombKart>(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<uint8_t (*)[1024]>(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<OBombKart>(40, 3, 0.8333333, 0, 0, 0, 0)); - gWorldInstance.AddObject(std::make_unique<OBombKart>(100, 3, 0.8333333, 0, 0, 0, 0)); - gWorldInstance.AddObject(std::make_unique<OBombKart>(265, 3, 0.8333333, 0, 0, 0, 0)); - gWorldInstance.AddObject(std::make_unique<OBombKart>(285, 1, 0.8333333, 0, 0, 0, 0)); - gWorldInstance.AddObject(std::make_unique<OBombKart>(420, 1, 0.8333333, 0, 0, 0, 0)); - gWorldInstance.AddObject(std::make_unique<OBombKart>(0, 0, 0.8333333, 0, 0, 0, 0)); - gWorldInstance.AddObject(std::make_unique<OBombKart>(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<OBombKart>(40, 3, 0.8333333, 0, 0, 0, 0)); - gWorldInstance.AddObject(std::make_unique<OBombKart>(100, 3, 0.8333333, 0, 0, 0, 0)); - gWorldInstance.AddObject(std::make_unique<OBombKart>(265, 3, 0.8333333, 0, 0, 0, 0)); - gWorldInstance.AddObject(std::make_unique<OBombKart>(285, 1, 0.8333333, 0, 0, 0, 0)); - gWorldInstance.AddObject(std::make_unique<OBombKart>(420, 1, 0.8333333, 0, 0, 0, 0)); - gWorldInstance.AddObject(std::make_unique<OBombKart>(0, 0, 0.8333333, 0, 0, 0, 0)); - gWorldInstance.AddObject(std::make_unique<OBombKart>(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; +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, 255, 255, 255); + 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, 255, 255, 255); + 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), 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]; + 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<uint8_t (*)[1024]>(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<OBombKart>(40, 3, 0.8333333, 0, 0, 0, 0)); - gWorldInstance.AddObject(std::make_unique<OBombKart>(100, 3, 0.8333333, 0, 0, 0, 0)); - gWorldInstance.AddObject(std::make_unique<OBombKart>(265, 3, 0.8333333, 0, 0, 0, 0)); - gWorldInstance.AddObject(std::make_unique<OBombKart>(285, 1, 0.8333333, 0, 0, 0, 0)); - gWorldInstance.AddObject(std::make_unique<OBombKart>(420, 1, 0.8333333, 0, 0, 0, 0)); - gWorldInstance.AddObject(std::make_unique<OBombKart>(0, 0, 0.8333333, 0, 0, 0, 0)); - gWorldInstance.AddObject(std::make_unique<OBombKart>(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<uint8_t (*)[1024]>(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<OBombKart>(40, 3, 0.8333333, 0, 0, 0, 0)); - gWorldInstance.AddObject(std::make_unique<OBombKart>(100, 3, 0.8333333, 0, 0, 0, 0)); - gWorldInstance.AddObject(std::make_unique<OBombKart>(265, 3, 0.8333333, 0, 0, 0, 0)); - gWorldInstance.AddObject(std::make_unique<OBombKart>(285, 1, 0.8333333, 0, 0, 0, 0)); - gWorldInstance.AddObject(std::make_unique<OBombKart>(420, 1, 0.8333333, 0, 0, 0, 0)); - gWorldInstance.AddObject(std::make_unique<OBombKart>(0, 0, 0.8333333, 0, 0, 0, 0)); - gWorldInstance.AddObject(std::make_unique<OBombKart>(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<uintptr_t>(&mario_Plane_001_mesh_vtx_1[0]); - //gSegmentTable[7] = reinterpret_cast<uintptr_t>(&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<OBombKart>(40, 3, 0.8333333, 0, 0, 0, 0)); - gWorldInstance.AddObject(std::make_unique<OBombKart>(100, 3, 0.8333333, 0, 0, 0, 0)); - gWorldInstance.AddObject(std::make_unique<OBombKart>(265, 3, 0.8333333, 0, 0, 0, 0)); - gWorldInstance.AddObject(std::make_unique<OBombKart>(285, 1, 0.8333333, 0, 0, 0, 0)); - gWorldInstance.AddObject(std::make_unique<OBombKart>(420, 1, 0.8333333, 0, 0, 0, 0)); - gWorldInstance.AddObject(std::make_unique<OBombKart>(0, 0, 0.8333333, 0, 0, 0, 0)); - gWorldInstance.AddObject(std::make_unique<OBombKart>(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<OBombKart>(40, 3, 0.8333333, 0, 0, 0, 0)); - gWorldInstance.AddObject(std::make_unique<OBombKart>(100, 3, 0.8333333, 0, 0, 0, 0)); - gWorldInstance.AddObject(std::make_unique<OBombKart>(265, 3, 0.8333333, 0, 0, 0, 0)); - gWorldInstance.AddObject(std::make_unique<OBombKart>(285, 1, 0.8333333, 0, 0, 0, 0)); - gWorldInstance.AddObject(std::make_unique<OBombKart>(420, 1, 0.8333333, 0, 0, 0, 0)); - gWorldInstance.AddObject(std::make_unique<OBombKart>(0, 0, 0.8333333, 0, 0, 0, 0)); - gWorldInstance.AddObject(std::make_unique<OBombKart>(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<AWarioSign>(pos)); + gWorldInstance.AddActor(new AWarioSign(pos)); Vec3f pos2 = {-2353.0f, 72.0f, -1608.0f}; pos2[0] *= gCourseDirection; - gWorldInstance.AddActor(std::make_unique<AWarioSign>(pos2)); + gWorldInstance.AddActor(new AWarioSign(pos2)); Vec3f pos3 = {-2622.0f, 79.0f, 739.0f}; pos3[0] *= gCourseDirection; - gWorldInstance.AddActor(std::make_unique<AWarioSign>(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<OBombKart>(40, 3, 0.8333333, 0, 0, 0, 0)); - gWorldInstance.AddObject(std::make_unique<OBombKart>(100, 3, 0.8333333, 0, 0, 0, 0)); - gWorldInstance.AddObject(std::make_unique<OBombKart>(265, 3, 0.8333333, 0, 0, 0, 0)); - gWorldInstance.AddObject(std::make_unique<OBombKart>(285, 1, 0.8333333, 0, 0, 0, 0)); - gWorldInstance.AddObject(std::make_unique<OBombKart>(420, 1, 0.8333333, 0, 0, 0, 0)); - gWorldInstance.AddObject(std::make_unique<OBombKart>(0, 0, 0.8333333, 0, 0, 0, 0)); - gWorldInstance.AddObject(std::make_unique<OBombKart>(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<OBombKart>(140, 3, 0.8333333, 0, 0, 0, 0)); - gWorldInstance.AddObject(std::make_unique<OBombKart>(165, 1, 0.8333333, 0, 0, 0, 0)); - gWorldInstance.AddObject(std::make_unique<OBombKart>(330, 3, 0.8333333, 0, 0, 0, 0)); - gWorldInstance.AddObject(std::make_unique<OBombKart>(550, 1, 0.8333333, 0, 0, 0, 0)); - gWorldInstance.AddObject(std::make_unique<OBombKart>(595, 3, 0.8333333, 0, 0, 0, 0)); - gWorldInstance.AddObject(std::make_unique<OBombKart>(0, 0, 0.8333333, 0, 0, 0, 0)); - gWorldInstance.AddObject(std::make_unique<OBombKart>(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 <libultraship.h> +#include "engine/vehicles/OBombKart.h" +#include <vector> + +#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<States>(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 <libultraship.h> +#include "Vehicle.h" +#include <vector> +#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 <iwasm/include/wasm_c_api.h> -#include <iwasm/include/wasm_export.h> -#include <iwasm/include/lib_export.h> -#include <iwasm/interpreter/wasm_runtime.h> -#include <stdint.h> -#include <stdio.h> -#include <stdlib.h> -#include <sys/stat.h> -#include <dirent.h> -} - -#include <fstream> -#include <iostream> -#include <vector> -#include <filesystem> -#include <functional> -#include <main.h> -#include <code_80091750.h> -#include <common_data.h> -#include <data_segment2.h> -#include <render_objects.h> - -struct mod_instance { - wasm_exec_env_t exec_env; - char* name; -}; - -std::vector<mod_instance> mods_instance = {}; - -std::vector<std::function<void()>> 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); }); -} - -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; -} - -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); - } - - /* 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 */ - - /* 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; -} - -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); -} - -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); -} - -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); -} - -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 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*)") -}; - -/* 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; - } - - file.seekg(0, std::ios::end); - - *size = file.tellg(); - - file.seekg(0); - - 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; - - /* initialize the wasm runtime by default configurations */ - wasm_runtime_init(); - - 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); - - /* 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); - } - - 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; - } - - /* 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); - - // 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 +// extern "C" { +// #include <iwasm/include/wasm_c_api.h> +// #include <iwasm/include/wasm_export.h> +// #include <iwasm/include/lib_export.h> +// #include <iwasm/interpreter/wasm_runtime.h> +// #include <stdint.h> +// #include <stdio.h> +// #include <stdlib.h> +// #include <sys/stat.h> +// #include <dirent.h> +// } + +// #include <fstream> +// #include <iostream> +// #include <vector> +// #include <filesystem> +// #include <functional> +// #include <main.h> +// #include <code_80091750.h> +// #include <common_data.h> +// #include <data_segment2.h> +// #include <render_objects.h> + +// struct mod_instance { +// wasm_exec_env_t exec_env; +// char* name; +// }; + +// std::vector<mod_instance> mods_instance = {}; + +// std::vector<std::function<void()>> 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); }); +// } + +// 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; +// } + +// 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); +// } + +// /* 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 */ + +// /* 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; +// } + +// 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); +// } + +// 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); +// } + +// 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); +// } + +// 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 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*)") +// }; + +// /* 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; +// } + +// file.seekg(0, std::ios::end); + +// *size = file.tellg(); + +// file.seekg(0); + +// 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; + +// /* initialize the wasm runtime by default configurations */ +// wasm_runtime_init(); + +// 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); + +// /* 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); +// } + +// 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; +// } + +// /* 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); + +// // 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 |
