From 4b658f2165fc19b1d1b37a8c135ebe14bd3d47f3 Mon Sep 17 00:00:00 2001 From: lepelog <25211966+lepelog@users.noreply.github.com> Date: Fri, 9 Oct 2026 01:20:51 +0200 Subject: 97% --- src/REL/d/a/obj/d_a_obj_control_panel.cpp | 884 +++++++++++++++++++++++++++++- 1 file changed, 879 insertions(+), 5 deletions(-) (limited to 'src') diff --git a/src/REL/d/a/obj/d_a_obj_control_panel.cpp b/src/REL/d/a/obj/d_a_obj_control_panel.cpp index 9e16c8bc..467ef2ee 100644 --- a/src/REL/d/a/obj/d_a_obj_control_panel.cpp +++ b/src/REL/d/a/obj/d_a_obj_control_panel.cpp @@ -1,4 +1,105 @@ #include "d/a/obj/d_a_obj_control_panel.h" +#include "c/c_lib.h" +#include "common.h" +#include "d/a/d_a_itembase.h" +#include "d/a/d_a_player.h" +#include "d/a/obj/d_a_obj_D3_dummy.h" +#include "d/a/obj/d_a_obj_base.h" +#include "d/col/bg/d_bg_s.h" +#include "d/d_base.h" +#include "d/d_camera.h" +#include "d/d_cs_game.h" +#include "d/d_pad.h" +#include "d/d_sc_game.h" +#include "d/flag/itemflag_manager.h" +#include "d/flag/sceneflag_manager.h" +#include "d/lyt/d_lyt_do_button.h" +#include "d/lyt/d_lyt_unknowns.h" +#include "d/lyt/meter/d_lyt_meter.h" +#include "d/lyt/msg_window/d_lyt_msg_window.h" +#include "d/snd/d_snd_small_effect_mgr.h" +#include "d/snd/d_snd_wzsound.h" +#include "egg/math/eggMath.h" +#include "f/f_base.h" +#include "f/f_manager.h" +#include "f/f_profile_name.h" +#include "m/m_angle.h" +#include "m/m_color.h" +#include "m/m_mtx.h" +#include "m/m_pad.h" +#include "m/m_vec.h" +#include "nw4r/g3d/res/g3d_resfile.h" +#include "nw4r/g3d/res/g3d_resmdl.h" +#include "nw4r/g3d/res/g3d_resnode.h" +#include "nw4r/math/math_triangular.h" +#include "rvl/GX/GXTypes.h" +#include "toBeSorted/attention.h" +#include "toBeSorted/d_d3d.h" +#include "toBeSorted/event.h" +#include "toBeSorted/event_manager.h" +#include "toBeSorted/file_manager.h" + + +static const char* eventName = "ControlPanel"; +static const char* firstAfterEvent = "AfterControlPanelFirst"; +static const char* afterEvent = "AfterControlPanel"; + +static const u8 unused[] = { 0x00, 0xff, 0x00, 0xaa, 0x00, 0x50, 0x00, 0x00, 0x00, 0x50, 0x00, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x43, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; + +const void* getUnused() { + return unused; +} + +static const char* sSkyKeepRooms[] = { + "D003_0", + "D003_1", + "D003_2", + "D003_3", + "D003_4", + "D003_5", + "D003_6", + "D003_7", +}; + +const void* getUnused2() { + return sSkyKeepRooms; +} + +static InteractionTargetDef interactionTarget = {0, 3, 1, EXAMINE_TALK, 0, 200.0f, + 60.0f, 60.0f, -100.0f, 100.0f, 50.0f, 1.0f}; + + + +static mVec3_c sSpotPositions[9] = { + mVec3_c( -43.2, + 14.78, + -40.59), + mVec3_c(0.0, + 14.78, + -40.59), + mVec3_c(43.2, + 14.78, + -40.59), + mVec3_c(-43.2, + 0.0, + 0.0), + mVec3_c(0.0, + 0.0, + 0.0), + mVec3_c(43.2, + 0.0, + 0.0), + mVec3_c(-43.2, + -14.78, + 40.59), + mVec3_c(0.0, + -14.78, + 40.59), + mVec3_c(43.2, + -14.78, + 40.59), +}; + SPECIAL_ACTOR_PROFILE(OBJ_CONTROL_PANEL, dAcOCtrlPnl_c, fProfile::OBJ_CONTROL_PANEL, 0x159, 0, 3); @@ -6,12 +107,785 @@ STATE_DEFINE(dAcOCtrlPnl_c, Wait); STATE_DEFINE(dAcOCtrlPnl_c, Control); STATE_DEFINE(dAcOCtrlPnl_c, EndEvent); +void enterMoveCb(void* actor) { + if (actor == nullptr) return; + static_cast(actor)->enterMove(); +} + +void finishMoveCb(void* actor) { + if (actor == nullptr) return; + static_cast(actor)->finishMove(); +} + +void afterControlPanelFirstCb(void* actor) { + if (actor == nullptr) return; + static_cast(actor)->afterControlPanelFirst(); +} + +void afterControlPanelCb(void* actor) { + if (actor == nullptr) return; + static_cast(actor)->afterControlPanel(); +} + +bool dAcOCtrlPnl_c::createHeap() { + const char* oarcName = "ControlPanel"; + mRes = nw4r::g3d::ResFile(getOarcResFile(oarcName)); + nw4r::g3d::ResMdl mdl = mRes.GetResMdl("ControlPanel"); + if (!mModel.create(mdl, &mAllocator, 0x120, 1, nullptr)) { + return false; + } + void* dzb = getOarcDZB(oarcName, "ControlPanel"); + void* plc = getOarcPLC(oarcName, "ControlPanel"); + updateMatrix(); + return !mBgW.Set((cBgD_t *)dzb, (PLC *)plc, 0x81, &mWorldMtx, &mScale); +} + +int dAcOCtrlPnl_c::actorCreate() { + CREATE_ALLOCATOR_SIZE(dAcOCtrlPnl_c, 0x8000); + dBgS::GetInstance()->Regist(&mBgW, this); + mAcceleration = 0.f; + mMaxSpeed = 0.f; + mBoundingBox.Set(mVec3_c(-200.f, -0.f, -200.f), mVec3_c(200.f, 200.f, 200.f)); + updatePuzzleFromFile(); + updateTilePositions(); + mMovingTile = -1; + setupNeighbors(); + updateDoorSceneflags(); + if ((s32)getFromParams(0x18, 3) == 1) { + return FAILED; + } + char* plateModels[] = { + "CPPlate1", + "CPPlate2", + "CPPlate3", + "CPPlate4", + "CPPlate5", + "CPPlate6", + "CPPlate7", + "CPPlate8", + }; + nw4r::g3d::ResMdl resMdl = mModel.getResMdl(); + for (int i = 0; i < 8; i++) { + nw4r::g3d::ResNode node = resMdl.GetResNode(plateModels[i]); + mCallback.setNodeID(i, node.GetID()); + mCallback.setPosAndScale(i, mTilePositions[i], 1.f); + } + mModel.setLocalMtx(mWorldMtx); + mModel.setCallback(&mCallback); + mModel.calc(false); + mCurrentlyHoveredTile = -1; + mStateMgr.changeState(StateID_Wait); + return SUCCEEDED; +} + +int dAcOCtrlPnl_c::actorPostCreate() { + dAcOD3Dummy_c* ptr = static_cast(fManager_c::searchBaseByProfName(fProfile::OBJ_D3_DUMMY)); + mD3DummyRef.link(ptr); + static const char* plateModels[] = { + "m_CPPlate1", + "m_CPPlate2", + "m_CPPlate3", + "m_CPPlate4", + "m_CPPlate5", + "m_CPPlate6", + "m_CPPlate7", + "m_CPPlate8", + }; + for (int i = 0; i < 8; i++) { + mTilePlateMatIDs[i] = mModel.getMatID(plateModels[i]); + if (mTilePlateMatIDs[i] < 0) { + return FAILED; + } + } + // just a guess + static const char* triforcePlates[] = { + "m_CPPlate1", + "m_CPPlate3", + "m_CPPlate4", + }; + for (int i = 0; i < 3; i++) { + mTriforceMatIDs[i] = mModel.getMatID(triforcePlates[i]); + if (mTriforceMatIDs[i] < 0) { + return FAILED; + } + } + if (!mModel.getResMdl().GetResMat("m_CPPlate1").GetResMatTevColor().GXGetTevColor(GX_TEVREG1, &mNormalPlateColor)) { + return FAILED; + } + return SUCCEEDED; +} + +extern "C" bool IS_IN_SKYKEEP_PUZZLE; + +int dAcOCtrlPnl_c::doDelete() { + IS_IN_SKYKEEP_PUZZLE = false; + return SUCCEEDED; +} + +int dAcOCtrlPnl_c::actorExecute() { + mTimer++; + mStateMgr.executeState(); + + for (int i = 0; i < 8; i++) { + mCallback.setPosAndScale(i, mTilePositions[i], mTileScales[i]); + } + updateTileColors(); + updateTileScales(); + mModel.calc(false); + return SUCCEEDED; +} + +int dAcOCtrlPnl_c::draw() { + drawModelType1(&mModel); + return SUCCEEDED; +} + void dAcOCtrlPnl_c::initializeState_Wait() {} -void dAcOCtrlPnl_c::executeState_Wait() {} +void dAcOCtrlPnl_c::executeState_Wait() { + AttentionManager::GetInstance()->addTarget(*this, interactionTarget, 0, nullptr); + if (EventManager::isInEvent(this, eventName)) { + handleEvent(); + mStateMgr.changeState(StateID_Control); + } +} void dAcOCtrlPnl_c::finalizeState_Wait() {} void dAcOCtrlPnl_c::initializeState_Control() {} -void dAcOCtrlPnl_c::executeState_Control() {} +void dAcOCtrlPnl_c::executeState_Control() { + handleEvent(); + dCamera_c* camera = dScGame_c::getCamera(); + if (camera != nullptr) { + f32 camVal = 60.f; + mVec3_c local48(0.f, 240.f, 0.f); + mVec3_c local54(0.f, 0.f, 0.f); + f32 fVar1 = nw4r::math::CosDeg(20); + f32 fVar2 = nw4r::math::SinDeg(20); + local54.y += (fVar2 * 100.f) / fVar1 + 70.f; + local48.rotX(0xe39); + fVar1 = nw4r::math::CosDeg(20); + fVar2 = nw4r::math::SinDeg(20); + local48.y += (fVar2 * 100.f) / fVar1 + 70.f; + local48.rotY(mRotation.y); + local54.rotY(mRotation.y); + local48 += mPosition; + local54 += mPosition; + camera->setEventCamView(local54, local48, camVal, 0.f); + } +} void dAcOCtrlPnl_c::finalizeState_Control() {} -void dAcOCtrlPnl_c::initializeState_EndEvent() {} -void dAcOCtrlPnl_c::executeState_EndEvent() {} -void dAcOCtrlPnl_c::finalizeState_EndEvent() {} +void dAcOCtrlPnl_c::initializeState_EndEvent() { + handleEvent(); +} +void dAcOCtrlPnl_c::executeState_EndEvent() { + handleEvent(); +} +void dAcOCtrlPnl_c::finalizeState_EndEvent() { + SceneflagManager::sInstance->setFlag(mRoomID, getFromParams(0x10, 0xFF)); +} + +void dAcOCtrlPnl_c::doInteraction(s32) { + Event event(eventName, getOarcZev("ControlPanel"), 100, 0x100001, (void*)enterMoveCb, (void*)finishMoveCb); + mEvent.scheduleEvent(event, 0); +} + +void dAcOCtrlPnl_c::enterMove() { + handleLinkObjProp0x200(false); + mCurrentlyHoveredSpot = 0xFF; + mCurrentlyHoveredTile = -1; + mHasMovedATile = false; + mLeavePuzzle = false; + updatePuzzleFromFile(); + IS_IN_SKYKEEP_PUZZLE = true; +} +void dAcOCtrlPnl_c::finishMove() { + handleLinkObjProp0x200(true); + bool changed = changedPuzzle(); + IS_IN_SKYKEEP_PUZZLE = false; + savePuzzleState(); + if (mD3DummyRef.isLinked()) { + mD3DummyRef.get()->setField_0x1570(1); + } + if (changed) { + mStateMgr.changeState(StateID_EndEvent); + } else { + mStateMgr.changeState(StateID_Wait); + } +} +void dAcOCtrlPnl_c::afterControlPanelFirst() { + mStateMgr.changeState(StateID_Wait); +} +void dAcOCtrlPnl_c::afterControlPanel() { + mStateMgr.changeState(StateID_Wait); +} +// returns true when the tile finished moving +bool dAcOCtrlPnl_c::handleSlidingTile() { + if (doChaseTilePosToTarget()) { + mMovingTile = -1; + return true; + } else { + return false; + } +} +void dAcOCtrlPnl_c::updateTileScales() { + updateMatrix(); + mModel.setLocalMtx(mWorldMtx); + for (int i = 0; i < 8; i++) { + if (i == mCurrentlyHoveredTile && hasAdjacentEmptySpot(mCurrentlyHoveredTile)) { + mTileScales[i] = 1.1f; + } else { + mTileScales[i] = 1.0f; + } + } +} +bool dAcOCtrlPnl_c::hasAdjacentEmptySpot(s32 idx) { + s32 out = -1; + return getAdjacentEmptySpot(idx, &out); +} +// this returns the tile id, TODO: rename +extern "C" s32 isInSkyKeepPuzzleRoom(); +bool dAcOCtrlPnl_c::getAdjacentEmptySpot(s32 tileID, s32* pEmptySpot) { + if (tileID < 0) { + return false; + } + if (tileID == isInSkyKeepPuzzleRoom()) { + return false; + } + s32 tileSpot = -1; + for (s32 spot = 0; spot < 9; spot++) { + if (tileID == mSpots[spot].mCurrentTile) { + tileSpot = spot; + break; + } + } + if (tileSpot < 0) { + return false; + } + for (int direction = 0; direction < 4; direction++) { + dAcOCtrlPnl_c::Spot* adjacent = mSpots[tileSpot].mNeighbors[direction]; + if (adjacent != nullptr && adjacent->mCurrentTile == 0xFF) { + *pEmptySpot = adjacent->mSpot; + return true; + } + } + return false; +} +void dAcOCtrlPnl_c::setupNeighbors() { + mSpots[0].mNeighbors[0] = nullptr; + mSpots[0].mNeighbors[1] = &mSpots[1]; + mSpots[0].mNeighbors[2] = &mSpots[3]; + mSpots[0].mNeighbors[3] = nullptr; + mSpots[1].mNeighbors[0] = nullptr; + mSpots[1].mNeighbors[1] = &mSpots[2]; + mSpots[1].mNeighbors[2] = &mSpots[4]; + mSpots[1].mNeighbors[3] = &mSpots[0]; + mSpots[2].mNeighbors[0] = nullptr; + mSpots[2].mNeighbors[1] = nullptr; + mSpots[2].mNeighbors[2] = &mSpots[5]; + mSpots[2].mNeighbors[3] = &mSpots[1]; + mSpots[3].mNeighbors[0] = &mSpots[0]; + mSpots[3].mNeighbors[1] = &mSpots[4]; + mSpots[3].mNeighbors[2] = &mSpots[6]; + mSpots[3].mNeighbors[3] = nullptr; + mSpots[4].mNeighbors[0] = &mSpots[1]; + mSpots[4].mNeighbors[1] = &mSpots[5]; + mSpots[4].mNeighbors[2] = &mSpots[7]; + mSpots[4].mNeighbors[3] = &mSpots[3]; + mSpots[5].mNeighbors[0] = &mSpots[2]; + mSpots[5].mNeighbors[1] = nullptr; + mSpots[5].mNeighbors[2] = &mSpots[8]; + mSpots[5].mNeighbors[3] = &mSpots[4]; + mSpots[6].mNeighbors[0] = &mSpots[3]; + mSpots[6].mNeighbors[1] = &mSpots[7]; + mSpots[6].mNeighbors[2] = nullptr; + mSpots[6].mNeighbors[3] = nullptr; + mSpots[7].mNeighbors[0] = &mSpots[4]; + mSpots[7].mNeighbors[1] = &mSpots[8]; + mSpots[7].mNeighbors[2] = nullptr; + mSpots[7].mNeighbors[3] = &mSpots[6]; + mSpots[8].mNeighbors[0] = &mSpots[5]; + mSpots[8].mNeighbors[1] = nullptr; + mSpots[8].mNeighbors[2] = nullptr; + mSpots[8].mNeighbors[3] = &mSpots[7]; + for (int i = 0; i < 9; i++) { + mSpots[i].mSpot = i; + } + updateSpotTilesFromPuzzle(); +} +extern "C" void setEvent__12EventManagerFP9dAcBase_cP5EventP9dAcBase_c(dBase_c*, Event*, dBase_c*); +void dAcOCtrlPnl_c::handleEvent() { + u16 flow = getFromParams(0, 0xFFFF); + switch (mEvent.getCurrentEventCommand()) { + case 'wait': + mEvent.advanceNext(); + break; + case 'ctrl': + handleControl(); + if (mLeavePuzzle) { + handleLinkObjProp0x200(true); + mCurrentlyHoveredSpot = 0xFF; + mCurrentlyHoveredTile = -1; + dSndSmallEffectMgr_c::GetInstance()->playSound(SE_S_CtrlPnl_DECIDE); + mEvent.advanceNext(); + } + break; + case 'msg ': + if (mEvent.isAdvance()) { + s32 part2 = flow < 10000U ? 1000 : 100; + s32 truncate = (flow / part2); + + u16 lower = flow - truncate * part2; + + s32 part1 = flow < 10000U ? 1000 : 100; + u16 upper = flow / part1; + mFlowMgr.triggerEntryPoint(upper, lower, 0, 0); + dLytMsgWindow_c::setFlowMgr(&mFlowMgr); + } else { + mFlowMgr.checkFinished(); + if (mFlowMgr.fn_800C40F0()) { + mEvent.advanceNext(); + } + } + break; + case 'end ': + void *zev = getOarcZev("ControlPanel"); + if (changedPuzzle()) { + if (isFirstTime()) { + Event event(firstAfterEvent, zev, 100, 0x100001, nullptr, (void*)afterControlPanelFirstCb); + setEvent__12EventManagerFP9dAcBase_cP5EventP9dAcBase_c(this, &event, nullptr); + } else { + Event event(afterEvent, zev, 100, 0x100001, nullptr, (void*)afterControlPanelCb); + setEvent__12EventManagerFP9dAcBase_cP5EventP9dAcBase_c(this, &event, nullptr); + } + } + mEvent.advanceNext(); + break; + } +} + +void dAcOCtrlPnl_c::handleControl() { + bool canGrabTile = hasAdjacentEmptySpot(mCurrentlyHoveredTile); + if (mIsGrabbing) { + dLytDobutton_c::setActionTextStuff(dLytDobutton_c::ICON_29, dLytDobutton_c::ACT_DO_MOVE_2, true); + } else if (canGrabTile) { + dLytDobutton_c::setActionTextStuff(dLytDobutton_c::ICON_11, dLytDobutton_c::ACT_DO_GRAB_3, true); + } else { + dLytDobutton_c::setActionTextStuff(dLytDobutton_c::ICON_4, dLytDobutton_c::ACT_DO_SELECT, true); + } + if (!mIsGrabbing) { + if (canGrabTile) { + dLytMeter_c::GetInstance()->setFlags(0x200); + LytDoButtonRelated::set(LytDoButtonRelated::DO_BUTTON_A, LytDoButtonRelated::ACT_IE_INFO_GRAB_2); + } else { + dLytMeter_c::GetInstance()->clearFlags(0x200); + } + } + dLytMeter_c::GetInstance()->setFlags(0x10); + LytDoButtonRelated::set(LytDoButtonRelated::DO_BUTTON_B, LytDoButtonRelated::ACT_IE_ETC_DONE); + dLytMeter_c::GetInstance()->setFlags(0x400); + LytDoButtonRelated::set(LytDoButtonRelated::DO_BUTTON_C, LytDoButtonRelated::ACT_IE_ETC_RESET_PANELS); + dLytMeter_c::GetInstance()->clearFlags(0x1); + dLytMeter_c::GetInstance()->clearFlags(0x4); + dLytMeter_c::GetInstance()->clearFlags(0x8); + dLytMeter_c::GetInstance()->clearFlags(0x40); + dLytMeter_c::GetInstance()->clearFlags(0x80); + dLytMeter_c::GetInstance()->clearFlags(0x800); + dLytMeter_c::GetInstance()->setFlags(0x2); + LytDoButtonRelated::setCrossDown(LytDoButtonRelated::ACT_IE_ETC_CENTER, true); + bool downPressed = dPad::getDownTrigDown(); + if (downPressed) { + dPad::ex_c::m_current_ex->centerCursor(mPad::getCurrentCoreID(), true); + } + dCsGame_c* game = dCsGame_c::GetInstance(); + if (game != nullptr) { + if (game != nullptr) { + if (mIsGrabbing) { + game->pointerCatSet(); + } else { + game->pointerDefSet(); + } + } + mVec2_c cursorPos = game->getCursorIf()->getCursorPos(); + // ??? weird branches here + bool allowInteraction = true; + if (mMovingTile >= 0) { + if (handleSlidingTile()) { + mHasMovedATile = true; + mIsGrabbing = false; + u8 tile0 = mSpots[mCurrentlyHoveredSpot].mCurrentTile; + u8 tile1 = mSpots[mGrabTargetSpot].mCurrentTile; + mSpots[mCurrentlyHoveredSpot].mCurrentTile = tile1; + mSpots[mGrabTargetSpot].mCurrentTile = tile0; + setTileID(mGrabTargetSpot, tile0); + setTileID(mCurrentlyHoveredSpot, tile1); + updateDoorSceneflags(); + dAcOD3Dummy_c* dummy = mD3DummyRef.get(); + if (dummy != nullptr) { + savePuzzleState(); + dummy->setField_0x1570(1); + } + } + allowInteraction = false; + } + if (!mIsGrabbing) { + if (dPad::getDownTrigB()) { + mLeavePuzzle = true; + allowInteraction = false; + } else if (dPad::getDownTrigC()) { + if (changedPuzzle()) { + dSndSmallEffectMgr_c::GetInstance()->playSound(SE_S_CtrlPnl_RESET); + } + resetPuzzleState(); + updateTilePositions(); + updateSpotTilesFromPuzzle(); + updateDoorSceneflags(); + allowInteraction = false; + } + } + if (allowInteraction) { + if (!mIsGrabbing) { + s32 hoveredSpot = getSpotForCursor(cursorPos); + mCurrentlyHoveredSpot = hoveredSpot; + if (hoveredSpot == 0xFF) { + mCurrentlyHoveredTile = -1; + } else { + s32 oldHoveredTile = mCurrentlyHoveredTile; + s32 hoveredTile = getTileID(hoveredSpot); + mCurrentlyHoveredTile = hoveredTile; + if (hoveredTile == 0xFF) { + mCurrentlyHoveredTile = -1; + } + if (oldHoveredTile != mCurrentlyHoveredTile && hasAdjacentEmptySpot(mCurrentlyHoveredTile)) { + startSound(SE_CtrlPnl_TAKE); + } + } + s32 emptyAdjacentSpot = -1; + // check if the player grabbed the tile + if (mCurrentlyHoveredTile >= 0 && dPad::getDownTrigA() && getAdjacentEmptySpot(mCurrentlyHoveredTile, &emptyAdjacentSpot)) { + mIsGrabbing = true; + mGrabTargetMoveDirection = getMoveDirection(mCurrentlyHoveredSpot, emptyAdjacentSpot); + mGrabStartCursorPos = cursorPos; + mGrabTargetSpot = emptyAdjacentSpot; + mGrabTargetPosition = sSpotPositions[emptyAdjacentSpot]; + } + } else if(dPad::getUpTrigA()) { + mIsGrabbing = false; + } else { + mVec2_c diff = cursorPos - mGrabStartCursorPos; + if (mGrabTargetMoveDirection == 0) { + if (diff.y > 30.f) { + mMovingTile = mCurrentlyHoveredTile; + startSound(SE_CtrlPnl_SLIDE); + } + } else if (mGrabTargetMoveDirection == 1) { + if (diff.x > 30.f) { + mMovingTile = mCurrentlyHoveredTile; + startSound(SE_CtrlPnl_SLIDE); + } + } else if (mGrabTargetMoveDirection == 2) { + if (diff.y < -30.f) { + mMovingTile = mCurrentlyHoveredTile; + startSound(SE_CtrlPnl_SLIDE); + } + } else { + if (diff.x < -30.f) { + mMovingTile = mCurrentlyHoveredTile; + startSound(SE_CtrlPnl_SLIDE); + } + } + } + } + } +} + +extern "C" s32 getSKDoorSceneflag(s32, s32); +extern "C" bool checkSKDoorHasSceneflag(s32, s32); + +void dAcOCtrlPnl_c::updateDoorSceneflags() { + for (int spot = 0; spot < 9; spot++) { + s32 tile = mSpots[spot].mCurrentTile; + if (tile != 0xFF) { + for (int direction = 0; direction < 4; direction++) { + if (checkSKDoorHasSceneflag(tile, direction)) { + s32 sceneflag = getSKDoorSceneflag(tile, direction); + if (spot == 7 && direction == 2 && checkSKDoorHasSceneflag(tile, direction)) { + // TODO: inline for set/unset flag + setSceneflag(sceneflag); + } else { + dAcOCtrlPnl_c::Spot* neighbor = mSpots[spot].mNeighbors[direction]; + if (neighbor == nullptr) { + unsetSceneflag(sceneflag); + } else { + s32 curTile = neighbor->mCurrentTile; + s32 otherDirection; + if (direction == 0) { + otherDirection = 2; + } + if (direction == 2) { + otherDirection = 0; + } + if (direction == 3) { + otherDirection = 1; + } + if (direction == 1) { + otherDirection = 3; + } + if (curTile == 0xFF) { + unsetSceneflag(sceneflag); + } else if (checkSKDoorHasSceneflag(curTile, otherDirection)) { + setSceneflag(sceneflag); + } else { + unsetSceneflag(sceneflag); + } + } + } + } + } + } + } +} + +inline bool checkSpotBounds(f32* spotBounds, const mVec2_c& vec, mVec2_c& cursorPos) { + return vec.x + spotBounds[0] < cursorPos.x && + cursorPos.x < vec.x + spotBounds[2] && + vec.y + spotBounds[1] < cursorPos.y && + cursorPos.y < vec.y + spotBounds[3]; +} + +u8 dAcOCtrlPnl_c::getSpotForCursor(mVec2_c& cursorPos) { + f32 spotBoundaries[9][4]; + mVec3_c vec; + spotBoundaries[0][0] = -90.0; + spotBoundaries[0][1] = 40.0; + spotBoundaries[0][2] = -30.0; + spotBoundaries[0][3] = 120.0; + spotBoundaries[1][0] = -30.0; + spotBoundaries[1][1] = 40.0; + spotBoundaries[1][2] = 30.0; + spotBoundaries[1][3] = 120.0; + spotBoundaries[2][0] = 30.0; + spotBoundaries[2][1] = 40.0; + spotBoundaries[2][2] = 90.0; + spotBoundaries[2][3] = 120.0; + spotBoundaries[3][0] = -90.0; + spotBoundaries[3][1] = -40.0; + spotBoundaries[3][2] = -30.0; + spotBoundaries[3][3] = 40.0; + spotBoundaries[4][0] = -30.0; + spotBoundaries[4][1] = -40.0; + spotBoundaries[4][2] = 30.0; + spotBoundaries[4][3] = 40.0; + spotBoundaries[5][0] = 30.0; + spotBoundaries[5][1] = -40.0; + spotBoundaries[5][2] = 90.0; + spotBoundaries[5][3] = 40.0; + spotBoundaries[6][0] = -90.0; + spotBoundaries[6][1] = -120.0; + spotBoundaries[6][2] = -30.0; + spotBoundaries[6][3] = -40.0; + spotBoundaries[7][0] = -30.0; + spotBoundaries[7][1] = -120.0; + spotBoundaries[7][2] = 30.0; + spotBoundaries[7][3] = -40.0; + spotBoundaries[8][0] = 30.0; + spotBoundaries[8][1] = -120.0; + spotBoundaries[8][2] = 90.0; + spotBoundaries[8][3] = -40.0; + getScreenCenter(vec); + // loop unrollng + + f32 (*current)[4] = spotBoundaries; + for (s32 j = 0; j < 9; j++) { + current = spotBoundaries; + current += j; + if (vec.x + (*current)[0] < cursorPos.x && + cursorPos.x < vec.x + (*current)[2] && + vec.y + (*current)[1] < cursorPos.y && + cursorPos.y < vec.y + (*current)[3] + ) { + return j; + } + } + return 0xFF; +} + +u8 dAcOCtrlPnl_c::getMoveDirection(s32 currentSpot, s32 targetSpot) { + s32 y1 = currentSpot / 3; + s32 y2 = targetSpot / 3; + s32 x1 = currentSpot % 3; + s32 x2 = targetSpot % 3; + if (x1 != x2 && y1 != y2) { + return 0xFF; + } + // nonmatching: regswap and instruction reordering + s32 xAbs = EGG::Math::abs(x1 - x2); + s32 yAbs = EGG::Math::abs(y1 - y2); + if (xAbs > 1 || yAbs > 1) { + return 0xFF; + } + s32 xDiff = x2 - x1; + s32 yDiff = y2 - y1; + if (xDiff == 1) { + return 1; + } + if (xDiff == -1) { + return 3; + } + if (yDiff == 1) { + return 2; + } + if (yDiff == -1) { + return 0; + } + return 0xFF; +} + +void dAcOCtrlPnl_c::updatePuzzleFromFile() { + for (int i = 0; i < 9; i++) { + mSkykeepPuzzle[i] = FileManager::GetInstance()->getSkykeepPuzzleTile(i); + } + for (int i = 0; i < 9; i++) { + mSkykeepPuzzleOriginal[i] = mSkykeepPuzzle[i]; + } +} + +void dAcOCtrlPnl_c::setTileID(u32 slot, u32 tile) { + if (slot > 8) { + return; + } + if (tile != 0xFF && tile > 7) { + return; + } + mSkykeepPuzzle[slot] = tile; +} + +u8 dAcOCtrlPnl_c::getTileID(u32 spot) { + if (spot <= 8) { + return mSkykeepPuzzle[spot]; + } + return 0xFF; +} + +void dAcOCtrlPnl_c::resetPuzzleState() { + for (int i = 0; i < 9; i++) { + mSkykeepPuzzle[i] = mSkykeepPuzzleOriginal[i]; + } +} + +void dAcOCtrlPnl_c::savePuzzleState() { + for (int i = 0; i < 9; i++) { + FileManager::GetInstance()->setSkykeepPuzzle(i, mSkykeepPuzzle[i]); + } +} + +void dAcOCtrlPnl_c::updateTilePositions() { + for (int i = 0; i < 9; i++) { + s32 tile = mSkykeepPuzzle[i]; + if (tile != 0xFF) { + mTilePositions[tile] = sSpotPositions[i]; + } + } +} + +void dAcOCtrlPnl_c::updateSpotTilesFromPuzzle() { + for (int i = 0; i < 9; i++) { + mSpots[i].mCurrentTile = mSkykeepPuzzle[i]; + } +} + +inline bool isFF(s32 flag) { + return flag >= 0xFF; +} + +bool dAcOCtrlPnl_c::isFirstTime() { + s32 flag = getFromParams(0x10, 0xFF); + // nonmatching: first comparison is weird + return flag >= 0xFF || (flag < 0xFF && !SceneflagManager::sInstance->checkBoolFlag(mRoomID, flag)); +} + +bool dAcOCtrlPnl_c::changedPuzzle() { + for (int i = 0; i < 9; i++) { + if (mSkykeepPuzzleOriginal[i] != getTileID(i)) { + return true; + } + } + return false; +} + +inline int getNum() { + return 0; +} + +void dAcOCtrlPnl_c::getScreenCenter(mVec3_c& outVec) { + // int to float??? + mVec3_c local = mPosition + sSpotPositions[4]; + s32 _weird_zero = 0; + local.y += (146.f + _weird_zero); + d3d::worldToScreen(outVec, local); +} + +void dAcOCtrlPnl_c::handleLinkObjProp0x200(bool shouldUnset) { + if (dAcPy_c::GetLinkM() == nullptr) { + return; + } + if (shouldUnset) { + dAcPy_c::GetLinkM()->unsetObjectProperty(OBJ_PROP_0x200); + } else { + dAcPy_c::GetLinkM()->setObjectProperty(OBJ_PROP_0x200); + } +} + +void dAcOCtrlPnl_c::callback_c::timingB(u32 nodeID, nw4r::g3d::WorldMtxManip * result, nw4r::g3d::ResMdl) { + bool isTileNode = false; + for (int i = 0; i < 8; i++) { + if (mNodeIDs[i] == nodeID) { + isTileNode = true; + break; + } + } + if (isTileNode) { + int tileId = -1; + for (int i = 0; i < 8; i++) { + if (mNodeIDs[i] == nodeID) { + tileId = i; + } + } + mMtx_c mtx; + result->GetMtx(mtx); + mtx.transM(field_0x0[tileId]); + mtx.scaleM(field_0x20[tileId],field_0x20[tileId],field_0x20[tileId]); + result->SetMtx(mtx); + } +} + +void dAcOCtrlPnl_c::updateTileColors() { + ITEM_ID triforceItemflags[3] = { + ITEM_TRI_COURAGE, + ITEM_TRI_POWER, + ITEM_TRI_WISDOM, + }; + mColor triforceColors[3] = { + mColor(0, 0xFF, 0, 0), + mColor(0xFF, 0, 0, 0), + mColor(0, 0, 0xFF, 0), + }; + mColor def; + for (int i = 0; i < 3; i++) { + if (ItemflagManager::sInstance->getFlagDirect(triforceItemflags[i])) { + mModel.setTevColor(mTriforceMatIDs[i], GX_TEVREG2, mColor(0,0,0,0), false); + } else { + def.r = triforceColors[i].r * (nw4r::math::SinIdx(mTimer * 0xFFFF / 0x3C) + 1.f) * 0.5f; + def.g = triforceColors[i].g * (nw4r::math::SinIdx(mTimer * 0xFFFF / 0x3C) + 1.f) * 0.5f; + def.b = triforceColors[i].b * (nw4r::math::SinIdx(mTimer * 0xFFFF / 0x3C) + 1.f) * 0.5f; + def.a = 0; + mModel.setTevColor(mTriforceMatIDs[i], GX_TEVREG2, def, false); + } + } + for (int i = 0; i < 8; i++) { + if (i == isInSkyKeepPuzzleRoom()) { + mModel.setTevColor(mTilePlateMatIDs[i], GX_TEVREG1, mColor(0,0,0,0), false); + } else { + mModel.setTevColor(mTilePlateMatIDs[i], GX_TEVREG1, mNormalPlateColor, false); + } + } +} + +// missing 0x0000003C in rodata -- cgit v1.2.3 From f5c650e46ad6a7690931fe911ecd2a3fffa6c928 Mon Sep 17 00:00:00 2001 From: lepelog <25211966+lepelog@users.noreply.github.com> Date: Fri, 16 Oct 2026 23:38:19 +0200 Subject: small improvements --- src/REL/d/a/obj/d_a_obj_control_panel.cpp | 35 +++++++++++++------------------ 1 file changed, 14 insertions(+), 21 deletions(-) (limited to 'src') diff --git a/src/REL/d/a/obj/d_a_obj_control_panel.cpp b/src/REL/d/a/obj/d_a_obj_control_panel.cpp index 467ef2ee..875e6c99 100644 --- a/src/REL/d/a/obj/d_a_obj_control_panel.cpp +++ b/src/REL/d/a/obj/d_a_obj_control_panel.cpp @@ -360,7 +360,7 @@ bool dAcOCtrlPnl_c::getAdjacentEmptySpot(s32 tileID, s32* pEmptySpot) { return false; } for (int direction = 0; direction < 4; direction++) { - dAcOCtrlPnl_c::Spot* adjacent = mSpots[tileSpot].mNeighbors[direction]; + dAcOCtrlPnl_c::Spot* adjacent = mSpots[tileSpot].getNeighbor(direction); if (adjacent != nullptr && adjacent->mCurrentTile == 0xFF) { *pEmptySpot = adjacent->mSpot; return true; @@ -461,6 +461,7 @@ void dAcOCtrlPnl_c::handleEvent() { } } +// non matching void dAcOCtrlPnl_c::handleControl() { bool canGrabTile = hasAdjacentEmptySpot(mCurrentlyHoveredTile); if (mIsGrabbing) { @@ -504,7 +505,7 @@ void dAcOCtrlPnl_c::handleControl() { } } mVec2_c cursorPos = game->getCursorIf()->getCursorPos(); - // ??? weird branches here + // non matching: weird branches here bool allowInteraction = true; if (mMovingTile >= 0) { if (handleSlidingTile()) { @@ -690,10 +691,9 @@ u8 dAcOCtrlPnl_c::getSpotForCursor(mVec2_c& cursorPos) { spotBoundaries[8][2] = 90.0; spotBoundaries[8][3] = -40.0; getScreenCenter(vec); - // loop unrollng - f32 (*current)[4] = spotBoundaries; - for (s32 j = 0; j < 9; j++) { + s32 j = 0; + for (s32 remaining = 9; remaining != 0; remaining--, j++) { current = spotBoundaries; current += j; if (vec.x + (*current)[0] < cursorPos.x && @@ -707,17 +707,18 @@ u8 dAcOCtrlPnl_c::getSpotForCursor(mVec2_c& cursorPos) { return 0xFF; } +// non matching u8 dAcOCtrlPnl_c::getMoveDirection(s32 currentSpot, s32 targetSpot) { - s32 y1 = currentSpot / 3; - s32 y2 = targetSpot / 3; s32 x1 = currentSpot % 3; s32 x2 = targetSpot % 3; + s32 y1 = currentSpot / 3; + s32 y2 = targetSpot / 3; if (x1 != x2 && y1 != y2) { return 0xFF; } - // nonmatching: regswap and instruction reordering - s32 xAbs = EGG::Math::abs(x1 - x2); - s32 yAbs = EGG::Math::abs(y1 - y2); + // non matching: regswap + s32 xAbs = EGG::Math::abs(x1 - x2); + s32 yAbs = EGG::Math::abs(y1 - y2); if (xAbs > 1 || yAbs > 1) { return 0xFF; } @@ -791,13 +792,10 @@ void dAcOCtrlPnl_c::updateSpotTilesFromPuzzle() { } } -inline bool isFF(s32 flag) { - return flag >= 0xFF; -} - +// non matching bool dAcOCtrlPnl_c::isFirstTime() { - s32 flag = getFromParams(0x10, 0xFF); - // nonmatching: first comparison is weird + u8 flag = getFromParams(0x10, 0xFF); + // non matching: first comparison is weird return flag >= 0xFF || (flag < 0xFF && !SceneflagManager::sInstance->checkBoolFlag(mRoomID, flag)); } @@ -810,12 +808,7 @@ bool dAcOCtrlPnl_c::changedPuzzle() { return false; } -inline int getNum() { - return 0; -} - void dAcOCtrlPnl_c::getScreenCenter(mVec3_c& outVec) { - // int to float??? mVec3_c local = mPosition + sSpotPositions[4]; s32 _weird_zero = 0; local.y += (146.f + _weird_zero); -- cgit v1.2.3 From 3ad9c6a55e37a6de73ead142e6dabed47220b397 Mon Sep 17 00:00:00 2001 From: lepelog <25211966+lepelog@users.noreply.github.com> Date: Sat, 17 Oct 2026 00:01:05 +0200 Subject: rename functions --- src/REL/d/a/obj/d_a_obj_control_panel.cpp | 26 ++++++++++---------------- 1 file changed, 10 insertions(+), 16 deletions(-) (limited to 'src') diff --git a/src/REL/d/a/obj/d_a_obj_control_panel.cpp b/src/REL/d/a/obj/d_a_obj_control_panel.cpp index 875e6c99..01812224 100644 --- a/src/REL/d/a/obj/d_a_obj_control_panel.cpp +++ b/src/REL/d/a/obj/d_a_obj_control_panel.cpp @@ -38,6 +38,7 @@ #include "toBeSorted/event.h" #include "toBeSorted/event_manager.h" #include "toBeSorted/file_manager.h" +#include "toBeSorted/misc_actor.h" static const char* eventName = "ControlPanel"; @@ -215,10 +216,8 @@ int dAcOCtrlPnl_c::actorPostCreate() { return SUCCEEDED; } -extern "C" bool IS_IN_SKYKEEP_PUZZLE; - int dAcOCtrlPnl_c::doDelete() { - IS_IN_SKYKEEP_PUZZLE = false; + sIsInSkykeepPuzzle = false; return SUCCEEDED; } @@ -294,12 +293,12 @@ void dAcOCtrlPnl_c::enterMove() { mHasMovedATile = false; mLeavePuzzle = false; updatePuzzleFromFile(); - IS_IN_SKYKEEP_PUZZLE = true; + sIsInSkykeepPuzzle = true; } void dAcOCtrlPnl_c::finishMove() { handleLinkObjProp0x200(true); bool changed = changedPuzzle(); - IS_IN_SKYKEEP_PUZZLE = false; + sIsInSkykeepPuzzle = false; savePuzzleState(); if (mD3DummyRef.isLinked()) { mD3DummyRef.get()->setField_0x1570(1); @@ -340,13 +339,12 @@ bool dAcOCtrlPnl_c::hasAdjacentEmptySpot(s32 idx) { s32 out = -1; return getAdjacentEmptySpot(idx, &out); } -// this returns the tile id, TODO: rename -extern "C" s32 isInSkyKeepPuzzleRoom(); + bool dAcOCtrlPnl_c::getAdjacentEmptySpot(s32 tileID, s32* pEmptySpot) { if (tileID < 0) { return false; } - if (tileID == isInSkyKeepPuzzleRoom()) { + if (tileID == getCurrentSkyKeepRoomTileId()) { return false; } s32 tileSpot = -1; @@ -410,7 +408,7 @@ void dAcOCtrlPnl_c::setupNeighbors() { } updateSpotTilesFromPuzzle(); } -extern "C" void setEvent__12EventManagerFP9dAcBase_cP5EventP9dAcBase_c(dBase_c*, Event*, dBase_c*); + void dAcOCtrlPnl_c::handleEvent() { u16 flow = getFromParams(0, 0xFFFF); switch (mEvent.getCurrentEventCommand()) { @@ -450,10 +448,10 @@ void dAcOCtrlPnl_c::handleEvent() { if (changedPuzzle()) { if (isFirstTime()) { Event event(firstAfterEvent, zev, 100, 0x100001, nullptr, (void*)afterControlPanelFirstCb); - setEvent__12EventManagerFP9dAcBase_cP5EventP9dAcBase_c(this, &event, nullptr); + EventManager::setEvent(this, &event, nullptr); } else { Event event(afterEvent, zev, 100, 0x100001, nullptr, (void*)afterControlPanelCb); - setEvent__12EventManagerFP9dAcBase_cP5EventP9dAcBase_c(this, &event, nullptr); + EventManager::setEvent(this, &event, nullptr); } } mEvent.advanceNext(); @@ -597,9 +595,6 @@ void dAcOCtrlPnl_c::handleControl() { } } -extern "C" s32 getSKDoorSceneflag(s32, s32); -extern "C" bool checkSKDoorHasSceneflag(s32, s32); - void dAcOCtrlPnl_c::updateDoorSceneflags() { for (int spot = 0; spot < 9; spot++) { s32 tile = mSpots[spot].mCurrentTile; @@ -608,7 +603,6 @@ void dAcOCtrlPnl_c::updateDoorSceneflags() { if (checkSKDoorHasSceneflag(tile, direction)) { s32 sceneflag = getSKDoorSceneflag(tile, direction); if (spot == 7 && direction == 2 && checkSKDoorHasSceneflag(tile, direction)) { - // TODO: inline for set/unset flag setSceneflag(sceneflag); } else { dAcOCtrlPnl_c::Spot* neighbor = mSpots[spot].mNeighbors[direction]; @@ -873,7 +867,7 @@ void dAcOCtrlPnl_c::updateTileColors() { } } for (int i = 0; i < 8; i++) { - if (i == isInSkyKeepPuzzleRoom()) { + if (i == getCurrentSkyKeepRoomTileId()) { mModel.setTevColor(mTilePlateMatIDs[i], GX_TEVREG1, mColor(0,0,0,0), false); } else { mModel.setTevColor(mTilePlateMatIDs[i], GX_TEVREG1, mNormalPlateColor, false); -- cgit v1.2.3 From 9c195c0a982e7f39a7936340db589df210909e41 Mon Sep 17 00:00:00 2001 From: lepelog <25211966+lepelog@users.noreply.github.com> Date: Sat, 17 Oct 2026 00:12:17 +0200 Subject: format --- src/REL/d/a/obj/d_a_obj_control_panel.cpp | 184 ++++++++++++------------------ 1 file changed, 70 insertions(+), 114 deletions(-) (limited to 'src') diff --git a/src/REL/d/a/obj/d_a_obj_control_panel.cpp b/src/REL/d/a/obj/d_a_obj_control_panel.cpp index 01812224..e6b341f8 100644 --- a/src/REL/d/a/obj/d_a_obj_control_panel.cpp +++ b/src/REL/d/a/obj/d_a_obj_control_panel.cpp @@ -1,4 +1,5 @@ #include "d/a/obj/d_a_obj_control_panel.h" + #include "c/c_lib.h" #include "common.h" #include "d/a/d_a_itembase.h" @@ -40,103 +41,78 @@ #include "toBeSorted/file_manager.h" #include "toBeSorted/misc_actor.h" +static const char *eventName = "ControlPanel"; +static const char *firstAfterEvent = "AfterControlPanelFirst"; +static const char *afterEvent = "AfterControlPanel"; -static const char* eventName = "ControlPanel"; -static const char* firstAfterEvent = "AfterControlPanelFirst"; -static const char* afterEvent = "AfterControlPanel"; - -static const u8 unused[] = { 0x00, 0xff, 0x00, 0xaa, 0x00, 0x50, 0x00, 0x00, 0x00, 0x50, 0x00, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x43, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; +static const u8 unused[] = {0x00, 0xff, 0x00, 0xaa, 0x00, 0x50, 0x00, 0x00, 0x00, 0x50, 0x00, 0x3c, 0x00, 0x00, + 0x00, 0x00, 0x43, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; -const void* getUnused() { +const void *getUnused() { return unused; } -static const char* sSkyKeepRooms[] = { - "D003_0", - "D003_1", - "D003_2", - "D003_3", - "D003_4", - "D003_5", - "D003_6", - "D003_7", +static const char *sSkyKeepRooms[] = { + "D003_0", "D003_1", "D003_2", "D003_3", "D003_4", "D003_5", "D003_6", "D003_7", }; -const void* getUnused2() { +const void *getUnused2() { return sSkyKeepRooms; } -static InteractionTargetDef interactionTarget = {0, 3, 1, EXAMINE_TALK, 0, 200.0f, - 60.0f, 60.0f, -100.0f, 100.0f, 50.0f, 1.0f}; - - +static InteractionTargetDef interactionTarget = {0, 3, 1, EXAMINE_TALK, 0, 200.0f, + 60.0f, 60.0f, -100.0f, 100.0f, 50.0f, 1.0f}; static mVec3_c sSpotPositions[9] = { - mVec3_c( -43.2, - 14.78, - -40.59), - mVec3_c(0.0, - 14.78, - -40.59), - mVec3_c(43.2, - 14.78, - -40.59), - mVec3_c(-43.2, - 0.0, - 0.0), - mVec3_c(0.0, - 0.0, - 0.0), - mVec3_c(43.2, - 0.0, - 0.0), - mVec3_c(-43.2, - -14.78, - 40.59), - mVec3_c(0.0, - -14.78, - 40.59), - mVec3_c(43.2, - -14.78, - 40.59), + mVec3_c(-43.2, 14.78, -40.59), mVec3_c(0.0, 14.78, -40.59), mVec3_c(43.2, 14.78, -40.59), + mVec3_c(-43.2, 0.0, 0.0), mVec3_c(0.0, 0.0, 0.0), mVec3_c(43.2, 0.0, 0.0), + mVec3_c(-43.2, -14.78, 40.59), mVec3_c(0.0, -14.78, 40.59), mVec3_c(43.2, -14.78, 40.59), }; - SPECIAL_ACTOR_PROFILE(OBJ_CONTROL_PANEL, dAcOCtrlPnl_c, fProfile::OBJ_CONTROL_PANEL, 0x159, 0, 3); STATE_DEFINE(dAcOCtrlPnl_c, Wait); STATE_DEFINE(dAcOCtrlPnl_c, Control); STATE_DEFINE(dAcOCtrlPnl_c, EndEvent); -void enterMoveCb(void* actor) { - if (actor == nullptr) return; - static_cast(actor)->enterMove(); +void enterMoveCb(void *actor) { + if (actor == nullptr) { + return; + } + static_cast(actor)->enterMove(); } -void finishMoveCb(void* actor) { - if (actor == nullptr) return; - static_cast(actor)->finishMove(); +void finishMoveCb(void *actor) { + if (actor == nullptr) { + return; + } + static_cast(actor)->finishMove(); } -void afterControlPanelFirstCb(void* actor) { - if (actor == nullptr) return; - static_cast(actor)->afterControlPanelFirst(); +void afterControlPanelFirstCb(void *actor) { + if (actor == nullptr) { + return; + } + static_cast(actor)->afterControlPanelFirst(); } -void afterControlPanelCb(void* actor) { - if (actor == nullptr) return; - static_cast(actor)->afterControlPanel(); +void afterControlPanelCb(void *actor) { + if (actor == nullptr) { + return; + } + static_cast(actor)->afterControlPanel(); } bool dAcOCtrlPnl_c::createHeap() { - const char* oarcName = "ControlPanel"; + const char *oarcName = "ControlPanel"; mRes = nw4r::g3d::ResFile(getOarcResFile(oarcName)); nw4r::g3d::ResMdl mdl = mRes.GetResMdl("ControlPanel"); if (!mModel.create(mdl, &mAllocator, 0x120, 1, nullptr)) { return false; } - void* dzb = getOarcDZB(oarcName, "ControlPanel"); - void* plc = getOarcPLC(oarcName, "ControlPanel"); + void *dzb = getOarcDZB(oarcName, "ControlPanel"); + void *plc = getOarcPLC(oarcName, "ControlPanel"); updateMatrix(); return !mBgW.Set((cBgD_t *)dzb, (PLC *)plc, 0x81, &mWorldMtx, &mScale); } @@ -155,15 +131,8 @@ int dAcOCtrlPnl_c::actorCreate() { if ((s32)getFromParams(0x18, 3) == 1) { return FAILED; } - char* plateModels[] = { - "CPPlate1", - "CPPlate2", - "CPPlate3", - "CPPlate4", - "CPPlate5", - "CPPlate6", - "CPPlate7", - "CPPlate8", + char *plateModels[] = { + "CPPlate1", "CPPlate2", "CPPlate3", "CPPlate4", "CPPlate5", "CPPlate6", "CPPlate7", "CPPlate8", }; nw4r::g3d::ResMdl resMdl = mModel.getResMdl(); for (int i = 0; i < 8; i++) { @@ -180,17 +149,10 @@ int dAcOCtrlPnl_c::actorCreate() { } int dAcOCtrlPnl_c::actorPostCreate() { - dAcOD3Dummy_c* ptr = static_cast(fManager_c::searchBaseByProfName(fProfile::OBJ_D3_DUMMY)); + dAcOD3Dummy_c *ptr = static_cast(fManager_c::searchBaseByProfName(fProfile::OBJ_D3_DUMMY)); mD3DummyRef.link(ptr); - static const char* plateModels[] = { - "m_CPPlate1", - "m_CPPlate2", - "m_CPPlate3", - "m_CPPlate4", - "m_CPPlate5", - "m_CPPlate6", - "m_CPPlate7", - "m_CPPlate8", + static const char *plateModels[] = { + "m_CPPlate1", "m_CPPlate2", "m_CPPlate3", "m_CPPlate4", "m_CPPlate5", "m_CPPlate6", "m_CPPlate7", "m_CPPlate8", }; for (int i = 0; i < 8; i++) { mTilePlateMatIDs[i] = mModel.getMatID(plateModels[i]); @@ -199,7 +161,7 @@ int dAcOCtrlPnl_c::actorPostCreate() { } } // just a guess - static const char* triforcePlates[] = { + static const char *triforcePlates[] = { "m_CPPlate1", "m_CPPlate3", "m_CPPlate4", @@ -251,7 +213,7 @@ void dAcOCtrlPnl_c::finalizeState_Wait() {} void dAcOCtrlPnl_c::initializeState_Control() {} void dAcOCtrlPnl_c::executeState_Control() { handleEvent(); - dCamera_c* camera = dScGame_c::getCamera(); + dCamera_c *camera = dScGame_c::getCamera(); if (camera != nullptr) { f32 camVal = 60.f; mVec3_c local48(0.f, 240.f, 0.f); @@ -282,7 +244,7 @@ void dAcOCtrlPnl_c::finalizeState_EndEvent() { } void dAcOCtrlPnl_c::doInteraction(s32) { - Event event(eventName, getOarcZev("ControlPanel"), 100, 0x100001, (void*)enterMoveCb, (void*)finishMoveCb); + Event event(eventName, getOarcZev("ControlPanel"), 100, 0x100001, (void *)enterMoveCb, (void *)finishMoveCb); mEvent.scheduleEvent(event, 0); } @@ -340,7 +302,7 @@ bool dAcOCtrlPnl_c::hasAdjacentEmptySpot(s32 idx) { return getAdjacentEmptySpot(idx, &out); } -bool dAcOCtrlPnl_c::getAdjacentEmptySpot(s32 tileID, s32* pEmptySpot) { +bool dAcOCtrlPnl_c::getAdjacentEmptySpot(s32 tileID, s32 *pEmptySpot) { if (tileID < 0) { return false; } @@ -358,7 +320,7 @@ bool dAcOCtrlPnl_c::getAdjacentEmptySpot(s32 tileID, s32* pEmptySpot) { return false; } for (int direction = 0; direction < 4; direction++) { - dAcOCtrlPnl_c::Spot* adjacent = mSpots[tileSpot].getNeighbor(direction); + dAcOCtrlPnl_c::Spot *adjacent = mSpots[tileSpot].getNeighbor(direction); if (adjacent != nullptr && adjacent->mCurrentTile == 0xFF) { *pEmptySpot = adjacent->mSpot; return true; @@ -412,9 +374,7 @@ void dAcOCtrlPnl_c::setupNeighbors() { void dAcOCtrlPnl_c::handleEvent() { u16 flow = getFromParams(0, 0xFFFF); switch (mEvent.getCurrentEventCommand()) { - case 'wait': - mEvent.advanceNext(); - break; + case 'wait': mEvent.advanceNext(); break; case 'ctrl': handleControl(); if (mLeavePuzzle) { @@ -447,10 +407,10 @@ void dAcOCtrlPnl_c::handleEvent() { void *zev = getOarcZev("ControlPanel"); if (changedPuzzle()) { if (isFirstTime()) { - Event event(firstAfterEvent, zev, 100, 0x100001, nullptr, (void*)afterControlPanelFirstCb); + Event event(firstAfterEvent, zev, 100, 0x100001, nullptr, (void *)afterControlPanelFirstCb); EventManager::setEvent(this, &event, nullptr); } else { - Event event(afterEvent, zev, 100, 0x100001, nullptr, (void*)afterControlPanelCb); + Event event(afterEvent, zev, 100, 0x100001, nullptr, (void *)afterControlPanelCb); EventManager::setEvent(this, &event, nullptr); } } @@ -493,7 +453,7 @@ void dAcOCtrlPnl_c::handleControl() { if (downPressed) { dPad::ex_c::m_current_ex->centerCursor(mPad::getCurrentCoreID(), true); } - dCsGame_c* game = dCsGame_c::GetInstance(); + dCsGame_c *game = dCsGame_c::GetInstance(); if (game != nullptr) { if (game != nullptr) { if (mIsGrabbing) { @@ -516,7 +476,7 @@ void dAcOCtrlPnl_c::handleControl() { setTileID(mGrabTargetSpot, tile0); setTileID(mCurrentlyHoveredSpot, tile1); updateDoorSceneflags(); - dAcOD3Dummy_c* dummy = mD3DummyRef.get(); + dAcOD3Dummy_c *dummy = mD3DummyRef.get(); if (dummy != nullptr) { savePuzzleState(); dummy->setField_0x1570(1); @@ -558,14 +518,15 @@ void dAcOCtrlPnl_c::handleControl() { } s32 emptyAdjacentSpot = -1; // check if the player grabbed the tile - if (mCurrentlyHoveredTile >= 0 && dPad::getDownTrigA() && getAdjacentEmptySpot(mCurrentlyHoveredTile, &emptyAdjacentSpot)) { + if (mCurrentlyHoveredTile >= 0 && dPad::getDownTrigA() && + getAdjacentEmptySpot(mCurrentlyHoveredTile, &emptyAdjacentSpot)) { mIsGrabbing = true; mGrabTargetMoveDirection = getMoveDirection(mCurrentlyHoveredSpot, emptyAdjacentSpot); mGrabStartCursorPos = cursorPos; mGrabTargetSpot = emptyAdjacentSpot; mGrabTargetPosition = sSpotPositions[emptyAdjacentSpot]; } - } else if(dPad::getUpTrigA()) { + } else if (dPad::getUpTrigA()) { mIsGrabbing = false; } else { mVec2_c diff = cursorPos - mGrabStartCursorPos; @@ -605,7 +566,7 @@ void dAcOCtrlPnl_c::updateDoorSceneflags() { if (spot == 7 && direction == 2 && checkSKDoorHasSceneflag(tile, direction)) { setSceneflag(sceneflag); } else { - dAcOCtrlPnl_c::Spot* neighbor = mSpots[spot].mNeighbors[direction]; + dAcOCtrlPnl_c::Spot *neighbor = mSpots[spot].mNeighbors[direction]; if (neighbor == nullptr) { unsetSceneflag(sceneflag); } else { @@ -638,14 +599,12 @@ void dAcOCtrlPnl_c::updateDoorSceneflags() { } } -inline bool checkSpotBounds(f32* spotBounds, const mVec2_c& vec, mVec2_c& cursorPos) { - return vec.x + spotBounds[0] < cursorPos.x && - cursorPos.x < vec.x + spotBounds[2] && - vec.y + spotBounds[1] < cursorPos.y && - cursorPos.y < vec.y + spotBounds[3]; +inline bool checkSpotBounds(f32 *spotBounds, const mVec2_c &vec, mVec2_c &cursorPos) { + return vec.x + spotBounds[0] < cursorPos.x && cursorPos.x < vec.x + spotBounds[2] && + vec.y + spotBounds[1] < cursorPos.y && cursorPos.y < vec.y + spotBounds[3]; } -u8 dAcOCtrlPnl_c::getSpotForCursor(mVec2_c& cursorPos) { +u8 dAcOCtrlPnl_c::getSpotForCursor(mVec2_c &cursorPos) { f32 spotBoundaries[9][4]; mVec3_c vec; spotBoundaries[0][0] = -90.0; @@ -685,16 +644,13 @@ u8 dAcOCtrlPnl_c::getSpotForCursor(mVec2_c& cursorPos) { spotBoundaries[8][2] = 90.0; spotBoundaries[8][3] = -40.0; getScreenCenter(vec); - f32 (*current)[4] = spotBoundaries; + f32(*current)[4] = spotBoundaries; s32 j = 0; for (s32 remaining = 9; remaining != 0; remaining--, j++) { current = spotBoundaries; current += j; - if (vec.x + (*current)[0] < cursorPos.x && - cursorPos.x < vec.x + (*current)[2] && - vec.y + (*current)[1] < cursorPos.y && - cursorPos.y < vec.y + (*current)[3] - ) { + if (vec.x + (*current)[0] < cursorPos.x && cursorPos.x < vec.x + (*current)[2] && + vec.y + (*current)[1] < cursorPos.y && cursorPos.y < vec.y + (*current)[3]) { return j; } } @@ -802,7 +758,7 @@ bool dAcOCtrlPnl_c::changedPuzzle() { return false; } -void dAcOCtrlPnl_c::getScreenCenter(mVec3_c& outVec) { +void dAcOCtrlPnl_c::getScreenCenter(mVec3_c &outVec) { mVec3_c local = mPosition + sSpotPositions[4]; s32 _weird_zero = 0; local.y += (146.f + _weird_zero); @@ -820,7 +776,7 @@ void dAcOCtrlPnl_c::handleLinkObjProp0x200(bool shouldUnset) { } } -void dAcOCtrlPnl_c::callback_c::timingB(u32 nodeID, nw4r::g3d::WorldMtxManip * result, nw4r::g3d::ResMdl) { +void dAcOCtrlPnl_c::callback_c::timingB(u32 nodeID, nw4r::g3d::WorldMtxManip *result, nw4r::g3d::ResMdl) { bool isTileNode = false; for (int i = 0; i < 8; i++) { if (mNodeIDs[i] == nodeID) { @@ -838,7 +794,7 @@ void dAcOCtrlPnl_c::callback_c::timingB(u32 nodeID, nw4r::g3d::WorldMtxManip * r mMtx_c mtx; result->GetMtx(mtx); mtx.transM(field_0x0[tileId]); - mtx.scaleM(field_0x20[tileId],field_0x20[tileId],field_0x20[tileId]); + mtx.scaleM(field_0x20[tileId], field_0x20[tileId], field_0x20[tileId]); result->SetMtx(mtx); } } @@ -857,7 +813,7 @@ void dAcOCtrlPnl_c::updateTileColors() { mColor def; for (int i = 0; i < 3; i++) { if (ItemflagManager::sInstance->getFlagDirect(triforceItemflags[i])) { - mModel.setTevColor(mTriforceMatIDs[i], GX_TEVREG2, mColor(0,0,0,0), false); + mModel.setTevColor(mTriforceMatIDs[i], GX_TEVREG2, mColor(0, 0, 0, 0), false); } else { def.r = triforceColors[i].r * (nw4r::math::SinIdx(mTimer * 0xFFFF / 0x3C) + 1.f) * 0.5f; def.g = triforceColors[i].g * (nw4r::math::SinIdx(mTimer * 0xFFFF / 0x3C) + 1.f) * 0.5f; @@ -868,7 +824,7 @@ void dAcOCtrlPnl_c::updateTileColors() { } for (int i = 0; i < 8; i++) { if (i == getCurrentSkyKeepRoomTileId()) { - mModel.setTevColor(mTilePlateMatIDs[i], GX_TEVREG1, mColor(0,0,0,0), false); + mModel.setTevColor(mTilePlateMatIDs[i], GX_TEVREG1, mColor(0, 0, 0, 0), false); } else { mModel.setTevColor(mTilePlateMatIDs[i], GX_TEVREG1, mNormalPlateColor, false); } -- cgit v1.2.3 From 012a744e2bec62d69e872af688beb4a2e09bbc93 Mon Sep 17 00:00:00 2001 From: lepelog <25211966+lepelog@users.noreply.github.com> Date: Sat, 17 Oct 2026 00:18:07 +0200 Subject: small cleanup --- src/REL/d/a/obj/d_a_obj_control_panel.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/REL/d/a/obj/d_a_obj_control_panel.cpp b/src/REL/d/a/obj/d_a_obj_control_panel.cpp index e6b341f8..8b1683ef 100644 --- a/src/REL/d/a/obj/d_a_obj_control_panel.cpp +++ b/src/REL/d/a/obj/d_a_obj_control_panel.cpp @@ -779,7 +779,7 @@ void dAcOCtrlPnl_c::handleLinkObjProp0x200(bool shouldUnset) { void dAcOCtrlPnl_c::callback_c::timingB(u32 nodeID, nw4r::g3d::WorldMtxManip *result, nw4r::g3d::ResMdl) { bool isTileNode = false; for (int i = 0; i < 8; i++) { - if (mNodeIDs[i] == nodeID) { + if (mTileNodeIDs[i] == nodeID) { isTileNode = true; break; } @@ -787,14 +787,14 @@ void dAcOCtrlPnl_c::callback_c::timingB(u32 nodeID, nw4r::g3d::WorldMtxManip *re if (isTileNode) { int tileId = -1; for (int i = 0; i < 8; i++) { - if (mNodeIDs[i] == nodeID) { + if (mTileNodeIDs[i] == nodeID) { tileId = i; } } mMtx_c mtx; result->GetMtx(mtx); - mtx.transM(field_0x0[tileId]); - mtx.scaleM(field_0x20[tileId], field_0x20[tileId], field_0x20[tileId]); + mtx.transM(mTilePositions[tileId]); + mtx.scaleM(mTileScales[tileId], mTileScales[tileId], mTileScales[tileId]); result->SetMtx(mtx); } } -- cgit v1.2.3 From 502cd46c8a112834276b96cd4095d0d19b0faf76 Mon Sep 17 00:00:00 2001 From: lepelog <25211966+lepelog@users.noreply.github.com> Date: Sat, 17 Oct 2026 01:53:56 +0200 Subject: updates --- src/REL/d/a/obj/d_a_obj_control_panel.cpp | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) (limited to 'src') diff --git a/src/REL/d/a/obj/d_a_obj_control_panel.cpp b/src/REL/d/a/obj/d_a_obj_control_panel.cpp index 8b1683ef..893c81bd 100644 --- a/src/REL/d/a/obj/d_a_obj_control_panel.cpp +++ b/src/REL/d/a/obj/d_a_obj_control_panel.cpp @@ -249,7 +249,7 @@ void dAcOCtrlPnl_c::doInteraction(s32) { } void dAcOCtrlPnl_c::enterMove() { - handleLinkObjProp0x200(false); + setLinkVisibility(false); mCurrentlyHoveredSpot = 0xFF; mCurrentlyHoveredTile = -1; mHasMovedATile = false; @@ -258,7 +258,7 @@ void dAcOCtrlPnl_c::enterMove() { sIsInSkykeepPuzzle = true; } void dAcOCtrlPnl_c::finishMove() { - handleLinkObjProp0x200(true); + setLinkVisibility(true); bool changed = changedPuzzle(); sIsInSkykeepPuzzle = false; savePuzzleState(); @@ -378,7 +378,7 @@ void dAcOCtrlPnl_c::handleEvent() { case 'ctrl': handleControl(); if (mLeavePuzzle) { - handleLinkObjProp0x200(true); + setLinkVisibility(true); mCurrentlyHoveredSpot = 0xFF; mCurrentlyHoveredTile = -1; dSndSmallEffectMgr_c::GetInstance()->playSound(SE_S_CtrlPnl_DECIDE); @@ -742,11 +742,9 @@ void dAcOCtrlPnl_c::updateSpotTilesFromPuzzle() { } } -// non matching bool dAcOCtrlPnl_c::isFirstTime() { u8 flag = getFromParams(0x10, 0xFF); - // non matching: first comparison is weird - return flag >= 0xFF || (flag < 0xFF && !SceneflagManager::sInstance->checkBoolFlag(mRoomID, flag)); + return !(flag < 0xFF) || (flag < 0xFF && !SceneflagManager::sInstance->checkBoolFlag(mRoomID, flag)); } bool dAcOCtrlPnl_c::changedPuzzle() { @@ -765,11 +763,11 @@ void dAcOCtrlPnl_c::getScreenCenter(mVec3_c &outVec) { d3d::worldToScreen(outVec, local); } -void dAcOCtrlPnl_c::handleLinkObjProp0x200(bool shouldUnset) { +void dAcOCtrlPnl_c::setLinkVisibility(bool isVisible) { if (dAcPy_c::GetLinkM() == nullptr) { return; } - if (shouldUnset) { + if (isVisible) { dAcPy_c::GetLinkM()->unsetObjectProperty(OBJ_PROP_0x200); } else { dAcPy_c::GetLinkM()->setObjectProperty(OBJ_PROP_0x200); -- cgit v1.2.3 From 26e6dd9867b896d07f1967bd2eafd3bf3170fea1 Mon Sep 17 00:00:00 2001 From: lepelog <25211966+lepelog@users.noreply.github.com> Date: Sun, 18 Oct 2026 23:29:26 +0200 Subject: review --- src/REL/d/a/obj/d_a_obj_control_panel.cpp | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) (limited to 'src') diff --git a/src/REL/d/a/obj/d_a_obj_control_panel.cpp b/src/REL/d/a/obj/d_a_obj_control_panel.cpp index 893c81bd..a6a0457d 100644 --- a/src/REL/d/a/obj/d_a_obj_control_panel.cpp +++ b/src/REL/d/a/obj/d_a_obj_control_panel.cpp @@ -114,7 +114,7 @@ bool dAcOCtrlPnl_c::createHeap() { void *dzb = getOarcDZB(oarcName, "ControlPanel"); void *plc = getOarcPLC(oarcName, "ControlPanel"); updateMatrix(); - return !mBgW.Set((cBgD_t *)dzb, (PLC *)plc, 0x81, &mWorldMtx, &mScale); + return !mBgW.Set((cBgD_t *)dzb, (PLC *)plc, cBgW::LOCK_e | cBgW::MOVE_BG_e, &mWorldMtx, &mScale); } int dAcOCtrlPnl_c::actorCreate() { @@ -431,23 +431,23 @@ void dAcOCtrlPnl_c::handleControl() { } if (!mIsGrabbing) { if (canGrabTile) { - dLytMeter_c::GetInstance()->setFlags(0x200); + dLytMeter_c::GetInstance()->setFlags(METER_BTN_NUN_STK); LytDoButtonRelated::set(LytDoButtonRelated::DO_BUTTON_A, LytDoButtonRelated::ACT_IE_INFO_GRAB_2); } else { - dLytMeter_c::GetInstance()->clearFlags(0x200); + dLytMeter_c::GetInstance()->clearFlags(METER_BTN_NUN_STK); } } - dLytMeter_c::GetInstance()->setFlags(0x10); + dLytMeter_c::GetInstance()->setFlags(METER_BTN_B); LytDoButtonRelated::set(LytDoButtonRelated::DO_BUTTON_B, LytDoButtonRelated::ACT_IE_ETC_DONE); - dLytMeter_c::GetInstance()->setFlags(0x400); + dLytMeter_c::GetInstance()->setFlags(METER_BTN_C); LytDoButtonRelated::set(LytDoButtonRelated::DO_BUTTON_C, LytDoButtonRelated::ACT_IE_ETC_RESET_PANELS); - dLytMeter_c::GetInstance()->clearFlags(0x1); - dLytMeter_c::GetInstance()->clearFlags(0x4); - dLytMeter_c::GetInstance()->clearFlags(0x8); - dLytMeter_c::GetInstance()->clearFlags(0x40); - dLytMeter_c::GetInstance()->clearFlags(0x80); - dLytMeter_c::GetInstance()->clearFlags(0x800); - dLytMeter_c::GetInstance()->setFlags(0x2); + dLytMeter_c::GetInstance()->clearFlags(METER_BTN_CROSS_UP); + dLytMeter_c::GetInstance()->clearFlags(METER_BTN_CROSS_LEFT); + dLytMeter_c::GetInstance()->clearFlags(METER_BTN_CROSS_RIGHT); + dLytMeter_c::GetInstance()->clearFlags(METER_BTN_MINUS); + dLytMeter_c::GetInstance()->clearFlags(METER_BTN_1); + dLytMeter_c::GetInstance()->clearFlags(METER_BTN_Z); + dLytMeter_c::GetInstance()->setFlags(METER_BTN_CROSS_DOWN); LytDoButtonRelated::setCrossDown(LytDoButtonRelated::ACT_IE_ETC_CENTER, true); bool downPressed = dPad::getDownTrigDown(); if (downPressed) { -- cgit v1.2.3