Add CIOWinManager

Former-commit-id: 8ca2500768
This commit is contained in:
Henrique Gemignani Passos Lima
2022-12-01 18:19:53 +02:00
parent 286110920f
commit 2e5ef5051a
31 changed files with 375 additions and 73 deletions

View File

@@ -0,0 +1,236 @@
#include "MetroidPrime/CIOWinManager.hpp"
#include "MetroidPrime/CIOWin.hpp"
#include "MetroidPrime/Decode.hpp"
#include "rstl/string.hpp"
CIOWinManager::CIOWinManager()
: x0_drawRoot(nullptr), x4_pumpRoot(nullptr), x8_localGatherQueue() {}
CIOWinManager::~CIOWinManager() { RemoveAllIOWins(); }
CIOWinManager::IOWinPQNode::IOWinPQNode(rstl::ncrc_ptr< CIOWin > iowin, int prio,
CIOWinManager::IOWinPQNode* next)
: x0_iowin(iowin), x4_prio(prio), x8_next(next) {}
void CIOWinManager::AddIOWin(rstl::ncrc_ptr< CIOWin > chIow, int pumpPrio, int drawPrio) {
IOWinPQNode* node;
IOWinPQNode* prevNode = nullptr;
for (node = x4_pumpRoot; node && node->x4_prio > pumpPrio; node = node->x8_next)
prevNode = node;
IOWinPQNode* newNode = new IOWinPQNode(chIow, pumpPrio, node);
if (prevNode)
prevNode->x8_next = newNode;
else
x4_pumpRoot = newNode;
prevNode = nullptr;
for (node = x0_drawRoot; node && drawPrio < node->x4_prio; node = node->x8_next)
prevNode = node;
newNode = new IOWinPQNode(chIow, drawPrio, node);
if (prevNode)
prevNode->x8_next = newNode;
else
x0_drawRoot = newNode;
}
void CIOWinManager::RemoveIOWin(rstl::ncrc_ptr< CIOWin > chIow) {
IOWinPQNode* prevNode = nullptr;
for (IOWinPQNode* node = x4_pumpRoot; node; node = node->x8_next) {
if (node->GetIOWin() == chIow) {
if (prevNode)
prevNode->x8_next = node->x8_next;
else
x4_pumpRoot = node->x8_next;
delete node;
break;
}
prevNode = node;
}
prevNode = nullptr;
for (IOWinPQNode* node = x0_drawRoot; node; node = node->x8_next) {
if (node->GetIOWin() == chIow) {
if (prevNode)
prevNode->x8_next = node->x8_next;
else
x0_drawRoot = node->x8_next;
delete node;
break;
}
prevNode = node;
}
}
void CIOWinManager::RemoveAllIOWins() {
while (x0_drawRoot) {
RemoveIOWin(x0_drawRoot->GetIOWin());
}
while (x4_pumpRoot) {
RemoveIOWin(x4_pumpRoot->GetIOWin());
}
}
void CIOWinManager::ChangeIOWinPriority(rstl::ncrc_ptr< CIOWin > toChange, int pumpPrio,
int drawPrio) {
IOWinPQNode* prevNode = nullptr;
for (IOWinPQNode* node = x4_pumpRoot; node; node = node->x8_next) {
if (node->GetIOWin() == toChange) {
if (prevNode == nullptr)
x4_pumpRoot = node->x8_next;
else
prevNode->x8_next = node->x8_next;
node->x4_prio = pumpPrio;
IOWinPQNode* testNode = x4_pumpRoot;
IOWinPQNode* testPrevNode = nullptr;
for (; testNode && testNode->x4_prio > pumpPrio; testNode = testNode->x8_next) {
testPrevNode = testNode;
}
node->x8_next = testNode;
if (testPrevNode == nullptr)
x4_pumpRoot = node;
else
testPrevNode->x8_next = node;
break;
}
prevNode = node;
}
prevNode = nullptr;
for (IOWinPQNode* node = x0_drawRoot; node; node = node->x8_next) {
if (node->GetIOWin() == toChange) {
if (prevNode == nullptr)
x0_drawRoot = node->x8_next;
else
prevNode->x8_next = node->x8_next;
node->x4_prio = drawPrio;
IOWinPQNode* testNode = x0_drawRoot;
IOWinPQNode* testPrevNode = nullptr;
for (; testNode && testNode->x4_prio > drawPrio; testNode = testNode->x8_next) {
testPrevNode = testNode;
}
node->x8_next = testNode;
if (testPrevNode == nullptr)
x0_drawRoot = node;
else
testPrevNode->x8_next = node;
break;
}
prevNode = node;
}
}
rstl::ncrc_ptr< CIOWin > CIOWinManager::FindIOWin(const char* name) {
const rstl::string& nameStr = reinterpret_cast<const rstl::string&>(*name);
for (IOWinPQNode* node = x4_pumpRoot; node; node = node->x8_next) {
if (node->GetIOWin()->GetName() == nameStr) {
return node->GetIOWin();
}
}
for (IOWinPQNode* node = x0_drawRoot; node; node = node->x8_next) {
if (node->GetIOWin()->GetName() == nameStr) {
return node->GetIOWin();
}
}
return rstl::ncrc_ptr< CIOWin >();
}
void CIOWinManager::PumpMessages(CArchitectureQueue& queue) {
while (!queue.IsEmpty()) {
CArchitectureMessage msg = queue.Pop();
DistributeOneMessage(msg, queue);
}
}
bool CIOWinManager::DistributeOneMessage(const CArchitectureMessage& msg,
CArchitectureQueue& queue) {
for (IOWinPQNode* node = x4_pumpRoot; node;) {
rstl::ncrc_ptr< CIOWin > iow = node->GetIOWin();
CIOWin::EMessageReturn mret = iow->OnMessage(msg, x8_localGatherQueue);
while (!x8_localGatherQueue.IsEmpty()) {
CArchitectureMessage msg = x8_localGatherQueue.Pop();
if (msg.GetTarget() == kAMT_IOWinManager) {
if (OnIOWinMessage(msg)) {
x8_localGatherQueue.Clear();
queue.Clear();
return true;
}
} else {
queue.Push(msg);
}
}
if (mret == CIOWin::kMR_RemoveIOWinAndExit || mret == CIOWin::kMR_RemoveIOWin) {
node = node->x8_next;
RemoveIOWin(iow);
} else {
node = node->x8_next;
}
if (mret == CIOWin::kMR_Exit || mret == CIOWin::kMR_RemoveIOWinAndExit) {
break;
}
}
return false;
}
void CIOWinManager::Draw() const {
for (IOWinPQNode* node = x0_drawRoot; node; node = node->x8_next) {
node->GetIOWin()->PreDraw();
if (!node->GetIOWin()->GetIsContinueDraw())
break;
}
for (IOWinPQNode* node = x0_drawRoot; node; node = node->x8_next) {
node->GetIOWin()->Draw();
if (!node->GetIOWin()->GetIsContinueDraw())
break;
}
}
bool CIOWinManager::OnIOWinMessage(const CArchitectureMessage& msg) {
switch (msg.GetType()) {
case kAM_RemoveIOWin: {
const CArchMsgParmNull& parm = MakeMsg::GetParmDeleteIOWin(msg);
rstl::ncrc_ptr< CIOWin > iow = FindIOWin((char*)&parm + 4);
if (iow)
RemoveIOWin(iow);
break;
}
case kAM_CreateIOWin: {
const CArchMsgParmInt32Int32VoidPtr& parm = MakeMsg::GetParmCreateIOWin(msg);
int pumpPrio = parm.GetInt1();
int drawPrio = parm.GetInt2();
rstl::rc_ptr< CIOWin > ptr(static_cast< CIOWin* >(const_cast< void* >(parm.GetPtr())));
AddIOWin(ptr, pumpPrio, drawPrio);
break;
}
case kAM_ChangeIOWinPriority: {
const CArchMsgParmInt32Int32VoidPtr& parm = MakeMsg::GetParmChangeIOWinPriority(msg);
int pumpPrio = parm.GetInt1();
int drawPrio = parm.GetInt2();
const void* ptr = parm.GetPtr();
rstl::ncrc_ptr< CIOWin > iow = FindIOWin((char*)&parm + 0xc);
if (iow)
ChangeIOWinPriority(iow, pumpPrio, drawPrio);
break;
}
case kAM_RemoveAllIOWins: {
RemoveAllIOWins();
return true;
}
default:
break;
}
return false;
}
rstl::ncrc_ptr<CIOWin> CIOWinManager::IOWinPQNode::GetIOWin() const {
return x0_iowin;
}

View File

@@ -161,6 +161,8 @@ CSfxHandle play_sfx(u16 sfx, bool underwater, bool looped, short pan) {
return hnd;
}
} // namespace NWeaponTypes
CDamageInfo CGunWeapon::GetShotDamageInfo(const SShotParam& shotParam, CStateManager& mgr) const {
// CWeaponMode mode(shotParam.x0_weaponType, 0);
// float damage = shotParam.x8_damage;
@@ -183,6 +185,9 @@ CDamageInfo CGunWeapon::GetShotDamageInfo(const SShotParam& shotParam, CStateMan
return result;
}
namespace NWeaponTypes {
int get_current_suit(const CStateManager& mgr) {
const CPlayerState* state = mgr.GetPlayerState();
CPlayerState::EPlayerSuit suit = state->GetCurrentSuit();