From b5dd6df1cd85edc4cb9c2faa87355414202b7c00 Mon Sep 17 00:00:00 2001 From: Alex Date: Fri, 12 Jan 2024 16:38:53 -0500 Subject: [PATCH] begin working on SndBank loading from raw --- src/ObjCommon/Game/T6/ObjConstantsT6.cpp | 137 ++++++++++ src/ObjCommon/Game/T6/ObjConstantsT6.h | 11 + .../T6/AssetLoaders/AssetLoaderSoundBank.cpp | 254 ++++++++++++++++++ .../T6/AssetLoaders/AssetLoaderSoundBank.h | 17 ++ src/ObjLoading/Game/T6/ObjLoaderT6.cpp | 3 +- .../T6/AssetDumpers/AssetDumperSndBank.cpp | 165 ++---------- src/Utils/Utils/StringUtils.cpp | 15 ++ src/Utils/Utils/StringUtils.h | 3 + 8 files changed, 456 insertions(+), 149 deletions(-) create mode 100644 src/ObjCommon/Game/T6/ObjConstantsT6.cpp create mode 100644 src/ObjLoading/Game/T6/AssetLoaders/AssetLoaderSoundBank.cpp create mode 100644 src/ObjLoading/Game/T6/AssetLoaders/AssetLoaderSoundBank.h diff --git a/src/ObjCommon/Game/T6/ObjConstantsT6.cpp b/src/ObjCommon/Game/T6/ObjConstantsT6.cpp new file mode 100644 index 00000000..3ac97809 --- /dev/null +++ b/src/ObjCommon/Game/T6/ObjConstantsT6.cpp @@ -0,0 +1,137 @@ +#include "ObjConstantsT6.h" + +namespace T6 +{ + const std::array ObjConstants::SOUND_GROUPS{ + "grp_reference", + "grp_master", + "grp_wpn_lfe", + "grp_lfe", + "grp_hdrfx", + "grp_music", + "grp_voice", + "grp_set_piece", + "grp_igc", + "grp_mp_game", + "grp_explosion", + "grp_player_impacts", + "grp_scripted_moment", + "grp_menu", + "grp_whizby", + "grp_weapon", + "grp_vehicle", + "grp_impacts", + "grp_foley", + "grp_destructible", + "grp_physics", + "grp_ambience", + "grp_alerts", + "grp_air", + "grp_bink", + "grp_announcer", + "", + }; + + const std::array ObjConstants::SOUND_CURVES{ + "default", + "defaultmin", + "allon", + "alloff", + "rcurve0", + "rcurve1", + "rcurve2", + "rcurve3", + "rcurve4", + "rcurve5", + "steep", + "sindelay", + "cosdelay", + "sin", + "cos", + "rev60", + "rev65", + "", + }; + + const std::array ObjConstants::SOUND_DUCK_GROUPS{ + "snp_alerts_gameplay", + "snp_ambience", + "snp_claw", + "snp_destructible", + "snp_dying", + "snp_dying_ice", + "snp_evt_2d", + "snp_explosion", + "snp_foley", + "snp_grenade", + "snp_hdrfx", + "snp_igc", + "snp_impacts", + "snp_menu", + "snp_movie", + "snp_music", + "snp_never_duck", + "snp_player_dead", + "snp_player_impacts", + "snp_scripted_moment", + "snp_set_piece", + "snp_special", + "snp_vehicle", + "snp_vehicle_interior", + "snp_voice", + "snp_weapon_decay_1p", + "snp_whizby", + "snp_wpn_1p", + "snp_wpn_3p", + "snp_wpn_turret", + "snp_x2", + "snp_x3", + }; + + const std::array ObjConstants::SOUND_LIMIT_TYPES{ + "none", + "oldest", + "reject", + "priority", + }; + + const std::array ObjConstants::SOUND_MOVE_TYPES{ + "none", + "left_player", + "center_player", + "right_player", + "random", + "left_shot", + "center_shot", + "right_shot", + }; + + const std::array ObjConstants::SOUND_LOAD_TYPES{ + "unknown", + "loaded", + "streamed", + "primed", + }; + + const std::array ObjConstants::SOUND_BUS_IDS{ + "bus_reverb", + "bus_fx", + "bus_voice", + "bus_pfutz", + "bus_hdrfx", + "bus_ui", + "bus_reference", + "bus_music", + "bus_movie", + "bus_reference", + "", + }; + + const std::array ObjConstants::SOUND_RANDOMIZE_TYPES{ + "volume", + "pitch", + "variant", + "", + }; + +} // namespace T6 diff --git a/src/ObjCommon/Game/T6/ObjConstantsT6.h b/src/ObjCommon/Game/T6/ObjConstantsT6.h index 73f1cad3..d5991d9a 100644 --- a/src/ObjCommon/Game/T6/ObjConstantsT6.h +++ b/src/ObjCommon/Game/T6/ObjConstantsT6.h @@ -1,4 +1,6 @@ #pragma once +#include +#include namespace T6 { @@ -24,5 +26,14 @@ namespace T6 static constexpr const char* GDF_FILENAME_WEAPON_ATTACHMENT = "attachment.gdf"; static constexpr const char* GDF_FILENAME_WEAPON_ATTACHMENT_UNIQUE = "attachmentunique.gdf"; static constexpr const char* GDF_FILENAME_ZBARRIER = "zbarrier.gdf"; + + static const std::array SOUND_GROUPS; + static const std::array SOUND_CURVES; + static const std::array SOUND_DUCK_GROUPS; + static const std::array SOUND_LIMIT_TYPES; + static const std::array SOUND_MOVE_TYPES; + static const std::array SOUND_LOAD_TYPES; + static const std::array SOUND_BUS_IDS; + static const std::array SOUND_RANDOMIZE_TYPES; }; } // namespace T6 diff --git a/src/ObjLoading/Game/T6/AssetLoaders/AssetLoaderSoundBank.cpp b/src/ObjLoading/Game/T6/AssetLoaders/AssetLoaderSoundBank.cpp new file mode 100644 index 00000000..d74aa12d --- /dev/null +++ b/src/ObjLoading/Game/T6/AssetLoaders/AssetLoaderSoundBank.cpp @@ -0,0 +1,254 @@ +#include "AssetLoaderSoundBank.h" + +#include "Csv/CsvStream.h" +#include "Game/T6/CommonT6.h" +#include "Game/T6/ObjConstantsT6.h" +#include "Game/T6/T6.h" +#include "Pool/GlobalAssetPool.h" + +#include +#include +#include + +using namespace T6; +std::unordered_map AliasHeaders{}; + +void* AssetLoaderSoundBank::CreateEmptyAsset(const std::string& assetName, MemoryManager* memory) +{ + auto* soundBank = memory->Create(); + memset(soundBank, 0, sizeof(SndBank)); + soundBank->name = memory->Dup(assetName.c_str()); + return soundBank; +} + +bool AssetLoaderSoundBank::CanLoadFromRaw() const +{ + return true; +} + +void LoadSoundAliasHeader(const std::vector& values) +{ + for (auto i = 0u; i < values.size(); i++) + { + AliasHeaders[values[i]] = i; + } +} + +const char* GetSoundAliasValue(const std::string& header, const std::vector& values, bool required = false) +{ + if (AliasHeaders.find(header) == AliasHeaders.end()) + { + if (required) + std::cerr << "ERROR: Required column \"" << header << "\" was not found"; + else + std::cerr << "WARNING: Expected column \"" << header << "\" was not found"; + return nullptr; + } + + auto value = values.at(AliasHeaders[header]).c_str(); + if (required && (!value || !*value)) + { + std::cerr << "ERROR: Required column \"" << header << "\" does not have a value"; + return nullptr; + } + + return value; +} + +char* GetSoundAliasValueString(const std::string& header, const std::vector& values, MemoryManager* memory, bool required = false) +{ + const auto* value = GetSoundAliasValue(header, values, required); + return value ? memory->Dup(value) : nullptr; +} + +int32_t GetSoundAliasValueInt(const std::string& header, const std::vector& values, bool required = false) +{ + const auto* value = GetSoundAliasValue(header, values, required); + if (value && *value) + return std::stoi(value); + return 0; +} + +size_t GetSoundAliasValueIndex( + const std::string& header, const std::vector& values, const std::string* lookupTable, size_t len, bool required = false) +{ + const auto* value = GetSoundAliasValue(header, values, required); + if (!value || !*value) + return 0; + + for (auto i = 0u; i < len; i++) + { + if (lookupTable[i] == value) + return i; + } + + return 0; +} + +bool GetSoundAliasValueBool(const std::string& header, const std::vector& values, const std::string& comparison, bool required = false) +{ + const auto* value = GetSoundAliasValue(header, values, required); + if (value && *value) + return comparison == value; + return false; +} + +bool LoadSoundAlias(MemoryManager* memory, SndAlias* alias, const std::vector& values) +{ + const auto* name = GetSoundAliasValue("name", values, true); + if (name == nullptr) + return false; + + const auto* aliasFileName = GetSoundAliasValue("file", values, true); + if (aliasFileName == nullptr) + return false; + + alias->name = memory->Dup(name); + alias->id = Common::SND_HashName(name); + alias->assetFileName = memory->Dup(aliasFileName); + alias->assetId = Common::SND_HashName(aliasFileName); + alias->secondaryname = GetSoundAliasValueString("secondary", values, memory); + alias->subtitle = GetSoundAliasValueString("subtitle", values, memory); + + alias->duck = Common::SND_HashName(GetSoundAliasValue("duck", values)); + + alias->volMin = GetSoundAliasValueInt("vol_min", values); + alias->volMax = GetSoundAliasValueInt("vol_max", values); + alias->distMin = GetSoundAliasValueInt("dist_min", values); + alias->distMax = GetSoundAliasValueInt("dist_max", values); + alias->distReverbMax = GetSoundAliasValueInt("dist_reverb_max", values); + alias->limitCount = GetSoundAliasValueInt("limit_count", values); + alias->entityLimitCount = GetSoundAliasValueInt("entity_limit_count", values); + alias->pitchMin = GetSoundAliasValueInt("pitch_min", values); + alias->pitchMax = GetSoundAliasValueInt("pitch_max", values); + alias->minPriority = GetSoundAliasValueInt("min_priority", values); + alias->maxPriority = GetSoundAliasValueInt("max_priority", values); + alias->minPriorityThreshold = GetSoundAliasValueInt("min_priority_threshold", values); + alias->maxPriorityThreshold = GetSoundAliasValueInt("max_priority_threshold", values); + alias->probability = GetSoundAliasValueInt("probability", values); + alias->startDelay = GetSoundAliasValueInt("start_delay", values); + alias->reverbSend = GetSoundAliasValueInt("reverb_send", values); + alias->centerSend = GetSoundAliasValueInt("center_send", values); + alias->envelopMin = GetSoundAliasValueInt("envelop_min", values); + alias->envelopMax = GetSoundAliasValueInt("envelop_max", values); + alias->envelopPercentage = GetSoundAliasValueInt("envelop_percentage", values); + alias->occlusionLevel = GetSoundAliasValueInt("occlusion_level", values); + alias->fluxTime = GetSoundAliasValueInt("move_time", values); + alias->futzPatch = GetSoundAliasValueInt("futz", values); + alias->contextType = GetSoundAliasValueInt("context_type", values); + alias->contextValue = GetSoundAliasValueInt("context_value", values); + alias->fadeIn = GetSoundAliasValueInt("fade_in", values); + alias->fadeOut = GetSoundAliasValueInt("fade_out", values); + + alias->flags.looping = GetSoundAliasValueBool("loop", values, "looping"); + alias->flags.panType = GetSoundAliasValueBool("pan", values, "3d"); + alias->flags.isBig = GetSoundAliasValueBool("is_big", values, "yes"); + alias->flags.distanceLpf = GetSoundAliasValueBool("distance_lpf", values, "yes"); + alias->flags.doppler = GetSoundAliasValueBool("doppler", values, "yes"); + alias->flags.timescale = GetSoundAliasValueBool("timescale", values, "yes"); + alias->flags.isMusic = GetSoundAliasValueBool("music", values, "yes"); + alias->flags.pauseable = GetSoundAliasValueBool("pause", values, "yes"); + alias->flags.stopOnDeath = GetSoundAliasValueBool("stop_on_death", values, "yes"); + + alias->flags.volumeGroup = GetSoundAliasValueIndex("group", values, ObjConstants::SOUND_GROUPS.data(), ObjConstants::SOUND_GROUPS.size()); + alias->flags.fluxType = GetSoundAliasValueIndex("move_type", values, ObjConstants::SOUND_MOVE_TYPES.data(), ObjConstants::SOUND_MOVE_TYPES.size()); + alias->flags.loadType = GetSoundAliasValueIndex("type", values, ObjConstants::SOUND_LOAD_TYPES.data(), ObjConstants::SOUND_LOAD_TYPES.size()); + alias->flags.busType = GetSoundAliasValueIndex("bus", values, ObjConstants::SOUND_BUS_IDS.data(), ObjConstants::SOUND_BUS_IDS.size()); + alias->flags.limitType = GetSoundAliasValueIndex("limit_type", values, ObjConstants::SOUND_LIMIT_TYPES.data(), ObjConstants::SOUND_LIMIT_TYPES.size()); + alias->flags.entityLimitType = + GetSoundAliasValueIndex("entity_limit_type", values, ObjConstants::SOUND_LIMIT_TYPES.data(), ObjConstants::SOUND_LIMIT_TYPES.size()); + alias->flags.volumeFalloffCurve = + GetSoundAliasValueIndex("volume_falloff_curve", values, ObjConstants::SOUND_CURVES.data(), ObjConstants::SOUND_CURVES.size()); + alias->flags.reverbFalloffCurve = + GetSoundAliasValueIndex("reverb_falloff_curve", values, ObjConstants::SOUND_CURVES.data(), ObjConstants::SOUND_CURVES.size()); + alias->flags.volumeMinFalloffCurve = + GetSoundAliasValueIndex("volume_min_falloff_curve", values, ObjConstants::SOUND_CURVES.data(), ObjConstants::SOUND_CURVES.size()); + alias->flags.reverbMinFalloffCurve = + GetSoundAliasValueIndex("reverb_min_falloff_curve", values, ObjConstants::SOUND_CURVES.data(), ObjConstants::SOUND_CURVES.size()); + alias->flags.randomizeType = + GetSoundAliasValueIndex("type", values, ObjConstants::SOUND_RANDOMIZE_TYPES.data(), ObjConstants::SOUND_RANDOMIZE_TYPES.size()); + + return true; +} + +bool LoadSoundAliasList(MemoryManager* memory, SndBank* sndBank, const SearchPathOpenFile& file) +{ + const CsvInputStream aliasCsv(*file.m_stream); + std::vector> csvLines; + std::vector currentLine; + auto maxCols = 0u; + + while (aliasCsv.NextRow(currentLine)) + { + if (currentLine.size() > maxCols) + maxCols = currentLine.size(); + csvLines.emplace_back(std::move(currentLine)); + currentLine = std::vector(); + } + + // Ensure there is at least one entry in the csv after the headers + if (maxCols * csvLines.size() > maxCols) + { + sndBank->aliasCount = 1; + sndBank->alias = static_cast(memory->Alloc(sizeof(SndAliasList))); + + sndBank->alias->count = csvLines.size() - 1; + sndBank->alias->head = static_cast(memory->Alloc(sizeof(SndAlias) * sndBank->alias->count)); + sndBank->alias->sequence = 0; + + LoadSoundAliasHeader(csvLines[0]); + + for (auto row = 1u; row < csvLines.size(); row++) + { + const auto& aliasValues = csvLines[row]; + if (!LoadSoundAlias(memory, &sndBank->alias->head[row - 1], aliasValues)) + return false; + } + + sndBank->alias->id = sndBank->alias->head[0].id; + sndBank->alias->name = sndBank->alias->head[0].name; + } + + return true; +} + +bool AssetLoaderSoundBank::LoadFromRaw( + const std::string& assetName, ISearchPath* searchPath, MemoryManager* memory, IAssetLoadingManager* manager, Zone* zone) const +{ + if (assetName.find('.') == std::string::npos) + { + std::cerr << "A language must be specific in the soundbank asset name! (Ex: mpl_common.all)" << std::endl; + return false; + } + + // open the soundbank aliases + const auto aliasFile = searchPath->Open("soundbank/" + assetName + ".aliases.csv"); + if (!aliasFile.IsOpen()) + return false; + + // set the defaults + auto* sndBank = memory->Create(); + sndBank->name = memory->Dup(assetName.c_str()); + + auto sndBankLocalization = utils::StringSplit(assetName, '.'); + const auto* zoneName = memory->Dup(sndBankLocalization.at(0).c_str()); + const auto* languageName = memory->Dup(sndBankLocalization.at(1).c_str()); + + sndBank->streamAssetBank.zone = zoneName; + sndBank->streamAssetBank.language = languageName; + sndBank->loadAssetBank.zone = zoneName; + sndBank->loadAssetBank.language = languageName; + sndBank->loadedAssets.zone = zoneName; + sndBank->loadedAssets.language = languageName; + sndBank->loadedAssets.loadedCount = 0; + + if (!LoadSoundAliasList(memory, sndBank, aliasFile)) + return false; + + // open the soundbank reverbs + + // open the soundbank ducks + + manager->AddAsset(ASSET_TYPE_SOUND, assetName, sndBank); + return true; +} diff --git a/src/ObjLoading/Game/T6/AssetLoaders/AssetLoaderSoundBank.h b/src/ObjLoading/Game/T6/AssetLoaders/AssetLoaderSoundBank.h new file mode 100644 index 00000000..f7f8154d --- /dev/null +++ b/src/ObjLoading/Game/T6/AssetLoaders/AssetLoaderSoundBank.h @@ -0,0 +1,17 @@ +#pragma once +#include "AssetLoading/BasicAssetLoader.h" +#include "AssetLoading/IAssetLoadingManager.h" +#include "Game/T6/T6.h" +#include "SearchPath/ISearchPath.h" + +namespace T6 +{ + class AssetLoaderSoundBank final : public BasicAssetLoader + { + public: + _NODISCARD void* CreateEmptyAsset(const std::string& assetName, MemoryManager* memory) override; + _NODISCARD bool CanLoadFromRaw() const override; + bool + LoadFromRaw(const std::string& assetName, ISearchPath* searchPath, MemoryManager* memory, IAssetLoadingManager* manager, Zone* zone) const override; + }; +} // namespace T6 diff --git a/src/ObjLoading/Game/T6/ObjLoaderT6.cpp b/src/ObjLoading/Game/T6/ObjLoaderT6.cpp index 431a3ca4..dcff00e5 100644 --- a/src/ObjLoading/Game/T6/ObjLoaderT6.cpp +++ b/src/ObjLoading/Game/T6/ObjLoaderT6.cpp @@ -9,6 +9,7 @@ #include "AssetLoaders/AssetLoaderRawFile.h" #include "AssetLoaders/AssetLoaderScriptParseTree.h" #include "AssetLoaders/AssetLoaderSlug.h" +#include "AssetLoaders/AssetLoaderSoundBank.h" #include "AssetLoaders/AssetLoaderStringTable.h" #include "AssetLoaders/AssetLoaderTracer.h" #include "AssetLoaders/AssetLoaderVehicle.h" @@ -51,7 +52,7 @@ namespace T6 REGISTER_ASSET_LOADER(BASIC_LOADER(ASSET_TYPE_MATERIAL, Material)) REGISTER_ASSET_LOADER(BASIC_LOADER(ASSET_TYPE_TECHNIQUE_SET, MaterialTechniqueSet)) REGISTER_ASSET_LOADER(AssetLoaderGfxImage) - REGISTER_ASSET_LOADER(BASIC_LOADER(ASSET_TYPE_SOUND, SndBank)) + REGISTER_ASSET_LOADER(AssetLoaderSoundBank) REGISTER_ASSET_LOADER(BASIC_LOADER(ASSET_TYPE_SOUND_PATCH, SndPatch)) REGISTER_ASSET_LOADER(BASIC_LOADER(ASSET_TYPE_CLIPMAP, clipMap_t)) REGISTER_ASSET_LOADER(BASIC_LOADER(ASSET_TYPE_CLIPMAP_PVS, clipMap_t)) diff --git a/src/ObjWriting/Game/T6/AssetDumpers/AssetDumperSndBank.cpp b/src/ObjWriting/Game/T6/AssetDumpers/AssetDumperSndBank.cpp index b36a4f3c..c01cc4e3 100644 --- a/src/ObjWriting/Game/T6/AssetDumpers/AssetDumperSndBank.cpp +++ b/src/ObjWriting/Game/T6/AssetDumpers/AssetDumperSndBank.cpp @@ -2,6 +2,7 @@ #include "Csv/CsvStream.h" #include "Game/T6/CommonT6.h" +#include "Game/T6/ObjConstantsT6.h" #include "ObjContainer/SoundBank/SoundBank.h" #include "Sound/WavWriter.h" #include "nlohmann/json.hpp" @@ -118,147 +119,15 @@ namespace 192000, }; - const std::string GROUPS_ENUM[]{ - "grp_reference", - "grp_master", - "grp_wpn_lfe", - "grp_lfe", - "grp_hdrfx", - "grp_music", - "grp_voice", - "grp_set_piece", - "grp_igc", - "grp_mp_game", - "grp_explosion", - "grp_player_impacts", - "grp_scripted_moment", - "grp_menu", - "grp_whizby", - "grp_weapon", - "grp_vehicle", - "grp_impacts", - "grp_foley", - "grp_destructible", - "grp_physics", - "grp_ambience", - "grp_alerts", - "grp_air", - "grp_bink", - "grp_announcer", - "", - }; - - const std::string CURVES_ENUM[]{ - "default", - "defaultmin", - "allon", - "alloff", - "rcurve0", - "rcurve1", - "rcurve2", - "rcurve3", - "rcurve4", - "rcurve5", - "steep", - "sindelay", - "cosdelay", - "sin", - "cos", - "rev60", - "rev65", - "", - }; - std::unordered_map CreateCurvesMap() { std::unordered_map result; - for (auto i = 0u; i < std::extent_v; i++) - result.emplace(T6::Common::SND_HashName(CURVES_ENUM[i].data()), CURVES_ENUM[i]); + for (auto i = 0u; i < ObjConstants::SOUND_CURVES.size(); i++) + result.emplace(T6::Common::SND_HashName(ObjConstants::SOUND_CURVES[i].data()), ObjConstants::SOUND_CURVES[i]); return result; } const std::unordered_map CURVES_MAP = CreateCurvesMap(); - - const std::string DUCK_GROUPS_ENUM[]{ - "snp_alerts_gameplay", - "snp_ambience", - "snp_claw", - "snp_destructible", - "snp_dying", - "snp_dying_ice", - "snp_evt_2d", - "snp_explosion", - "snp_foley", - "snp_grenade", - "snp_hdrfx", - "snp_igc", - "snp_impacts", - "snp_menu", - "snp_movie", - "snp_music", - "snp_never_duck", - "snp_player_dead", - "snp_player_impacts", - "snp_scripted_moment", - "snp_set_piece", - "snp_special", - "snp_vehicle", - "snp_vehicle_interior", - "snp_voice", - "snp_weapon_decay_1p", - "snp_whizby", - "snp_wpn_1p", - "snp_wpn_3p", - "snp_wpn_turret", - "snp_x2", - "snp_x3", - }; - - const std::string LIMIT_TYPES_ENUM[]{ - "none", - "oldest", - "reject", - "priority", - }; - - const std::string MOVE_TYPES_ENUM[]{ - "none", - "left_player", - "center_player", - "right_player", - "random", - "left_shot", - "center_shot", - "right_shot", - }; - - const std::string LOAD_TYPES_ENUM[]{ - "unknown", - "loaded", - "streamed", - "primed", - }; - - const std::string BUS_IDS_ENUM[]{ - "bus_reverb", - "bus_fx", - "bus_voice", - "bus_pfutz", - "bus_hdrfx", - "bus_ui", - "bus_reference", - "bus_music", - "bus_movie", - "bus_reference", - "", - }; - - const std::string RANDOMIZE_TYPES_ENUM[]{ - "volume", - "pitch", - "variant", - "", - }; } // namespace class AssetDumperSndBank::Internal @@ -356,7 +225,7 @@ class AssetDumperSndBank::Internal stream.WriteColumn((alias->secondaryname && *alias->secondaryname) ? alias->secondaryname : ""); // group - stream.WriteColumn(GROUPS_ENUM[alias->flags.volumeGroup]); + stream.WriteColumn(ObjConstants::SOUND_GROUPS[alias->flags.volumeGroup]); // vol_min stream.WriteColumn(std::to_string(alias->volMin)); @@ -377,28 +246,28 @@ class AssetDumperSndBank::Internal stream.WriteColumn(std::to_string(alias->distReverbMax)); // volume_falloff_curve - stream.WriteColumn(CURVES_ENUM[alias->flags.volumeFalloffCurve]); + stream.WriteColumn(ObjConstants::SOUND_CURVES[alias->flags.volumeFalloffCurve]); // reverb_falloff_curve - stream.WriteColumn(CURVES_ENUM[alias->flags.reverbFalloffCurve]); + stream.WriteColumn(ObjConstants::SOUND_CURVES[alias->flags.reverbFalloffCurve]); // volume_min_falloff_curve - stream.WriteColumn(CURVES_ENUM[alias->flags.volumeMinFalloffCurve]); + stream.WriteColumn(ObjConstants::SOUND_CURVES[alias->flags.volumeMinFalloffCurve]); // reverb_min_falloff_curve" - stream.WriteColumn(CURVES_ENUM[alias->flags.reverbMinFalloffCurve]); + stream.WriteColumn(ObjConstants::SOUND_CURVES[alias->flags.reverbMinFalloffCurve]); // limit_count stream.WriteColumn(std::to_string(alias->limitCount)); // limit_type - stream.WriteColumn(LIMIT_TYPES_ENUM[alias->flags.limitType]); + stream.WriteColumn(ObjConstants::SOUND_LIMIT_TYPES[alias->flags.limitType]); // entity_limit_count stream.WriteColumn(std::to_string(alias->entityLimitCount)); // entity_limit_type - stream.WriteColumn(LIMIT_TYPES_ENUM[alias->flags.entityLimitType]); + stream.WriteColumn(ObjConstants::SOUND_LIMIT_TYPES[alias->flags.entityLimitType]); // pitch_min stream.WriteColumn(std::to_string(alias->pitchMin)); @@ -425,13 +294,13 @@ class AssetDumperSndBank::Internal stream.WriteColumn(""); // type - stream.WriteColumn(LOAD_TYPES_ENUM[alias->flags.loadType]); + stream.WriteColumn(ObjConstants::SOUND_LOAD_TYPES[alias->flags.loadType]); // loop stream.WriteColumn(alias->flags.looping == T6::SA_NON_LOOPING ? "nonlooping" : "looping"); // randomize_type - stream.WriteColumn(RANDOMIZE_TYPES_ENUM[alias->flags.randomizeType]); + stream.WriteColumn(ObjConstants::SOUND_RANDOMIZE_TYPES[std::min(alias->flags.randomizeType, 3u)]); // probability", stream.WriteColumn(std::to_string(alias->probability)); @@ -473,7 +342,7 @@ class AssetDumperSndBank::Internal stream.WriteColumn(alias->flags.distanceLpf ? "yes" : "no"); // move_type", - stream.WriteColumn(MOVE_TYPES_ENUM[alias->flags.fluxType]); + stream.WriteColumn(ObjConstants::SOUND_MOVE_TYPES[alias->flags.fluxType]); // move_time", stream.WriteColumn(std::to_string(alias->fluxTime)); @@ -524,7 +393,7 @@ class AssetDumperSndBank::Internal stream.WriteColumn(alias->flags.stopOnDeath ? "yes" : "no"); // bus", - stream.WriteColumn(BUS_IDS_ENUM[alias->flags.busType]); + stream.WriteColumn(ObjConstants::SOUND_BUS_IDS[alias->flags.busType]); // snapshot", stream.WriteColumn(""); @@ -757,9 +626,9 @@ class AssetDumperSndBank::Internal for (auto i = 0u; i < 32u; i++) { values.push_back({ - {"duckGroup", DUCK_GROUPS_ENUM[i]}, - {"attenuation", duck.attenuation[i]}, - {"filter", duck.filter[i] } + {"duckGroup", ObjConstants::SOUND_DUCK_GROUPS[i]}, + {"attenuation", duck.attenuation[i] }, + {"filter", duck.filter[i] } }); } diff --git a/src/Utils/Utils/StringUtils.cpp b/src/Utils/Utils/StringUtils.cpp index bf8904da..31368acd 100644 --- a/src/Utils/Utils/StringUtils.cpp +++ b/src/Utils/Utils/StringUtils.cpp @@ -1,6 +1,7 @@ #include "StringUtils.h" #include +#include namespace utils { @@ -100,4 +101,18 @@ namespace utils for (auto& c : str) c = static_cast(toupper(static_cast(c))); } + + std::vector StringSplit(const std::string& str, const char delim) + { + std::vector strings{}; + std::istringstream stream(str); + + std::string s; + while (std::getline(stream, s, delim)) + { + strings.push_back(s); + } + + return strings; + } } // namespace utils diff --git a/src/Utils/Utils/StringUtils.h b/src/Utils/Utils/StringUtils.h index ca3f771d..4104c4f1 100644 --- a/src/Utils/Utils/StringUtils.h +++ b/src/Utils/Utils/StringUtils.h @@ -1,5 +1,6 @@ #pragma once #include +#include namespace utils { @@ -14,4 +15,6 @@ namespace utils void MakeStringLowerCase(std::string& str); void MakeStringUpperCase(std::string& str); + + std::vector StringSplit(const std::string& str, const char delim); } // namespace utils