Match and link CMidiManager

This commit is contained in:
Phillip Stephens 2023-10-26 12:50:31 -07:00
parent 147cd11849
commit 6544d347a6
9 changed files with 254 additions and 22 deletions

View File

@ -12772,12 +12772,12 @@ LocateHandle__11CSfxManagerFs = .text:0x802E9660; // type:function size:0xAC sco
TurnOnChannel__11CSfxManagerFQ211CSfxManager12ESfxChannels = .text:0x802E970C; // type:function size:0x98 scope:global
TurnOffChannel__11CSfxManagerFi = .text:0x802E97A4; // type:function size:0x110 scope:global
SetChannel__11CSfxManagerFQ211CSfxManager12ESfxChannels = .text:0x802E98B4; // type:function size:0x50 scope:global
SetDuration__10CSfxHandleFf = .text:0x802E9904; // type:function size:0xB8 scope:global
StopSound__11CSfxManagerFRC10CSfxHandle = .text:0x802E99BC; // type:function size:0xF8 scope:global
SetDuration__11CSfxManagerFRC10CSfxHandlef = .text:0x802E9904; // type:function size:0xB8 scope:global
StopSound__11CSfxManagerF10CSfxHandle = .text:0x802E99BC; // type:function size:0xF8 scope:global
KillAll__11CSfxManagerFQ211CSfxManager12ESfxChannels = .text:0x802E9AB4; // type:function size:0xC0 scope:global
SfxSpan__11CSfxManagerF10CSfxHandleUc = .text:0x802E9B74; // type:function size:0xE4 scope:global
SfxVolume__11CSfxManagerF10CSfxHandleUc = .text:0x802E9C58; // type:function size:0xF0 scope:global
SfxStop__11CSfxManagerFRC10CSfxHandle = .text:0x802E9D48; // type:function size:0x2C scope:global
SfxStop__11CSfxManagerF10CSfxHandle = .text:0x802E9D48; // type:function size:0x2C scope:global
SfxStart__11CSfxManagerFUsssbsbi = .text:0x802E9D74; // type:function size:0x110 scope:global
RemoveEmitter__11CSfxManagerF10CSfxHandle = .text:0x802E9E84; // type:function size:0x2C scope:global
UpdateEmitter__11CSfxManagerF10CSfxHandleRC9CVector3fRC9CVector3fUc = .text:0x802E9EB0; // type:function size:0x130 scope:global
@ -14968,7 +14968,7 @@ __ct__10CARAMTokenFPvUii = .text:0x80358A4C; // type:function size:0xB0 scope:gl
__ct__10CARAMTokenFv = .text:0x80358AFC; // type:function size:0x68 scope:global
FMidiDataFactory__FRC10SObjectTagR12CInputStreamRC15CVParamTransfer = .text:0x80358B64; // type:function size:0x64 scope:global
__ct<Q212CMidiManager9CMidiData>__16CFactoryFnReturnFPQ212CMidiManager9CMidiData = .text:0x80358BC8; // type:function size:0xDC scope:global
fn_80358CA4 = .text:0x80358CA4; // type:function size:0xB8
__dt__52TObjOwnerDerivedFromIObj<Q212CMidiManager9CMidiData>Fv = .text:0x80358CA4; // type:function size:0xB8
GetIObjObjectFor__34TToken<Q212CMidiManager9CMidiData>FRCQ24rstl36auto_ptr<Q212CMidiManager9CMidiData> = .text:0x80358D5C; // type:function size:0x2C scope:global
GetNewDerivedObject__52TObjOwnerDerivedFromIObj<Q212CMidiManager9CMidiData>FRCQ24rstl36auto_ptr<Q212CMidiManager9CMidiData> = .text:0x80358D88; // type:function size:0x9C scope:global
__ct__Q212CMidiManager9CMidiDataFR12CInputStream = .text:0x80358E24; // type:function size:0x118 scope:global
@ -19530,8 +19530,8 @@ mpDefaultInvalidString__9CAudioSys = .bss:0x805A67CC; // type:object size:0x10 s
lbl_805A67DC = .bss:0x805A67DC; // type:object size:0x10
lbl_805A67FC = .bss:0x805A67FC; // type:object size:0x10
sLists__10CARAMToken = .bss:0x805A680C; // type:object size:0x1C scope:global
lbl_805A6828 = .bss:0x805A6828; // type:object size:0x38 data:4byte
lbl_805A6860 = .bss:0x805A6860; // type:object size:0x300 data:4byte
mMidiWrappers__12CMidiManager = .bss:0x805A6828; // type:object size:0x28 data:4byte
lbl_805A6860 = .bss:0x805A6860; // type:object size:0x300 align:32 data:4byte
lbl_805A6B60 = .bss:0x805A6B60; // type:object size:0x10 data:4byte
lbl_805A6B90 = .bss:0x805A6B90; // type:object size:0x10 data:4byte
lbl_805A6BA0 = .bss:0x805A6BA0; // type:object size:0x10 data:4byte

View File

@ -12787,12 +12787,12 @@ LocateHandle__11CSfxManagerFs = .text:0x802E9740; // type:function size:0xAC sco
TurnOnChannel__11CSfxManagerFQ211CSfxManager12ESfxChannels = .text:0x802E97EC; // type:function size:0x98 scope:global
TurnOffChannel__11CSfxManagerFi = .text:0x802E9884; // type:function size:0x110 scope:global
SetChannel__11CSfxManagerFQ211CSfxManager12ESfxChannels = .text:0x802E9994; // type:function size:0x50 scope:global
SetDuration__10CSfxHandleFf = .text:0x802E99E4; // type:function size:0xB8 scope:global
StopSound__11CSfxManagerFRC10CSfxHandle = .text:0x802E9A9C; // type:function size:0xF8 scope:global
SetDuration__11CSfxManagerFRC10CSfxHandlef = .text:0x802E99E4; // type:function size:0xB8 scope:global
StopSound__11CSfxManagerF10CSfxHandle = .text:0x802E9A9C; // type:function size:0xF8 scope:global
KillAll__11CSfxManagerFQ211CSfxManager12ESfxChannels = .text:0x802E9B94; // type:function size:0xC0 scope:global
SfxSpan__11CSfxManagerF10CSfxHandleUc = .text:0x802E9C54; // type:function size:0xE4 scope:global
SfxVolume__11CSfxManagerF10CSfxHandleUc = .text:0x802E9D38; // type:function size:0xF0 scope:global
SfxStop__11CSfxManagerFRC10CSfxHandle = .text:0x802E9E28; // type:function size:0x2C scope:global
SfxStop__11CSfxManagerF10CSfxHandle = .text:0x802E9E28; // type:function size:0x2C scope:global
SfxStart__11CSfxManagerFUsssbsbi = .text:0x802E9E54; // type:function size:0x110 scope:global
RemoveEmitter__11CSfxManagerF10CSfxHandle = .text:0x802E9F64; // type:function size:0x2C scope:global
UpdateEmitter__11CSfxManagerF10CSfxHandleRC9CVector3fRC9CVector3fUc = .text:0x802E9F90; // type:function size:0x130 scope:global
@ -14983,7 +14983,7 @@ __ct__10CARAMTokenFPvUii = .text:0x80358B50; // type:function size:0xB0 scope:gl
__ct__10CARAMTokenFv = .text:0x80358C00; // type:function size:0x68 scope:global
FMidiDataFactory__FRC10SObjectTagR12CInputStreamRC15CVParamTransfer = .text:0x80358C68; // type:function size:0x64 scope:global
__ct<Q212CMidiManager9CMidiData>__16CFactoryFnReturnFPQ212CMidiManager9CMidiData = .text:0x80358CCC; // type:function size:0xDC scope:global
fn_80358CA4 = .text:0x80358DA8; // type:function size:0xB8 scope:global
__dt__52TObjOwnerDerivedFromIObj<Q212CMidiManager9CMidiData>Fv = .text:0x80358DA8; // type:function size:0xB8 scope:global
GetIObjObjectFor__34TToken<Q212CMidiManager9CMidiData>FRCQ24rstl36auto_ptr<Q212CMidiManager9CMidiData> = .text:0x80358E60; // type:function size:0x2C scope:global
GetNewDerivedObject__52TObjOwnerDerivedFromIObj<Q212CMidiManager9CMidiData>FRCQ24rstl36auto_ptr<Q212CMidiManager9CMidiData> = .text:0x80358E8C; // type:function size:0x9C scope:global
__ct__Q212CMidiManager9CMidiDataFR12CInputStream = .text:0x80358F28; // type:function size:0x118 scope:global
@ -19573,7 +19573,7 @@ lbl_805A67DC = .bss:0x805A69BC; // type:object size:0x30 scope:global
lbl_805A67EC = .bss:0x805A69CC; // type:object size:0x10 scope:global
lbl_805A67FC = .bss:0x805A69DC; // type:object size:0x10 scope:global
sLists__10CARAMToken = .bss:0x805A69EC; // type:object size:0x1C scope:global
lbl_805A6828 = .bss:0x805A6A08; // type:object size:0x38 scope:global data:4byte
mMidiWrappers__12CMidiManager = .bss:0x805A6A08; // type:object size:0x38 scope:global data:4byte
lbl_805A6860 = .bss:0x805A6A40; // type:object size:0x300 scope:global data:4byte
lbl_805A6B60 = .bss:0x805A6D40; // type:object size:0x50 scope:global data:4byte
lbl_805A6B90 = .bss:0x805A6D70; // type:object size:0x10 scope:global data:4byte

View File

@ -953,7 +953,7 @@ config.libs = [
Object(NonMatching, "Kyoto/Animation/CSkinnedModelWithAvgNormals.cpp"),
Object(Matching, "Kyoto/CTimeProvider.cpp"),
Object(Matching, "Kyoto/CARAMToken.cpp"),
Object(NonMatching, "Kyoto/Audio/CMidiManager.cpp"),
Object(Matching, "Kyoto/Audio/CMidiManager.cpp"),
Object(Matching, "Kyoto/Text/CFontImageDef.cpp"),
Object(NonMatching, "Kyoto/Text/CImageInstruction.cpp"),
Object(NonMatching, "Kyoto/Text/CTextRenderBuffer.cpp"),

View File

@ -100,6 +100,10 @@ public:
static void S3dAddEmitter(SND_FXID fxid, const CVector3f& pos, const CVector3f& dir,
const bool b1, const bool b2, short, int);
static u32 SeqPlayEx(unsigned short, unsigned short, void*, SND_PLAYPARA*, unsigned char);
static void SeqStop(u32);
static void SeqVolume(u8, u16, u32, u8);
static bool mInitialized;
static bool mIsListenerActive;
static bool mVerbose;

View File

@ -3,13 +3,54 @@
#include "Kyoto/Audio/CSfxHandle.hpp"
#include <rstl/auto_ptr.hpp>
#include <rstl/reserved_vector.hpp>
class CInputStream;
class CMidiManager {
public:
class CMidiWrapper {};
class CMidiData {};
class CMidiWrapper {
public:
CMidiWrapper();
const CSfxHandle& GetManagerHandle() const;
const u32 GetAudioSysHandle() const;
const bool IsAvailable() const;
static CSfxHandle Play(const CMidiData&, unsigned short fadeTime, bool stopExisting, short volume);
void SetAvailable(const bool v);
void SetAudioSysHandle(const u32 handle);
const short GetSongId() const;
void SetMidiHandle(const CSfxHandle& handle);
void SetSongId(const short id);
private:
u32 x0_;
CSfxHandle x4_;
short x8_;
bool xa_;
};
class CMidiData {
public:
CMidiData(CInputStream& in);
const short GetSongId() const { return x0_songId; }
const short GetGroupId() const { return x2_groupId; }
const int GetSetupId() const { return x4_setupId; }
uchar* GetData() const { return x8_data.get(); }
private:
short x0_songId;
short x2_groupId;
int x4_setupId;
rstl::auto_ptr< uchar > x8_data;
};
static CSfxHandle Play(const CMidiData&, unsigned short fadeTime, bool stopExisting,
short volume);
static void Stop(const CSfxHandle&, unsigned short);
static void StopAll();
static CSfxHandle LocateHandle();
static rstl::reserved_vector< CMidiWrapper, 3 > mMidiWrappers;
};
#endif // _CMIDIMANAGER

View File

@ -8,11 +8,11 @@ public:
CSfxHandle() : mID(0) {}
CSfxHandle(uint value);
uint GetIndex() const { return mID & 0xFF; }
int GetIndex() const { return mID & 0xFFF; }
static CSfxHandle NullHandle() { return CSfxHandle(); }
void operator=(const CSfxHandle& other) { mID = other.mID; }
bool operator==(const CSfxHandle& other) { return mID == other.mID; }
bool operator!=(const CSfxHandle& other) { return mID != other.mID; }
const bool operator==(const CSfxHandle& other) const { return mID == other.mID; }
const bool operator!=(const CSfxHandle& other) const { return mID != other.mID; }
operator bool() const { return mID != 0; }
void Clear() { mID = 0; }

View File

@ -211,9 +211,12 @@ public:
static CSfxHandle SfxStart(ushort id, short vol, short pan, bool useAcoustics,
short prio = kMaxPriority, bool looped = false,
int areaId = kAllAreas);
static void SfxStop(CSfxHandle handle);
static void SfxVolume(CSfxHandle handle, uchar volume);
static void SfxSpan(CSfxHandle, uchar);
static bool IsPlaying(const CSfxHandle& handle);
static void StopSound(CSfxHandle handle);
static void SetChannel(ESfxChannels);
static void KillAll(ESfxChannels);

View File

@ -0,0 +1,128 @@
#include "Kyoto/Audio/CSfxHandle.hpp"
#include <Kyoto/Audio/CMidiManager.hpp>
#include "Kyoto/Audio/CAudioSys.hpp"
#include <Kyoto/CFactoryMgr.hpp>
#include <Kyoto/Streams/CInputStream.hpp>
rstl::reserved_vector< CMidiManager::CMidiWrapper, 3 > CMidiManager::mMidiWrappers;
CMidiManager::CMidiWrapper::CMidiWrapper() : x0_(0), xa_(1) {}
const CSfxHandle& CMidiManager::CMidiWrapper::GetManagerHandle() const { return x4_; }
const u32 CMidiManager::CMidiWrapper::GetAudioSysHandle() const { return x0_; }
const bool CMidiManager::CMidiWrapper::IsAvailable() const { return xa_; }
const short CMidiManager::CMidiWrapper::GetSongId() const { return x8_; }
void CMidiManager::CMidiWrapper::SetAvailable(const bool v) { xa_ = v; }
void CMidiManager::CMidiWrapper::SetAudioSysHandle(const u32 handle) { x0_ = handle; }
void CMidiManager::CMidiWrapper::SetMidiHandle(const CSfxHandle& handle) { x4_ = handle; }
void CMidiManager::CMidiWrapper::SetSongId(const short id) { x8_ = id; }
CSfxHandle CMidiManager::Play(const CMidiData& data, unsigned short fadeTime, bool stopExisting,
short volume) {
bool bVar2 = false;
u32 uVar6 = 0;
CSfxHandle handle = LocateHandle();
if (!handle) {
return CSfxHandle();
}
CMidiWrapper& wrapper = mMidiWrappers[handle.GetIndex()];
wrapper.SetAvailable(false);
wrapper.SetMidiHandle(handle);
if (stopExisting) {
for (int i = 0; i < mMidiWrappers.size(); ++i) {
if (mMidiWrappers[i].IsAvailable()) {
continue;
}
if (data.GetSongId() == mMidiWrappers[i].GetSongId()) {
bVar2 = true;
uVar6 = mMidiWrappers[i].GetAudioSysHandle();
mMidiWrappers[i].SetAvailable(true);
} else {
Stop(mMidiWrappers[i].GetManagerHandle(), fadeTime);
}
}
}
if (bVar2) {
wrapper.SetAudioSysHandle(uVar6);
wrapper.SetSongId(data.GetSongId());
} else {
u32 tmp = CAudioSys::SeqPlayEx(data.GetGroupId(), data.GetSongId(), data.GetData(), nullptr, 0);
if (fadeTime != 0) {
CAudioSys::SeqVolume(0, 0, tmp, 0);
}
CAudioSys::SeqVolume(volume, fadeTime, tmp, 0);
wrapper.SetAudioSysHandle(tmp);
wrapper.SetSongId(data.GetSongId());
}
return handle;
}
void CMidiManager::Stop(const CSfxHandle& handle, ushort fadeTime) {
if (!handle) {
return;
}
if (handle != mMidiWrappers[handle.GetIndex()].GetManagerHandle()) {
return;
}
u32 sysHandle = mMidiWrappers[handle.GetIndex()].GetAudioSysHandle();
if (fadeTime == 0) {
CAudioSys::SeqStop(sysHandle);
} else {
CAudioSys::SeqVolume(0, fadeTime, sysHandle, 1);
}
mMidiWrappers[handle.GetIndex()].SetAvailable(true);
}
void CMidiManager::StopAll() {
for (int i = 0; i < mMidiWrappers.size(); ++i) {
if (!mMidiWrappers[i].IsAvailable()) {
Stop(mMidiWrappers[i].GetManagerHandle(), 0);
}
}
}
CSfxHandle CMidiManager::LocateHandle() {
for (int i = 0; i < mMidiWrappers.size(); ++i) {
if (mMidiWrappers[i].IsAvailable()) {
return CSfxHandle(i);
}
}
if (mMidiWrappers.size() == mMidiWrappers.capacity()) {
return CSfxHandle();
}
mMidiWrappers.push_back(CMidiWrapper());
return CSfxHandle(mMidiWrappers.size() - 1);
}
CMidiManager::CMidiData::CMidiData(CInputStream& in)
: x0_songId(-1), x2_groupId(-1), x4_setupId(-1) {
in.ReadLong();
x0_songId = in.ReadLong();
x2_groupId = in.ReadLong();
x4_setupId = in.ReadLong();
int len = in.ReadInt32();
x8_data = rs_new uchar[len];
in.Get(x8_data.get(), len);
}
#pragma inline_max_size(250)
CFactoryFnReturn FMidiDataFactory(const SObjectTag& tag, CInputStream& in, const CVParamTransfer&) {
return rs_new CMidiManager::CMidiData(in);
}

View File

@ -1,6 +1,7 @@
#include "Kyoto/Alloc/CMemory.hpp"
#include "Kyoto/Audio/CAudioSys.hpp"
#include "Kyoto/Audio/CSfxHandle.hpp"
#include "dolphin/types.h"
#include "musyx/musyx.h"
#include "rstl/vector.hpp"
#include <Kyoto/Audio/CSfxManager.hpp>
@ -208,7 +209,7 @@ short CSfxManager::CSfxWrapper::GetAudible(const CVector3f&) { return kSA_Aud3;
const SND_VOICEID CSfxManager::CSfxWrapper::GetVoice() const { return x1c_voiceHandle; }
void CSfxManager::CSfxWrapper::SetVolume(short vol) { x20_vol = vol; }
void CSfxManager::CSfxWrapper::SetVolume(const short vol) { x20_vol = vol; }
void CSfxManager::CSfxWrapper::UpdateEmitterSilent() { CAudioSys::SfxVolume(x1c_voiceHandle, 1); }
@ -264,7 +265,8 @@ void CSfxManager::UpdateListener(const CVector3f& pos, const CVector3f& dir, con
}
CSfxHandle CSfxManager::AddEmitter(const SND_FXID id, const CVector3f& pos, const CVector3f& dir,
const bool useAcoustics, const bool looped, const short prio, const int areaId) {
const bool useAcoustics, const bool looped, const short prio,
const int areaId) {
CAudioSys::C3DEmitterParmData emitterParm;
emitterParm.x24_sfxId = id;
emitterParm.x29_prio = prio;
@ -274,8 +276,8 @@ CSfxHandle CSfxManager::AddEmitter(const SND_FXID id, const CVector3f& pos, cons
}
CSfxHandle CSfxManager::AddEmitter(const SND_FXID id, const CVector3f& pos, const CVector3f& dir,
const uchar vol, const bool useAcoustics, const bool looped, const short prio,
const int areaId) {
const uchar vol, const bool useAcoustics, const bool looped,
const short prio, const int areaId) {
CAudioSys::C3DEmitterParmData emitterParm(150.f, 0.1f, 1, vol > 20 ? vol : 21);
emitterParm.x0_pos = pos;
emitterParm.xc_dir = dir;
@ -286,6 +288,60 @@ CSfxHandle CSfxManager::AddEmitter(const SND_FXID id, const CVector3f& pos, cons
CSfxHandle CSfxManager::AddEmitter(CAudioSys::C3DEmitterParmData& parmData, const bool useAcoustics,
const short prio, const bool looped, const int areaId) {}
void CSfxManager::UpdateEmitter(CSfxHandle handle, const CVector3f& pos, const CVector3f& dir,
uchar maxVol) {}
void CSfxManager::RemoveEmitter(CSfxHandle handle) { StopSound(handle); }
CSfxHandle CSfxManager::SfxStart(ushort id, short vol, short pan, bool useAcoustics, short prio,
bool looped, int areaId) {}
void CSfxManager::SfxStop(CSfxHandle handle) { StopSound(handle); }
void CSfxManager::SfxVolume(CSfxHandle handle, uchar volume) {
if (handle.GetIndex() > mChannels[mCurrentChannel].x48_.size()) {
} else {
CSfxWrapper* wrapper = (CSfxWrapper*)mChannels[mCurrentChannel].x48_[handle.GetIndex()];
if (wrapper == nullptr || wrapper->GetSfxHandle() != handle) {
return;
}
wrapper->SetVolume(volume);
if (wrapper->IsPlaying()) {
CAudioSys::SfxVolume(wrapper->GetVoice(), volume);
}
}
}
void CSfxManager::SfxSpan(CSfxHandle handle, uchar span) {}
void CSfxManager::KillAll(ESfxChannels channel) {
CSfxChannel& chan = mChannels[channel];
for (int i = 0; i < chan.x48_.size(); ++i) {
CBaseSfxWrapper* wrapper = chan.x48_[i];
if (wrapper != NULL && wrapper->IsPlaying()) {
wrapper->Stop();
}
if (wrapper) {
wrapper->Release();
}
chan.x48_[i] = nullptr;
}
}
ushort CSfxManager::TranslateSFXID(ushort id) {
if (mTranslationTable == nullptr || id >= mTranslationTable->size()) {
return -1;
}
short ret = (*mTranslationTable)[id];
if (ret < 0) {
return -1;
}
return ret;
}
#pragma inline_max_size(250)
CFactoryFnReturn FAudioTranslationTableFactory(const SObjectTag& obj, CInputStream& in,
const CVParamTransfer& xfer) {