mirror of https://github.com/PrimeDecomp/prime.git
Add CScriptMidi
This commit is contained in:
parent
890d2bb2d1
commit
1b5ee3bee8
|
@ -3,8 +3,8 @@
|
|||
.section .data
|
||||
.balign 8
|
||||
|
||||
.global lbl_803E7048
|
||||
lbl_803E7048:
|
||||
.global __vt__11CScriptMidi
|
||||
__vt__11CScriptMidi:
|
||||
# ROM: 0x3E4048
|
||||
.4byte 0
|
||||
.4byte 0
|
||||
|
@ -202,9 +202,9 @@ __dt__11CScriptMidiFv:
|
|||
/* 8020BBDC 00208B3C 93 C1 00 08 */ stw r30, 8(r1)
|
||||
/* 8020BBE0 00208B40 7C 7E 1B 79 */ or. r30, r3, r3
|
||||
/* 8020BBE4 00208B44 41 82 00 48 */ beq lbl_8020BC2C
|
||||
/* 8020BBE8 00208B48 3C 80 80 3E */ lis r4, lbl_803E7048@ha
|
||||
/* 8020BBE8 00208B48 3C 80 80 3E */ lis r4, __vt__11CScriptMidi@ha
|
||||
/* 8020BBEC 00208B4C C0 22 B1 B0 */ lfs f1, lbl_805ACED0@sda21(r2)
|
||||
/* 8020BBF0 00208B50 38 04 70 48 */ addi r0, r4, lbl_803E7048@l
|
||||
/* 8020BBF0 00208B50 38 04 70 48 */ addi r0, r4, __vt__11CScriptMidi@l
|
||||
/* 8020BBF4 00208B54 90 1E 00 00 */ stw r0, 0(r30)
|
||||
/* 8020BBF8 00208B58 4B FF FD 45 */ bl StopInternal__11CScriptMidiFf
|
||||
/* 8020BBFC 00208B5C 34 1E 00 34 */ addic. r0, r30, 0x34
|
||||
|
@ -324,9 +324,9 @@ Accept__11CScriptMidiFR8IVisitor:
|
|||
/* 8020BD84 00208CE4 7C 87 23 78 */ mr r7, r4
|
||||
/* 8020BD88 00208CE8 38 81 00 08 */ addi r4, r1, 8
|
||||
/* 8020BD8C 00208CEC 4B E4 55 99 */ bl "__ct__7CEntityF9TUniqueIdRC11CEntityInfobRCQ24rstl66basic_string<c,Q24rstl14char_traits<c>,Q24rstl17rmemory_allocator>"
|
||||
/* 8020BD90 00208CF0 3C 60 80 3E */ lis r3, lbl_803E7048@ha
|
||||
/* 8020BD90 00208CF0 3C 60 80 3E */ lis r3, __vt__11CScriptMidi@ha
|
||||
/* 8020BD94 00208CF4 3C 80 43 53 */ lis r4, 0x43534E47@ha
|
||||
/* 8020BD98 00208CF8 38 03 70 48 */ addi r0, r3, lbl_803E7048@l
|
||||
/* 8020BD98 00208CF8 38 03 70 48 */ addi r0, r3, __vt__11CScriptMidi@l
|
||||
/* 8020BD9C 00208CFC 38 61 00 0C */ addi r3, r1, 0xc
|
||||
/* 8020BDA0 00208D00 90 1D 00 00 */ stw r0, 0(r29)
|
||||
/* 8020BDA4 00208D04 38 04 4E 47 */ addi r0, r4, 0x43534E47@l
|
||||
|
|
|
@ -312,7 +312,7 @@ LIBS = [
|
|||
"MetroidPrime/CVisorFlare",
|
||||
"MetroidPrime/Enemies/CFlaahgraPlants",
|
||||
"MetroidPrime/CWorldTransManager",
|
||||
"MetroidPrime/ScriptObjects/CScriptMidi",
|
||||
["MetroidPrime/ScriptObjects/CScriptMidi", False],
|
||||
"MetroidPrime/ScriptObjects/CScriptStreamedAudio",
|
||||
"MetroidPrime/CRagDoll",
|
||||
"MetroidPrime/Player/CGameOptions",
|
||||
|
|
|
@ -0,0 +1,15 @@
|
|||
#ifndef _CMIDIMANAGER
|
||||
#define _CMIDIMANAGER
|
||||
|
||||
#include "Kyoto/Audio/CSfxHandle.hpp"
|
||||
|
||||
class CMidiManager {
|
||||
public:
|
||||
class CMidiWrapper {};
|
||||
class CMidiData {};
|
||||
|
||||
static CSfxHandle Play(const CMidiData&, unsigned short fadeTime, bool stopExisting, short volume);
|
||||
static void Stop(const CSfxHandle&, unsigned short);
|
||||
};
|
||||
|
||||
#endif // _CMIDIMANAGER
|
|
@ -36,10 +36,22 @@ inline short FtoS(register float in) {
|
|||
}
|
||||
return *ptr;
|
||||
}
|
||||
|
||||
inline ushort FtoUS(register float in) {
|
||||
ushort a;
|
||||
register ushort* ptr = &a;
|
||||
|
||||
asm {
|
||||
psq_st in, 0(ptr), 1, OS_FASTCAST_U16
|
||||
}
|
||||
return *ptr;
|
||||
}
|
||||
|
||||
#else
|
||||
inline uchar ToUint8(float in) { return static_cast< uchar >(in); }
|
||||
inline float ToReal32(uchar in) { return static_cast< float >(in); }
|
||||
inline short FtoS(float in) { return static_cast< short >(in); }
|
||||
inline ushort FtoUS(float in) { return static_cast< ushort >(in); }
|
||||
#endif
|
||||
|
||||
inline int ToInt32(float in) { return static_cast< int >(in); }
|
||||
|
|
|
@ -99,6 +99,7 @@ public:
|
|||
EOcclusionState x10dc_occlusionState;
|
||||
};
|
||||
|
||||
CAssetId GetAreaAssetId() const { return x84_mrea; }
|
||||
const CAreaFog* GetAreaFog() const { return x12c_postConstructed->x10c4_areaFog.get(); }
|
||||
CAreaFog* AreaFog() { return x12c_postConstructed->x10c4_areaFog.get(); }
|
||||
EOcclusionState GetOcclusionState() const { return x12c_postConstructed->x10dc_occlusionState; }
|
||||
|
|
|
@ -58,8 +58,12 @@ class CInGameTweakManager {
|
|||
public:
|
||||
CInGameTweakManager();
|
||||
|
||||
bool HasTweakValue(const rstl::string& name) const;
|
||||
const CTweakValue* GetTweakValue(const rstl::string& name) const;
|
||||
bool ReadFromMemoryCard(const rstl::string&);
|
||||
|
||||
static rstl::string GetIdentifierForMidiEvent(CAssetId world, CAssetId area, const rstl::string& midiObj);
|
||||
|
||||
private:
|
||||
rstl::vector< CTweakValue > x0_values;
|
||||
};
|
||||
|
|
|
@ -0,0 +1,29 @@
|
|||
#ifndef _CSCRIPTMIDI
|
||||
#define _CSCRIPTMIDI
|
||||
|
||||
#include "MetroidPrime/CEntity.hpp"
|
||||
|
||||
#include "Kyoto/Audio/CMidiManager.hpp"
|
||||
|
||||
class CScriptMidi : public CEntity {
|
||||
public:
|
||||
CScriptMidi(TUniqueId id, const CEntityInfo& info, const rstl::string& name, bool active,
|
||||
CAssetId csng, float, float, int);
|
||||
~CScriptMidi() override;
|
||||
|
||||
void Stop(CStateManager& mgr, float fadeTime);
|
||||
void Play(CStateManager& mgr, float fadeTime);
|
||||
void Accept(IVisitor& visitor) override;
|
||||
void AcceptScriptMsg(EScriptObjectMessage msg, TUniqueId objId, CStateManager& stateMgr) override;
|
||||
|
||||
private:
|
||||
TToken< CMidiManager::CMidiData > x34_song;
|
||||
CSfxHandle x3c_handle;
|
||||
float x40_fadeInTime;
|
||||
float x44_fadeOutTime;
|
||||
ushort x48_volume;
|
||||
|
||||
void StopInternal(float fadeTime);
|
||||
};
|
||||
|
||||
#endif // _CSCRIPTMIDI
|
|
@ -6,6 +6,7 @@ extern "C" {
|
|||
#endif
|
||||
|
||||
#define OS_FASTCAST_U8 2
|
||||
#define OS_FASTCAST_U16 3
|
||||
#define OS_FASTCAST_S16 5
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
|
|
@ -30,7 +30,7 @@ TUniqueId CScriptCameraWaypoint::GetRandomNextWaypointId(const CStateManager& mg
|
|||
rstl::vector< TUniqueId > candidateIds;
|
||||
|
||||
rstl::vector< SConnection >::const_iterator conn = x20_conns.begin();
|
||||
|
||||
|
||||
for (; conn != x20_conns.end(); ++conn) {
|
||||
if (conn->x0_state == kSS_Arrived && conn->x4_msg == kSM_Next) {
|
||||
TUniqueId uid = mgr.GetIdForScript(conn->x8_objId);
|
||||
|
|
|
@ -0,0 +1,79 @@
|
|||
#include "MetroidPrime/ScriptObjects/CScriptMidi.hpp"
|
||||
|
||||
#include "MetroidPrime/CGameArea.hpp"
|
||||
#include "MetroidPrime/CInGameTweakManager.hpp"
|
||||
#include "MetroidPrime/CWorld.hpp"
|
||||
|
||||
CScriptMidi::CScriptMidi(TUniqueId id, const CEntityInfo& info, const rstl::string& name,
|
||||
bool active, CAssetId csng, float fadeIn, float fadeOut, int volume)
|
||||
: CEntity(id, info, active, name)
|
||||
, x34_song(gpSimplePool->GetObj(SObjectTag('CSNG', csng)))
|
||||
, x3c_handle()
|
||||
, x40_fadeInTime(fadeIn)
|
||||
, x44_fadeOutTime(fadeOut)
|
||||
, x48_volume(volume) {}
|
||||
|
||||
void CScriptMidi::Accept(IVisitor& visitor) { visitor.Visit(*this); }
|
||||
|
||||
void CScriptMidi::AcceptScriptMsg(EScriptObjectMessage msg, TUniqueId objId,
|
||||
CStateManager& stateMgr) {
|
||||
CEntity::AcceptScriptMsg(msg, objId, stateMgr);
|
||||
switch (msg) {
|
||||
case kSM_Play:
|
||||
if (GetActive()) {
|
||||
Play(stateMgr, x40_fadeInTime);
|
||||
}
|
||||
break;
|
||||
case kSM_Stop:
|
||||
if (GetActive()) {
|
||||
Stop(stateMgr, x44_fadeOutTime);
|
||||
}
|
||||
break;
|
||||
case kSM_Deactivate:
|
||||
StopInternal(0.f);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
CScriptMidi::~CScriptMidi() { StopInternal(0.f); }
|
||||
|
||||
void CScriptMidi::Play(CStateManager& mgr, float fadeTime) {
|
||||
short volume = x48_volume;
|
||||
|
||||
const CWorld* wld = mgr.GetWorld();
|
||||
const CGameArea& area = wld->GetAreaAlways(GetAreaIdAlways());
|
||||
rstl::string twkName = CInGameTweakManager::GetIdentifierForMidiEvent(
|
||||
wld->GetWorldAssetId(), area.GetAreaAssetId(), x10_name);
|
||||
|
||||
if (gpTweakManager->HasTweakValue(twkName)) {
|
||||
const CTweakValue::Audio& audio = gpTweakManager->GetTweakValue(twkName)->GetAudio();
|
||||
x34_song = gpSimplePool->GetObj(SObjectTag('CSNG', audio.GetResId()));
|
||||
fadeTime = audio.GetFadeIn();
|
||||
volume = static_cast< short >(audio.GetVolume() * 127.f);
|
||||
}
|
||||
|
||||
x3c_handle = CMidiManager::Play(**x34_song, CCast::FtoUS(fadeTime * 1000.f), false, volume);
|
||||
}
|
||||
|
||||
void CScriptMidi::Stop(CStateManager& mgr, float fadeTime) {
|
||||
const CWorld* wld = mgr.GetWorld();
|
||||
const CGameArea& area = wld->GetAreaAlways(GetAreaIdAlways());
|
||||
const rstl::string twkName = CInGameTweakManager::GetIdentifierForMidiEvent(
|
||||
wld->GetWorldAssetId(), area.GetAreaAssetId(), x10_name);
|
||||
|
||||
if (gpTweakManager->HasTweakValue(twkName)) {
|
||||
const CTweakValue::Audio& audio = gpTweakManager->GetTweakValue(twkName)->GetAudio();
|
||||
fadeTime = audio.GetFadeOut();
|
||||
}
|
||||
|
||||
StopInternal(fadeTime);
|
||||
}
|
||||
|
||||
void CScriptMidi::StopInternal(float fadeTime) {
|
||||
if (x3c_handle != CSfxHandle::NullHandle()) {
|
||||
CMidiManager::Stop(x3c_handle, CCast::FtoUS(fadeTime * 1000.f));
|
||||
}
|
||||
x3c_handle.Clear();
|
||||
}
|
Loading…
Reference in New Issue