diff --git a/src/Components/Modules/AssetInterfaces/Isnd_alias_list_t.cpp b/src/Components/Modules/AssetInterfaces/Isnd_alias_list_t.cpp index 9acc177d..4ec32792 100644 --- a/src/Components/Modules/AssetInterfaces/Isnd_alias_list_t.cpp +++ b/src/Components/Modules/AssetInterfaces/Isnd_alias_list_t.cpp @@ -2,6 +2,117 @@ namespace Assets { + void Isnd_alias_list_t::load(Game::XAssetHeader* header, std::string name, Components::ZoneBuilder::Zone* builder) + { + Components::FileSystem::File aliasFile(Utils::String::VA("sounds/%s", name.data())); + if (!aliasFile.exists()) { + header->sound = Components::AssetHandler::FindOriginalAsset(this->getType(), name.data()).sound; + } + + Game::snd_alias_list_t* aliasList = builder->getAllocator()->allocate(); + if (!aliasList) + { + Components::Logger::Print("Error allocating memory for sound alias structure!\n"); + return; + } + + aliasList->head = builder->getAllocator()->allocate(); + if (!aliasList->head) + { + Components::Logger::Print("Error allocating memory for sound alias structure!\n"); + return; + } + aliasList->head->soundFile = builder->getAllocator()->allocate(); + if (!aliasList->head->soundFile) + { + Components::Logger::Print("Error allocating memory for sound alias structure!\n"); + return; + } + + aliasList->count = 1; + + std::string errors; + json11::Json infoData = json11::Json::parse(aliasFile.getBuffer(), errors); + + if (!infoData.is_object()) + { + Components::Logger::Error("Failed to load sound %s!", name.data()); + return; + } + + Game::snd_alias_t* alias = aliasList->head; + + // try and parse everything and if it fails then fail for the whole file + auto type = infoData["type"]; + auto subtitle = infoData["subtitle"]; + auto secondaryAliasName = infoData["secondaryAliasName"]; + auto chainAliasName = infoData["chainAliasName"]; + auto soundFile = infoData["soundFile"]; + auto sequence = infoData["sequence"]; + auto volMin = infoData["volMin"]; + auto volMax = infoData["volMax"]; + auto pitchMin = infoData["pitchMin"]; + auto pitchMax = infoData["pitchMax"]; + auto distMin = infoData["distMin"]; + auto distMax = infoData["distMax"]; + auto flags = infoData["flags"]; + auto slavePercentage = infoData["slavePercentage"]; + auto probability = infoData["probability"]; + auto lfePercentage = infoData["lfePercentage"]; + auto centerPercentage = infoData["centerPercentage"]; + auto startDelay = infoData["startDelay"]; + auto volumeFalloffCurve = infoData["volumeFalloffCurve"]; + auto envelopMin = infoData["envelopMin"]; + auto envelopMax = infoData["envelopMax"]; + auto envelopPercentage = infoData["envelopPercentage"]; + auto speakerMap = infoData["speakerMap"]; + + if (type.is_null() || soundFile.is_null()) + { + Components::Logger::Error("Failed to parse sound %s! Each alias must have at least a type and a soundFile", name.data()); + return; + } + +#define CHECK(x, type) (x.is_##type##() || x.is_null()) + + // TODO: actually support all of those properties + if (CHECK(type, string) && CHECK(subtitle, string) && CHECK(secondaryAliasName, string) && CHECK(chainAliasName, string) && + CHECK(soundFile, string) && CHECK(sequence, number) && CHECK(volMin, number) && CHECK(volMax, number) && CHECK(pitchMin, number) && + CHECK(pitchMax, number) && CHECK(distMin, number) && CHECK(distMax, number) && CHECK(flags, number) && CHECK(slavePercentage, number) && + CHECK(probability, number) && CHECK(lfePercentage, number) && CHECK(centerPercentage, number) && CHECK(startDelay, number) && + CHECK(volumeFalloffCurve, string) && CHECK(envelopMin, number) && CHECK(envelopMax, number) && CHECK(envelopPercentage, number) && + CHECK(speakerMap, string)) + { + alias->soundFile->exists = true; + + if (type.string_value() == "loaded"s) + { + alias->soundFile->type = Game::SAT_LOADED; + alias->soundFile->data.loaded = Components::AssetHandler::FindAssetForZone(Game::XAssetType::ASSET_TYPE_LOADED_SOUND, soundFile.string_value(), builder).loadSnd; + } + else if (type.string_value() == "streamed"s) + { + alias->soundFile->type = Game::SAT_STREAMED; + std::string streamedFile = soundFile.string_value(); + int split = streamedFile.find_last_of('/'); + alias->soundFile->data.stream.dir = builder->getAllocator()->duplicateString(streamedFile.substr(0, split).c_str()); + alias->soundFile->data.stream.name = builder->getAllocator()->duplicateString(streamedFile.substr(split).c_str()); + } + else + { + Components::Logger::Error("Failed to parse sound %s! Invalid sound type %s", name.data(), type.string_value().c_str()); + } + } + else + { + Components::Logger::Error("Failed to parse sound %s!", name.data()); + return; + } + +#undef CHECK + + } + void Isnd_alias_list_t::mark(Game::XAssetHeader header, Components::ZoneBuilder::Zone* builder) { Game::snd_alias_list_t* asset = header.sound; diff --git a/src/Components/Modules/AssetInterfaces/Isnd_alias_list_t.hpp b/src/Components/Modules/AssetInterfaces/Isnd_alias_list_t.hpp index 513903a0..62cc698e 100644 --- a/src/Components/Modules/AssetInterfaces/Isnd_alias_list_t.hpp +++ b/src/Components/Modules/AssetInterfaces/Isnd_alias_list_t.hpp @@ -7,6 +7,7 @@ namespace Assets public: virtual Game::XAssetType getType() override { return Game::XAssetType::ASSET_TYPE_SOUND; }; + virtual void load(Game::XAssetHeader* header, std::string name, Components::ZoneBuilder::Zone* builder) override; virtual void save(Game::XAssetHeader header, Components::ZoneBuilder::Zone* builder) override; virtual void mark(Game::XAssetHeader header, Components::ZoneBuilder::Zone* builder) override; };