T6 SndBank & SndDriverGlobals

This commit is contained in:
Alex 2023-12-11 22:43:20 -05:00
parent 2a6318e3ca
commit 15669fd58c
4 changed files with 870 additions and 152 deletions

View File

@ -4,6 +4,7 @@
#include "ObjContainer/SoundBank/SoundBank.h"
#include "Sound/WavWriter.h"
#include "Utils/ClassUtils.h"
#include "nlohmann/json.hpp"
#include <filesystem>
#include <fstream>
@ -15,71 +16,89 @@ namespace fs = std::filesystem;
namespace
{
const std::string ALIAS_HEADERS[]{
"# name",
"# file",
"# template",
"# loadspec",
"# secondary",
"# group",
"# vol_min",
"# vol_max",
"# team_vol_mod",
"# dist_min",
"# dist_max",
"# dist_reverb_max",
"# volume_falloff_curve",
"# reverb_falloff_curve",
"# volume_min_falloff_curve",
"# reverb_min_falloff_curve",
"# limit_count",
"# limit_type",
"# entity_limit_count",
"# entity_limit_type",
"# pitch_min",
"# pitch_max",
"# team_pitch_mod",
"# min_priority",
"# max_priority",
"# min_priority_threshold",
"# max_priority_threshold",
"# spatialized",
"# type",
"# loop",
"# randomize_type",
"# probability",
"# start_delay",
"# reverb_send",
"# duck",
"# pan",
"# center_send",
"# envelop_min",
"# envelop_max",
"# envelop_percentage",
"# occlusion_level",
"# occlusion_wet_dry",
"# is_big",
"# distance_lpf",
"# move_type",
"# move_time",
"# real_delay",
"# subtitle",
"# mature",
"# doppler",
"# futz",
"# context_type",
"# context_value",
"# compression",
"# timescale",
"# music",
"# fade_in",
"# fade_out",
"# pc_format",
"# pause",
"# stop_on_death",
"# bus",
"# snapshot",
"name",
"file",
"template",
"loadspec",
"secondary",
"group",
"vol_min",
"vol_max",
"team_vol_mod",
"dist_min",
"dist_max",
"dist_reverb_max",
"volume_falloff_curve",
"reverb_falloff_curve",
"volume_min_falloff_curve",
"reverb_min_falloff_curve",
"limit_count",
"limit_type",
"entity_limit_count",
"entity_limit_type",
"pitch_min",
"pitch_max",
"team_pitch_mod",
"min_priority",
"max_priority",
"min_priority_threshold",
"max_priority_threshold",
"spatialized",
"type",
"loop",
"randomize_type",
"probability",
"start_delay",
"reverb_send",
"duck",
"pan",
"center_send",
"envelop_min",
"envelop_max",
"envelop_percentage",
"occlusion_level",
"occlusion_wet_dry",
"is_big",
"distance_lpf",
"move_type",
"move_time",
"real_delay",
"subtitle",
"mature",
"doppler",
"futz",
"context_type",
"context_value",
"compression",
"timescale",
"music",
"fade_in",
"fade_out",
"pc_format",
"pause",
"stop_on_death",
"bus",
"snapshot",
};
const std::string REVERB_HEADERS[]{"name",
"smoothing",
"earlyTime",
"lateTime",
"earlyGain",
"lateGain",
"returnGain",
"earlyLpf",
"lateLpf",
"inputLpf",
"dampLpf",
"wallReflect",
"dryGain",
"earlySize",
"lateSize",
"diffusion",
"returnHighpass"};
const std::string PREFIXES_TO_DROP[]{
"raw/",
"devraw/",
@ -96,6 +115,119 @@ namespace
96000,
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",
""};
const std::unordered_map<unsigned int, std::string> CURVES_MAP{
{4135636924, CURVES_ENUM[0] }, // "default"
{1298231670, CURVES_ENUM[1] }, // "defaultmin"
{2783299419, CURVES_ENUM[2] }, // "allon"
{2598309331, CURVES_ENUM[3] }, // "alloff"
{2462421902, CURVES_ENUM[4] }, // "rcurve0"
{2462421903, CURVES_ENUM[5] }, // "rcurve1"
{2462421904, CURVES_ENUM[6] }, // "rcurve2"
{2462421905, CURVES_ENUM[7] }, // "rcurve3"
{2462421906, CURVES_ENUM[8] }, // "rcurve4"
{2462421907, CURVES_ENUM[9] }, // "rcurve5"
{3711863914, CURVES_ENUM[10]}, // "steep"
{4107033168, CURVES_ENUM[11]}, // "sindelay"
{932232097, CURVES_ENUM[12]}, // "cosdelay"
{818663411, CURVES_ENUM[13]}, // "sin"
{686872930, CURVES_ENUM[14]}, // "cos"
{3885755896, CURVES_ENUM[15]}, // "rev60"
{3885755901, CURVES_ENUM[16]}, // "rev65"
};
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 LOOP_TYPES_ENUM[]{"nonlooping", "looping"};
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", ""};
} // namespace
class AssetDumperSndBank::Internal
@ -142,11 +274,6 @@ class AssetDumperSndBank::Internal
return nullptr;
}
static std::unique_ptr<std::ostream> OpenAliasOutputFile(const SndBank* sndBank)
{
return nullptr;
}
static void WriteAliasFileHeader(CsvOutputStream& stream)
{
for (const auto& headerField : ALIAS_HEADERS)
@ -157,7 +284,30 @@ class AssetDumperSndBank::Internal
stream.NextRow();
}
static void WriteAliasToFile(CsvOutputStream& stream, const SndAlias* alias)
static void WriteReverbFileHeader(CsvOutputStream& stream)
{
for (const auto& headerField : REVERB_HEADERS)
{
stream.WriteColumn(headerField);
}
stream.NextRow();
}
static const char* FindNameForDuck(unsigned int id, const SndDuck* ducks, unsigned int duckCount)
{
for (auto i = 0u; i < duckCount; i++)
{
if (id == ducks[i].id)
{
return ducks[i].name;
}
}
return "";
}
static void WriteAliasToFile(CsvOutputStream& stream, const SndAlias* alias, const SndBank* bank)
{
// name
stream.WriteColumn(alias->name);
@ -165,96 +315,188 @@ class AssetDumperSndBank::Internal
// file
stream.WriteColumn(alias->assetFileName);
// "# template",
// template
stream.WriteColumn("");
// loadspec
stream.WriteColumn("");
// "# secondary",
// "# group",
// "# vol_min",
// "# vol_max",
// "# team_vol_mod",
// "# dist_min",
// "# dist_max",
// "# dist_reverb_max",
// "# volume_falloff_curve",
// "# reverb_falloff_curve",
// "# volume_min_falloff_curve",
// "# reverb_min_falloff_curve",
// "# limit_count",
// "# limit_type",
// "# entity_limit_count",
// "# entity_limit_type",
// "# pitch_min",
// "# pitch_max",
// "# team_pitch_mod",
// "# min_priority",
// "# max_priority",
// "# min_priority_threshold",
// "# max_priority_threshold",
// "# spatialized",
// "# type",
// "# loop",
// "# randomize_type",
// "# probability",
// "# start_delay",
// "# reverb_send",
// "# duck",
// "# pan",
// "# center_send",
// "# envelop_min",
// "# envelop_max",
// "# envelop_percentage",
// "# occlusion_level",
// "# occlusion_wet_dry",
// "# is_big",
// "# distance_lpf",
// "# move_type",
// "# move_time",
// "# real_delay",
// "# subtitle",
// "# mature",
// "# doppler",
// "# futz",
// "# context_type",
// "# context_value",
// "# compression",
// "# timescale",
// "# music",
// "# fade_in",
// "# fade_out",
// "# pc_format",
// "# pause",
// "# stop_on_death",
// "# bus",
// "# snapshot",
}
// secondary
stream.WriteColumn((alias->secondaryname && *alias->secondaryname) ? alias->secondaryname : "");
static void DumpSndBankAliases(const SndBank* sndBank)
{
const auto outputFile = OpenAliasOutputFile(sndBank);
// group
stream.WriteColumn(GROUPS_ENUM[std::min((alias->flags0 >> 17) & 0x1F, 26u)]);
if (outputFile == nullptr)
{
std::cout << "Failed to open sound alias output file for: \"" << sndBank->name << "\"" << std::endl;
return;
}
// vol_min
stream.WriteColumn(std::to_string(alias->volMin));
CsvOutputStream csvStream(*outputFile);
WriteAliasFileHeader(csvStream);
// vol_max
stream.WriteColumn(std::to_string(alias->volMax));
for (auto i = 0u; i < sndBank->aliasCount; i++)
{
const auto& aliasList = sndBank->alias[i];
for (auto j = 0; j < aliasList.count; j++)
{
const auto& alias = aliasList.head[j];
WriteAliasToFile(csvStream, &alias);
}
}
// team_vol_mod
stream.WriteColumn("");
// dist_min
stream.WriteColumn(std::to_string(alias->distMin));
// dist_max
stream.WriteColumn(std::to_string(alias->distMax));
// dist_reverb_max
stream.WriteColumn(std::to_string(alias->distReverbMax));
// volume_falloff_curve
stream.WriteColumn(CURVES_ENUM[std::min((alias->flags1 >> 14) & 0x1F, 17u)]);
// reverb_falloff_curve
stream.WriteColumn(CURVES_ENUM[std::min((alias->flags1 >> 20) & 0x1F, 17u)]);
// volume_min_falloff_curve
stream.WriteColumn(CURVES_ENUM[std::min((alias->flags1 >> 2) & 0x1F, 17u)]);
// reverb_min_falloff_curve"
stream.WriteColumn(CURVES_ENUM[std::min((alias->flags1 >> 8) & 0x1F, 17u)]);
// limit_count
stream.WriteColumn(std::to_string(alias->limitCount));
// limit_type
stream.WriteColumn(LIMIT_TYPES_ENUM[(alias->flags0 >> 25) & 0x3]);
// entity_limit_count
stream.WriteColumn(std::to_string(alias->entityLimitCount));
// entity_limit_type
stream.WriteColumn(LIMIT_TYPES_ENUM[(alias->flags0 >> 27) & 0x3]);
// pitch_min
stream.WriteColumn(std::to_string(alias->pitchMin));
// pitch_max
stream.WriteColumn(std::to_string(alias->pitchMax));
// team_pitch_mod
stream.WriteColumn("");
// min_priority
stream.WriteColumn(std::to_string(alias->minPriority));
// max_priority
stream.WriteColumn(std::to_string(alias->maxPriority));
// min_priority_threshold
stream.WriteColumn(std::to_string(alias->minPriorityThreshold));
// max_priority_threshold
stream.WriteColumn(std::to_string(alias->maxPriorityThreshold));
// spatialized
stream.WriteColumn("");
// type
stream.WriteColumn(std::to_string(alias->contextType));
// loop
stream.WriteColumn((alias->flags0 & 0x1) == 0 ? "nonlooping" : "looping");
// randomize_type
stream.WriteColumn(LIMIT_TYPES_ENUM[(alias->flags0 >> 15) & 0x3]);
// probability",
stream.WriteColumn(std::to_string(alias->probability));
// start_delay",
stream.WriteColumn(std::to_string(alias->startDelay));
// reverb_send",
stream.WriteColumn(std::to_string(alias->reverbSend));
// duck",
stream.WriteColumn(FindNameForDuck(alias->duck, bank->ducks, bank->duckCount));
// pan",
stream.WriteColumn(((alias->flags0 >> 6) & 0x1) == 0 ? "2d" : "3d");
// center_send",
stream.WriteColumn(std::to_string(alias->centerSend));
// envelop_min",
stream.WriteColumn(std::to_string(alias->envelopMin));
// envelop_max",
stream.WriteColumn(std::to_string(alias->envelopMax));
// envelop_percentage",
stream.WriteColumn(std::to_string(alias->envelopPercentage));
// occlusion_level",
stream.WriteColumn(std::to_string(alias->occlusionLevel));
// occlusion_wet_dry",
stream.WriteColumn("");
// is_big",
stream.WriteColumn(((alias->flags0 >> 4) & 0x1) == 0 ? "no" : "yes");
// distance_lpf"
stream.WriteColumn(((alias->flags0 >> 2) & 0x1) == 0 ? "no" : "yes");
// move_type",
stream.WriteColumn(MOVE_TYPES_ENUM[std::min((alias->flags0 >> 22) & 0x7, 7u)]);
// move_time",
stream.WriteColumn(std::to_string(alias->fluxTime));
// real_delay",
stream.WriteColumn("");
// subtitle",
stream.WriteColumn((alias->subtitle && *alias->subtitle) ? alias->subtitle : "");
// mature",
stream.WriteColumn("");
// doppler",
stream.WriteColumn(((alias->flags0 >> 1) & 0x1) == 0 ? "no" : "yes");
// futz",
stream.WriteColumn("");
// context_type",
stream.WriteColumn(std::to_string(alias->contextType));
// context_value",
stream.WriteColumn(std::to_string(alias->contextValue));
// compression",
stream.WriteColumn("");
// timescale",
stream.WriteColumn(((alias->flags0 >> 8) & 0x1) == 0 ? "no" : "yes");
// music",
stream.WriteColumn(((alias->flags0 >> 10) & 0x1) == 0 ? "no" : "yes");
// fade_in",
stream.WriteColumn(std::to_string(alias->fadeIn));
// fade_out",
stream.WriteColumn(std::to_string(alias->fadeOut));
// pc_format",
stream.WriteColumn("");
// pause",
stream.WriteColumn(((alias->flags0 >> 5) & 0x1) == 0 ? "no" : "yes");
// stop_on_death",
stream.WriteColumn(((alias->flags0 >> 7) & 0x1) == 0 ? "no" : "yes");
// bus",
stream.WriteColumn(BUS_IDS_ENUM[std::min((alias->flags0 >> 13) & 0xF, 10u)]);
// snapshot",
stream.WriteColumn("");
}
static SoundBankEntryInputStream FindSoundDataInSoundBanks(const unsigned assetId)
@ -353,10 +595,20 @@ class AssetDumperSndBank::Internal
}
}
void DumpSoundData(const SndBank* sndBank) const
void DumpSndBankAliases(const SndBank* sndBank) const
{
std::unordered_set<unsigned> dumpedAssets;
const auto outFile = OpenAssetOutputFile("soundbank\\" + std::string(sndBank->name) + ".aliases", ".csv");
if (!outFile)
{
std::cerr << "Failed to open sound alias output file: \"" << sndBank->name << "\"\n";
return;
}
CsvOutputStream csvStream(*outFile);
WriteAliasFileHeader(csvStream);
for (auto i = 0u; i < sndBank->aliasCount; i++)
{
const auto& aliasList = sndBank->alias[i];
@ -368,17 +620,130 @@ class AssetDumperSndBank::Internal
{
DumpSndAlias(alias);
dumpedAssets.emplace(alias.assetId);
WriteAliasToFile(csvStream, &alias, sndBank);
csvStream.NextRow();
}
}
}
}
void DumpSoundRadverb(const SndBank* sndBank) const
{
if (sndBank->radverbCount <= 0)
{
return;
}
const auto outFile = OpenAssetOutputFile("soundbank\\" + std::string(sndBank->name) + ".reverbs", ".csv");
if (!outFile)
{
std::cerr << "Failed to open sound reverb output file: \"" << sndBank->name << "\"\n";
return;
}
CsvOutputStream csvStream(*outFile);
WriteReverbFileHeader(csvStream);
for (auto i = 0u; i < sndBank->radverbCount; i++)
{
const auto& reverb = sndBank->radverbs[i];
csvStream.WriteColumn(reverb.name);
csvStream.WriteColumn(std::to_string(reverb.smoothing));
csvStream.WriteColumn(std::to_string(reverb.earlyTime));
csvStream.WriteColumn(std::to_string(reverb.lateTime));
csvStream.WriteColumn(std::to_string(reverb.earlyGain));
csvStream.WriteColumn(std::to_string(reverb.lateGain));
csvStream.WriteColumn(std::to_string(reverb.returnGain));
csvStream.WriteColumn(std::to_string(reverb.earlyLpf));
csvStream.WriteColumn(std::to_string(reverb.lateLpf));
csvStream.WriteColumn(std::to_string(reverb.inputLpf));
csvStream.WriteColumn(std::to_string(reverb.dampLpf));
csvStream.WriteColumn(std::to_string(reverb.wallReflect));
csvStream.WriteColumn(std::to_string(reverb.dryGain));
csvStream.WriteColumn(std::to_string(reverb.earlySize));
csvStream.WriteColumn(std::to_string(reverb.lateSize));
csvStream.WriteColumn(std::to_string(reverb.diffusion));
csvStream.WriteColumn(std::to_string(reverb.returnHighpass));
csvStream.NextRow();
}
}
void DumpSoundDucks(const SndBank* sndBank) const
{
if (sndBank->duckCount <= 0)
{
return;
}
const auto outFile = OpenAssetOutputFile("soundbank\\" + std::string(sndBank->name) + ".ducklist", ".csv");
if (!outFile)
{
std::cerr << "Failed to open sound reverb output file: \"" << sndBank->name << "\"\n";
return;
}
CsvOutputStream csvStream(*outFile);
csvStream.WriteColumn("name");
csvStream.NextRow();
for (auto i = 0u; i < sndBank->duckCount; i++)
{
const auto& duck = sndBank->ducks[i];
csvStream.WriteColumn(duck.name);
csvStream.NextRow();
const auto duckFile = OpenAssetOutputFile("soundbank\\ducks\\" + std::string(duck.name), ".duk");
if (!outFile)
{
std::cerr << "Failed to open sound duck output file: \"" << duck.name << "\"\n";
return;
}
nlohmann::json duckObj{};
duckObj["fadeIn"] = duck.fadeIn;
duckObj["fadeOut"] = duck.fadeOut;
duckObj["startDelay"] = duck.startDelay;
duckObj["distance"] = duck.distance;
duckObj["length"] = duck.length;
duckObj["fadeInCurveId"] = duck.fadeInCurve;
duckObj["fadeOutCurveId"] = duck.fadeOutCurve;
duckObj["updateWhilePaused"] = duck.updateWhilePaused;
auto fadeInItr = CURVES_MAP.find(duck.fadeInCurve);
if (fadeInItr != CURVES_MAP.end())
{
duckObj["fadeInCurve"] = fadeInItr->second;
}
auto fadeOutItr = CURVES_MAP.find(duck.fadeOutCurve);
if (fadeOutItr != CURVES_MAP.end())
{
duckObj["fadeOutCurve"] = fadeOutItr->second;
}
auto values = std::vector<nlohmann::json>{};
for (auto i = 0u; i < 32u; i++)
{
values.push_back({
{"duckGroup", DUCK_GROUPS_ENUM[i]},
{"attenuation", duck.attenuation[i]},
{"filter", duck.filter[i] }
});
}
duckObj["values"] = values;
*duckFile << duckObj.dump(4) << std::endl;
}
}
void DumpSndBank(const XAssetInfo<SndBank>* sndBankInfo) const
{
const auto* sndBank = sndBankInfo->Asset();
DumpSndBankAliases(sndBank);
DumpSoundData(sndBank);
DumpSoundRadverb(sndBank);
DumpSoundDucks(sndBank);
}
public:

View File

@ -0,0 +1,337 @@
#include "AssetDumperSndDriverGlobals.h"
#include "Csv/CsvStream.h"
#include "ObjContainer/SoundBank/SoundBank.h"
#include "Utils/ClassUtils.h"
#include <filesystem>
#include <fstream>
#include <unordered_map>
using namespace T6;
namespace fs = std::filesystem;
class AssetDumperSndDriverGlobals::Internal
{
AssetDumpingContext& m_context;
inline static const std::string GROUPS_HEADERS[]{"name", "attenuationSp", "attenuationMp", "category", "parent", "id"};
inline static const std::string GROUPS_CATEGORIES[]{"sfx", "music", "void", "ui", "cinematic", "id"};
inline static const std::string CURVE_HEADERS[]{
"name", "x0", "y0", "x1", "y1", "x2", "y2", "x3", "y3", "x4", "y4", "x5", "y5", "x6", "y6", "x7", "y7", "id"};
inline static const std::string PAN_HEADERS[]{"name", "front", "back", "center", "lfe", "left", "right", "id"};
inline static const std::string MASTER_HEADERS[]{
"name", "lowE", "lowG", "lowF", "lowQ", "peak1E", "peak1G", "peak1F", "peak1Q", "peak2E", "peak2G",
"peak2F", "peak2Q", "hiE", "hiG", "hiF", "hiQ", "eqG", "compE", "compPG", "compMG", "compT",
"compR", "compTA", "compTR", "limitE", "limitPG", "limitMG", "limitT", "limitR", "limitTA", "limitTR", "busReverbG",
"busFxG", "busVoiceG", "busPfutzG", "busHdrfxG", "busUiG", "busMusicG", "busMovieG", "busVcsG", "busReverbE", "busFxE", "busVoiceE",
"busPfutzE", "busHdrfxE", "busUiE", "busMusicE", "busMovieE", "hdrfxCompE", "voiceEqE", "voiceCompE", "id"};
inline static const std::string SIDECHAIN_HEADERS[]{"name", "g", "f", "q", "ta", "tr", "tf", "id"};
inline static const std::string FUTZ_HEADERS[]{"name",
"bpfF",
"bpfQ",
"lsG",
"lsF",
"lsQ",
"dist",
"preG",
"postG",
"th",
"tg",
"clippre",
"clippost",
"blend",
"startAliasId",
"stopAliasId",
"loopAliasId",
"id"};
std::unique_ptr<std::ostream> OpenAssetFile(const std::string& filename)
{
auto outputFile = this->m_context.OpenAssetFile(filename);
if (outputFile == nullptr)
{
std::cout << "Failed to open sound driver globals output file for: \"" << filename << "\"" << std::endl;
}
return outputFile;
}
static void WriteFileHeader(CsvOutputStream& stream, const std::string* headers, size_t count)
{
for (auto i = 0u; i < count; i++)
{
stream.WriteColumn(headers[i]);
}
stream.NextRow();
}
void DumpSndVolumesGroups(const SndVolumeGroup* groups, const size_t count)
{
const auto outputFile = this->OpenAssetFile("soundbank\\globals\\group.csv");
if (outputFile != nullptr)
{
CsvOutputStream csvStream(*outputFile);
WriteFileHeader(csvStream, GROUPS_HEADERS, 6);
for (auto i = 0u; i < count; i++)
{
const auto& group = groups[i];
csvStream.WriteColumn(group.name);
csvStream.WriteColumn(std::to_string(group.attenuationSp));
csvStream.WriteColumn(std::to_string(group.attenuationMp));
csvStream.WriteColumn(GROUPS_CATEGORIES[group.category]);
csvStream.WriteColumn(group.parentName);
csvStream.WriteColumn(std::to_string(group.id));
csvStream.NextRow();
}
}
}
void DumpSndCurves(const SndCurve* curves, const size_t count)
{
const auto outputFile = this->OpenAssetFile("soundbank\\globals\\curves.csv");
if (outputFile != nullptr)
{
CsvOutputStream csvStream(*outputFile);
WriteFileHeader(csvStream, CURVE_HEADERS, 18);
for (auto i = 0u; i < count; i++)
{
const auto& curve = curves[i];
csvStream.WriteColumn(curve.name);
for (auto j = 0u; j < 8; j++)
{
csvStream.WriteColumn(std::to_string(curve.points[j].x));
csvStream.WriteColumn(std::to_string(curve.points[j].y));
}
csvStream.WriteColumn(std::to_string(curve.id));
csvStream.NextRow();
}
}
}
void DumpSndPans(const SndPan* pans, const size_t count)
{
const auto outputFile = this->OpenAssetFile("soundbank\\globals\\pan.csv");
if (outputFile != nullptr)
{
CsvOutputStream csvStream(*outputFile);
WriteFileHeader(csvStream, PAN_HEADERS, 8);
for (auto i = 0u; i < count; i++)
{
const auto& pan = pans[i];
csvStream.WriteColumn(pan.name);
csvStream.WriteColumn(std::to_string(pan.front));
csvStream.WriteColumn(std::to_string(pan.back));
csvStream.WriteColumn(std::to_string(pan.center));
csvStream.WriteColumn(std::to_string(pan.lfe));
csvStream.WriteColumn(std::to_string(pan.left));
csvStream.WriteColumn(std::to_string(pan.right));
csvStream.WriteColumn(std::to_string(pan.id));
csvStream.NextRow();
}
}
}
void DumpSndDuckGroups(const SndDuckGroup* duckGroups, const size_t count)
{
const auto outputFile = this->OpenAssetFile("soundbank\\globals\\duck_groups.csv");
if (outputFile != nullptr)
{
CsvOutputStream csvStream(*outputFile);
csvStream.WriteColumn("name");
csvStream.NextRow();
for (auto i = 0u; i < count; i++)
{
const auto& duckGroup = duckGroups[i];
csvStream.WriteColumn(duckGroup.name);
csvStream.WriteColumn(std::to_string(duckGroup.id));
csvStream.NextRow();
}
}
}
void DumpSndMasters(const SndMaster* masters, const size_t count)
{
const auto outputFile = this->OpenAssetFile("soundbank\\globals\\master.csv");
if (outputFile != nullptr)
{
CsvOutputStream csvStream(*outputFile);
WriteFileHeader(csvStream, MASTER_HEADERS, 53);
for (auto i = 0u; i < count; i++)
{
const auto& master = masters[i];
csvStream.WriteColumn(master.name);
csvStream.WriteColumn(std::to_string(master.lowE));
csvStream.WriteColumn(std::to_string(master.lowG));
csvStream.WriteColumn(std::to_string(master.lowF));
csvStream.WriteColumn(std::to_string(master.lowQ));
csvStream.WriteColumn(std::to_string(master.peak1E));
csvStream.WriteColumn(std::to_string(master.peak1G));
csvStream.WriteColumn(std::to_string(master.peak1F));
csvStream.WriteColumn(std::to_string(master.peak1Q));
csvStream.WriteColumn(std::to_string(master.peak2E));
csvStream.WriteColumn(std::to_string(master.peak2G));
csvStream.WriteColumn(std::to_string(master.peak2F));
csvStream.WriteColumn(std::to_string(master.peak2Q));
csvStream.WriteColumn(std::to_string(master.hiE));
csvStream.WriteColumn(std::to_string(master.hiG));
csvStream.WriteColumn(std::to_string(master.hiF));
csvStream.WriteColumn(std::to_string(master.hiQ));
csvStream.WriteColumn(std::to_string(master.eqG));
csvStream.WriteColumn(std::to_string(master.compE));
csvStream.WriteColumn(std::to_string(master.compPG));
csvStream.WriteColumn(std::to_string(master.compMG));
csvStream.WriteColumn(std::to_string(master.compT));
csvStream.WriteColumn(std::to_string(master.compR));
csvStream.WriteColumn(std::to_string(master.compTA));
csvStream.WriteColumn(std::to_string(master.compTR));
csvStream.WriteColumn(std::to_string(master.limitE));
csvStream.WriteColumn(std::to_string(master.limitPG));
csvStream.WriteColumn(std::to_string(master.limitMG));
csvStream.WriteColumn(std::to_string(master.limitT));
csvStream.WriteColumn(std::to_string(master.limitR));
csvStream.WriteColumn(std::to_string(master.limitTA));
csvStream.WriteColumn(std::to_string(master.limitTR));
csvStream.WriteColumn(std::to_string(master.busReverbG));
csvStream.WriteColumn(std::to_string(master.busFxG));
csvStream.WriteColumn(std::to_string(master.busVoiceG));
csvStream.WriteColumn(std::to_string(master.busPfutzG));
csvStream.WriteColumn(std::to_string(master.busHdrfxG));
csvStream.WriteColumn(std::to_string(master.busUiG));
csvStream.WriteColumn(std::to_string(master.busMusicG));
csvStream.WriteColumn(std::to_string(master.busMovieG));
csvStream.WriteColumn(std::to_string(master.busVcsG));
csvStream.WriteColumn(std::to_string(master.busReverbE));
csvStream.WriteColumn(std::to_string(master.busFxE));
csvStream.WriteColumn(std::to_string(master.busVoiceE));
csvStream.WriteColumn(std::to_string(master.busPfutzE));
csvStream.WriteColumn(std::to_string(master.busHdrfxE));
csvStream.WriteColumn(std::to_string(master.busUiE));
csvStream.WriteColumn(std::to_string(master.busMusicE));
csvStream.WriteColumn(std::to_string(master.busMovieE));
csvStream.WriteColumn(std::to_string(master.hdrfxCompE));
csvStream.WriteColumn(std::to_string(master.voiceEqE));
csvStream.WriteColumn(std::to_string(master.voiceCompE));
csvStream.WriteColumn(std::to_string(master.id));
csvStream.NextRow();
}
}
}
void DumpSndSidechainDucks(const SndSidechainDuck* sidechains, const size_t count)
{
const auto outputFile = this->OpenAssetFile("soundbank\\globals\\sidechain_duck.csv");
if (outputFile != nullptr)
{
CsvOutputStream csvStream(*outputFile);
WriteFileHeader(csvStream, SIDECHAIN_HEADERS, 8);
for (auto i = 0u; i < count; i++)
{
const auto& sidechain = sidechains[i];
csvStream.WriteColumn(sidechain.name);
csvStream.WriteColumn(std::to_string(sidechain.g));
csvStream.WriteColumn(std::to_string(sidechain.f));
csvStream.WriteColumn(std::to_string(sidechain.q));
csvStream.WriteColumn(std::to_string(sidechain.ta));
csvStream.WriteColumn(std::to_string(sidechain.tr));
csvStream.WriteColumn(std::to_string(sidechain.tf));
csvStream.WriteColumn(std::to_string(sidechain.id));
csvStream.NextRow();
}
}
}
void DumpSndFutz(const SndFutz* futzes, const size_t count)
{
const auto outputFile = this->OpenAssetFile("soundbank\\globals\\futz.csv");
if (outputFile != nullptr)
{
CsvOutputStream csvStream(*outputFile);
WriteFileHeader(csvStream, FUTZ_HEADERS, 18);
for (auto i = 0u; i < count; i++)
{
const auto& futz = futzes[i];
csvStream.WriteColumn(futz.name);
csvStream.WriteColumn(std::to_string(futz.bpfF));
csvStream.WriteColumn(std::to_string(futz.bpfQ));
csvStream.WriteColumn(std::to_string(futz.lsG));
csvStream.WriteColumn(std::to_string(futz.lsF));
csvStream.WriteColumn(std::to_string(futz.lsQ));
csvStream.WriteColumn(std::to_string(futz.dist));
csvStream.WriteColumn(std::to_string(futz.preG));
csvStream.WriteColumn(std::to_string(futz.postG));
csvStream.WriteColumn(std::to_string(futz.th));
csvStream.WriteColumn(std::to_string(futz.tg));
csvStream.WriteColumn(std::to_string(futz.clippre));
csvStream.WriteColumn(std::to_string(futz.clippost));
csvStream.WriteColumn(std::to_string(futz.blend));
csvStream.WriteColumn(std::to_string(futz.startAliasId));
csvStream.WriteColumn(std::to_string(futz.stopAliasId));
csvStream.WriteColumn(std::to_string(futz.loopAliasId));
csvStream.WriteColumn(std::to_string(futz.id));
csvStream.NextRow();
}
}
}
void DumpSndDriverGlobals(const XAssetInfo<SndDriverGlobals>* sndDriverGlobalsInfo)
{
const auto* sndDriverGlobals = sndDriverGlobalsInfo->Asset();
DumpSndVolumesGroups(sndDriverGlobals->groups, sndDriverGlobals->groupCount);
DumpSndCurves(sndDriverGlobals->curves, sndDriverGlobals->curveCount);
DumpSndPans(sndDriverGlobals->pans, sndDriverGlobals->panCount);
DumpSndDuckGroups(sndDriverGlobals->duckGroups, sndDriverGlobals->duckGroupCount);
// DumpSndContexts(sndDriverGlobals->contexts, sndDriverGlobals->contextCount);
DumpSndMasters(sndDriverGlobals->masters, sndDriverGlobals->masterCount);
DumpSndSidechainDucks(sndDriverGlobals->voiceDucks, sndDriverGlobals->voiceDuckCount);
DumpSndFutz(sndDriverGlobals->futzes, sndDriverGlobals->futzCount);
}
public:
explicit Internal(AssetDumpingContext& context)
: m_context(context)
{
}
void DumpPool(AssetPool<SndDriverGlobals>* pool)
{
for (const auto* assetInfo : *pool)
{
if (!assetInfo->m_name.empty() && assetInfo->m_name[0] == ',')
continue;
DumpSndDriverGlobals(assetInfo);
}
}
};
void AssetDumperSndDriverGlobals::DumpPool(AssetDumpingContext& context, AssetPool<SndDriverGlobals>* pool)
{
Internal internal(context);
internal.DumpPool(pool);
}

View File

@ -0,0 +1,15 @@
#pragma once
#include "Dumping/AbstractAssetDumper.h"
#include "Game/T6/T6.h"
namespace T6
{
class AssetDumperSndDriverGlobals final : public IAssetDumper<SndDriverGlobals>
{
class Internal;
public:
void DumpPool(AssetDumpingContext& context, AssetPool<SndDriverGlobals>* pool) override;
};
} // namespace T6

View File

@ -10,6 +10,7 @@
#include "AssetDumpers/AssetDumperScriptParseTree.h"
#include "AssetDumpers/AssetDumperSlug.h"
#include "AssetDumpers/AssetDumperSndBank.h"
#include "AssetDumpers/AssetDumperSndDriverGlobals.h"
#include "AssetDumpers/AssetDumperStringTable.h"
#include "AssetDumpers/AssetDumperTracer.h"
#include "AssetDumpers/AssetDumperVehicle.h"
@ -66,7 +67,7 @@ bool ZoneDumper::DumpZone(AssetDumpingContext& context) const
DUMP_ASSET_POOL(AssetDumperWeaponAttachment, m_attachment, ASSET_TYPE_ATTACHMENT)
DUMP_ASSET_POOL(AssetDumperWeaponAttachmentUnique, m_attachment_unique, ASSET_TYPE_ATTACHMENT_UNIQUE)
// DUMP_ASSET_POOL(AssetDumperWeaponCamo, m_camo, ASSET_TYPE_WEAPON_CAMO)
// DUMP_ASSET_POOL(AssetDumperSndDriverGlobals, m_snd_driver_globals, ASSET_TYPE_SNDDRIVER_GLOBALS)
DUMP_ASSET_POOL(AssetDumperSndDriverGlobals, m_snd_driver_globals, ASSET_TYPE_SNDDRIVER_GLOBALS)
// DUMP_ASSET_POOL(AssetDumperFxEffectDef, m_fx, ASSET_TYPE_FX)
// DUMP_ASSET_POOL(AssetDumperFxImpactTable, m_fx_impact_table, ASSET_TYPE_IMPACT_FX)
DUMP_ASSET_POOL(AssetDumperRawFile, m_raw_file, ASSET_TYPE_RAWFILE)