diff options
| author | Nicholas Estelami <NEstelami@users.noreply.github.com> | 2022-06-01 13:06:32 -0400 |
|---|---|---|
| committer | Nicholas Estelami <NEstelami@users.noreply.github.com> | 2022-06-01 13:06:32 -0400 |
| commit | 2d546b2cd3ca634ee5c8dbdca45cfbf5b2cc299d (patch) | |
| tree | fc4ecdbe816e304cd779efdacefead27772f9b93 | |
| parent | 932fcff5bba8eace5f8502a454d39ce57daef6c2 (diff) | |
Audio decompiled and WIP custom sample support
| -rw-r--r-- | .gitignore | 1 | ||||
| -rw-r--r-- | OTRExporter/AudioExporter.cpp | 174 | ||||
| -rw-r--r-- | OTRExporter/AudioExporter.h | 16 | ||||
| -rw-r--r-- | OTRExporter/DisplayListExporter.cpp | 23 | ||||
| -rw-r--r-- | OTRExporter/Main.cpp | 27 | ||||
| -rw-r--r-- | OTRExporter/Main.h | 4 | ||||
| -rw-r--r-- | OTRExporter/OTRExporter.vcxproj | 2 | ||||
| -rw-r--r-- | OTRExporter/OTRExporter.vcxproj.filters | 6 | ||||
| -rw-r--r-- | OTRExporter/RoomExporter.cpp | 17 |
9 files changed, 229 insertions, 41 deletions
@@ -341,6 +341,7 @@ build/ ZAPDUtils/build/ ZAPD/BuildInfo.h baserom/ +baserom_ntsc/ *.vtx.inc *.otr *.swp diff --git a/OTRExporter/AudioExporter.cpp b/OTRExporter/AudioExporter.cpp new file mode 100644 index 0000000..7fb0658 --- /dev/null +++ b/OTRExporter/AudioExporter.cpp @@ -0,0 +1,174 @@ +#include "AudioExporter.h" +#include "Main.h" +#include <Animation.h> +#include <Utils/MemoryStream.h> +#include <Globals.h> +#include <Utils/File.h> +#include "DisplayListExporter.h" + +void OTRExporter_Audio::WriteSampleEntryReference(SampleEntry* entry, std::map<uint32_t, SampleEntry*> samples, BinaryWriter* writer) +{ + writer->Write((uint8_t)(entry != nullptr ? 1 : 0)); + + uint32_t addr = 0; + + for (auto pair : samples) + { + if (pair.second == entry) + { + addr = pair.first; + break; + } + } + + writer->Write(addr); +} + +void OTRExporter_Audio::WriteSampleEntry(SampleEntry* entry, BinaryWriter* writer) +{ + WriteHeader(nullptr, "", writer, Ship::ResourceType::AudioSample); + + writer->Write(entry->codec); + writer->Write(entry->medium); + writer->Write(entry->unk_bit26); + writer->Write(entry->unk_bit25); + + writer->Write((uint32_t)entry->data.size()); + writer->Write((char*)entry->data.data(), entry->data.size()); + + writer->Write((uint32_t)(entry->loop.start)); + writer->Write((uint32_t)(entry->loop.end)); + writer->Write((uint32_t)(entry->loop.count)); + writer->Write((uint32_t)entry->loop.states.size()); + + for (int i = 0; i < entry->loop.states.size(); i++) + writer->Write((entry->loop.states[i])); + + writer->Write((uint32_t)(entry->book.order)); + writer->Write((uint32_t)(entry->book.npredictors)); + writer->Write((uint32_t)entry->book.books.size()); + + for (int i = 0; i < entry->book.books.size(); i++) + writer->Write((entry->book.books[i])); +} + +void OTRExporter_Audio::WriteSoundFontEntry(SoundFontEntry* entry, std::map<uint32_t, SampleEntry*> samples, BinaryWriter* writer) +{ + writer->Write((uint8_t)(entry != nullptr ? 1 : 0)); + + if (entry != nullptr) + { + WriteSampleEntryReference(entry->sampleEntry, samples, writer); + writer->Write(entry->tuning); + } +} + +void OTRExporter_Audio::WriteEnvData(std::vector<AdsrEnvelope*> envelopes, BinaryWriter* writer) +{ + writer->Write((uint32_t)envelopes.size()); + + for (auto env : envelopes) + { + writer->Write(env->delay); + writer->Write(env->arg); + } +} + +void OTRExporter_Audio::Save(ZResource* res, const fs::path& outPath, BinaryWriter* writer) +{ + ZAudio* audio = (ZAudio*)res; + + WriteHeader(res, outPath, writer, Ship::ResourceType::Audio); + + // Write Samples as individual files + for (auto pair : audio->samples) + { + MemoryStream* sampleStream = new MemoryStream(); + BinaryWriter sampleWriter = BinaryWriter(sampleStream); + + WriteSampleEntry(pair.second, &sampleWriter); + + std::string fName = OTRExporter_DisplayList::GetPathToRes(res, StringHelper::Sprintf("samples/sample_%08X", pair.first)); + AddFile(fName, sampleStream->ToVector()); + } + + // Write the samplebank table + //writer->Write((uint32_t)audio->sampleBankTable.size()); + //for (size_t i = 0; i < audio->sampleBankTable.size(); i++) + //{ + //} + + // Write the soundfont table + //writer->Write((uint32_t)audio->soundFontTable.size()); + + for (size_t i = 0; i < audio->soundFontTable.size(); i++) + { + MemoryStream* fntStream = new MemoryStream(); + BinaryWriter fntWriter = BinaryWriter(fntStream); + + WriteHeader(nullptr, "", &fntWriter, Ship::ResourceType::AudioSoundFont); + + fntWriter.Write(audio->soundFontTable[i].medium); + fntWriter.Write(audio->soundFontTable[i].cachePolicy); + fntWriter.Write(audio->soundFontTable[i].data1); + fntWriter.Write(audio->soundFontTable[i].data2); + fntWriter.Write(audio->soundFontTable[i].data3); + + fntWriter.Write((uint32_t)audio->soundFontTable[i].drums.size()); + fntWriter.Write((uint32_t)audio->soundFontTable[i].instruments.size()); + fntWriter.Write((uint32_t)audio->soundFontTable[i].soundEffects.size()); + + for (int k = 0; k < audio->soundFontTable[i].drums.size(); k++) + { + fntWriter.Write(audio->soundFontTable[i].drums[k].releaseRate); + fntWriter.Write(audio->soundFontTable[i].drums[k].pan); + fntWriter.Write(audio->soundFontTable[i].drums[k].loaded); + + WriteEnvData(audio->soundFontTable[i].drums[k].env, &fntWriter); + + WriteSampleEntryReference(audio->soundFontTable[i].drums[k].sample, audio->samples, &fntWriter); + fntWriter.Write(audio->soundFontTable[i].drums[k].tuning); + } + + for (int k = 0; k < audio->soundFontTable[i].instruments.size(); k++) + { + fntWriter.Write((uint8_t)audio->soundFontTable[i].instruments[k].isValidInstrument); + + fntWriter.Write(audio->soundFontTable[i].instruments[k].loaded); + fntWriter.Write(audio->soundFontTable[i].instruments[k].normalRangeLo); + fntWriter.Write(audio->soundFontTable[i].instruments[k].normalRangeHi); + fntWriter.Write(audio->soundFontTable[i].instruments[k].releaseRate); + + WriteEnvData(audio->soundFontTable[i].instruments[k].env, &fntWriter); + + WriteSoundFontEntry(audio->soundFontTable[i].instruments[k].lowNotesSound, audio->samples, &fntWriter); + WriteSoundFontEntry(audio->soundFontTable[i].instruments[k].normalNotesSound, audio->samples, &fntWriter); + WriteSoundFontEntry(audio->soundFontTable[i].instruments[k].highNotesSound, audio->samples, &fntWriter); + } + + for (int k = 0; k < audio->soundFontTable[i].soundEffects.size(); k++) + { + WriteSoundFontEntry(audio->soundFontTable[i].soundEffects[k], audio->samples, &fntWriter); + } + + std::string fName = OTRExporter_DisplayList::GetPathToRes(res, StringHelper::Sprintf("fonts/font_%02X", i)); + AddFile(fName, fntStream->ToVector()); + } + + // Write Sequences + for (int i = 0; i < audio->sequences.size(); i++) + { + auto seq = audio->sequences[i]; + + MemoryStream* seqStream = new MemoryStream(); + BinaryWriter seqWriter = BinaryWriter(seqStream); + + seqWriter.Write((uint8_t)audio->sequenceTable[i].medium); + seqWriter.Write((uint8_t)audio->sequenceTable[i].cachePolicy); + + seqWriter.Write(seq.data(), seq.size()); + + std::string fName = OTRExporter_DisplayList::GetPathToRes(res, StringHelper::Sprintf("sequences/seq_%02X", i)); + AddFile(fName, seqStream->ToVector()); + } +} diff --git a/OTRExporter/AudioExporter.h b/OTRExporter/AudioExporter.h new file mode 100644 index 0000000..bd91da6 --- /dev/null +++ b/OTRExporter/AudioExporter.h @@ -0,0 +1,16 @@ +#pragma once + +#include "ZResource.h" +#include "ZAudio.h" +#include "Exporter.h" +#include <Utils/BinaryWriter.h> + +class OTRExporter_Audio : public OTRExporter +{ +public: + void WriteSampleEntry(SampleEntry* entry, BinaryWriter* writer); + void WriteSampleEntryReference(SampleEntry* entry, std::map<uint32_t, SampleEntry*> samples, BinaryWriter* writer); + void WriteSoundFontEntry(SoundFontEntry* entry, std::map<uint32_t, SampleEntry*> samples, BinaryWriter* writer); + void WriteEnvData(std::vector<AdsrEnvelope*> envelopes, BinaryWriter* writer); + virtual void Save(ZResource* res, const fs::path& outPath, BinaryWriter* writer) override; +};
\ No newline at end of file diff --git a/OTRExporter/DisplayListExporter.cpp b/OTRExporter/DisplayListExporter.cpp index d03a063..ed46943 100644 --- a/OTRExporter/DisplayListExporter.cpp +++ b/OTRExporter/DisplayListExporter.cpp @@ -362,18 +362,7 @@ void OTRExporter_DisplayList::Save(ZResource* res, const fs::path& outPath, Bina BinaryWriter dlWriter = BinaryWriter(dlStream); Save(dList->otherDLists[i], outPath, &dlWriter); - -#ifdef _DEBUG - //if (otrArchive->HasFile(fName)) - //otrArchive->RemoveFile(fName); -#endif - - if (Globals::Instance->fileMode != ZFileMode::ExtractDirectory) - File::WriteAllBytes("Extract/" + fName, dlStream->ToVector()); - else - files[fName] = dlStream->ToVector(); - - //otrArchive->AddFile(fName, (uintptr_t)dlStream->ToVector().data(), dlWriter.GetBaseAddress()); + AddFile(fName, dlStream->ToVector()); } } else @@ -460,10 +449,7 @@ void OTRExporter_DisplayList::Save(ZResource* res, const fs::path& outPath, Bina Save(dList->otherDLists[i], outPath, &dlWriter); - if (Globals::Instance->fileMode != ZFileMode::ExtractDirectory) - File::WriteAllBytes("Extract/" + fName, dlStream->ToVector()); - else - files[fName] = dlStream->ToVector(); + AddFile(fName, dlStream->ToVector()); } } else @@ -827,10 +813,7 @@ void OTRExporter_DisplayList::Save(ZResource* res, const fs::path& outPath, Bina } } - if (Globals::Instance->fileMode != ZFileMode::ExtractDirectory) - File::WriteAllBytes("Extract/" + fName, vtxStream->ToVector()); - else - files[fName] = vtxStream->ToVector(); + AddFile(fName, vtxStream->ToVector()); auto end = std::chrono::steady_clock::now(); size_t diff = std::chrono::duration_cast<std::chrono::milliseconds>(end - start).count(); diff --git a/OTRExporter/Main.cpp b/OTRExporter/Main.cpp index 2ed9cb4..e0a5254 100644 --- a/OTRExporter/Main.cpp +++ b/OTRExporter/Main.cpp @@ -15,6 +15,7 @@ #include "TextExporter.h" #include "BlobExporter.h" #include "MtxExporter.h" +#include "AudioExporter.h" #include <Globals.h> #include <Utils/File.h> #include <Utils/Directory.h> @@ -26,6 +27,7 @@ std::shared_ptr<Ship::Archive> otrArchive; BinaryWriter* fileWriter; std::chrono::steady_clock::time_point fileStart, resStart; std::map<std::string, std::vector<char>> files; +std::mutex fileMutex; void InitVersionInfo(); @@ -45,7 +47,7 @@ static void ExporterParseFileMode(const std::string& buildMode, ZFileMode& fileM if (File::Exists(otrFileName)) otrArchive = std::shared_ptr<Ship::Archive>(new Ship::Archive(otrFileName, true)); else - otrArchive = Ship::Archive::CreateArchive(otrFileName, 65536 / 2); + otrArchive = Ship::Archive::CreateArchive(otrFileName, 40000); auto lst = Directory::ListFiles("Extract"); @@ -62,7 +64,7 @@ static void ExporterProgramEnd() if (Globals::Instance->fileMode == ZFileMode::ExtractDirectory) { printf("Generating OTR Archive...\n"); - otrArchive = Ship::Archive::CreateArchive(otrFileName, 65536 / 2); + otrArchive = Ship::Archive::CreateArchive(otrFileName, 40000); for (auto item : files) { @@ -79,9 +81,9 @@ static void ExporterProgramEnd() otrArchive->AddFile(StringHelper::Split(item, "Extract/")[1], (uintptr_t)fileData.data(), fileData.size()); } - otrArchive->AddFile("Audiobank", (uintptr_t)Globals::Instance->GetBaseromFile("Audiobank").data(), Globals::Instance->GetBaseromFile("Audiobank").size()); - otrArchive->AddFile("Audioseq", (uintptr_t)Globals::Instance->GetBaseromFile("Audioseq").data(), Globals::Instance->GetBaseromFile("Audioseq").size()); - otrArchive->AddFile("Audiotable", (uintptr_t)Globals::Instance->GetBaseromFile("Audiotable").data(), Globals::Instance->GetBaseromFile("Audiotable").size()); + //otrArchive->AddFile("Audiobank", (uintptr_t)Globals::Instance->GetBaseromFile("Audiobank").data(), Globals::Instance->GetBaseromFile("Audiobank").size()); + //otrArchive->AddFile("Audioseq", (uintptr_t)Globals::Instance->GetBaseromFile("Audioseq").data(), Globals::Instance->GetBaseromFile("Audioseq").size()); + //otrArchive->AddFile("Audiotable", (uintptr_t)Globals::Instance->GetBaseromFile("Audiotable").data(), Globals::Instance->GetBaseromFile("Audiotable").size()); } } @@ -158,7 +160,10 @@ static void ExporterResourceEnd(ZResource* res, BinaryWriter& writer) fName = StringHelper::Sprintf("%s/%s", oName.c_str(), rName.c_str()); if (Globals::Instance->fileMode == ZFileMode::ExtractDirectory) + { + std::unique_lock Lock(fileMutex); files[fName] = strem->ToVector(); + } else File::WriteAllBytes("Extract/" + fName, strem->ToVector()); } @@ -178,6 +183,17 @@ static void ExporterXMLEnd() { } +void AddFile(std::string fName, std::vector<char> data) +{ + if (Globals::Instance->fileMode != ZFileMode::ExtractDirectory) + File::WriteAllBytes("Extract/" + fName, data); + else + { + std::unique_lock Lock(fileMutex); + files[fName] = data; + } +} + static void ImportExporters() { // In this example we set up a new exporter called "EXAMPLE". @@ -211,6 +227,7 @@ static void ImportExporters() exporterSet->exporters[ZResourceType::Text] = new OTRExporter_Text(); exporterSet->exporters[ZResourceType::Blob] = new OTRExporter_Blob(); exporterSet->exporters[ZResourceType::Mtx] = new OTRExporter_MtxExporter(); + exporterSet->exporters[ZResourceType::Audio] = new OTRExporter_Audio(); Globals::AddExporter("OTR", exporterSet); diff --git a/OTRExporter/Main.h b/OTRExporter/Main.h index af4ada7..df98bfe 100644 --- a/OTRExporter/Main.h +++ b/OTRExporter/Main.h @@ -3,4 +3,6 @@ #include <Archive.h> extern std::shared_ptr<Ship::Archive> otrArchive; -extern std::map<std::string, std::vector<char>> files;
\ No newline at end of file +extern std::map<std::string, std::vector<char>> files; + +void AddFile(std::string fName, std::vector<char> data);
\ No newline at end of file diff --git a/OTRExporter/OTRExporter.vcxproj b/OTRExporter/OTRExporter.vcxproj index 4ed7d72..9ec691d 100644 --- a/OTRExporter/OTRExporter.vcxproj +++ b/OTRExporter/OTRExporter.vcxproj @@ -20,6 +20,7 @@ </ItemGroup>
<ItemGroup>
<ClInclude Include="ArrayExporter.h" />
+ <ClInclude Include="AudioExporter.h" />
<ClInclude Include="BackgroundExporter.h" />
<ClInclude Include="BlobExporter.h" />
<ClInclude Include="CollisionExporter.h" />
@@ -44,6 +45,7 @@ </ItemGroup>
<ItemGroup>
<ClCompile Include="ArrayExporter.cpp" />
+ <ClCompile Include="AudioExporter.cpp" />
<ClCompile Include="BackgroundExporter.cpp" />
<ClCompile Include="BlobExporter.cpp" />
<ClCompile Include="CollisionExporter.cpp" />
diff --git a/OTRExporter/OTRExporter.vcxproj.filters b/OTRExporter/OTRExporter.vcxproj.filters index 8ecc347..a8cf567 100644 --- a/OTRExporter/OTRExporter.vcxproj.filters +++ b/OTRExporter/OTRExporter.vcxproj.filters @@ -81,6 +81,9 @@ <ClInclude Include="VersionInfo.h">
<Filter>Header Files</Filter>
</ClInclude>
+ <ClInclude Include="AudioExporter.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
</ItemGroup>
<ItemGroup>
<ClCompile Include="CollisionExporter.cpp">
@@ -140,5 +143,8 @@ <ClCompile Include="VersionInfo.cpp">
<Filter>Source Files</Filter>
</ClCompile>
+ <ClCompile Include="AudioExporter.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
</ItemGroup>
</Project>
\ No newline at end of file diff --git a/OTRExporter/RoomExporter.cpp b/OTRExporter/RoomExporter.cpp index 9a5704b..fe022a6 100644 --- a/OTRExporter/RoomExporter.cpp +++ b/OTRExporter/RoomExporter.cpp @@ -453,13 +453,7 @@ void OTRExporter_Room::Save(ZResource* res, const fs::path& outPath, BinaryWrite OTRExporter_Cutscene cs; cs.Save(cmdSetCutscenes->cutscenes[0], "", &csWriter); - if (Globals::Instance->fileMode != ZFileMode::ExtractDirectory) - File::WriteAllBytes("Extract/" + fName, csStream->ToVector()); - else - files[fName] = csStream->ToVector(); - - //std::string fName = OTRExporter_DisplayList::GetPathToRes(res, vtxDecl->varName); - //otrArchive->AddFile(fName, (uintptr_t)csStream->ToVector().data(), csWriter.GetBaseAddress()); + AddFile(fName, csStream->ToVector()); } break; case RoomCommand::SetPathways: @@ -480,14 +474,7 @@ void OTRExporter_Room::Save(ZResource* res, const fs::path& outPath, BinaryWrite OTRExporter_Path pathExp; pathExp.Save(&cmdSetPathways->pathwayList, outPath, &pathWriter); - if (Globals::Instance->fileMode != ZFileMode::ExtractDirectory) - File::WriteAllBytes("Extract/" + path, pathStream->ToVector()); - else - files[path] = pathStream->ToVector(); - - //otrArchive->AddFile(path, (uintptr_t)pathStream->ToVector().data(), pathWriter.GetBaseAddress()); - - int bp = 0; + AddFile(path, pathStream->ToVector()); } } break; |
