Add wip CCredits

This commit is contained in:
Henrique Gemignani Passos Lima 2023-01-19 11:05:39 +02:00
parent b24751b60c
commit 7d627be624
No known key found for this signature in database
GPG Key ID: E224F951761145F8
9 changed files with 380 additions and 14 deletions

View File

@ -475,8 +475,8 @@ lbl_80025468:
/* 80025484 000223E4 38 21 00 20 */ addi r1, r1, 0x20
/* 80025488 000223E8 4E 80 00 20 */ blr
.global sub_8002548c
sub_8002548c:
.global DrawVideo__8CCreditsCFv
DrawVideo__8CCreditsCFv:
/* 8002548C 000223EC 94 21 FF C0 */ stwu r1, -0x40(r1)
/* 80025490 000223F0 7C 08 02 A6 */ mflr r0
/* 80025494 000223F4 90 01 00 44 */ stw r0, 0x44(r1)
@ -489,7 +489,7 @@ sub_8002548c:
/* 800254B0 00022410 80 63 00 28 */ lwz r3, 0x28(r3)
/* 800254B4 00022414 28 03 00 00 */ cmplwi r3, 0
/* 800254B8 00022418 41 82 00 A0 */ beq lbl_80025558
/* 800254BC 0002241C 48 00 2A 89 */ bl sub_80027f44
/* 800254BC 0002241C 48 00 2A 89 */ bl DrawVideo__12CMoviePlayerCFv
/* 800254C0 00022420 54 60 06 3F */ clrlwi. r0, r3, 0x18
/* 800254C4 00022424 41 82 00 94 */ beq lbl_80025558
/* 800254C8 00022428 88 7F 00 5C */ lbz r3, 0x5c(r31)
@ -541,8 +541,8 @@ lbl_80025558:
/* 80025574 000224D4 38 21 00 40 */ addi r1, r1, 0x40
/* 80025578 000224D8 4E 80 00 20 */ blr
.global sub_8002557c
sub_8002557c:
.global DrawText__8CCreditsCFv
DrawText__8CCreditsCFv:
/* 8002557C 000224DC 94 21 FF 70 */ stwu r1, -0x90(r1)
/* 80025580 000224E0 7C 08 02 A6 */ mflr r0
/* 80025584 000224E4 90 01 00 94 */ stw r0, 0x94(r1)
@ -658,9 +658,9 @@ Draw__8CCreditsCFv:
/* 80025724 00022684 80 03 00 14 */ lwz r0, 0x14(r3)
/* 80025728 00022688 2C 00 00 03 */ cmpwi r0, 3
/* 8002572C 0002268C 40 82 00 10 */ bne lbl_8002573C
/* 80025730 00022690 4B FF FD 5D */ bl sub_8002548c
/* 80025730 00022690 4B FF FD 5D */ bl DrawVideo__8CCreditsCFv
/* 80025734 00022694 7F E3 FB 78 */ mr r3, r31
/* 80025738 00022698 4B FF FE 45 */ bl sub_8002557c
/* 80025738 00022698 4B FF FE 45 */ bl DrawText__8CCreditsCFv
lbl_8002573C:
/* 8002573C 0002269C 80 01 00 14 */ lwz r0, 0x14(r1)
/* 80025740 000226A0 83 E1 00 0C */ lwz r31, 0xc(r1)
@ -1927,7 +1927,7 @@ sub_8002692c:
/* 80026938 00023898 80 63 00 38 */ lwz r3, 0x38(r3)
/* 8002693C 0002389C 28 03 00 00 */ cmplwi r3, 0
/* 80026940 000238A0 41 82 00 08 */ beq lbl_80026948
/* 80026944 000238A4 48 00 16 01 */ bl sub_80027f44
/* 80026944 000238A4 48 00 16 01 */ bl DrawVideo__12CMoviePlayerCFv
lbl_80026948:
/* 80026948 000238A8 80 01 00 14 */ lwz r0, 0x14(r1)
/* 8002694C 000238AC 7C 08 03 A6 */ mtlr r0
@ -3474,8 +3474,8 @@ lbl_80027F30:
/* 80027F3C 00024E9C 38 21 00 20 */ addi r1, r1, 0x20
/* 80027F40 00024EA0 4E 80 00 20 */ blr
.global sub_80027f44
sub_80027f44:
.global DrawVideo__12CMoviePlayerCFv
DrawVideo__12CMoviePlayerCFv:
/* 80027F44 00024EA4 94 21 FF 60 */ stwu r1, -0xa0(r1)
/* 80027F48 00024EA8 7C 08 02 A6 */ mflr r0
/* 80027F4C 00024EAC 90 01 00 A4 */ stw r0, 0xa4(r1)

View File

@ -29,7 +29,7 @@ LIBS = [
["MetroidPrime/CInputGenerator", False],
["MetroidPrime/CMainFlow", False],
"MetroidPrime/CMFGame",
"MetroidPrime/CCredits",
["MetroidPrime/CCredits", False],
"MetroidPrime/CSplashScreen",
["MetroidPrime/CAnimData", False],
"MetroidPrime/Factories/CCharacterFactory",

View File

@ -2,25 +2,86 @@
#define _CGUITEXTSUPPORT
#include "rstl/string.hpp"
#include "rstl/vector.hpp"
class CColor;
class CGuiFrame;
class CTextExecuteBuffer;
class CTextParser;
enum EJustification {
kJ_Left = 0,
kJ_Center,
kJ_Right,
kJ_Full,
kJ_NLeft,
kJ_NCenter,
kJ_NRight,
kJ_LeftMono,
kJ_CenterMono,
kJ_RightMono,
};
enum EVerticalJustification {
kVJ_Top = 0,
kVJ_Center,
kVJ_Bottom,
kVJ_Full,
kVJ_NTop,
kVJ_NCenter,
kVJ_NBottom,
kVJ_TopMono,
kVJ_CenterMono,
kVJ_RightMono,
};
enum ETextDirection {
kTD_Horizontal,
kTD_Vertical,
};
class CGuiTextProperties {
friend class CGuiTextSupport;
public:
CGuiTextProperties(bool wordWrap, bool horizontal, EJustification justification,
EVerticalJustification vertJustification,
const rstl::vector< rstl::pair< CAssetId, CAssetId > >* txtrMap = nullptr)
: x0_wordWrap(wordWrap)
, x1_horizontal(horizontal)
, x4_justification(justification)
, x8_vertJustification(vertJustification)
, xc_txtrMap(txtrMap) {}
private:
bool x0_wordWrap;
bool x1_horizontal;
EJustification x4_justification;
EVerticalJustification x8_vertJustification;
const rstl::vector< rstl::pair< CAssetId, CAssetId > >* xc_txtrMap;
};
class CGuiTextSupport {
static CTextExecuteBuffer* gpExecBuf;
static CTextParser* gpTextParser;
public:
CGuiTextSupport(CAssetId fontId, const CGuiTextProperties& props, const CColor& fontCol,
const CColor& outlineCol, const CColor& geomCol, int extX, int extY,
CSimplePool* store, int /*CGuiWidget::EGuiModelDrawFlags*/ drawFlags);
void SetText(const rstl::string&, bool multipage = false);
void SetOutlineColor(const CColor& col);
void SetFontColor(const CColor& col);
void Render() const;
static void Initialize(CTextExecuteBuffer* buf, CTextParser* parser) {
gpExecBuf = buf;
gpTextParser = parser;
}
private:
char x0_pad[0x30c];
};
#endif // _CGUITEXTSUPPORT

View File

@ -6,6 +6,15 @@
class CMoviePlayer {
public:
static void SetSfxVolume(uchar);
CMoviePlayer(const char*, float, bool, bool);
~CMoviePlayer();
void Update(float);
bool DrawVideo() const;
private:
char x0_pad[0x100];
};
#endif // _CMOVIEPLAYER

View File

@ -42,6 +42,8 @@ public:
CFinalInput ScaleAnalogueSticks(float leftDiv, float rightDiv) const;
float DeltaTime() const { return x0_dt; }
float ALAUp() const { return xc_anaLeftY > 0.f ? xc_anaLeftY : 0.f; }
float ALADown() const { return xc_anaLeftY < 0.f ? -xc_anaLeftY : 0.f; }

View File

@ -14,6 +14,7 @@ class CStringTable {
public:
CStringTable(CInputStream& in);
const wchar_t* GetString(int idx) const;
int GetStringCount() const { return x0_stringCount; }
};
extern CStringTable* gpStringTable;

View File

@ -3,13 +3,53 @@
#include "MetroidPrime/CIOWin.hpp"
#include "Kyoto/TToken.hpp"
#include "Kyoto/Math/CVector2i.hpp"
#include "rstl/single_ptr.hpp"
class CFinalInput;
class CStringTable;
class CRasterFont;
class CMoviePlayer;
class CStaticAudioPlayer;
class CGuiTextSupport;
class CVector3f;
class CCredits : public CIOWin {
public:
CCredits();
EMessageReturn OnMessage(const CArchitectureMessage& msg, CArchitectureQueue& queue);
~CCredits() override;
EMessageReturn OnMessage(const CArchitectureMessage&, CArchitectureQueue&) override;
bool GetIsContinueDraw() const override;
void Draw() const override;
EMessageReturn Update(float, CArchitectureQueue& queue);
EMessageReturn ProcessUserInput(const CFinalInput& input);
private:
char data[0x4c];
int x14_; // = 0;
TLockedToken< CStringTable > x18_creditsTable;
TLockedToken< CRasterFont > x20_creditsFont;
rstl::single_ptr< CMoviePlayer > x28_moviePlayer;
rstl::single_ptr< CStaticAudioPlayer > x2c_;
rstl::vector< rstl::pair< rstl::single_ptr< CGuiTextSupport >, CVector2i > > x30_text;
int x44_textSupport; // = 0;
float x48_; // = 0.f;
float x4c_; // = 0.f;
float x50_; // = 8.f;
float x54_;
float x58_; // = 0.f;
bool x5c_24_ : 1; // = false;
bool x5c_25_ : 1; // = false;
bool x5c_26_ : 1; // = false;
bool x5c_27_ : 1; // = true;
bool x5c_28_ : 1; // = false;
void DrawVideo() const;
void DrawText() const;
static void DrawText(CGuiTextSupport&, const CVector3f& translation);
};
#endif // _CCREDITS

View File

@ -154,7 +154,9 @@ public:
const rstl::string& GetJapaneseCreditsFont() const { return x2f0_japaneseCreditsFont; }
const CColor& GetCreditsTextFontColor() const { return x300_; }
const CColor& GetCreditsTextBorderColor() const { return x304_; }
float GetCredits_x30c() const { return x30c_; }
float GetCredits_x310() const { return x310_; }
static float FaceReflectionDistanceDebugValueToActualValue(float v);
static float FaceReflectionHeightDebugValueToActualValue(float v);
static float FaceReflectionAspectDebugValueToActualValue(float v);

View File

@ -0,0 +1,251 @@
#include "MetroidPrime/CCredits.hpp"
#include "MetroidPrime/CArchitectureMessage.hpp"
#include "MetroidPrime/Cameras/CCameraFilterPass.hpp"
#include "MetroidPrime/Decode.hpp"
#include "MetroidPrime/Tweaks/CTweakGui.hpp"
#include "GuiSys/CGuiTextSupport.hpp"
#include "GuiSys/CGuiWidget.hpp"
#include "Kyoto/CResFactory.hpp"
#include "Kyoto/Graphics/CGraphics.hpp"
#include "Kyoto/Graphics/CMoviePlayer.hpp"
#include "Kyoto/Text/CRasterFont.hpp"
#include "Kyoto/Text/CStringTable.hpp"
#include "MetaRender/CCubeRenderer.hpp"
#include "rstl/math.hpp"
bool CCredits::GetIsContinueDraw() const { return false; }
CCredits::CCredits()
: CIOWin("Credits")
, x18_creditsTable(gpSimplePool->GetObj(gpTweakGui->GetCreditsTable().data()))
, x20_creditsFont(gpSimplePool->GetObj(gpTweakGui->GetJapaneseCreditsFont().data()))
, x54_(gpTweakGui->GetCredits_x30c()) {
// x18_creditsTable.Lock();
// x20_creditsFont.Lock();
}
CCredits::~CCredits() {}
CIOWin::EMessageReturn CCredits::OnMessage(const CArchitectureMessage& msg,
CArchitectureQueue& queue) {
switch (msg.GetType()) {
case kAM_UserInput: {
return ProcessUserInput(MakeMsg::GetParmUserInput(msg).GetUserInput());
break;
case kAM_TimerTick: {
return Update(MakeMsg::GetParmTimerTick(msg).GetReal(), queue);
}
default:
break;
}
}
return kMR_Normal;
}
CIOWin::EMessageReturn CCredits::Update(float dt, CArchitectureQueue& queue) {
switch (x14_) {
case 0: {
if (!x18_creditsTable.IsLoaded() || !x20_creditsFont.IsLoaded()) {
return kMR_Exit;
}
if (x30_text.empty()) {
for (int i = 0; i < x18_creditsTable->GetStringCount(); ++i) {
x30_text.push_back(rstl::pair< rstl::single_ptr< CGuiTextSupport >, CVector2i >(
new CGuiTextSupport(
gpResourceFactory->GetResourceIdByName(gpTweakGui->GetCreditsFont().data())->id,
CGuiTextProperties(true, true, kJ_Center, kVJ_Top),
gpTweakGui->GetCreditsTextFontColor(), gpTweakGui->GetCreditsTextBorderColor(),
CColor::White(), CGraphics::GetViewport().mWidth - 64, 0, gpSimplePool,
CGuiWidget::kGMDF_Alpha),
CVector2i(0, 0)));
// x30_text.back().first->SetText(x18_creditsTable->GetString(i));
}
// auto tmp = std::make_pair(std::make_unique<CGuiTextSupport>(
// gpResourceFactory->GetResourceIdByName(gpTweakGui->GetCreditsFont())->id,
// CGuiTextProperties(true, true, kJ_Center,
// EVerticalJustification::Top),
// gpTweakGui->GetCreditsTextFontColor(),
// gpTweakGui->GetCreditsTextBorderColor(),
// CColor::White(), g_Viewport.x8_width
// - 64, 0, gpSimplePool,
// CGuiWidget::EGuiModelDrawFlags::Alpha),
// CVector2i(0, 0));
// tmp.first->SetText(
// "\n&push;&font=C29C51F1;&main-color=#89D6FF;URDE DEVELOPMENT TEAM&pop;\n"
// "&push;&main-color=#89D6FF;LEAD REVERSE ENGINEERING TEAM&pop\n;"
// "Jack \"Cirrus\" Andersen\n"
// "Phillip \"Antidote\" Stephens\n"
// "Luke \"encounter\" Street\n\n"
// "&push;&main-color=#89D6FF;C++ COMPLIANCE & CLEANUP&pop;\n"
// "Lioncache\n");
// x30_text.insert(x30_text.end() - 1, std::move(tmp));
// x30_text.back().first->SetOutlineColor(gpTweakGui->GetCreditsTextBorderColor());
}
// for (const auto& [text, offset] : x30_text) {
// if (!text->GetIsTextSupportFinishedLoading()) {
// return kMR_Exit;
// }
// }
// int scaleY = 0;
// for (auto& [text, offset] : x30_text) {
// auto bounds = text->GetBounds();
// offset.y = (bounds.second.y - bounds.first.y);
// offset.x = scaleY;
// text->SetExtentX(CGraphics::GetViewportWidth() - 1280);
// text->SetExtentY((bounds.second.y - bounds.first.y));
// scaleY += (bounds.second.y - bounds.first.y);
// }
// x4c_ = float(scaleY + CGraphics::GetViewportHeight() - 896); // * 0.5f;
// const float divVal = rstl::max_val(gpTweakGui->x310_, gpTweakGui->x30c_);
// x50_ = x4c_ / (gpTweakGui->x308_ - divVal);
x14_ = 1;
break;
}
case 1: {
if (x28_moviePlayer.null()) {
x28_moviePlayer = new CMoviePlayer("Video/creditBG.thp", 0.f, true, true);
}
x14_ = 2;
break;
}
case 2: {
// if (x2c_.null()) {
// x2c_ = new CStaticAudioPlayer("Audio/ending3.rsf", 0, 0x5d7c00);
// }
// if (!x2c_->IsReady()) {
// return kMR_Exit;
// }
// x2c_->SetVolume(1.f);
// x2c_->StartMixing();
x14_ = 3;
}
// [[fallthrough]];
case 3: {
// if (!x28_moviePlayer->PumpIndexLoad())
// break;
x28_moviePlayer->Update(dt);
if (x5c_24_) {
x5c_28_ = true;
if (x5c_27_) {
x5c_27_ = false;
x58_ = gpTweakGui->GetCredits_x310() - x58_;
}
}
if (x5c_27_ || x5c_28_) {
x58_ = CMath::Clamp(0.f, x58_ + dt, gpTweakGui->GetCredits_x310());
if (x58_ == gpTweakGui->GetCredits_x310()) {
if (x5c_27_) {
x5c_27_ = false;
x58_ = 0.f;
} else if (x5c_28_) {
x5c_25_ = true;
}
}
if (x58_ != 0.f && x5c_28_) {
const float volume = CMath::Clamp(0.f, 1.f - x58_ / gpTweakGui->GetCredits_x310(), 1.f);
// x2c_->SetVolume(volume);
}
}
x48_ = rstl::min_val(x4c_, (dt * x50_) + x48_);
if (x48_ == x4c_ || x5c_24_) {
x5c_24_ = true;
x54_ = rstl::max_val(0.f, x54_ - dt);
const float alpha = x54_ / gpTweakGui->GetCredits_x30c();
// for (const auto& [text, offset] : x30_text) {
// CColor col = CColor::White();
// col.a() *= alpha;
// text->SetGeometryColor(col);
// }
if (x54_ <= 0.f) {
x5c_26_ = true;
}
}
if (x5c_26_ && x5c_25_) {
// queue.Push(MakeMsg::CreateCreateIOWin(
// EArchMsgTarget::IOWinManager, 12, 11,
// std::make_shared< CPlayMovie >(CPlayMovie::EWhichMovie::AfterCredits)));
return kMR_RemoveIOWinAndExit;
}
break;
}
default:
break;
}
return kMR_Exit;
}
CIOWin::EMessageReturn CCredits::ProcessUserInput(const CFinalInput& input) {
if (input.DA()) {
x48_ = CMath::Clamp(0.f, x48_ - ((x50_ * input.DeltaTime())), x4c_);
} else {
float leftY = input.ALAUp();
float offset = 0.f;
if (leftY < 0.f) {
offset = -leftY;
leftY = 0.f;
}
x48_ = CMath::Clamp(0.f, x48_ - (leftY - offset) * 10.f * x50_ * input.DeltaTime(), x4c_);
}
return kMR_Exit;
}
void CCredits::DrawText(CGuiTextSupport& text, const CVector3f& translation) {
CGraphics::SetCullMode(kCM_None);
gpRender->SetViewportOrtho(true, -4096.f, 4096.f);
gpRender->SetModelMatrix(CTransform4f::Translate(translation));
gpRender->SetDepthReadWrite(false, false);
text.Render();
}
void CCredits::Draw() const {
if (x14_ != 3) {
return;
}
DrawVideo();
DrawText();
}
void CCredits::DrawText() const {
// float width = 896.f * CGraphics::GetViewportAspect();
// CGraphics::SetOrtho(0.f, width, 896.f, 0.f, -4096.f, 4096.f);
// auto region = std::make_pair(CVector2f{0.f, 0.f}, CVector2f{width, 896.f});
// CGraphics::SetViewPointMatrix(CTransform4f());
// CGraphics::SetModelMatrix(CTransform4f::Translate((width - 1280.f) / 2.f, 0.f, 896.f));
// float dVar5 = (x48_ - (region.second.y() - region.first.y()));
// for (const auto& [text, offset] : x30_text) {
// if (offset.y + offset.x >= dVar5 && offset.x <= x48_) {
// DrawText(*text, {0.5f * (region.second.x() - text->GetExtentX()), 0.f, x48_ - offset.x});
// }
// }
// CCameraFilterPass::DrawFilter(EFilterType::Multiply, EFilterShape::CinemaBars, skBlack,
// nullptr,
// 1.f);
}
void CCredits::DrawVideo() const {
/* Render movie */
if (x28_moviePlayer.get() && x28_moviePlayer->DrawVideo() && (x5c_27_ || x5c_28_)) {
float alpha = x58_ / gpTweakGui->GetCredits_x310();
if (x5c_27_) {
alpha = 1.f - alpha;
}
alpha = CMath::Clamp(0.f, alpha, 1.f);
CColor filterCol = CColor::Black().WithAlphaOf(alpha);
CCameraFilterPass::DrawFilter(CCameraFilterPass::kFT_Blend, CCameraFilterPass::kFS_Fullscreen,
filterCol, nullptr, 1.f);
}
}