diff --git a/src/Components/Modules/AssetInterfaces/ILoadedSound.cpp b/src/Components/Modules/AssetInterfaces/ILoadedSound.cpp index f2ddb8b0..376a21d9 100644 --- a/src/Components/Modules/AssetInterfaces/ILoadedSound.cpp +++ b/src/Components/Modules/AssetInterfaces/ILoadedSound.cpp @@ -4,7 +4,7 @@ namespace Assets { void ILoadedSound::load(Game::XAssetHeader* header, const std::string& name, Components::ZoneBuilder::Zone* builder) { - Components::FileSystem::File soundFile(Utils::String::VA("sounds/%s", name.data())); + Components::FileSystem::File soundFile(Utils::String::VA("loaded_sound/%s", name.data())); if (!soundFile.exists()) { header->loadSnd = Components::AssetHandler::FindOriginalAsset(this->getType(), name.data()).loadSnd; diff --git a/src/Components/Modules/AssetInterfaces/Isnd_alias_list_t.cpp b/src/Components/Modules/AssetInterfaces/Isnd_alias_list_t.cpp index 8bae003d..881355b4 100644 --- a/src/Components/Modules/AssetInterfaces/Isnd_alias_list_t.cpp +++ b/src/Components/Modules/AssetInterfaces/Isnd_alias_list_t.cpp @@ -4,10 +4,10 @@ namespace Assets { void Isnd_alias_list_t::load(Game::XAssetHeader* header, const std::string& name, Components::ZoneBuilder::Zone* builder) { - Components::FileSystem::File aliasFile(Utils::String::VA("sounds/%s", name.data())); + Components::FileSystem::File aliasFile(Utils::String::VA("sounds/%s", name.c_str())); if (!aliasFile.exists()) { - header->sound = Components::AssetHandler::FindOriginalAsset(this->getType(), name.data()).sound; + header->sound = Components::AssetHandler::FindOriginalAsset(this->getType(), name.c_str()).sound; return; } @@ -18,232 +18,304 @@ namespace Assets 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); - json11::Json head = infoData["head"][0]; + json11::Json aliasesContainer = infoData["head"]; + auto aliases = aliasesContainer.array_items(); - if (!infoData.is_object()) + aliasList->count = aliases.size(); + aliasList->aliasName = builder->getAllocator()->duplicateString(infoData["aliasName"].string_value().c_str()); + + for (size_t i = 0; i < aliasList->count; i++) { - Components::Logger::Error("Failed to load sound %s!", name.data()); - return; - } + json11::Json head = aliasesContainer[i]; - Game::snd_alias_t* alias = aliasList->head; + if (!infoData.is_object()) + { + Components::Logger::Error("Failed to load sound %s!", name.c_str()); + return; + } - // try and parse everything and if it fails then fail for the whole file - auto type = head["type"]; - auto subtitle = head["subtitle"]; - auto secondaryAliasName = head["secondaryAliasName"]; - auto chainAliasName = head["chainAliasName"]; - auto soundFile = head["soundFile"]; - auto sequence = head["sequence"]; - auto volMin = head["volMin"]; - auto volMax = head["volMax"]; - auto pitchMin = head["pitchMin"]; - auto pitchMax = head["pitchMax"]; - auto distMin = head["distMin"]; - auto distMax = head["distMax"]; - auto flags = head["flags"]; - auto slavePercentage = head["slavePercentage"]; - auto probability = head["probability"]; - auto lfePercentage = head["lfePercentage"]; - auto centerPercentage = head["centerPercentage"]; - auto startDelay = head["startDelay"]; - auto volumeFalloffCurve = head["volumeFalloffCurve"]; - auto envelopMin = head["envelopMin"]; - auto envelopMax = head["envelopMax"]; - auto envelopPercentage = head["envelopPercentage"]; - auto speakerMap = head["speakerMap"]; - - // Fix casing - if (soundFile.is_null()) { - soundFile = head["soundfile"]; + // Allocate + aliasList->head = builder->getAllocator()->allocate(); + if (!aliasList->head) + { + Components::Logger::Print("Error allocating memory for sound alias structure!\n"); + return; + } - Components::Logger::Print("Fixed casing on %s\n", name.data()); - } + aliasList->head->soundFile = builder->getAllocator()->allocate(); + if (!aliasList->head->soundFile) + { + Components::Logger::Print("Error allocating memory for sound alias structure!\n"); + return; + } - if (type.is_null() || soundFile.is_null()) - { - //auto p = fopen("test", "w"); - //fwrite(aliasFile.getBuffer().data(), aliasFile.getBuffer().length(), 1, p); - //fflush(p); - //fclose(p); + Game::snd_alias_t* alias = aliasList->head; - //auto p2 = fopen("test2", "w"); - //fwrite(infoData.dump().data(), infoData.dump().length(), 1, p2); - //fflush(p2); - //fclose(p2); + // try and parse everything and if it fails then fail for the whole file + auto type = head["type"]; + auto subtitle = head["subtitle"]; + auto secondaryAliasName = head["secondaryAliasName"]; + auto chainAliasName = head["chainAliasName"]; + auto soundFile = head["soundFile"]; + auto sequence = head["sequence"]; + auto volMin = head["volMin"]; + auto volMax = head["volMax"]; + auto pitchMin = head["pitchMin"]; + auto pitchMax = head["pitchMax"]; + auto distMin = head["distMin"]; + auto distMax = head["distMax"]; + auto flags = head["flags"]; + auto slavePercentage = head["slavePercentage"]; + auto probability = head["probability"]; + auto lfePercentage = head["lfePercentage"]; + auto centerPercentage = head["centerPercentage"]; + auto startDelay = head["startDelay"]; + auto volumeFalloffCurve = head["volumeFalloffCurve"]; + auto envelopMin = head["envelopMin"]; + auto envelopMax = head["envelopMax"]; + auto envelopPercentage = head["envelopPercentage"]; + auto speakerMap = head["speakerMap"]; - Components::Logger::Print("Type is %s\n", type.dump().data()); - Components::Logger::Print("SoundFile is %s\n", soundFile.dump().data()); - Components::Logger::Error("Failed to parse sound %s! Each alias must have at least a type and a soundFile\n", name.data()); - return; - } + // Fix casing + if (soundFile.is_null()) + { + soundFile = head["soundfile"]; + + Components::Logger::Print("Fixed casing on %s\n", name.c_str()); + } + + if (type.is_null() || soundFile.is_null()) + { + Components::Logger::Print("Type is %s\n", type.dump().c_str()); + Components::Logger::Print("SoundFile is %s\n", soundFile.dump().c_str()); + Components::Logger::Error("Failed to parse sound %s! Each alias must have at least a type and a soundFile\n", name.c_str()); + return; + } #define CHECK(x, type) (x.is_##type##() || x.is_null()) - // TODO: actually support all of those properties - if (!CHECK(type, string)) { - Components::Logger::Print("%s is not string but %d (%s)\n", "type", type.type(), type.dump().data()); - } - - if (!CHECK(subtitle, string)) { - Components::Logger::Print("%s is not string but %d (%s)\n", "subtitle", subtitle.type(), subtitle.dump().data()); - } - - if (!CHECK(secondaryAliasName, string)) { - Components::Logger::Print("%s is not string but %d (%s)\n", "secondaryAliasName", secondaryAliasName.type(), secondaryAliasName.dump().data()); - } - - if (!CHECK(chainAliasName, string)) { - Components::Logger::Print("%s is not string but %d (%s)\n", "chainAliasName", chainAliasName.type(), chainAliasName.dump().data()); - } - - if (!CHECK(soundFile, string)) { - Components::Logger::Print("%s is not string but %d (%s)\n", "soundFile", soundFile.type(), soundFile.dump().data()); - } - - if (!CHECK(sequence, number)) { - Components::Logger::Print("%s is not number but %d (%s)\n", "sequence", sequence.type(), sequence.dump().data()); - } - - if (!CHECK(volMin, number)) { - Components::Logger::Print("%s is not number but %d (%s)\n", "volMin", volMin.type(), volMin.dump().data()); - } - - if (!CHECK(volMax, number)) { - Components::Logger::Print("%s is not number but %d (%s)\n", "volMax", volMax.type(), volMax.dump().data()); - } - - if (!CHECK(pitchMin, number)) { - Components::Logger::Print("%s is not number but %d (%s)\n", "pitchMin", pitchMin.type(), pitchMin.dump().data()); - } - - if (!CHECK(pitchMax, number)) { - Components::Logger::Print("%s is not number but %d (%s)\n", "pitchMax", pitchMax.type(), pitchMax.dump().data()); - } - - if (!CHECK(probability, number)) { - Components::Logger::Print("%s is not number but %d (%s)\n", "probability", probability.type(), probability.dump().data()); - } - - if (!CHECK(lfePercentage, number)) { - Components::Logger::Print("%s is not number but %d (%s)\n", "lfePercentage", lfePercentage.type(), lfePercentage.dump().data()); - } - - if (!CHECK(centerPercentage, number)) { - Components::Logger::Print("%s is not number but %d (%s)\n", "centerPercentage", centerPercentage.type(), centerPercentage.dump().data()); - } - - if (!CHECK(startDelay, number)) { - Components::Logger::Print("%s is not number but %d (%s)\n", "startDelay", startDelay.type(), startDelay.dump().data()); - } - - if (!CHECK(volumeFalloffCurve, string)) { - Components::Logger::Print("%s is not string but %d (%s)\n", "volumeFalloffCurve", volumeFalloffCurve.type(), volumeFalloffCurve.dump().data()); - } - - if (!CHECK(envelopMin, number)) { - Components::Logger::Print("%s is not number but %d (%s)\n", "envelopMin", envelopMin.type(), envelopMin.dump().data()); - } - - if (!CHECK(envelopMax, number)) { - Components::Logger::Print("%s is not number but %d (%s)\n", "envelopMax", envelopMax.type(), envelopMax.dump().data()); - } - - if (!CHECK(envelopPercentage, number)) { - Components::Logger::Print("%s is not number but %d (%s)\n", "envelopPercentage", envelopPercentage.type(), envelopPercentage.dump().data()); - } - - if (!CHECK(speakerMap, object)) { - Components::Logger::Print("%s is not object but %d (%s)\n", "speakerMap", speakerMap.type(), speakerMap.dump().data()); - } - - - if (CHECK(type, number) && 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, object)) - { - - alias->soundFile->exists = true; - - if (subtitle.is_string()) + // TODO: actually support all of those properties + if (!CHECK(type, number)) { - alias->subtitle = subtitle.string_value().data(); - } - if (secondaryAliasName.is_string()) - { - alias->secondaryAliasName = secondaryAliasName.string_value().data(); - } - if (chainAliasName.is_string()) - { - alias->chainAliasName = chainAliasName.string_value().data(); + Components::Logger::Print("%s is not number but %d (%s)\n", "type", type.type(), type.dump().c_str()); } - alias->sequence = sequence.int_value(); - alias->volMin = float(volMin.number_value()); - alias->volMax = float(volMax.number_value()); - alias->pitchMin = float(pitchMin.number_value()); - alias->pitchMax = float(pitchMax.number_value()); - alias->distMin = float(distMin.number_value()); - alias->distMax = float(distMax.number_value()); - alias->flags = flags.int_value(); - alias->___u15.slavePercentage = float(slavePercentage.number_value()); - alias->probability = float(probability.number_value()); - alias->lfePercentage = float(lfePercentage.number_value()); - alias->centerPercentage = float(centerPercentage.number_value()); - alias->startDelay = startDelay.int_value(); - alias->envelopMin = float(envelopMin.number_value()); - alias->envelopMax = float(envelopMax.number_value()); - alias->envelopPercentage = float(envelopPercentage.number_value()); - - if (volumeFalloffCurve.is_string()) + if (!CHECK(subtitle, string)) { - alias->volumeFalloffCurve = Components::AssetHandler::FindAssetForZone(Game::XAssetType::ASSET_TYPE_SOUND_CURVE, volumeFalloffCurve.string_value(), builder).sndCurve; + Components::Logger::Print("%s is not string but %d (%s)\n", "subtitle", subtitle.type(), subtitle.dump().c_str()); } - if (type.number_value() == 1) // Loaded + if (!CHECK(secondaryAliasName, string)) { - alias->soundFile->type = Game::SAT_LOADED; - alias->soundFile->u.loadSnd = Components::AssetHandler::FindAssetForZone(Game::XAssetType::ASSET_TYPE_LOADED_SOUND, soundFile.string_value(), builder).loadSnd; + Components::Logger::Print("%s is not string but %d (%s)\n", "secondaryAliasName", secondaryAliasName.type(), secondaryAliasName.dump().c_str()); } - else if (type.number_value() == 2) // Streamed + + if (!CHECK(chainAliasName, string)) { - alias->soundFile->type = Game::SAT_STREAMED; - std::string streamedFile = soundFile.string_value(); - int split = streamedFile.find_last_of('/'); - alias->soundFile->u.streamSnd.filename.info.raw.dir = builder->getAllocator()->duplicateString(streamedFile.substr(0, split).c_str()); - alias->soundFile->u.streamSnd.filename.info.raw.name = builder->getAllocator()->duplicateString(streamedFile.substr(split).c_str()); + Components::Logger::Print("%s is not string but %d (%s)\n", "chainAliasName", chainAliasName.type(), chainAliasName.dump().c_str()); + } + + if (!CHECK(soundFile, string)) + { + Components::Logger::Print("%s is not string but %d (%s)\n", "soundFile", soundFile.type(), soundFile.dump().c_str()); + } + + if (!CHECK(sequence, number)) + { + Components::Logger::Print("%s is not number but %d (%s)\n", "sequence", sequence.type(), sequence.dump().c_str()); + } + + if (!CHECK(volMin, number)) + { + Components::Logger::Print("%s is not number but %d (%s)\n", "volMin", volMin.type(), volMin.dump().c_str()); + } + + if (!CHECK(volMax, number)) + { + Components::Logger::Print("%s is not number but %d (%s)\n", "volMax", volMax.type(), volMax.dump().c_str()); + } + + if (!CHECK(pitchMin, number)) + { + Components::Logger::Print("%s is not number but %d (%s)\n", "pitchMin", pitchMin.type(), pitchMin.dump().c_str()); + } + + if (!CHECK(pitchMax, number)) + { + Components::Logger::Print("%s is not number but %d (%s)\n", "pitchMax", pitchMax.type(), pitchMax.dump().c_str()); + } + + if (!CHECK(probability, number)) + { + Components::Logger::Print("%s is not number but %d (%s)\n", "probability", probability.type(), probability.dump().c_str()); + } + + if (!CHECK(lfePercentage, number)) + { + Components::Logger::Print("%s is not number but %d (%s)\n", "lfePercentage", lfePercentage.type(), lfePercentage.dump().c_str()); + } + + if (!CHECK(centerPercentage, number)) + { + Components::Logger::Print("%s is not number but %d (%s)\n", "centerPercentage", centerPercentage.type(), centerPercentage.dump().c_str()); + } + + if (!CHECK(startDelay, number)) + { + Components::Logger::Print("%s is not number but %d (%s)\n", "startDelay", startDelay.type(), startDelay.dump().c_str()); + } + + if (!CHECK(volumeFalloffCurve, string)) + { + Components::Logger::Print("%s is not string but %d (%s)\n", "volumeFalloffCurve", volumeFalloffCurve.type(), volumeFalloffCurve.dump().c_str()); + } + + if (!CHECK(envelopMin, number)) + { + Components::Logger::Print("%s is not number but %d (%s)\n", "envelopMin", envelopMin.type(), envelopMin.dump().c_str()); + } + + if (!CHECK(envelopMax, number)) + { + Components::Logger::Print("%s is not number but %d (%s)\n", "envelopMax", envelopMax.type(), envelopMax.dump().c_str()); + } + + if (!CHECK(envelopPercentage, number)) + { + Components::Logger::Print("%s is not number but %d (%s)\n", "envelopPercentage", envelopPercentage.type(), envelopPercentage.dump().c_str()); + } + + if (!CHECK(speakerMap, object)) + { + Components::Logger::Print("%s is not object but %d (%s)\n", "speakerMap", speakerMap.type(), speakerMap.dump().c_str()); + } + + + if (CHECK(type, number) && 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, object)) + { + + alias->soundFile->exists = true; + alias->aliasName = aliasList->aliasName; + + if (subtitle.is_string()) + { + alias->subtitle = builder->getAllocator()->duplicateString(subtitle.string_value().c_str()); + } + if (secondaryAliasName.is_string()) + { + alias->secondaryAliasName = builder->getAllocator()->duplicateString(secondaryAliasName.string_value().c_str()); + } + if (chainAliasName.is_string()) + { + alias->chainAliasName = builder->getAllocator()->duplicateString(chainAliasName.string_value().c_str()); + } + + alias->sequence = sequence.int_value(); + alias->volMin = float(volMin.number_value()); + alias->volMax = float(volMax.number_value()); + alias->pitchMin = float(pitchMin.number_value()); + alias->pitchMax = float(pitchMax.number_value()); + alias->distMin = float(distMin.number_value()); + alias->distMax = float(distMax.number_value()); + alias->flags = flags.int_value(); + alias->___u15.slavePercentage = float(slavePercentage.number_value()); + alias->probability = float(probability.number_value()); + alias->lfePercentage = float(lfePercentage.number_value()); + alias->centerPercentage = float(centerPercentage.number_value()); + alias->startDelay = startDelay.int_value(); + alias->envelopMin = float(envelopMin.number_value()); + alias->envelopMax = float(envelopMax.number_value()); + alias->envelopPercentage = float(envelopPercentage.number_value()); + + // Speaker map object + if (!speakerMap.is_null()) + { + alias->speakerMap = builder->getAllocator()->allocate(); + if (!alias->speakerMap) + { + Components::Logger::Print("Error allocating memory for speakermap in sound alias%s!\n", alias->aliasName); + return; + } + + alias->speakerMap->name = builder->getAllocator()->duplicateString(speakerMap["name"].string_value().c_str()); + alias->speakerMap->isDefault = speakerMap["isDefault"].bool_value(); + + if (speakerMap["channelMaps"].is_array()) + { + json11::Json::array channelMaps = speakerMap["channelMaps"].array_items(); + + assert(channelMaps.size() <= 4); + + // channelMapIndex should never exceed 1 + for (size_t channelMapIndex = 0; channelMapIndex < 2; channelMapIndex++) + { + // subChannelIndex should never exceed 1 + for (size_t subChannelIndex = 0; subChannelIndex < 2; subChannelIndex++) + { + json11::Json channelMap = channelMaps[channelMapIndex * 2 + subChannelIndex]; // 0-3 + + auto speakers = channelMap["speakers"].array_items(); + + alias->speakerMap->channelMaps[channelMapIndex][subChannelIndex].speakerCount = speakers.size(); + + for (size_t speakerIndex = 0; speakerIndex < alias->speakerMap->channelMaps[channelMapIndex][subChannelIndex].speakerCount; speakerIndex++) + { + auto speaker = speakers[speakerIndex]; + alias->speakerMap->channelMaps[channelMapIndex][subChannelIndex].speakers[speakerIndex].levels[0] = static_cast(speaker["levels0"].number_value()); + alias->speakerMap->channelMaps[channelMapIndex][subChannelIndex].speakers[speakerIndex].levels[1] = static_cast(speaker["levels1"].number_value()); + alias->speakerMap->channelMaps[channelMapIndex][subChannelIndex].speakers[speakerIndex].numLevels = static_cast(speaker["numLevels"].number_value()); + alias->speakerMap->channelMaps[channelMapIndex][subChannelIndex].speakers[speakerIndex].speaker = static_cast(speaker["speaker"].number_value()); + } + } + } + } + } + + if (volumeFalloffCurve.is_string()) + { + alias->volumeFalloffCurve = Components::AssetHandler::FindAssetForZone(Game::XAssetType::ASSET_TYPE_SOUND_CURVE, volumeFalloffCurve.string_value(), builder).sndCurve; + } + + if (type.number_value() == 1) // Loaded + { + alias->soundFile->type = Game::SAT_LOADED; + alias->soundFile->u.loadSnd = Components::AssetHandler::FindAssetForZone(Game::XAssetType::ASSET_TYPE_LOADED_SOUND, soundFile.string_value(), builder).loadSnd; + } + else if (type.number_value() == 2) // Streamed + { + alias->soundFile->type = Game::SAT_STREAMED; + std::string streamedFile = soundFile.string_value(); + int split = streamedFile.find_last_of('/'); + alias->soundFile->u.streamSnd.filename.info.raw.dir = builder->getAllocator()->duplicateString(streamedFile.substr(0, split).c_str()); + alias->soundFile->u.streamSnd.filename.info.raw.name = builder->getAllocator()->duplicateString(streamedFile.substr(split).c_str()); + } + else + { + Components::Logger::Error("Failed to parse sound %s! Invalid sound type %s\n", name.c_str(), type.string_value().c_str()); + return; + } + + if (i == 0) + { + aliasList->head = alias; + } } else { - Components::Logger::Error("Failed to parse sound %s! Invalid sound type %s\n", name.data(), type.string_value().c_str()); + Components::Logger::Error("Failed to parse sound %s!\n", name.c_str()); + return; } } - else - { - Components::Logger::Error("Failed to parse sound %s!\n", name.data()); - return; - } + + header->sound = aliasList; #undef CHECK @@ -253,7 +325,7 @@ namespace Assets { Game::snd_alias_list_t* asset = header.sound; - for (int i = 0; i < asset->count; ++i) + for (unsigned int i = 0; i < asset->count; ++i) { Game::snd_alias_t* alias = &asset->head[i]; @@ -302,7 +374,7 @@ namespace Assets Game::snd_alias_t* destHead = buffer->dest(); buffer->saveArray(asset->head, asset->count); - for (int i = 0; i < asset->count; ++i) + for (unsigned int i = 0; i < asset->count; ++i) { Game::snd_alias_t* destAlias = &destHead[i]; Game::snd_alias_t* alias = &asset->head[i]; diff --git a/src/Components/Modules/ZoneBuilder.cpp b/src/Components/Modules/ZoneBuilder.cpp index 1c8329a6..b03b3708 100644 --- a/src/Components/Modules/ZoneBuilder.cpp +++ b/src/Components/Modules/ZoneBuilder.cpp @@ -223,10 +223,6 @@ namespace Components Game::XAssetHeader assetHeader = AssetHandler::FindAssetForZone(type, name, this, isSubAsset); - if (type == Game::XAssetType::ASSET_TYPE_LOADED_SOUND) { - Logger::Print("Loading loaded_sound '%s'\n", name.data()); - } - if (!assetHeader.data) { Logger::Error("Error: Missing asset '%s' of type '%s'\n", name.data(), Game::DB_GetXAssetTypeName(type)); diff --git a/src/Game/Structs.hpp b/src/Game/Structs.hpp index b7bfe710..7fdf309a 100644 --- a/src/Game/Structs.hpp +++ b/src/Game/Structs.hpp @@ -906,7 +906,7 @@ namespace Game struct MSSChannelMap { - int speakerCount; + unsigned int speakerCount; MSSSpeakerLevels speakers[6]; }; @@ -950,7 +950,7 @@ namespace Game { const char *aliasName; snd_alias_t *head; - int count; + unsigned int count; }; struct cStaticModel_s