diff --git a/include/JSystem/JAudio/JASSimpleWaveBank.h b/include/JSystem/JAudio/JASSimpleWaveBank.h index 633167735..6aacc958f 100644 --- a/include/JSystem/JAudio/JASSimpleWaveBank.h +++ b/include/JSystem/JAudio/JASSimpleWaveBank.h @@ -6,7 +6,7 @@ #include "dolphin/types.h" namespace JASystem { - class TSimpleWaveBank : public TWaveBank, TWaveArc { + class TSimpleWaveBank : public TWaveBank, public TWaveArc { public: class TWaveHandle : public JASystem::TWaveHandle { public: diff --git a/include/JSystem/JAudio/JASWSParser.h b/include/JSystem/JAudio/JASWSParser.h index 2e29c5365..f49613cae 100644 --- a/include/JSystem/JAudio/JASWSParser.h +++ b/include/JSystem/JAudio/JASWSParser.h @@ -7,17 +7,61 @@ namespace JASystem { class TBasicWaveBank; class TSimpleWaveBank; namespace WSParser { - struct TCtrl; - struct TCtrlGroup; - struct TCtrlScene; - struct TCtrlWave; - struct TWave; - struct TWaveArchive; - struct TWaveArchiveBank; + struct TCtrl { + /* 0x00 */ u32 mMagic; + /* 0x04 */ u32 mWaveCount; + /* 0x08 */ u32 mCtrlWaveOffsets[1]; + }; + struct TCtrlGroup { + /* 0x00 */ u32 mMagic; + /* 0x04 */ u8 field_0x4[0x08 - 0x04]; + /* 0x08 */ u32 mCtrlGroupCount; + /* 0x0C */ u32 mCtrlSceneOffsets[1]; + }; + struct TCtrlScene { + /* 0x00 */ u32 mMagic; + /* 0x04 */ u8 field_0x4[0x0C - 0x04]; + /* 0x0C */ u32 mCtrlOffset; + }; + struct TCtrlWave { + /* 0x00 */ u32 field_0x0; + }; + struct THeader { + /* 0x00 */ u8 field_0x0[0x10]; + /* 0x10 */ u32 mArchiveBankOffset; + /* 0x14 */ u32 mCtrlGroupOffset; + }; + struct TWave { + /* 0x00 */ u8 field_0x0; + /* 0x01 */ u8 field_0x1; + /* 0x02 */ u8 field_0x2; + /* 0x04 */ f32 field_0x4; + /* 0x08 */ u32 mOffset; + /* 0x0C */ u32 field_0xc; + /* 0x10 */ u32 field_0x10; + /* 0x14 */ u32 field_0x14; + /* 0x18 */ u32 field_0x18; + /* 0x1C */ u32 field_0x1c; + /* 0x20 */ s16 field_0x20; + /* 0x22 */ s16 field_0x22; + /* 0x24 */ u8 field_0x24[0x28 - 0x24]; + /* 0x28 */ int field_0x28; + }; + struct TWaveArchive { + /* 0x00 */ char mFileName[0x74]; + /* 0x74 */ u32 mWaveOffsets[1]; + }; + struct TWaveArchiveBank { + /* 0x00 */ u32 mMagic; + /* 0x04 */ u8 field_0x4[0x08 - 0x04]; + /* 0x08 */ u32 mArchiveOffsets[1]; + }; u32 getGroupCount(void*); TBasicWaveBank* createBasicWaveBank(void*); TSimpleWaveBank* createSimpleWaveBank(void*); + + extern u32 sUsedHeapSize; } } diff --git a/include/JSystem/JAudio/JASWaveBank.h b/include/JSystem/JAudio/JASWaveBank.h index b7b529425..8653864fe 100644 --- a/include/JSystem/JAudio/JASWaveBank.h +++ b/include/JSystem/JAudio/JASWaveBank.h @@ -9,14 +9,14 @@ namespace JASystem { class TWaveArc; struct TWaveInfo { - /* 0x00 */ u8 field_0x0; + /* 0x00 */ u8 mBlockType; /* 0x01 */ u8 field_0x1; /* 0x02 */ u8 field_0x2; /* 0x04 */ f32 field_0x4; /* 0x08 */ int mWavePtrOffs; /* 0x0C */ int field_0xc; /* 0x10 */ int field_0x10; - /* 0x14 */ int field_0x14; + /* 0x14 */ int mBlockCount; /* 0x18 */ int field_0x18; /* 0x1C */ int field_0x1c; /* 0x20 */ s16 field_0x20; diff --git a/src/JSystem/JAudio/JASWSParser.cpp b/src/JSystem/JAudio/JASWSParser.cpp index 95f0b5308..8c8b587b9 100644 --- a/src/JSystem/JAudio/JASWSParser.cpp +++ b/src/JSystem/JAudio/JASWSParser.cpp @@ -4,19 +4,117 @@ // #include "JSystem/JAudio/JASWSParser.h" -#include "dolphin/types.h" +#include "JSystem/JAudio/JASBasicWaveBank.h" +#include "JSystem/JAudio/JASSimpleWaveBank.h" +#include "JSystem/JKernel/JKRHeap.h" +#include "JSystem/JSupport/JSupport.h" + +u32 JASystem::WSParser::sUsedHeapSize; /* 80286BF4-80286C1C .text getGroupCount__Q28JASystem8WSParserFPv */ -u32 JASystem::WSParser::getGroupCount(void*) { - /* Nonmatching */ +u32 JASystem::WSParser::getGroupCount(void* stream) { + THeader* header = (THeader*)stream; + return JSUConvertOffsetToPtr(header, header->mCtrlGroupOffset)->mCtrlGroupCount; } /* 80286C1C-80286E38 .text createBasicWaveBank__Q28JASystem8WSParserFPv */ -JASystem::TBasicWaveBank* JASystem::WSParser::createBasicWaveBank(void*) { +JASystem::TBasicWaveBank* JASystem::WSParser::createBasicWaveBank(void* stream) { /* Nonmatching */ + JKRHeap* heap = TWaveBank::getCurrentHeap(); + const u32 priorFreeSize = heap->getFreeSize(); + const THeader* header = (THeader*)stream; + TBasicWaveBank* bank = new (heap, 0) TBasicWaveBank(); + if (bank == NULL) { + return NULL; + } + + const TCtrlGroup* ctrlGroupRaw = JSUConvertOffsetToPtr(header, header->mCtrlGroupOffset); + bank->setGroupCount(ctrlGroupRaw->mCtrlGroupCount); + u32 maxSize = 0; + for (int groupIndex = 0; groupIndex < ctrlGroupRaw->mCtrlGroupCount; groupIndex++) { + TCtrlScene* ctrlSceneRaw = JSUConvertOffsetToPtr(header, ctrlGroupRaw->mCtrlSceneOffsets[groupIndex]); + TCtrl* ctrlRaw = JSUConvertOffsetToPtr(header, ctrlSceneRaw->mCtrlOffset); + TBasicWaveBank::TWaveGroup* waveGroup = bank->getWaveGroup(groupIndex); + TWaveArchiveBank* archiveBankRaw = JSUConvertOffsetToPtr(header, header->mArchiveBankOffset); + TWaveArchive* archiveRaw = JSUConvertOffsetToPtr(header, archiveBankRaw->mArchiveOffsets[groupIndex]); + waveGroup->setWaveCount(ctrlRaw->mWaveCount); + for (int waveIndex = 0; waveIndex < ctrlRaw->mWaveCount; waveIndex++) { + TWave* waveRaw = JSUConvertOffsetToPtr(header, archiveRaw->mWaveOffsets[waveIndex]); + TWaveInfo info; + + info.mBlockType = waveRaw->field_0x0; + info.field_0x1 = waveRaw->field_0x1; + info.field_0x2 = waveRaw->field_0x2; + info.field_0x4 = waveRaw->field_0x4; + info.mWavePtrOffs = waveRaw->mOffset; + info.field_0xc = waveRaw->field_0xc; + info.field_0x10 = waveRaw->field_0x10; + info.mBlockCount = waveRaw->field_0x14; + info.field_0x18 = waveRaw->field_0x18; + info.field_0x1c = waveRaw->field_0x1c; + info.field_0x20 = waveRaw->field_0x20; + info.field_0x22 = waveRaw->field_0x22; + info.field_0x28 = waveRaw->field_0x28; + TCtrlWave* ctrlWaveRaw = JSUConvertOffsetToPtr(header, ctrlRaw->mCtrlWaveOffsets[waveIndex]); + u32 size = ctrlWaveRaw->field_0x0 & 0xFFFF; + waveGroup->setWaveInfo(waveIndex, size, info); + if (maxSize < size) { + maxSize = size; + } + } + waveGroup->setFileName(archiveRaw->mFileName); + } + bank->setWaveTableSize(maxSize + 1); + sUsedHeapSize += priorFreeSize - heap->getFreeSize(); + return bank; } /* 80286E38-80287048 .text createSimpleWaveBank__Q28JASystem8WSParserFPv */ -JASystem::TSimpleWaveBank* JASystem::WSParser::createSimpleWaveBank(void*) { +JASystem::TSimpleWaveBank* JASystem::WSParser::createSimpleWaveBank(void* stream) { /* Nonmatching */ + JKRHeap* heap = TWaveBank::getCurrentHeap(); + const u32 priorFreeSize = heap->getFreeSize(); + const THeader* header = (THeader*)stream; + const TCtrlGroup* ctrlGroupRaw = JSUConvertOffsetToPtr(header, header->mCtrlGroupOffset); + if (ctrlGroupRaw->mCtrlGroupCount != 1) { + return NULL; + } + TSimpleWaveBank* bank = new (heap, 0) TSimpleWaveBank(); + if (bank == NULL) { + return NULL; + } + u32 maxSize = 0; + + const TCtrlScene* ctrlSceneRaw = JSUConvertOffsetToPtr(header, ctrlGroupRaw->mCtrlSceneOffsets[0]); + const TCtrl* ctrlRaw = JSUConvertOffsetToPtr(header, ctrlSceneRaw->mCtrlOffset); + const TWaveArchiveBank* archiveBankRaw = JSUConvertOffsetToPtr(header, header->mArchiveBankOffset); + const TWaveArchive* archiveRaw = JSUConvertOffsetToPtr(header, archiveBankRaw->mArchiveOffsets[0]); + for (int waveIndex = 0; waveIndex < ctrlRaw->mWaveCount; waveIndex++) { + TCtrlWave* ctrlWaveRaw = JSUConvertOffsetToPtr(header, ctrlRaw->mCtrlWaveOffsets[waveIndex]); + u32 size = ctrlWaveRaw->field_0x0 & 0xFFFF; + if (maxSize < size) { + maxSize = size; + } + } + bank->setWaveTableSize(maxSize + 1); + for (int waveIndex = 0; waveIndex < ctrlRaw->mWaveCount; waveIndex++) { + TWave* waveRaw = JSUConvertOffsetToPtr(header, archiveRaw->mWaveOffsets[waveIndex]); + TWaveInfo info; + info.mBlockType = waveRaw->field_0x1; + info.field_0x1 = waveRaw->field_0x2; + info.field_0x4 = waveRaw->field_0x4; + info.mWavePtrOffs = waveRaw->mOffset; + info.field_0xc = waveRaw->field_0xc; + info.field_0x10 = waveRaw->field_0x10; + info.mBlockCount = waveRaw->field_0x14; + info.field_0x18 = waveRaw->field_0x18; + info.field_0x1c = waveRaw->field_0x1c; + info.field_0x20 = waveRaw->field_0x20; + info.field_0x22 = waveRaw->field_0x22; + TCtrlWave* ctrlWaveRaw = JSUConvertOffsetToPtr(header, ctrlRaw->mCtrlWaveOffsets[waveIndex]); + bank->setWaveInfo(ctrlWaveRaw->field_0x0 & 0xFFFF, info); + } + bank->setFileName(archiveRaw->mFileName); + sUsedHeapSize += priorFreeSize - heap->getFreeSize(); + return bank; }