summaryrefslogtreecommitdiff
path: root/src/d/d_stage.cpp
diff options
context:
space:
mode:
authorrobojumper <robojumper@gmail.com>2025-03-08 18:54:53 +0100
committerrobojumper <robojumper@gmail.com>2025-03-09 10:09:08 +0100
commitc558c88f2534c699661671d41fcbd84633be74b3 (patch)
tree1d5e01a23e18b5bee5239575a55abe4a33374743 /src/d/d_stage.cpp
parent03c99fc37c5a833d4334f43c14b6206d65108663 (diff)
d_stage progress
Diffstat (limited to 'src/d/d_stage.cpp')
-rw-r--r--src/d/d_stage.cpp392
1 files changed, 392 insertions, 0 deletions
diff --git a/src/d/d_stage.cpp b/src/d/d_stage.cpp
new file mode 100644
index 00000000..91759aba
--- /dev/null
+++ b/src/d/d_stage.cpp
@@ -0,0 +1,392 @@
+#include "d/d_stage.h"
+
+#include "common.h"
+#include "d/col/bg/d_bg_s.h"
+#include "d/d_base.h"
+#include "d/d_room.h"
+#include "d/d_sc_game.h"
+#include "d/d_sc_title.h"
+#include "d/flag/dungeonflag_manager.h"
+#include "d/flag/sceneflag_manager.h"
+#include "d/flag/storyflag_manager.h"
+#include "f/f_base.h"
+#include "f/f_profile.h"
+#include "f/f_profile_name.h"
+#include "m/m_fader_base.h"
+#include "m/m_vec.h"
+#include "nw4r/g3d/res/g3d_resfile.h"
+#include "nw4r/g3d/res/g3d_resmat.h"
+#include "nw4r/g3d/res/g3d_resmdl.h"
+#include "nw4r/math/math_types.h"
+#include "s/s_FPhase.h"
+#include "toBeSorted/arc_managers/current_stage_arc_manager.h"
+#include "toBeSorted/arc_managers/layout_arc_manager.h"
+#include "toBeSorted/arc_managers/oarc_manager.h"
+#include "toBeSorted/event_manager.h"
+#include "toBeSorted/music_mgrs.h"
+#include "toBeSorted/time_area_mgr.h"
+
+#include <cstring>
+
+SPECIAL_BASE_PROFILE(STAGE, dStage_c, fProfile::STAGE, 6, 0x4E0);
+
+sFPhase<dStage_c>::phaseCallback dStage_c::sCallbacks[] = {
+ &dStage_c::createRooms,
+ &dStage_c::waitForRooms,
+ nullptr,
+};
+
+extern "C" void fn_8001BE60(f32, f32);
+extern "C" void *SCRAPPER_PTR;
+
+dStage_c::dStage_c() : mPhase(this, sCallbacks) {
+ memset(loaded_entities, 0, sizeof(loaded_entities));
+ sInstance = this;
+ dScGame_c::resetUpdateFrameCount();
+ SCRAPPER_PTR = nullptr;
+ fn_8001BE60(2000.0f, 1700.0f);
+}
+
+extern "C" void *SCRAPPER_PICKUP_TARGET;
+extern "C" void ScrapperPickupMgr__update(void *);
+extern "C" void ScrapperPickupMgr__dtor();
+extern "C" void fn_80028A80();
+extern "C" void fn_80028EC0();
+extern "C" void fn_80066D30(s32);
+
+int dStage_c::create() {
+ if (mPhase.step() != sFPhaseBase::PHASE_ALL_DONE) {
+ return NOT_READY;
+ }
+
+ // dStageMgr_c *stageMgr = dStageMgr_c::GetInstance();
+ // for (int i = 0; i < dSta)
+
+ if (mapRelated.field_0x1EB == 0) {
+ mVec3_c min, max;
+ for (s32 i = 0; i < MAX_ROOM_NUMBER - 1; i++) {
+ dRoom_c *room = getRoom(i);
+ if (room != nullptr) {
+ mVec3_c tmin, tmax;
+ room->getBounds(&tmin, &tmax);
+ if (i == 0) {
+ min = tmin;
+ max = tmax;
+ } else {
+ nw4r::math::VEC3Minimize(min, min, tmin);
+ nw4r::math::VEC3Maximize(max, max, tmax);
+ }
+ }
+ }
+ max.y += 6000.0f;
+ mVec3_c size = max - min;
+ mVec3_c center = mVec3_c(min.x + size.x * 0.5f, min.y, min.z + size.z * 0.5f);
+ mapRelated.fn_801B4B80(0, center, size);
+ mVec3_c v = mVec3_c(10000.0f, 10000.0f, 100000.0f);
+ mapRelated.fn_801B4C70(v);
+ }
+ mapRelated.fn_801B50C0(0);
+ fn_80028A80();
+
+ return SUCCEEDED;
+}
+
+int dStage_c::doDelete() {
+ fn_80028EC0();
+ fn_80066D30(-1);
+ ScrapperPickupMgr__dtor();
+ return SUCCEEDED;
+}
+
+int dStage_c::execute() {
+ mFader.calc();
+ ScrapperPickupMgr__update(SCRAPPER_PICKUP_TARGET);
+ return SUCCEEDED;
+}
+
+extern "C" void resetViewClipVals();
+
+int dStage_c::draw() {
+ resetViewClipVals();
+ return SUCCEEDED;
+}
+
+void dStage_c::deleteReady() {}
+
+sFPhaseBase::sFPhaseState dStage_c::createRooms() {
+ // TODO
+ // if (dScGame_c::sCo)
+ mFader.create();
+ mFader.setTypes(1, 1);
+ mFader.setFadeInFrame(1);
+ mFader.fadeIn();
+ mFader.calc();
+ mFader.setFrames(15, 15);
+ mFader.initForLyt();
+ // TODO
+
+ if (dScTitle_c::sInstance != nullptr) {
+ dBase_c::createBase(fProfile::TITLE, this, 0, OTHER);
+ }
+
+ dTimeAreaMgr_c::sInstance->setField0x78(false);
+
+ return sFPhaseBase::PHASE_NEXT;
+}
+
+sFPhaseBase::sFPhaseState dStage_c::waitForRooms() {
+ if (checkChildProcessCreateState()) {
+ return sFPhaseBase::PHASE_RETRY;
+ }
+ return sFPhaseBase::PHASE_NEXT;
+}
+
+void dStage_c::setRoom(int roomid, dRoom_c *room) {
+ rooms.setRoom(roomid, room);
+}
+
+dRoom_c *dStage_c::getRoom(s32 idx) {
+ return rooms.getRoom(idx);
+}
+
+bool dStage_c::fadeIn(s32 fadeType, u16 frames) {
+ if (mFader.getStatus() != mFaderBase_c::FADED_OUT) {
+ return false;
+ }
+ mFader.setFadeInType(fadeType);
+ mFader.setFadeInFrame(frames);
+ mFader.fadeIn();
+ fn_80384570(ENEMY_BGM_RELATED_MGR, false);
+ return true;
+}
+
+bool dStage_c::fadeOut(s32 fadeType, u16 frames) {
+ if (mFader.getStatus() != mFaderBase_c::FADED_IN) {
+ return false;
+ }
+ mFader.setFadeOutType(fadeType);
+ mFader.setFadeOutFrame(frames);
+ mFader.fadeOut();
+ fn_80384570(ENEMY_BGM_RELATED_MGR, true);
+ return true;
+}
+
+void dStage_c::forceFadeOut() {
+ mFader.setStatus(mFaderBase_c::FADED_OUT);
+ fn_80384570(ENEMY_BGM_RELATED_MGR, true);
+}
+
+void dStage_c::forceFadeIn() {
+ mFader.setStatus(mFaderBase_c::FADED_IN);
+ fn_80384570(ENEMY_BGM_RELATED_MGR, false);
+}
+
+void dStage_c::drawMap(mMtx_c *mtx, int param) {
+ dBgS::GetInstance()->UpdateScrollTex();
+ for (s32 i = 0; i < MAX_ROOM_NUMBER - 1; i++) {
+ dRoom_c *room = getRoom(i);
+ if (room != nullptr) {
+ room->drawOnMapIfVisible(mtx, param);
+ }
+ }
+ dBgS::GetInstance()->DrawSkyKeepMap(mtx, param);
+}
+
+static void getFlagPositionForRoomVisit(int roomid, u16 *o_flag, u16 *o_shift) {
+ *o_flag = (roomid / 16) + 8;
+ *o_shift = 1 << (roomid % 16);
+}
+
+bool dStage_c::hasVisitedRoom(int roomid) const {
+ u16 flag, shift;
+ getFlagPositionForRoomVisit(roomid, &flag, &shift);
+ DungeonflagManager *mg = DungeonflagManager::sInstance;
+ return (mg->getCounterOrFlag(flag, 8) & shift) != 0;
+}
+
+void dStage_c::setRoomVisited(int roomid) {
+ // TODO this is probably an inline but inline bools cause extra instructions
+ if (EventManager::getCurrentEventName() != nullptr &&
+ std::strncmp(EventManager::getCurrentEventName(), "Save", 0x20) == 0) {
+ return;
+ }
+
+ if (dScGame_c::sInstance == nullptr || dScGame_c::sInstance->profile_name == fProfile::GAME) {
+ u16 flag, shift;
+ getFlagPositionForRoomVisit(roomid, &flag, &shift);
+ DungeonflagManager *mg = DungeonflagManager::sInstance;
+ u16 newVal = shift | mg->getCounterOrFlag(flag, 8);
+ mg->setToValue(flag, newVal);
+ }
+}
+
+dRoom_c *dStage_c::createRoom(int roomid, bool flag0x40) {
+ return static_cast<dRoom_c *>(
+ dBase_c::createBase(fProfile::ROOM, this, (roomid & 0x3F) | (flag0x40 ? 0x40 : 0), OTHER)
+ );
+}
+
+void dStage_c::createLytSeekerStone() {
+ dBase_c::createBase(fProfile::LYT_CONTROL_GAME, this, 0, OTHER);
+ if (LayoutArcManager::sInstance->hasEntry("SeekerStone")) {
+ dBase_c::createBase(fProfile::LYT_SEEKER_STONE, this, 0, OTHER);
+ }
+}
+
+dBase_c *dStage_c::getParentForRoom(s32 idx) {
+ if (idx == -1) {
+ return dStage_c::GetInstance();
+ }
+ return dStage_c::GetInstance()->getRoom(idx);
+}
+
+void dStage_c::bindStageResToFile(nw4r::g3d::ResFile *file) {
+ nw4r::g3d::ResFile f = nw4r::g3d::ResFile(CurrentStageArcManager::sInstance->getData("g3d/stage.brres"));
+ if (f.IsValid()) {
+ file->Bind(f);
+ }
+}
+
+void dStage_c::bindSkyCmnToResFile(nw4r::g3d::ResFile *file) {
+ nw4r::g3d::ResFile f = nw4r::g3d::ResFile(OarcManager::sInstance->getSubEntryData("SkyCmn", "g3d/model.brres"));
+ if (f.IsValid()) {
+ file->Bind(f);
+ }
+}
+
+static const char *sMatsToTry[] = {
+ "MA01",
+ "MA02",
+ "MA04",
+};
+
+bool dStage_c::getMA0AnmTexSrt(nw4r::g3d::ResAnmTexSrt *o_srt, const char *matName) {
+ const char **candidate = sMatsToTry;
+ for (int i = 0; i < ARRAY_LENGTH(sMatsToTry); i++, candidate++) {
+ if (!std::strncmp(matName, *candidate, std::strlen(*candidate))) {
+ nw4r::g3d::ResFile mdl = nw4r::g3d::ResFile(OarcManager::sInstance->getMdlFromArc2("Common"));
+ *o_srt = mdl.GetResAnmTexSrt(*candidate);
+ return true;
+ }
+ }
+ return false;
+}
+
+bool dStage_c::getMA0IndirectSrt(nw4r::g3d::ResAnmTexSrt *o_srt, const nw4r::g3d::ResMdl &mdl) {
+ for (u32 i = 0; i < mdl.GetResMatNumEntries(); i++) {
+ nw4r::g3d::ResMat mat = mdl.GetResMat(i);
+ const char *name = mat.GetName();
+ if (getMA0AnmTexSrt(o_srt, name)) {
+ return true;
+ }
+ }
+ return false;
+}
+
+dRoomTable_c::dRoomTable_c() {
+ // Okay
+ mRooms[0] = nullptr;
+ mRooms[1] = nullptr;
+ mRooms[2] = nullptr;
+ mRooms[3] = nullptr;
+ mRooms[4] = nullptr;
+ mRooms[5] = nullptr;
+ mRooms[6] = nullptr;
+ mRooms[7] = nullptr;
+ mRooms[8] = nullptr;
+ mRooms[9] = nullptr;
+ mRooms[10] = nullptr;
+ mRooms[11] = nullptr;
+ mRooms[12] = nullptr;
+ mRooms[13] = nullptr;
+ mRooms[14] = nullptr;
+ mRooms[15] = nullptr;
+ mRooms[16] = nullptr;
+ mRooms[17] = nullptr;
+ mRooms[18] = nullptr;
+ mRooms[19] = nullptr;
+ mRooms[20] = nullptr;
+ mRooms[21] = nullptr;
+ mRooms[22] = nullptr;
+ mRooms[23] = nullptr;
+ mRooms[24] = nullptr;
+ mRooms[25] = nullptr;
+ mRooms[26] = nullptr;
+ mRooms[27] = nullptr;
+ mRooms[28] = nullptr;
+ mRooms[29] = nullptr;
+ mRooms[30] = nullptr;
+ mRooms[31] = nullptr;
+ mRooms[32] = nullptr;
+ mRooms[33] = nullptr;
+ mRooms[34] = nullptr;
+ mRooms[35] = nullptr;
+ mRooms[36] = nullptr;
+ mRooms[37] = nullptr;
+ mRooms[38] = nullptr;
+ mRooms[39] = nullptr;
+ mRooms[40] = nullptr;
+ mRooms[41] = nullptr;
+ mRooms[42] = nullptr;
+ mRooms[43] = nullptr;
+ mRooms[44] = nullptr;
+ mRooms[45] = nullptr;
+ mRooms[46] = nullptr;
+ mRooms[47] = nullptr;
+ mRooms[48] = nullptr;
+ mRooms[49] = nullptr;
+ mRooms[50] = nullptr;
+ mRooms[51] = nullptr;
+ mRooms[52] = nullptr;
+ mRooms[53] = nullptr;
+ mRooms[54] = nullptr;
+ mRooms[55] = nullptr;
+ mRooms[56] = nullptr;
+ mRooms[57] = nullptr;
+ mRooms[58] = nullptr;
+ mRooms[59] = nullptr;
+ mRooms[60] = nullptr;
+ mRooms[61] = nullptr;
+ mRooms[62] = nullptr;
+}
+
+MapRelated::MapRelated()
+ : field_0x0FC(0.0f, 0.0f, 0.0f),
+ field_0x108(0.0f),
+ field_0x10C(0.0f),
+ field_0x110(0.0f),
+ field_0x114(0.0f),
+ field_0x118(0.0f),
+ field_0x11C(0.0f),
+ field_0x120(0.0f),
+ field_0x124(0.0f),
+ field_0x128(0.0f),
+ field_0x12C(0.0f),
+ field_0x1E0(0),
+ field_0x1E6(0),
+ field_0x1E8(0),
+ field_0x1E9(4),
+ field_0x1EA(-3),
+ field_0x1EB(0),
+ field_0x1EC(0),
+ field_0x1ED(0),
+ field_0x1EE(0),
+ field_0x1F0(0) {
+ mPostEffect.setField0x30(0.15f);
+ bool showPastVariant = true;
+ bool showDesertPast = dScGame_c::isCurrentStage("S300") ||
+ ((dScGame_c::isCurrentStage("F300") || dScGame_c::isCurrentStage("F300_4")) &&
+ SceneflagManager::sInstance->checkTempOrSceneflag(3));
+ if (!showDesertPast) {
+ bool hideSeaPast = !(dScGame_c::isCurrentStage("F301_1") && StoryflagManager::sInstance->getCounterOrFlag(519));
+ if (hideSeaPast) {
+ showPastVariant = false;
+ }
+ }
+ field_0x1EF = showPastVariant;
+}
+
+extern "C" void fn_801B4AE0();
+MapRelated::~MapRelated() {
+ fn_801B4AE0();
+}