mirror of
https://github.com/Laupetin/OpenAssetTools.git
synced 2025-04-20 16:15:43 +00:00
begin working on SndBank loading from raw
This commit is contained in:
parent
48d320c99d
commit
b5dd6df1cd
137
src/ObjCommon/Game/T6/ObjConstantsT6.cpp
Normal file
137
src/ObjCommon/Game/T6/ObjConstantsT6.cpp
Normal file
@ -0,0 +1,137 @@
|
|||||||
|
#include "ObjConstantsT6.h"
|
||||||
|
|
||||||
|
namespace T6
|
||||||
|
{
|
||||||
|
const std::array<std::string, 27> 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<std::string, 18> ObjConstants::SOUND_CURVES{
|
||||||
|
"default",
|
||||||
|
"defaultmin",
|
||||||
|
"allon",
|
||||||
|
"alloff",
|
||||||
|
"rcurve0",
|
||||||
|
"rcurve1",
|
||||||
|
"rcurve2",
|
||||||
|
"rcurve3",
|
||||||
|
"rcurve4",
|
||||||
|
"rcurve5",
|
||||||
|
"steep",
|
||||||
|
"sindelay",
|
||||||
|
"cosdelay",
|
||||||
|
"sin",
|
||||||
|
"cos",
|
||||||
|
"rev60",
|
||||||
|
"rev65",
|
||||||
|
"",
|
||||||
|
};
|
||||||
|
|
||||||
|
const std::array<std::string, 32> 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<std::string, 4> ObjConstants::SOUND_LIMIT_TYPES{
|
||||||
|
"none",
|
||||||
|
"oldest",
|
||||||
|
"reject",
|
||||||
|
"priority",
|
||||||
|
};
|
||||||
|
|
||||||
|
const std::array<std::string, 8> ObjConstants::SOUND_MOVE_TYPES{
|
||||||
|
"none",
|
||||||
|
"left_player",
|
||||||
|
"center_player",
|
||||||
|
"right_player",
|
||||||
|
"random",
|
||||||
|
"left_shot",
|
||||||
|
"center_shot",
|
||||||
|
"right_shot",
|
||||||
|
};
|
||||||
|
|
||||||
|
const std::array<std::string, 4> ObjConstants::SOUND_LOAD_TYPES{
|
||||||
|
"unknown",
|
||||||
|
"loaded",
|
||||||
|
"streamed",
|
||||||
|
"primed",
|
||||||
|
};
|
||||||
|
|
||||||
|
const std::array<std::string, 11> 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<std::string, 4> ObjConstants::SOUND_RANDOMIZE_TYPES{
|
||||||
|
"volume",
|
||||||
|
"pitch",
|
||||||
|
"variant",
|
||||||
|
"",
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace T6
|
@ -1,4 +1,6 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
#include <array>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
namespace T6
|
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 = "attachment.gdf";
|
||||||
static constexpr const char* GDF_FILENAME_WEAPON_ATTACHMENT_UNIQUE = "attachmentunique.gdf";
|
static constexpr const char* GDF_FILENAME_WEAPON_ATTACHMENT_UNIQUE = "attachmentunique.gdf";
|
||||||
static constexpr const char* GDF_FILENAME_ZBARRIER = "zbarrier.gdf";
|
static constexpr const char* GDF_FILENAME_ZBARRIER = "zbarrier.gdf";
|
||||||
|
|
||||||
|
static const std::array<std::string, 27> SOUND_GROUPS;
|
||||||
|
static const std::array<std::string, 18> SOUND_CURVES;
|
||||||
|
static const std::array<std::string, 32> SOUND_DUCK_GROUPS;
|
||||||
|
static const std::array<std::string, 4> SOUND_LIMIT_TYPES;
|
||||||
|
static const std::array<std::string, 8> SOUND_MOVE_TYPES;
|
||||||
|
static const std::array<std::string, 4> SOUND_LOAD_TYPES;
|
||||||
|
static const std::array<std::string, 11> SOUND_BUS_IDS;
|
||||||
|
static const std::array<std::string, 4> SOUND_RANDOMIZE_TYPES;
|
||||||
};
|
};
|
||||||
} // namespace T6
|
} // namespace T6
|
||||||
|
254
src/ObjLoading/Game/T6/AssetLoaders/AssetLoaderSoundBank.cpp
Normal file
254
src/ObjLoading/Game/T6/AssetLoaders/AssetLoaderSoundBank.cpp
Normal file
@ -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 <Utils/StringUtils.h>
|
||||||
|
#include <cstring>
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
|
using namespace T6;
|
||||||
|
std::unordered_map<std::string, unsigned int> AliasHeaders{};
|
||||||
|
|
||||||
|
void* AssetLoaderSoundBank::CreateEmptyAsset(const std::string& assetName, MemoryManager* memory)
|
||||||
|
{
|
||||||
|
auto* soundBank = memory->Create<SndBank>();
|
||||||
|
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<std::string>& values)
|
||||||
|
{
|
||||||
|
for (auto i = 0u; i < values.size(); i++)
|
||||||
|
{
|
||||||
|
AliasHeaders[values[i]] = i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const char* GetSoundAliasValue(const std::string& header, const std::vector<std::string>& 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<std::string>& 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<std::string>& 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<std::string>& 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<std::string>& 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<std::string>& 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<std::vector<std::string>> csvLines;
|
||||||
|
std::vector<std::string> currentLine;
|
||||||
|
auto maxCols = 0u;
|
||||||
|
|
||||||
|
while (aliasCsv.NextRow(currentLine))
|
||||||
|
{
|
||||||
|
if (currentLine.size() > maxCols)
|
||||||
|
maxCols = currentLine.size();
|
||||||
|
csvLines.emplace_back(std::move(currentLine));
|
||||||
|
currentLine = std::vector<std::string>();
|
||||||
|
}
|
||||||
|
|
||||||
|
// 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<SndAliasList*>(memory->Alloc(sizeof(SndAliasList)));
|
||||||
|
|
||||||
|
sndBank->alias->count = csvLines.size() - 1;
|
||||||
|
sndBank->alias->head = static_cast<SndAlias*>(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>();
|
||||||
|
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;
|
||||||
|
}
|
17
src/ObjLoading/Game/T6/AssetLoaders/AssetLoaderSoundBank.h
Normal file
17
src/ObjLoading/Game/T6/AssetLoaders/AssetLoaderSoundBank.h
Normal file
@ -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<ASSET_TYPE_SOUND, SndBank>
|
||||||
|
{
|
||||||
|
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
|
@ -9,6 +9,7 @@
|
|||||||
#include "AssetLoaders/AssetLoaderRawFile.h"
|
#include "AssetLoaders/AssetLoaderRawFile.h"
|
||||||
#include "AssetLoaders/AssetLoaderScriptParseTree.h"
|
#include "AssetLoaders/AssetLoaderScriptParseTree.h"
|
||||||
#include "AssetLoaders/AssetLoaderSlug.h"
|
#include "AssetLoaders/AssetLoaderSlug.h"
|
||||||
|
#include "AssetLoaders/AssetLoaderSoundBank.h"
|
||||||
#include "AssetLoaders/AssetLoaderStringTable.h"
|
#include "AssetLoaders/AssetLoaderStringTable.h"
|
||||||
#include "AssetLoaders/AssetLoaderTracer.h"
|
#include "AssetLoaders/AssetLoaderTracer.h"
|
||||||
#include "AssetLoaders/AssetLoaderVehicle.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_MATERIAL, Material))
|
||||||
REGISTER_ASSET_LOADER(BASIC_LOADER(ASSET_TYPE_TECHNIQUE_SET, MaterialTechniqueSet))
|
REGISTER_ASSET_LOADER(BASIC_LOADER(ASSET_TYPE_TECHNIQUE_SET, MaterialTechniqueSet))
|
||||||
REGISTER_ASSET_LOADER(AssetLoaderGfxImage)
|
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_SOUND_PATCH, SndPatch))
|
||||||
REGISTER_ASSET_LOADER(BASIC_LOADER(ASSET_TYPE_CLIPMAP, clipMap_t))
|
REGISTER_ASSET_LOADER(BASIC_LOADER(ASSET_TYPE_CLIPMAP, clipMap_t))
|
||||||
REGISTER_ASSET_LOADER(BASIC_LOADER(ASSET_TYPE_CLIPMAP_PVS, clipMap_t))
|
REGISTER_ASSET_LOADER(BASIC_LOADER(ASSET_TYPE_CLIPMAP_PVS, clipMap_t))
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
#include "Csv/CsvStream.h"
|
#include "Csv/CsvStream.h"
|
||||||
#include "Game/T6/CommonT6.h"
|
#include "Game/T6/CommonT6.h"
|
||||||
|
#include "Game/T6/ObjConstantsT6.h"
|
||||||
#include "ObjContainer/SoundBank/SoundBank.h"
|
#include "ObjContainer/SoundBank/SoundBank.h"
|
||||||
#include "Sound/WavWriter.h"
|
#include "Sound/WavWriter.h"
|
||||||
#include "nlohmann/json.hpp"
|
#include "nlohmann/json.hpp"
|
||||||
@ -118,147 +119,15 @@ namespace
|
|||||||
192000,
|
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<unsigned int, std::string> CreateCurvesMap()
|
std::unordered_map<unsigned int, std::string> CreateCurvesMap()
|
||||||
{
|
{
|
||||||
std::unordered_map<unsigned int, std::string> result;
|
std::unordered_map<unsigned int, std::string> result;
|
||||||
for (auto i = 0u; i < std::extent_v<decltype(CURVES_ENUM)>; i++)
|
for (auto i = 0u; i < ObjConstants::SOUND_CURVES.size(); i++)
|
||||||
result.emplace(T6::Common::SND_HashName(CURVES_ENUM[i].data()), CURVES_ENUM[i]);
|
result.emplace(T6::Common::SND_HashName(ObjConstants::SOUND_CURVES[i].data()), ObjConstants::SOUND_CURVES[i]);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
const std::unordered_map<unsigned int, std::string> CURVES_MAP = CreateCurvesMap();
|
const std::unordered_map<unsigned int, std::string> 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
|
} // namespace
|
||||||
|
|
||||||
class AssetDumperSndBank::Internal
|
class AssetDumperSndBank::Internal
|
||||||
@ -356,7 +225,7 @@ class AssetDumperSndBank::Internal
|
|||||||
stream.WriteColumn((alias->secondaryname && *alias->secondaryname) ? alias->secondaryname : "");
|
stream.WriteColumn((alias->secondaryname && *alias->secondaryname) ? alias->secondaryname : "");
|
||||||
|
|
||||||
// group
|
// group
|
||||||
stream.WriteColumn(GROUPS_ENUM[alias->flags.volumeGroup]);
|
stream.WriteColumn(ObjConstants::SOUND_GROUPS[alias->flags.volumeGroup]);
|
||||||
|
|
||||||
// vol_min
|
// vol_min
|
||||||
stream.WriteColumn(std::to_string(alias->volMin));
|
stream.WriteColumn(std::to_string(alias->volMin));
|
||||||
@ -377,28 +246,28 @@ class AssetDumperSndBank::Internal
|
|||||||
stream.WriteColumn(std::to_string(alias->distReverbMax));
|
stream.WriteColumn(std::to_string(alias->distReverbMax));
|
||||||
|
|
||||||
// volume_falloff_curve
|
// volume_falloff_curve
|
||||||
stream.WriteColumn(CURVES_ENUM[alias->flags.volumeFalloffCurve]);
|
stream.WriteColumn(ObjConstants::SOUND_CURVES[alias->flags.volumeFalloffCurve]);
|
||||||
|
|
||||||
// reverb_falloff_curve
|
// reverb_falloff_curve
|
||||||
stream.WriteColumn(CURVES_ENUM[alias->flags.reverbFalloffCurve]);
|
stream.WriteColumn(ObjConstants::SOUND_CURVES[alias->flags.reverbFalloffCurve]);
|
||||||
|
|
||||||
// volume_min_falloff_curve
|
// volume_min_falloff_curve
|
||||||
stream.WriteColumn(CURVES_ENUM[alias->flags.volumeMinFalloffCurve]);
|
stream.WriteColumn(ObjConstants::SOUND_CURVES[alias->flags.volumeMinFalloffCurve]);
|
||||||
|
|
||||||
// reverb_min_falloff_curve"
|
// reverb_min_falloff_curve"
|
||||||
stream.WriteColumn(CURVES_ENUM[alias->flags.reverbMinFalloffCurve]);
|
stream.WriteColumn(ObjConstants::SOUND_CURVES[alias->flags.reverbMinFalloffCurve]);
|
||||||
|
|
||||||
// limit_count
|
// limit_count
|
||||||
stream.WriteColumn(std::to_string(alias->limitCount));
|
stream.WriteColumn(std::to_string(alias->limitCount));
|
||||||
|
|
||||||
// limit_type
|
// limit_type
|
||||||
stream.WriteColumn(LIMIT_TYPES_ENUM[alias->flags.limitType]);
|
stream.WriteColumn(ObjConstants::SOUND_LIMIT_TYPES[alias->flags.limitType]);
|
||||||
|
|
||||||
// entity_limit_count
|
// entity_limit_count
|
||||||
stream.WriteColumn(std::to_string(alias->entityLimitCount));
|
stream.WriteColumn(std::to_string(alias->entityLimitCount));
|
||||||
|
|
||||||
// entity_limit_type
|
// entity_limit_type
|
||||||
stream.WriteColumn(LIMIT_TYPES_ENUM[alias->flags.entityLimitType]);
|
stream.WriteColumn(ObjConstants::SOUND_LIMIT_TYPES[alias->flags.entityLimitType]);
|
||||||
|
|
||||||
// pitch_min
|
// pitch_min
|
||||||
stream.WriteColumn(std::to_string(alias->pitchMin));
|
stream.WriteColumn(std::to_string(alias->pitchMin));
|
||||||
@ -425,13 +294,13 @@ class AssetDumperSndBank::Internal
|
|||||||
stream.WriteColumn("");
|
stream.WriteColumn("");
|
||||||
|
|
||||||
// type
|
// type
|
||||||
stream.WriteColumn(LOAD_TYPES_ENUM[alias->flags.loadType]);
|
stream.WriteColumn(ObjConstants::SOUND_LOAD_TYPES[alias->flags.loadType]);
|
||||||
|
|
||||||
// loop
|
// loop
|
||||||
stream.WriteColumn(alias->flags.looping == T6::SA_NON_LOOPING ? "nonlooping" : "looping");
|
stream.WriteColumn(alias->flags.looping == T6::SA_NON_LOOPING ? "nonlooping" : "looping");
|
||||||
|
|
||||||
// randomize_type
|
// randomize_type
|
||||||
stream.WriteColumn(RANDOMIZE_TYPES_ENUM[alias->flags.randomizeType]);
|
stream.WriteColumn(ObjConstants::SOUND_RANDOMIZE_TYPES[std::min(alias->flags.randomizeType, 3u)]);
|
||||||
|
|
||||||
// probability",
|
// probability",
|
||||||
stream.WriteColumn(std::to_string(alias->probability));
|
stream.WriteColumn(std::to_string(alias->probability));
|
||||||
@ -473,7 +342,7 @@ class AssetDumperSndBank::Internal
|
|||||||
stream.WriteColumn(alias->flags.distanceLpf ? "yes" : "no");
|
stream.WriteColumn(alias->flags.distanceLpf ? "yes" : "no");
|
||||||
|
|
||||||
// move_type",
|
// move_type",
|
||||||
stream.WriteColumn(MOVE_TYPES_ENUM[alias->flags.fluxType]);
|
stream.WriteColumn(ObjConstants::SOUND_MOVE_TYPES[alias->flags.fluxType]);
|
||||||
|
|
||||||
// move_time",
|
// move_time",
|
||||||
stream.WriteColumn(std::to_string(alias->fluxTime));
|
stream.WriteColumn(std::to_string(alias->fluxTime));
|
||||||
@ -524,7 +393,7 @@ class AssetDumperSndBank::Internal
|
|||||||
stream.WriteColumn(alias->flags.stopOnDeath ? "yes" : "no");
|
stream.WriteColumn(alias->flags.stopOnDeath ? "yes" : "no");
|
||||||
|
|
||||||
// bus",
|
// bus",
|
||||||
stream.WriteColumn(BUS_IDS_ENUM[alias->flags.busType]);
|
stream.WriteColumn(ObjConstants::SOUND_BUS_IDS[alias->flags.busType]);
|
||||||
|
|
||||||
// snapshot",
|
// snapshot",
|
||||||
stream.WriteColumn("");
|
stream.WriteColumn("");
|
||||||
@ -757,9 +626,9 @@ class AssetDumperSndBank::Internal
|
|||||||
for (auto i = 0u; i < 32u; i++)
|
for (auto i = 0u; i < 32u; i++)
|
||||||
{
|
{
|
||||||
values.push_back({
|
values.push_back({
|
||||||
{"duckGroup", DUCK_GROUPS_ENUM[i]},
|
{"duckGroup", ObjConstants::SOUND_DUCK_GROUPS[i]},
|
||||||
{"attenuation", duck.attenuation[i]},
|
{"attenuation", duck.attenuation[i] },
|
||||||
{"filter", duck.filter[i] }
|
{"filter", duck.filter[i] }
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
#include "StringUtils.h"
|
#include "StringUtils.h"
|
||||||
|
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
namespace utils
|
namespace utils
|
||||||
{
|
{
|
||||||
@ -100,4 +101,18 @@ namespace utils
|
|||||||
for (auto& c : str)
|
for (auto& c : str)
|
||||||
c = static_cast<char>(toupper(static_cast<unsigned char>(c)));
|
c = static_cast<char>(toupper(static_cast<unsigned char>(c)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::vector<std::string> StringSplit(const std::string& str, const char delim)
|
||||||
|
{
|
||||||
|
std::vector<std::string> strings{};
|
||||||
|
std::istringstream stream(str);
|
||||||
|
|
||||||
|
std::string s;
|
||||||
|
while (std::getline(stream, s, delim))
|
||||||
|
{
|
||||||
|
strings.push_back(s);
|
||||||
|
}
|
||||||
|
|
||||||
|
return strings;
|
||||||
|
}
|
||||||
} // namespace utils
|
} // namespace utils
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
#include <string>
|
#include <string>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
namespace utils
|
namespace utils
|
||||||
{
|
{
|
||||||
@ -14,4 +15,6 @@ namespace utils
|
|||||||
|
|
||||||
void MakeStringLowerCase(std::string& str);
|
void MakeStringLowerCase(std::string& str);
|
||||||
void MakeStringUpperCase(std::string& str);
|
void MakeStringUpperCase(std::string& str);
|
||||||
|
|
||||||
|
std::vector<std::string> StringSplit(const std::string& str, const char delim);
|
||||||
} // namespace utils
|
} // namespace utils
|
||||||
|
Loading…
x
Reference in New Issue
Block a user