diff options
| author | MegaMech <MegaMech@users.noreply.github.com> | 2025-01-18 08:58:12 -0700 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2025-01-18 08:58:12 -0700 |
| commit | 8c46368d5d93ad278c124ffc6446ab691dff8082 (patch) | |
| tree | 3506dce3de08c514eeb3ee9d1dc575e7713331ca /src/engine | |
| parent | 04d56d6ba0705776149358608a27db8ab23e9449 (diff) | |
Fix data, option menus, impl boos, fix demo camera (#156)
* Fix data and option menus
* safer code
* wip boos impl
* finish impl boos
* Fix demo camera
* slightly better match
Diffstat (limited to 'src/engine')
| -rw-r--r-- | src/engine/courses/BansheeBoardwalk.cpp | 7 | ||||
| -rw-r--r-- | src/engine/courses/TestCourse.cpp | 6 | ||||
| -rw-r--r-- | src/engine/objects/Boos.cpp | 272 | ||||
| -rw-r--r-- | src/engine/objects/Boos.h | 75 |
4 files changed, 357 insertions, 3 deletions
diff --git a/src/engine/courses/BansheeBoardwalk.cpp b/src/engine/courses/BansheeBoardwalk.cpp index 83bc1e151..03b4a9bd2 100644 --- a/src/engine/courses/BansheeBoardwalk.cpp +++ b/src/engine/courses/BansheeBoardwalk.cpp @@ -10,6 +10,7 @@ #include "engine/objects/CheepCheep.h" #include "engine/objects/TrashBin.h" #include "engine/objects/Bat.h" +#include "engine/objects/Boos.h" #include "assets/banshee_boardwalk_data.h" #include "assets/boo_frames.h" @@ -171,6 +172,8 @@ void BansheeBoardwalk::SpawnActors() { if ((gGamestate != CREDITS_SEQUENCE) && (gModeSelection != TIME_TRIALS)) { gWorldInstance.AddObject(new OBat(FVector(0,0,0), FRotation(0, 0, 90.0f))); + gWorldInstance.AddObject(new OBoos(5, IPathSpan(180, 190), IPathSpan(200, 210), IPathSpan(280, 290))); + gWorldInstance.AddObject(new OBoos(5, IPathSpan(490, 500), IPathSpan(510, 520), IPathSpan(620, 630))); } } @@ -210,14 +213,14 @@ void BansheeBoardwalk::UpdateCourseObjects() { if (gModeSelection != TIME_TRIALS) { //update_bat(); } - wrapper_update_boos(); + //wrapper_update_boos(); } } void BansheeBoardwalk::RenderCourseObjects(s32 cameraId) { if (gGamestate != CREDITS_SEQUENCE) { //render_object_bat(cameraId); - render_object_boos(cameraId); + //render_object_boos(cameraId); } } diff --git a/src/engine/courses/TestCourse.cpp b/src/engine/courses/TestCourse.cpp index 7e25d3357..cf35a062b 100644 --- a/src/engine/courses/TestCourse.cpp +++ b/src/engine/courses/TestCourse.cpp @@ -24,6 +24,7 @@ #include "engine/objects/Flagpole.h" #include "engine/objects/HotAirBalloon.h" #include "engine/objects/Crab.h" +#include "engine/objects/Boos.h" #include "engine/particles/StarEmitter.h" extern "C" { @@ -216,7 +217,10 @@ void TestCourse::SpawnActors() { // gWorldInstance.AddObject(new OHotAirBalloon(FVector(0.0, 20.0f, -200.0f))); //gWorldInstance.AddObject(new OCrab(FVector2D(0, 0), FVector2D(0, -200))); - gWorldInstance.AddActor(new ABowserStatue(FVector(-200, 0, 0), ABowserStatue::Behaviour::CRUSH)); +// gWorldInstance.AddActor(new ABowserStatue(FVector(-200, 0, 0), ABowserStatue::Behaviour::CRUSH)); + +// gWorldInstance.AddObject(new OBoos(10, IPathSpan(0, 5), IPathSpan(18, 23), IPathSpan(25, 50))); + } // Likely sets minimap boundaries diff --git a/src/engine/objects/Boos.cpp b/src/engine/objects/Boos.cpp new file mode 100644 index 000000000..0e64c673e --- /dev/null +++ b/src/engine/objects/Boos.cpp @@ -0,0 +1,272 @@ +#include "Boos.h" +#include "World.h" +#include "CoreMath.h" + +extern "C" { +#include "render_objects.h" +#include "update_objects.h" +#include "assets/banshee_boardwalk_data.h" +#include "assets/common_data.h" +#include "assets/boo_frames.h" +#include "assets/other_textures.h" +#include "math_util.h" +#include "math_util_2.h" +#include "code_80086E70.h" +#include "code_80057C60.h" +#include "code_800029B0.h" +#include "code_80005FD0.h" +#include "menus.h" +#include "race_logic.h" +#include "external.h" +} + +size_t OBoos::_count = 0; + +OBoos::OBoos(size_t numBoos, const IPathSpan& leftBoundary, const IPathSpan& active, const IPathSpan& rightBoundary) { + // Max five boos allowed due to limited splines + // D_800E5D9C + if (numBoos > 10) { + printf("Boos.cpp: Only 10 boos allowed.\n"); + numBoos = 10; + } + + _indices.resize(numBoos, 0); + + + // Generate objects + for (size_t i = 0; i < numBoos; i++) { + find_unused_obj_index(&_indices[i]); + } + + _numBoos = numBoos; + _leftBoundary = leftBoundary; + _active = active; + _rightBoundary = rightBoundary; +} + +void OBoos::Tick() { + u16 temp_t4; + s32 objectIndex; + Player* player; + Camera* camera; + Object* object; + + OBoos::func_8007CA70(); + for (size_t i = 0; i < _numBoos; i++) { + objectIndex = _indices[i]; //indexObjectList3[i]; + object = &gObjectList[objectIndex]; + if (object->state != 0) { + func_8007C684(objectIndex); + func_8008B78C(objectIndex); + player = &gPlayerOne[object->unk_0D1]; + camera = &camera1[object->unk_0D1]; + temp_t4 = (0x8000 - camera->rot[1]); + object->pos[0] = player->pos[0] + (coss(temp_t4) * (object->origin_pos[0] + object->offset[0])) - + (sins(temp_t4) * (object->origin_pos[2] + object->offset[2])); + object->pos[1] = 6.5 + player->unk_074 + object->origin_pos[1] + object->offset[1]; + object->pos[2] = player->pos[2] + (sins(temp_t4) * (object->origin_pos[0] + object->offset[0])) + + (coss(temp_t4) * (object->origin_pos[2] + object->offset[2])); + OBoos::func_8007C550(objectIndex); + if (is_obj_flag_status_active(objectIndex, 0x00000080) != 0) { + object->vertex = D_800E44B0; + } else { + object->vertex = D_800E4470; + } + } + } +} + +void OBoos::Draw(s32 cameraId) { + u32 temp_s2; + s32 objectIndex; + + for (size_t i = 0; i < _numBoos; i++) { + objectIndex = _indices[i]; //indexObjectList3[i]; + if (gObjectList[objectIndex].state >= 2) { + temp_s2 = func_8008A364(objectIndex, cameraId, 0x4000U, 0x00000320); + if (CVarGetInteger("gNoCulling", 0) == 1) { + temp_s2 = MIN(temp_s2, 0x15F91U); + } + if (is_obj_flag_status_active(objectIndex, VISIBLE) != 0) { + func_800523B8(objectIndex, cameraId, temp_s2); + } + } + } +} + +void OBoos::func_800523B8(s32 objectIndex, s32 arg1, u32 arg2) { + UNUSED s32 pad[2]; + Object* object; + Camera* camera = &camera1[arg1]; + + object = &gObjectList[objectIndex]; + object->orientation[1] = func_800418AC(object->pos[0], object->pos[2], camera->pos); + func_800484BC(object->pos, object->orientation, object->sizeScaling, object->primAlpha, (u8*) object->activeTLUT, + (u8*)object->activeTexture, object->vertex, 0x00000030, 0x00000028, 0x00000030, 0x00000028); + if ((is_obj_flag_status_active(objectIndex, 0x00000020) != 0) && (arg2 < 0x15F91U)) { + func_8004A630(&D_8018C830, object->pos, 0.4f); + } +} + +void OBoos::func_8007CA70(void) { + // wtf is up with this pointer? Its such a dumb way of going about things + u16* point; + + if (_isActive == false) { + _playerId = OBoos::func_8007C9F8(); + point = &gNearestWaypointByPlayerId[_playerId]; + printf("point %d\n", *point); + if ((*point > _active.Start) && (*point < _active.End)) { + // First group entrance + OBoos::BooStart(0, _playerId); + } + } + if (_isActive == true) { + point = &gNearestWaypointByPlayerId[_playerId]; + printf("point %d\n", *point); + + if ((*point > _leftBoundary.Start) && (*point < _leftBoundary.End)) { + // First group exit reverse direction + OBoos::BooExit(0); + } + if ((*point > _rightBoundary.Start) && (*point < _rightBoundary.End)) { + // First group exit + OBoos::BooExit(0); + } + } +} + +void OBoos::func_8007C5B4(s32 objectIndex) { + Object* object; + + init_texture_object(objectIndex, (u8*)d_course_banshee_boardwalk_boo_tlut, gTextureGhosts, 48, 40); + object = &gObjectList[objectIndex]; + object->pos[0] = 0.0f; + object->pos[1] = 0.0f; + object->pos[2] = 0.0f; + set_object_flag(objectIndex, 0x00000020); + object_next_state(objectIndex); + object->primAlpha = 0; + func_80073844(objectIndex); + object->sizeScaling = 0.15f; + object->unk_034 = 1.0f; + func_80073FD4(objectIndex); + func_80086EF0(objectIndex); + set_object_flag(objectIndex, 0x00000800); + object->orientation[0] = 0; + object->orientation[2] = 0x8000; +} + +void OBoos::func_8007C684(s32 objectIndex) { + switch (gObjectList[objectIndex].state) { + case 0: + break; + case 1: + OBoos::func_8007C5B4(objectIndex); + break; + } + if (gObjectList[objectIndex].state >= 2) { + switch (gObjectList[objectIndex].unk_0DC) { + case 0: + break; + case 1: + func_80073998(objectIndex, &gObjectList[objectIndex].primAlpha, 0, 0x00000050, 2, 1, 0); + break; + case 2: + func_80073CB0(objectIndex, &gObjectList[objectIndex].primAlpha, 0x00000050, 0x00000078, 1, 0, -1); + break; + case 3: + func_80073DC0(objectIndex, &gObjectList[objectIndex].primAlpha, 0, 2); + break; + case 4: + func_80072428(objectIndex); + func_80086F60(objectIndex); + func_80073884(objectIndex); + break; + } + func_80073514(objectIndex); + } +} + +void OBoos::func_8007C4A4(s32 objectIndex) { + u16 var_t9; + + var_t9 = gObjectList[objectIndex].direction_angle[1] * 0x24 / 0x10000; + + if (var_t9 < 0x13) { + clear_object_flag(objectIndex, 0x80); + gObjectList[objectIndex].textureListIndex = var_t9; + } else { + set_object_flag(objectIndex, 0x80); + gObjectList[objectIndex].textureListIndex = 0x24 - var_t9; + } +} + +void OBoos::func_8007C550(s32 objectIndex) { + gObjectList[objectIndex].direction_angle[1] = + func_800417B4(gObjectList[objectIndex].direction_angle[1], + atan2s(gObjectList[objectIndex].velocity[0], gObjectList[objectIndex].velocity[2])); + OBoos::func_8007C4A4(objectIndex); +} + +s32 OBoos::func_8007C9F8(void) { + s32 ret; + s32 first, second; + if (gPlayerCount == 1) { + ret = 0; + } else { + if (gPlayerCount == 2) { + if (gModeSelection == 0) { + first = gGPCurrentRaceRankByPlayerId[0]; + second = gGPCurrentRaceRankByPlayerId[1]; + if (first < second) { + ret = 0; + } else { + ret = 1; + } + } else { + ret = gGPCurrentRacePlayerIdByRank[0]; + } + } else { + ret = gGPCurrentRacePlayerIdByRank[0]; + } + } + return ret; +} + +void OBoos::BooStart(s32 group, s32 playerId) { + s32 objectIndex; + s16 temp_s1_2; + s16 temp_s4; + s16 temp_s5; + SplineData* spline; +printf("Boo Start\n"); + for (size_t i = 0; i < _numBoos; i++) { + objectIndex = _indices[i]; // indexObjectList3[group + i]; + init_object(objectIndex, 1); + gObjectList[objectIndex].unk_0D1 = playerId; + temp_s1_2 = random_int(0x003CU) - 0x1E; + temp_s4 = random_int(0x0014U) - 0xA; + temp_s5 = random_int(0x0050U) - 0x28; + random_int(0x1000U); + spline = D_800E5D9C[i]; + gObjectList[objectIndex].spline = spline; + gObjectList[objectIndex].origin_pos[0] = (f32) temp_s1_2; + gObjectList[objectIndex].origin_pos[1] = (f32) temp_s4; + gObjectList[objectIndex].origin_pos[2] = (f32) temp_s5; + } + func_800C9060(playerId, 0x1900705AU); + + _isActive = true; +} + +void OBoos::BooExit(s32 group) { + s32 objectIndex; +printf("Boo Exit\n"); + for (size_t i = 0; i < _numBoos; i++) { + objectIndex = _indices[i]; //indexObjectList3[group + temp_a0]; + gObjectList[objectIndex].unk_0DC += 1; + } + + _isActive = false; +} diff --git a/src/engine/objects/Boos.h b/src/engine/objects/Boos.h new file mode 100644 index 000000000..cc49df474 --- /dev/null +++ b/src/engine/objects/Boos.h @@ -0,0 +1,75 @@ +#pragma once + +#include <libultraship.h> +#include <vector> +#include "Object.h" + +#include "World.h" +#include "CoreMath.h" + +extern "C" { +#include "macros.h" +#include "main.h" +#include "vehicles.h" +#include "waypoints.h" +#include "common_structs.h" +#include "objects.h" +#include "camera.h" +#include "some_data.h" +} + +/** + * OBoos + * + * Args use path indices or path points. Recommended to use a span of 10 + * for each IPathSpan as that's how the original game did it. Ex. IPathSpan(10, 20) + * + * Once boos are active, they do not deactivate until the player drives into leftBoundary + * or rightBoundary. leftBoundary is really only used to deactivate the boos when the player is + * driving in the reverse direction. + * + * @arg numBoos to show, default 5, maximum 10 allowed due to limited splines + * @arg leftBoundary When the player enters this area, deactivate the boos. + * @arg active When the player enters this area, activate the boos. + * @arg rightBoundary When the player enters this area, deactivate the boos. + * + */ +class OBoos : public OObject { +public: + explicit OBoos(size_t numBoos, const IPathSpan& leftBoundary, const IPathSpan& active, const IPathSpan& rightBoundary); + + ~OBoos() { + _count--; + } + + static size_t GetCount() { + return _count; + } + + virtual void Tick() override; + virtual void Draw(s32 cameraId) override; + void func_800523B8(s32 objectIndex, s32 arg1, u32 arg2); + + void func_8007CA70(void); + void func_8007C5B4(s32 objectIndex); + void func_8007C684(s32 objectIndex); + void func_8007C4A4(s32 objectIndex); + s32 func_8007C9F8(void); + void BooStart(s32 someIndex, s32 arg1); + void BooExit(s32 someIndex); + void func_8007C550(s32 objectIndex); + +private: + FVector _pos; + static size_t _count; + size_t _idx; + std::vector<s32> _indices; // indices into gObjectList + size_t _numBoos; + + bool _isActive = false; + s32 _playerId = 0; + + IPathSpan _leftBoundary; + IPathSpan _active; + IPathSpan _rightBoundary; +}; |
