diff --git a/src/ObjWriting/Game/T6/AssetDumpers/AssetDumperSndBank.cpp b/src/ObjWriting/Game/T6/AssetDumpers/AssetDumperSndBank.cpp index 320ea76b..0f782ba3 100644 --- a/src/ObjWriting/Game/T6/AssetDumpers/AssetDumperSndBank.cpp +++ b/src/ObjWriting/Game/T6/AssetDumpers/AssetDumperSndBank.cpp @@ -1,6 +1,7 @@ #include "AssetDumperSndBank.h" #include "Game/T6/Sound/AliasDumperCsv.h" +#include "Game/T6/Sound/AliasDumperJson.h" #include "Game/T6/Sound/SoundFileDumper.h" using namespace T6; @@ -11,8 +12,10 @@ namespace T6::sound { const auto* sndBank = sndBankInfo->Asset(); - const AliasDumperCsv aliasDumper(context); - aliasDumper.DumpSndBankAliases(sndBank); + // const AliasDumperCsv aliasDumper(context); + // aliasDumper.DumpSndBankAliases(sndBank); + const auto aliasDumper = CreateAliasDumperJson(context); + aliasDumper->DumpSndBankAliases(sndBank); DumpSoundData(context, sndBank); } diff --git a/src/ObjWriting/Game/T6/Sound/AbstractAliasDumper.cpp b/src/ObjWriting/Game/T6/Sound/AbstractAliasDumper.cpp new file mode 100644 index 00000000..37fd4b4a --- /dev/null +++ b/src/ObjWriting/Game/T6/Sound/AbstractAliasDumper.cpp @@ -0,0 +1,42 @@ +#include "AbstractAliasDumper.h" + +#include "ObjContainer/SoundBank/SoundBank.h" + +#include + +using namespace T6::sound; + +AbstractAliasDumper::AbstractAliasDumper(const AssetDumpingContext& context) + : m_context(context) +{ +} + +bool AbstractAliasDumper::FindSoundBankEntry(const unsigned assetId, SoundAssetBankEntry& entry) +{ + for (const auto* soundBank : SoundBank::Repository) + { + if (soundBank->GetEntry(assetId, entry)) + return true; + } + + return false; +} + +std::unique_ptr AbstractAliasDumper::OpenAliasOutputFile(const SndBank* sndBank, const std::string& extension) const +{ + std::ostringstream ss; + + const char* name; + if (sndBank->streamAssetBank.zone) + name = sndBank->streamAssetBank.zone; + else if (sndBank->loadAssetBank.zone) + name = sndBank->loadAssetBank.zone; + else if (sndBank->loadedAssets.zone) + name = sndBank->loadedAssets.zone; + else + name = sndBank->name; + + ss << "soundaliases/" << name << "_aliases" << extension; + + return m_context.OpenAssetFile(ss.str()); +} diff --git a/src/ObjWriting/Game/T6/Sound/AbstractAliasDumper.h b/src/ObjWriting/Game/T6/Sound/AbstractAliasDumper.h new file mode 100644 index 00000000..f2ddc462 --- /dev/null +++ b/src/ObjWriting/Game/T6/Sound/AbstractAliasDumper.h @@ -0,0 +1,33 @@ +#pragma once + +#include "Dumping/AssetDumpingContext.h" +#include "Game/T6/T6.h" +#include "ObjContainer/SoundBank/SoundBankTypes.h" + +#include +#include +#include + +namespace T6::sound +{ + class AbstractAliasDumper + { + protected: + explicit AbstractAliasDumper(const AssetDumpingContext& context); + + public: + virtual ~AbstractAliasDumper() = default; + AbstractAliasDumper(const AbstractAliasDumper& other) = default; + AbstractAliasDumper(AbstractAliasDumper&& other) noexcept = default; + AbstractAliasDumper& operator=(const AbstractAliasDumper& other) = delete; + AbstractAliasDumper& operator=(AbstractAliasDumper&& other) noexcept = delete; + + virtual void DumpSndBankAliases(const SndBank* sndBank) const = 0; + + protected: + static bool FindSoundBankEntry(unsigned assetId, SoundAssetBankEntry& entry); + std::unique_ptr OpenAliasOutputFile(const SndBank* sndBank, const std::string& extension) const; + + const AssetDumpingContext& m_context; + }; +} \ No newline at end of file diff --git a/src/ObjWriting/Game/T6/Sound/AliasDumperCsv.cpp b/src/ObjWriting/Game/T6/Sound/AliasDumperCsv.cpp index 269608d6..3b471102 100644 --- a/src/ObjWriting/Game/T6/Sound/AliasDumperCsv.cpp +++ b/src/ObjWriting/Game/T6/Sound/AliasDumperCsv.cpp @@ -82,29 +82,10 @@ namespace T6::sound }; AliasDumperCsv::AliasDumperCsv(const AssetDumpingContext& context) - : m_context(context) + : AbstractAliasDumper(context) { } - std::unique_ptr AliasDumperCsv::OpenAliasOutputFile(const SndBank* sndBank) const - { - std::ostringstream ss; - - const char* name; - if (sndBank->streamAssetBank.zone) - name = sndBank->streamAssetBank.zone; - else if (sndBank->loadAssetBank.zone) - name = sndBank->loadAssetBank.zone; - else if (sndBank->loadedAssets.zone) - name = sndBank->loadedAssets.zone; - else - name = sndBank->name; - - ss << "soundaliases/" << name << "_aliases.csv"; - - return m_context.OpenAssetFile(ss.str()); - } - void AliasDumperCsv::WriteAliasFileHeader(CsvOutputStream& stream) { for (const auto& headerField : ALIAS_HEADERS) @@ -115,18 +96,7 @@ namespace T6::sound stream.NextRow(); } - bool AliasDumperCsv::FindSoundBankEntry(const unsigned assetId, SoundAssetBankEntry& entry) - { - for (const auto* soundBank : SoundBank::Repository) - { - if (soundBank->GetEntry(assetId, entry)) - return true; - } - - return false; - } - - void AliasDumperCsv::WriteAliasToFile(CsvOutputStream& stream, const SndAlias* alias) const + void AliasDumperCsv::WriteAliasToFile(CsvOutputStream& stream, const SndAlias* alias) { SoundAssetBankEntry entry; std::string extension; @@ -142,7 +112,7 @@ namespace T6::sound // file if (alias->assetFileName) - stream.WriteColumn(GetAssetFilename(m_context.m_base_path, alias->assetFileName, extension)); + stream.WriteColumn(GetAssetFilename(alias->assetFileName, extension)); else stream.WriteColumn(""); @@ -370,7 +340,7 @@ namespace T6::sound void AliasDumperCsv::DumpSndBankAliases(const SndBank* sndBank) const { - const auto outputFile = OpenAliasOutputFile(sndBank); + const auto outputFile = OpenAliasOutputFile(sndBank, ".csv"); if (outputFile == nullptr) { diff --git a/src/ObjWriting/Game/T6/Sound/AliasDumperCsv.h b/src/ObjWriting/Game/T6/Sound/AliasDumperCsv.h index bcee5afe..e5ce6254 100644 --- a/src/ObjWriting/Game/T6/Sound/AliasDumperCsv.h +++ b/src/ObjWriting/Game/T6/Sound/AliasDumperCsv.h @@ -1,5 +1,6 @@ #pragma once +#include "AbstractAliasDumper.h" #include "Csv/CsvStream.h" #include "Dumping/AssetDumpingContext.h" #include "Game/T6/T6.h" @@ -7,24 +8,20 @@ namespace T6::sound { - class AliasDumperCsv + class AliasDumperCsv : AbstractAliasDumper { public: explicit AliasDumperCsv(const AssetDumpingContext& context); - void DumpSndBankAliases(const SndBank* sndBank) const; + void DumpSndBankAliases(const SndBank* sndBank) const override; private: - std::unique_ptr OpenAliasOutputFile(const SndBank* sndBank) const; static void WriteAliasFileHeader(CsvOutputStream& stream); - static bool FindSoundBankEntry(unsigned assetId, SoundAssetBankEntry& entry); - void WriteAliasToFile(CsvOutputStream& stream, const SndAlias* alias) const; + static void WriteAliasToFile(CsvOutputStream& stream, const SndAlias* alias); static void WriteColumnNullSafe(CsvOutputStream& stream, const char* value); static void WriteColumnFloat8(CsvOutputStream& stream, uint8_t value); static void WriteColumnFloat16(CsvOutputStream& stream, uint16_t value); static void WriteColumnSignedNumeric(CsvOutputStream& stream, int value); static void WriteColumnUnsignedNumeric(CsvOutputStream& stream, unsigned value); - - const AssetDumpingContext& m_context; }; } \ No newline at end of file diff --git a/src/ObjWriting/Game/T6/Sound/AliasDumperJson.cpp b/src/ObjWriting/Game/T6/Sound/AliasDumperJson.cpp new file mode 100644 index 00000000..c863977e --- /dev/null +++ b/src/ObjWriting/Game/T6/Sound/AliasDumperJson.cpp @@ -0,0 +1,144 @@ +#include "AliasDumperJson.h" + +#include "ObjContainer/SoundBank/SoundBankTypes.h" +#include "SoundCommon.h" + +#include +#include + +using namespace nlohmann; + +// #define PRETTY_PRINT_ALIAS 1 + +namespace T6::sound +{ + class AliasDumperJson final : public AbstractAliasDumper + { + public: + explicit AliasDumperJson(const AssetDumpingContext& context) + : AbstractAliasDumper(context) + { + } + + private: + static void SetJsonString(json& j, const std::string& key, const char* value) + { + if (value) + j[key] = value; + else + j[key] = nullptr; + } + + static void AddAliasToJson(const SndAlias& alias, json& jAlias) + { + SoundAssetBankEntry entry; + std::string extension; + if (FindSoundBankEntry(alias.assetId, entry)) + { + assert(entry.format < SND_ASSET_FORMAT_COUNT); + if (entry.format < SND_ASSET_FORMAT_COUNT) + extension = EXTENSION_BY_FORMAT[entry.format]; + } + + SetJsonString(jAlias, "name", alias.name); + jAlias["id"] = alias.id; + SetJsonString(jAlias, "subtitle", alias.subtitle); + SetJsonString(jAlias, "secondaryname", alias.secondaryname); + jAlias["assetId"] = alias.assetId; + + if (alias.assetFileName) + jAlias["assetFileName"] = GetAssetFilename(alias.assetFileName, extension); + else + jAlias["assetFileName"] = nullptr; + + jAlias["flags0"] = alias.flags0; + jAlias["flags1"] = alias.flags1; + jAlias["duck"] = alias.duck; + jAlias["contextType"] = alias.contextType; + jAlias["contextValue"] = alias.contextValue; + jAlias["stopOnPlay"] = alias.stopOnPlay; + jAlias["futzPatch"] = alias.futzPatch; + jAlias["fluxTime"] = alias.fluxTime; + jAlias["startDelay"] = alias.startDelay; + jAlias["reverbSend"] = alias.reverbSend; + jAlias["centerSend"] = alias.centerSend; + jAlias["volMin"] = alias.volMin; + jAlias["volMax"] = alias.volMax; + jAlias["pitchMin"] = alias.pitchMin; + jAlias["pitchMax"] = alias.pitchMax; + jAlias["distMin"] = alias.distMin; + jAlias["distMax"] = alias.distMax; + jAlias["distReverbMax"] = alias.distReverbMax; + jAlias["envelopMin"] = alias.envelopMin; + jAlias["envelopMax"] = alias.envelopMax; + jAlias["envelopPercentage"] = alias.envelopPercentage; + jAlias["fadeIn"] = alias.fadeIn; + jAlias["fadeOut"] = alias.fadeOut; + jAlias["dopplerScale"] = alias.dopplerScale; + jAlias["minPriorityThreshold"] = alias.minPriorityThreshold; + jAlias["maxPriorityThreshold"] = alias.maxPriorityThreshold; + jAlias["probability"] = alias.probability; + jAlias["occlusionLevel"] = alias.occlusionLevel; + jAlias["minPriority"] = alias.minPriority; + jAlias["maxPriority"] = alias.maxPriority; + jAlias["pan"] = alias.pan; + jAlias["limitCount"] = alias.limitCount; + jAlias["entityLimitCount"] = alias.entityLimitCount; + jAlias["duckGroup"] = alias.duckGroup; + } + + static void AddAliasListToJson(const SndAliasList& aliasList, json& jAliasList) + { + jAliasList["name"] = aliasList.name; + jAliasList["id"] = aliasList.id; + jAliasList["sequence"] = aliasList.sequence; + + json jAliases; + for (auto j = 0; j < aliasList.count; j++) + { + json jAlias; + + AddAliasToJson(aliasList.head[j], jAlias); + + jAliases.push_back(std::move(jAlias)); + } + jAliasList["aliases"] = std::move(jAliases); + } + + void DumpSndBankAliases(const SndBank* sndBank) const override + { + const auto outputFile = OpenAliasOutputFile(sndBank, ".json"); + + if (outputFile == nullptr) + { + std::cout << "Failed to open sound alias output file for: \"" << sndBank->name << "\"" << std::endl; + return; + } + + json jRoot; + jRoot["version"] = 1; + + json jAliasLists = json::array(); + for (auto i = 0u; i < sndBank->aliasCount; i++) + { + json jAliasList; + + AddAliasListToJson(sndBank->alias[i], jAliasList); + + jAliasLists.push_back(std::move(jAliasList)); + } + jRoot["aliasLists"] = std::move(jAliasLists); + + *outputFile +#ifdef PRETTY_PRINT_ALIAS + << std::setw(4) +#endif + << jRoot << std::endl; + } + }; + + std::unique_ptr CreateAliasDumperJson(const AssetDumpingContext& context) + { + return std::make_unique(context); + } +} \ No newline at end of file diff --git a/src/ObjWriting/Game/T6/Sound/AliasDumperJson.h b/src/ObjWriting/Game/T6/Sound/AliasDumperJson.h new file mode 100644 index 00000000..b7891ce3 --- /dev/null +++ b/src/ObjWriting/Game/T6/Sound/AliasDumperJson.h @@ -0,0 +1,11 @@ +#pragma once + +#include "AbstractAliasDumper.h" +#include "Dumping/AssetDumpingContext.h" + +#include + +namespace T6::sound +{ + std::unique_ptr CreateAliasDumperJson(const AssetDumpingContext& context); +} diff --git a/src/ObjWriting/Game/T6/Sound/SoundCommon.cpp b/src/ObjWriting/Game/T6/Sound/SoundCommon.cpp index 593f4961..d8170fd7 100644 --- a/src/ObjWriting/Game/T6/Sound/SoundCommon.cpp +++ b/src/ObjWriting/Game/T6/Sound/SoundCommon.cpp @@ -11,10 +11,8 @@ namespace T6::sound "devraw/", }; - _NODISCARD std::string GetAssetFilename(const std::string& basePath, std::string outputFileName, const std::string& extension) + _NODISCARD std::string GetAssetFilename(std::string outputFileName, const std::string& extension) { - fs::path assetPath(basePath); - std::replace(outputFileName.begin(), outputFileName.end(), '\\', '/'); for (const auto& droppedPrefix : PREFIXES_TO_DROP) { @@ -25,7 +23,7 @@ namespace T6::sound } } - assetPath.append(outputFileName); + fs::path assetPath(outputFileName); if (!extension.empty()) assetPath.concat(extension); diff --git a/src/ObjWriting/Game/T6/Sound/SoundCommon.h b/src/ObjWriting/Game/T6/Sound/SoundCommon.h index 2d3cd517..feaaf459 100644 --- a/src/ObjWriting/Game/T6/Sound/SoundCommon.h +++ b/src/ObjWriting/Game/T6/Sound/SoundCommon.h @@ -32,5 +32,5 @@ namespace T6::sound ".mpc", // SND_ASSET_FORMAT_MPC }; - _NODISCARD std::string GetAssetFilename(const std::string& basePath, std::string outputFileName, const std::string& extension); + _NODISCARD std::string GetAssetFilename(std::string outputFileName, const std::string& extension); } \ No newline at end of file diff --git a/src/ObjWriting/Game/T6/Sound/SoundFileDumper.cpp b/src/ObjWriting/Game/T6/Sound/SoundFileDumper.cpp index eb525934..4110dca3 100644 --- a/src/ObjWriting/Game/T6/Sound/SoundFileDumper.cpp +++ b/src/ObjWriting/Game/T6/Sound/SoundFileDumper.cpp @@ -20,7 +20,8 @@ namespace T6::sound _NODISCARD std::unique_ptr OpenAssetOutputFile(const AssetDumpingContext& context, const std::string& outputFileName, const std::string& extension) { - fs::path assetPath(GetAssetFilename(context.m_base_path, outputFileName, extension)); + fs::path assetPath(context.m_base_path); + assetPath.append(GetAssetFilename(outputFileName, extension)); auto assetDir(assetPath); assetDir.remove_filename(); @@ -37,7 +38,7 @@ namespace T6::sound return nullptr; } - static SoundBankEntryInputStream FindSoundDataInSoundBanks(const unsigned assetId) + SoundBankEntryInputStream FindSoundDataInSoundBanks(const unsigned assetId) { for (const auto* soundBank : SoundBank::Repository) {