diff --git a/include/amuse/AudioGroupProject.hpp b/include/amuse/AudioGroupProject.hpp index e5df122..10b0c52 100644 --- a/include/amuse/AudioGroupProject.hpp +++ b/include/amuse/AudioGroupProject.hpp @@ -76,8 +76,8 @@ class AudioGroupProject std::unique_ptr m_convNormalPages; std::unique_ptr m_convDrumPages; std::unique_ptr[]> m_convMidiSetups; - void _allocateConvBuffers(const unsigned char* data, bool absOffs, N64DataTag); - void _allocateConvBuffers(const unsigned char* data, bool absOffs, PCDataTag); + void _allocateConvBuffers(const unsigned char* data, N64DataTag); + void _allocateConvBuffers(const unsigned char* data, PCDataTag); public: AudioGroupProject(const unsigned char* data, GCNDataTag); diff --git a/include/amuse/ContainerRegistry.hpp b/include/amuse/ContainerRegistry.hpp index 4f7bd0e..3bc050e 100644 --- a/include/amuse/ContainerRegistry.hpp +++ b/include/amuse/ContainerRegistry.hpp @@ -21,8 +21,7 @@ public: MetroidPrime2, RogueSquadronPC, RogueSquadronN64, - BattleForNabooPC, - BattleForNabooN64, + Factor5N64Rev, RogueSquadron2, RogueSquadron3 }; diff --git a/include/amuse/Envelope.hpp b/include/amuse/Envelope.hpp index 715e1dd..bb39f82 100644 --- a/include/amuse/Envelope.hpp +++ b/include/amuse/Envelope.hpp @@ -22,10 +22,10 @@ public: private: State m_phase = State::Attack; /**< Current envelope state */ - double m_attackTime = 0.0; /**< Time of attack in seconds */ + double m_attackTime = 0.01; /**< Time of attack in seconds */ double m_decayTime = 0.0; /**< Time of decay in seconds */ double m_sustainFactor = 1.0; /**< Evaluated sustain percentage */ - double m_releaseTime = 0.0; /**< Time of release in seconds */ + double m_releaseTime = 0.01; /**< Time of release in seconds */ double m_releaseStartFactor = 0.0; /**< Level at whenever release event occurs */ double m_curTime = 0.0; /**< Current time of envelope stage in seconds */ bool m_adsrSet = false; diff --git a/lib/AudioGroupProject.cpp b/lib/AudioGroupProject.cpp index 72f971e..59d5476 100644 --- a/lib/AudioGroupProject.cpp +++ b/lib/AudioGroupProject.cpp @@ -152,7 +152,7 @@ struct MusyX1MIDISetup } }; -void AudioGroupProject::_allocateConvBuffers(const unsigned char* data, bool absOffs, N64DataTag) +void AudioGroupProject::_allocateConvBuffers(const unsigned char* data, N64DataTag) { size_t normPageCount = 0; size_t drumPageCount = 0; @@ -161,7 +161,7 @@ void AudioGroupProject::_allocateConvBuffers(const unsigned char* data, bool abs const GroupHeader* group = reinterpret_cast(data); while (group->groupEndOff != 0xffffffff) { - const unsigned char* subData = absOffs ? data : data + 8; + const unsigned char* subData = data + 8; GroupHeader header = *group; header.swapBig(); @@ -187,20 +187,16 @@ void AudioGroupProject::_allocateConvBuffers(const unsigned char* data, bool abs /* MIDI setups */ const uint8_t* setupData = subData + header.midiSetupsOff; - while (*reinterpret_cast(setupData) != 0xffffffff) + const uint8_t* setupEnd = subData + header.groupEndOff; + while (setupData < setupEnd) { ++midiSetupCount; setupData += 8 * 16 + 4; } } - if (absOffs) - group = reinterpret_cast(data + header.groupEndOff); - else - { - data += header.groupEndOff; - group = reinterpret_cast(data); - } + data += header.groupEndOff; + group = reinterpret_cast(data); } if (normPageCount) @@ -213,7 +209,8 @@ void AudioGroupProject::_allocateConvBuffers(const unsigned char* data, bool abs AudioGroupProject::AudioGroupProject(const unsigned char* data, bool absOffs, N64DataTag) { - _allocateConvBuffers(data, absOffs, N64DataTag{}); + if (!absOffs) + _allocateConvBuffers(data, N64DataTag{}); SongGroupIndex::PageEntry* normPagesBuf = m_convNormalPages.get(); SongGroupIndex::PageEntry* drumPagesBuf = m_convDrumPages.get(); std::array* midiSetupsBuf = m_convMidiSetups.get(); @@ -232,42 +229,77 @@ AudioGroupProject::AudioGroupProject(const unsigned char* data, bool absOffs, N6 SongGroupIndex& idx = m_songGroups[header.groupId]; bIdx = &idx; - /* Normal pages */ - const MusyX1PageEntry* normEntries = - reinterpret_cast(subData + header.pageTableOff); - while (normEntries->objId != 0xffff) + if (absOffs) { - normEntries->setIntoMusyX2(*normPagesBuf); - idx.m_normPages[normEntries->programNo] = normPagesBuf; - ++normEntries; - ++normPagesBuf; + /* Normal pages */ + const SongGroupIndex::PageEntry* normEntries = + reinterpret_cast(data + header.pageTableOff); + while (normEntries->objId != 0xffff) + { + idx.m_normPages[normEntries->programNo] = normEntries; + ++normEntries; + } + + /* Drum pages */ + const SongGroupIndex::PageEntry* drumEntries = + reinterpret_cast(data + header.drumTableOff); + while (drumEntries->objId != 0xffff) + { + idx.m_drumPages[drumEntries->programNo] = drumEntries; + ++drumEntries; + } + + /* MIDI setups */ + const uint8_t* setupData = data + header.midiSetupsOff; + const uint8_t* setupEnd = data + header.groupEndOff; + while (setupData < setupEnd) + { + uint16_t songId = SBig(*reinterpret_cast(setupData)); + idx.m_midiSetups[songId] = + reinterpret_cast*>(setupData + 4); + setupData += 5 * 16 + 4; + } } - - /* Drum pages */ - const MusyX1PageEntry* drumEntries = - reinterpret_cast(subData + header.drumTableOff); - while (drumEntries->objId != 0xffff) + else { - drumEntries->setIntoMusyX2(*drumPagesBuf); - idx.m_drumPages[drumEntries->programNo] = drumPagesBuf; - ++drumEntries; - ++drumPagesBuf; - } + /* Normal pages */ + const MusyX1PageEntry* normEntries = + reinterpret_cast(subData + header.pageTableOff); + while (normEntries->objId != 0xffff) + { + normEntries->setIntoMusyX2(*normPagesBuf); + idx.m_normPages[normEntries->programNo] = normPagesBuf; + ++normEntries; + ++normPagesBuf; + } - /* MIDI setups */ - const uint8_t* setupData = subData + header.midiSetupsOff; - while (*reinterpret_cast(setupData) != 0xffffffff) - { - uint16_t songId = SBig(*reinterpret_cast(setupData)); - const std::array* midiSetups = - reinterpret_cast*>(setupData + 4); + /* Drum pages */ + const MusyX1PageEntry* drumEntries = + reinterpret_cast(subData + header.drumTableOff); + while (drumEntries->objId != 0xffff) + { + drumEntries->setIntoMusyX2(*drumPagesBuf); + idx.m_drumPages[drumEntries->programNo] = drumPagesBuf; + ++drumEntries; + ++drumPagesBuf; + } - for (int i = 0; i < 16; ++i) - (*midiSetups)[i].setIntoMusyX2((*midiSetupsBuf)[i]); + /* MIDI setups */ + const uint8_t* setupData = subData + header.midiSetupsOff; + const uint8_t* setupEnd = subData + header.groupEndOff; + while (setupData < setupEnd) + { + uint16_t songId = SBig(*reinterpret_cast(setupData)); + const std::array* midiSetups = + reinterpret_cast*>(setupData + 4); - idx.m_midiSetups[songId] = midiSetupsBuf; - setupData += 8 * 16 + 4; - ++midiSetupsBuf; + for (int i = 0; i < 16; ++i) + (*midiSetups)[i].setIntoMusyX2((*midiSetupsBuf)[i]); + + idx.m_midiSetups[songId] = midiSetupsBuf; + setupData += 8 * 16 + 4; + ++midiSetupsBuf; + } } } else if (header.type == GroupType::SFX) @@ -304,7 +336,7 @@ AudioGroupProject::AudioGroupProject(const unsigned char* data, bool absOffs, N6 } } -void AudioGroupProject::_allocateConvBuffers(const unsigned char* data, bool absOffs, PCDataTag) +void AudioGroupProject::_allocateConvBuffers(const unsigned char* data, PCDataTag) { size_t normPageCount = 0; size_t drumPageCount = 0; @@ -313,7 +345,7 @@ void AudioGroupProject::_allocateConvBuffers(const unsigned char* data, bool abs const GroupHeader* group = reinterpret_cast(data); while (group->groupEndOff != 0xffffffff) { - const unsigned char* subData = absOffs ? data : data + 8; + const unsigned char* subData = data + 8; if (group->type == GroupType::Song) { @@ -337,20 +369,16 @@ void AudioGroupProject::_allocateConvBuffers(const unsigned char* data, bool abs /* MIDI setups */ const uint8_t* setupData = subData + group->midiSetupsOff; - while (*reinterpret_cast(setupData) != 0xffffffff) + const uint8_t* setupEnd = subData + group->groupEndOff; + while (setupData < setupEnd) { ++midiSetupCount; setupData += 8 * 16 + 4; } } - if (absOffs) - group = reinterpret_cast(data + group->groupEndOff); - else - { - data += group->groupEndOff; - group = reinterpret_cast(data); - } + data += group->groupEndOff; + group = reinterpret_cast(data); } if (normPageCount) @@ -363,7 +391,8 @@ void AudioGroupProject::_allocateConvBuffers(const unsigned char* data, bool abs AudioGroupProject::AudioGroupProject(const unsigned char* data, bool absOffs, PCDataTag) { - _allocateConvBuffers(data, absOffs, PCDataTag{}); + if (!absOffs) + _allocateConvBuffers(data, PCDataTag{}); SongGroupIndex::PageEntry* normPagesBuf = m_convNormalPages.get(); SongGroupIndex::PageEntry* drumPagesBuf = m_convDrumPages.get(); std::array* midiSetupsBuf = m_convMidiSetups.get(); @@ -380,42 +409,77 @@ AudioGroupProject::AudioGroupProject(const unsigned char* data, bool absOffs, PC SongGroupIndex& idx = m_songGroups[group->groupId]; bIdx = &idx; - /* Normal pages */ - const MusyX1PageEntry* normEntries = - reinterpret_cast(subData + group->pageTableOff); - while (normEntries->objId != 0xffff) + if (absOffs) { - normEntries->setIntoMusyX2(*normPagesBuf); - idx.m_normPages[normEntries->programNo] = normPagesBuf; - ++normEntries; - ++normPagesBuf; + /* Normal pages */ + const SongGroupIndex::PageEntry* normEntries = + reinterpret_cast(data + group->pageTableOff); + while (normEntries->objId != 0xffff) + { + idx.m_normPages[normEntries->programNo] = normEntries; + ++normEntries; + } + + /* Drum pages */ + const SongGroupIndex::PageEntry* drumEntries = + reinterpret_cast(data + group->drumTableOff); + while (drumEntries->objId != 0xffff) + { + idx.m_drumPages[drumEntries->programNo] = drumEntries; + ++drumEntries; + } + + /* MIDI setups */ + const uint8_t* setupData = data + group->midiSetupsOff; + const uint8_t* setupEnd = data + group->groupEndOff; + while (setupData < setupEnd) + { + uint16_t songId = *reinterpret_cast(setupData); + idx.m_midiSetups[songId] = + reinterpret_cast*>(setupData + 4); + setupData += 5 * 16 + 4; + } } - - /* Drum pages */ - const MusyX1PageEntry* drumEntries = - reinterpret_cast(subData + group->drumTableOff); - while (drumEntries->objId != 0xffff) + else { - drumEntries->setIntoMusyX2(*drumPagesBuf); - idx.m_drumPages[drumEntries->programNo] = drumPagesBuf; - ++drumEntries; - ++drumPagesBuf; - } + /* Normal pages */ + const MusyX1PageEntry* normEntries = + reinterpret_cast(subData + group->pageTableOff); + while (normEntries->objId != 0xffff) + { + normEntries->setIntoMusyX2(*normPagesBuf); + idx.m_normPages[normEntries->programNo] = normPagesBuf; + ++normEntries; + ++normPagesBuf; + } - /* MIDI setups */ - const uint8_t* setupData = subData + group->midiSetupsOff; - while (*reinterpret_cast(setupData) != 0xffffffff) - { - uint16_t songId = *reinterpret_cast(setupData); - const std::array* midiSetups = - reinterpret_cast*>(setupData + 4); + /* Drum pages */ + const MusyX1PageEntry* drumEntries = + reinterpret_cast(subData + group->drumTableOff); + while (drumEntries->objId != 0xffff) + { + drumEntries->setIntoMusyX2(*drumPagesBuf); + idx.m_drumPages[drumEntries->programNo] = drumPagesBuf; + ++drumEntries; + ++drumPagesBuf; + } - for (int i = 0; i < 16; ++i) - (*midiSetups)[i].setIntoMusyX2((*midiSetupsBuf)[i]); + /* MIDI setups */ + const uint8_t* setupData = subData + group->midiSetupsOff; + const uint8_t* setupEnd = subData + group->groupEndOff; + while (setupData < setupEnd) + { + uint16_t songId = *reinterpret_cast(setupData); + const std::array* midiSetups = + reinterpret_cast*>(setupData + 4); - idx.m_midiSetups[songId] = midiSetupsBuf; - setupData += 8 * 16 + 4; - ++midiSetupsBuf; + for (int i = 0; i < 16; ++i) + (*midiSetups)[i].setIntoMusyX2((*midiSetupsBuf)[i]); + + idx.m_midiSetups[songId] = midiSetupsBuf; + setupData += 8 * 16 + 4; + ++midiSetupsBuf; + } } } else if (group->type == GroupType::SFX) diff --git a/lib/ContainerRegistry.cpp b/lib/ContainerRegistry.cpp index f28340e..b198cee 100644 --- a/lib/ContainerRegistry.cpp +++ b/lib/ContainerRegistry.cpp @@ -69,10 +69,8 @@ const SystemChar* ContainerRegistry::TypeToName(Type tp) return _S("Star Wars - Rogue Squadron (PC)"); case Type::RogueSquadronN64: return _S("Star Wars - Rogue Squadron (N64)"); - case Type::BattleForNabooPC: - return _S("Star Wars Episode I - Battle for Naboo (PC)"); - case Type::BattleForNabooN64: - return _S("Star Wars Episode I - Battle for Naboo (N64)"); + case Type::Factor5N64Rev: + return _S("Factor5 Revision ROM (N64)"); case Type::RogueSquadron2: return _S("Star Wars - Rogue Squadron 2 (GCN)"); case Type::RogueSquadron3: @@ -1087,148 +1085,7 @@ static std::vector> LoadRS1 return ret; } -static bool ValidateBFNPC(FILE* fp) -{ - size_t endPos = FileLength(fp); - if (endPos > 100 * 1024 * 1024) - return false; - - uint32_t fstOff; - uint32_t fstSz; - if (fread(&fstOff, 1, 4, fp) == 4 && fread(&fstSz, 1, 4, fp) == 4) - { - if (fstOff + fstSz <= endPos) - { - FSeek(fp, fstOff, SEEK_SET); - uint32_t elemCount = fstSz / 32; - std::unique_ptr entries(new RS1FSTEntry[elemCount]); - fread(entries.get(), fstSz, 1, fp); - - uint8_t foundComps = 0; - for (uint32_t i = 0; i < elemCount; ++i) - { - RS1FSTEntry& entry = entries[i]; - if (!strncmp("proj", entry.name, 16)) - foundComps |= 1; - else if (!strncmp("pool", entry.name, 16)) - foundComps |= 2; - else if (!strncmp("sdir", entry.name, 16)) - foundComps |= 4; - else if (!strncmp("samp", entry.name, 16)) - foundComps |= 8; - } - - if (foundComps == 0xf) - return true; - } - } - - return false; -} - -static std::vector> LoadBFNPC(FILE* fp) -{ - std::vector> ret; - size_t endPos = FileLength(fp); - - uint32_t fstOff; - uint32_t fstSz; - if (fread(&fstOff, 1, 4, fp) == 4 && fread(&fstSz, 1, 4, fp) == 4) - { - if (fstOff + fstSz <= endPos) - { - FSeek(fp, fstOff, SEEK_SET); - uint32_t elemCount = fstSz / 32; - std::unique_ptr entries(new RS1FSTEntry[elemCount]); - fread(entries.get(), fstSz, 1, fp); - - std::unique_ptr proj; - size_t projSz = 0; - std::unique_ptr pool; - size_t poolSz = 0; - std::unique_ptr sdir; - size_t sdirSz = 0; - std::unique_ptr samp; - size_t sampSz = 0; - - for (uint32_t i = 0; i < elemCount; ++i) - { - RS1FSTEntry& entry = entries[i]; - if (!strncmp("proj", entry.name, 16)) - { - proj.reset(new uint8_t[entry.decompSz]); - FSeek(fp, entry.offset, SEEK_SET); - fread(proj.get(), 1, entry.decompSz, fp); - projSz = entry.decompSz; - } - else if (!strncmp("pool", entry.name, 16)) - { - pool.reset(new uint8_t[entry.decompSz]); - FSeek(fp, entry.offset, SEEK_SET); - fread(pool.get(), 1, entry.decompSz, fp); - poolSz = entry.decompSz; - } - else if (!strncmp("sdir", entry.name, 16)) - { - sdir.reset(new uint8_t[entry.decompSz]); - FSeek(fp, entry.offset, SEEK_SET); - fread(sdir.get(), 1, entry.decompSz, fp); - sdirSz = entry.decompSz; - } - else if (!strncmp("samp", entry.name, 16)) - { - samp.reset(new uint8_t[entry.decompSz]); - FSeek(fp, entry.offset, SEEK_SET); - fread(samp.get(), 1, entry.decompSz, fp); - sampSz = entry.decompSz; - } - } - - ret.emplace_back(_S("Group"), - IntrusiveAudioGroupData{proj.release(), projSz, pool.release(), poolSz, sdir.release(), - sdirSz, samp.release(), sampSz, true, PCDataTag{}}); - } - } - - return ret; -} - -static std::vector> LoadBFNPCSongs(FILE* fp) -{ - std::vector> ret; - size_t endPos = FileLength(fp); - - uint32_t fstOff; - uint32_t fstSz; - if (fread(&fstOff, 1, 4, fp) == 4 && fread(&fstSz, 1, 4, fp) == 4) - { - if (fstOff + fstSz <= endPos) - { - FSeek(fp, fstOff, SEEK_SET); - uint32_t elemCount = fstSz / 32; - std::unique_ptr entries(new RS1FSTEntry[elemCount]); - fread(entries.get(), fstSz, 1, fp); - - for (uint32_t i = 0; i < elemCount; ++i) - { - RS1FSTEntry& entry = entries[i]; - if (!strncmp(entry.name, "s_", 2)) - { - std::unique_ptr song(new uint8_t[entry.decompSz]); - FSeek(fp, entry.offset, SEEK_SET); - fread(song.get(), 1, entry.decompSz, fp); - - SystemString name = StrToSys(entry.name); - ret.emplace_back(name, ContainerRegistry::SongData(std::move(song), entry.decompSz, -1, -1)); - } - } - } - } - - return ret; -} - -static bool ValidateBFNN64(FILE* fp) +static bool ValidateFactor5N64Rev(FILE* fp) { size_t endPos = FileLength(fp); if (endPos > 32 * 1024 * 1024) @@ -1282,7 +1139,7 @@ static bool ValidateBFNN64(FILE* fp) return false; } -static std::vector> LoadBFNN64(FILE* fp) +static std::vector> LoadFactor5N64Rev(FILE* fp) { std::vector> ret; size_t endPos = FileLength(fp); @@ -1393,7 +1250,7 @@ static std::vector> LoadBFNN64( return ret; } -static std::vector> LoadBFNN64Songs(FILE* fp) +static std::vector> LoadFactor5N64RevSongs(FILE* fp) { std::vector> ret; size_t endPos = FileLength(fp); @@ -1427,6 +1284,8 @@ static std::vector> LoadBFN if (!strncmp(ent.name, "s_", 2)) { + long idx = strtol(ent.name + 2, nullptr, 10); + std::unique_ptr song(new uint8_t[ent.decompSz]); if (ent.compSz == 0xffffffff) @@ -1440,7 +1299,7 @@ static std::vector> LoadBFN } SystemString name = StrToSys(ent.name); - ret.emplace_back(name, ContainerRegistry::SongData(std::move(song), ent.decompSz, -1, -1)); + ret.emplace_back(name, ContainerRegistry::SongData(std::move(song), ent.decompSz, -1, idx)); } } } @@ -2011,16 +1870,10 @@ ContainerRegistry::Type ContainerRegistry::DetectContainerType(const SystemChar* return Type::RogueSquadronN64; } - if (ValidateBFNPC(fp)) + if (ValidateFactor5N64Rev(fp)) { fclose(fp); - return Type::BattleForNabooPC; - } - - if (ValidateBFNN64(fp)) - { - fclose(fp); - return Type::BattleForNabooN64; + return Type::Factor5N64Rev; } if (ValidateRS2(fp)) @@ -2195,19 +2048,11 @@ std::vector> ContainerRegistry: return ret; } - if (ValidateBFNPC(fp)) + if (ValidateFactor5N64Rev(fp)) { - auto ret = LoadBFNPC(fp); + auto ret = LoadFactor5N64Rev(fp); fclose(fp); - typeOut = Type::BattleForNabooPC; - return ret; - } - - if (ValidateBFNN64(fp)) - { - auto ret = LoadBFNN64(fp); - fclose(fp); - typeOut = Type::BattleForNabooN64; + typeOut = Type::Factor5N64Rev; return ret; } @@ -2282,16 +2127,9 @@ std::vector> ContainerRegis return ret; } - if (ValidateBFNPC(fp)) + if (ValidateFactor5N64Rev(fp)) { - auto ret = LoadBFNPCSongs(fp); - fclose(fp); - return ret; - } - - if (ValidateBFNN64(fp)) - { - auto ret = LoadBFNN64Songs(fp); + auto ret = LoadFactor5N64RevSongs(fp); fclose(fp); return ret; }