Library/Audio: Implement al::trySetAudioInfo and al::tryFindAudioInfo (#951)

This commit is contained in:
Narr the Reg 2026-03-12 16:56:52 -06:00 committed by GitHub
parent 11afa7251e
commit fc33c409ec
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 143 additions and 41 deletions

View file

@ -224041,13 +224041,13 @@ Library/Audio/AudioEventController.o:
label:
- _ZN2al21AudioSoundArchiveInfoC1Ev
- _ZN2al21AudioSoundArchiveInfoC2Ev
status: NotDecompiled
status: Matching
- offset: 0x811904
size: 8
label:
- _ZN2al24AudioResourceLoadingInfoC1Ev
- _ZN2al24AudioResourceLoadingInfoC2Ev
status: NotDecompiled
status: Matching
- offset: 0x81190c
size: 72
label: _ZN2al26AudioAddonSoundArchiveInfo10createInfoERKNS_9ByamlIterE
@ -224055,16 +224055,16 @@ Library/Audio/AudioEventController.o:
- offset: 0x811954
size: 108
label: _ZN2al21AudioSoundArchiveInfo10createInfoERKNS_9ByamlIterE
status: NotDecompiled
status: Matching
- offset: 0x8119c0
size: 332
label: _ZN2al19createAudioInfoListINS_26AudioAddonSoundArchiveInfoEEEPNS_22AudioInfoListWithPartsIT_EERKNS_9ByamlIterEi
status: NotDecompiled
status: Matching
lazy: true
- offset: 0x811b0c
size: 344
label: _ZN2al24AudioResourceLoadingInfo10createInfoEPKNS_8ResourceE
status: NotDecompiled
status: Matching
- offset: 0x811c64
size: 12
label: _ZN2al26AudioAddonSoundArchiveInfo11compareInfoEPKS0_S2_
@ -224072,7 +224072,7 @@ Library/Audio/AudioEventController.o:
- offset: 0x811c70
size: 104
label: _ZN2al26AudioInfoListCreateFunctorINS_26AudioAddonSoundArchiveInfoEE30tryCreateAudioInfoAndSetToListERKNS_9ByamlIterE
status: NotDecompiled
status: Matching
lazy: true
- offset: 0x811cd8
size: 76

View file

@ -1,5 +1,7 @@
#include "Library/Audio/AudioEventController.h"
#include "Library/Audio/AudioInfo.h"
#include "Library/Resource/Resource.h"
#include "Library/Yaml/ByamlIter.h"
namespace al {
@ -20,4 +22,36 @@ s32 AudioAddonSoundArchiveInfo::compareInfo(const AudioAddonSoundArchiveInfo* lh
return strcmp(lhs->name, rhs->name);
}
AudioSoundArchiveInfo::AudioSoundArchiveInfo() = default;
AudioSoundArchiveInfo* AudioSoundArchiveInfo::createInfo(const ByamlIter& iter) {
AudioSoundArchiveInfo* info = new AudioSoundArchiveInfo();
ByamlIter addonIter;
if (!iter.tryGetIterByKey(&addonIter, "AddonSoundArchiveInfoList"))
info->addonInfo = nullptr;
// BUG: addonIter can be invalid. It should have returned early on the previous check
info->addonInfo = createAudioInfoList<AudioAddonSoundArchiveInfo>(addonIter, 0);
return info;
}
AudioResourceLoadingInfo::AudioResourceLoadingInfo() = default;
AudioResourceLoadingInfo* AudioResourceLoadingInfo::createInfo(const Resource* resource) {
AudioResourceLoadingInfo* info = new AudioResourceLoadingInfo();
if (resource->isExistFile("SeSoundArchiveInfo.byml")) {
ByamlIter iter(static_cast<const u8*>(resource->getOtherFile("SeSoundArchiveInfo.byml")));
info->seInfo = AudioSoundArchiveInfo::createInfo(iter);
}
if (resource->isExistFile("BgmSoundArchiveInfo.byml")) {
ByamlIter iter(static_cast<const u8*>(resource->getOtherFile("BgmSoundArchiveInfo.byml")));
info->bgmInfo = AudioSoundArchiveInfo::createInfo(iter);
}
return info;
}
} // namespace al

View file

@ -4,6 +4,10 @@
namespace al {
class ByamlIter;
class Resource;
template <typename T>
class AudioInfoListWithParts;
struct AudioAddonSoundArchiveInfo {
AudioAddonSoundArchiveInfo();
@ -17,4 +21,25 @@ struct AudioAddonSoundArchiveInfo {
static_assert(sizeof(AudioAddonSoundArchiveInfo) == 0x8);
struct AudioSoundArchiveInfo {
AudioSoundArchiveInfo();
static AudioSoundArchiveInfo* createInfo(const ByamlIter& iter);
AudioInfoListWithParts<AudioAddonSoundArchiveInfo>* addonInfo = nullptr;
};
static_assert(sizeof(AudioSoundArchiveInfo) == 0x8);
struct AudioResourceLoadingInfo {
AudioResourceLoadingInfo();
static AudioResourceLoadingInfo* createInfo(const Resource* resource);
AudioSoundArchiveInfo* seInfo = nullptr;
AudioSoundArchiveInfo* bgmInfo = nullptr;
};
static_assert(sizeof(AudioResourceLoadingInfo) == 0x10);
} // namespace al

View file

@ -10,7 +10,7 @@ class ByamlIter;
class AudioInfoListCreateFunctorBase;
template <typename T>
struct AudioInfoList;
class AudioInfoList;
class AudioInfoListCreateFunctorBase {
public:
@ -33,7 +33,7 @@ public:
if (!info)
return false;
return mAudioInfoList->list->pushBack(info);
return mAudioInfoList->setInfo(info);
}
private:
@ -42,25 +42,65 @@ private:
};
template <typename T>
struct AudioInfoList {
class AudioInfoList {
public:
static s32 compareInfoAndKey(const T* info, const char* key) { return strcmp(info->name, key); }
sead::PtrArray<T>* list;
AudioInfoList() = default;
void init(s32 listSize) {
mIsLinearSearch = false;
mList = new sead::PtrArray<const T>();
mList->allocBuffer((listSize == 0) ? 1 : listSize, nullptr);
}
bool setInfo(const T* audioInfo) const { return mList->pushBack(audioInfo); }
void sort() const {
if (mList->size() >= 10)
mList->heapSort(T::compareInfo);
else
mList->sort(T::compareInfo);
}
private:
sead::PtrArray<const T>* mList;
bool mIsLinearSearch;
};
template <typename T>
struct AudioInfoListWithParts : public AudioInfoList<T> {
s32 tryGetInfoIndex(const char*) const;
T* tryFindInfo(const char*) const;
class AudioInfoListWithParts : public AudioInfoList<T> {
public:
AudioInfoListWithParts() = default;
s32 getPartsSize() const {
if (!parts)
return 0;
return parts->size();
s32 tryGetInfoIndex(const char* key) const;
const T* tryFindInfo(const char* key) const;
void init(s32 listSize, s32 maxNumParts) {
AudioInfoList<T>::init(listSize);
mParts = nullptr;
if (maxNumParts != 0) {
mParts = new sead::PtrArray<AudioInfoList<T>>();
mParts->allocBuffer(maxNumParts, nullptr);
}
}
bool _8;
sead::PtrArray<AudioInfoList<T>>* parts;
void sort() const {
AudioInfoList<T>::sort();
for (s32 i = 0; i < getPartsSize(); i++)
mParts->at(i)->sort();
}
s32 getPartsSize() const {
if (!mParts)
return 0;
return mParts->size();
}
private:
sead::PtrArray<AudioInfoList<T>>* mParts;
};
template <typename T>
@ -68,33 +108,36 @@ AudioInfoListWithParts<T>* createAudioInfoList(const ByamlIter& iter, s32 maxNum
AudioInfoListWithParts<T>* audioInfoList = new AudioInfoListWithParts<T>;
s32 listSize = alAudioInfoListFunction::getCreateAudioInfoListSize(iter, 0);
audioInfoList->_8 = false;
audioInfoList->list = new sead::PtrArray<T>();
audioInfoList->list->allocBuffer((listSize == 0) ? 1 : listSize, nullptr);
audioInfoList->parts = nullptr;
if (maxNumParts != 0) {
audioInfoList->parts = new sead::PtrArray<AudioInfoList<T>>();
audioInfoList->parts->allocBuffer(maxNumParts, nullptr);
}
audioInfoList->init(listSize, maxNumParts);
AudioInfoListCreateFunctor<T> functor(audioInfoList, T::createInfo);
alAudioInfoListFunction::createAudioInfoAndSetToList(&functor, iter);
audioInfoList->sort();
if (audioInfoList->list->size() >= 10)
audioInfoList->list->heapSort(T::compareInfo);
else
audioInfoList->list->sort(T::compareInfo);
for (s32 i = 0; i < audioInfoList->getPartsSize(); i++) {
sead::PtrArray<T>* partsList = audioInfoList->parts->at(i)->list;
if (partsList->size() >= 10)
partsList->heapSort(T::compareInfo);
else
partsList->sort(T::compareInfo);
}
return audioInfoList;
}
template <typename T>
bool trySetAudioInfo(const AudioInfoListWithParts<T>* audioInfoList, const T* audioInfo,
bool disableSort) {
if (!audioInfoList || !audioInfo)
return false;
if (!audioInfoList->setInfo(audioInfo))
return false;
if (!disableSort)
audioInfoList->sort();
return true;
}
template <typename T>
const T* tryFindAudioInfo(const AudioInfoListWithParts<T>* audioInfoList, const char* name) {
if (!audioInfoList || !name)
return nullptr;
return audioInfoList->tryFindInfo(name);
}
} // namespace al