From 147f47e31c1cf4cb3cf2f637f4ba4c82e346cea0 Mon Sep 17 00:00:00 2001 From: dpogue Date: Sat, 10 Aug 2024 16:27:56 -0700 Subject: [PATCH] Add SoundDecompress tool --- Build/VS2010/Plasma/AllClient.sln | 14 + .../SoundDecompress/SoundDecompress.vcxproj | 418 ++++++++++++++++++ .../SoundDecompress.vcxproj.filters | 22 + Sources/Plasma/Apps/SoundDecompress/main.cpp | 261 +++++++++++ 4 files changed, 715 insertions(+) create mode 100644 Build/VS2010/Plasma/Apps/SoundDecompress/SoundDecompress.vcxproj create mode 100644 Build/VS2010/Plasma/Apps/SoundDecompress/SoundDecompress.vcxproj.filters create mode 100644 Sources/Plasma/Apps/SoundDecompress/main.cpp diff --git a/Build/VS2010/Plasma/AllClient.sln b/Build/VS2010/Plasma/AllClient.sln index ec567d79..1869be06 100644 --- a/Build/VS2010/Plasma/AllClient.sln +++ b/Build/VS2010/Plasma/AllClient.sln @@ -228,6 +228,12 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "pfMoviePlayer", "FeatureLib {B2270EDB-6E92-332F-60C8-255E8AF2CFFC} = {B2270EDB-6E92-332F-60C8-255E8AF2CFFC} EndProjectSection EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "SoundDecompress", "Apps\SoundDecompress\SoundDecompress.vcxproj", "{885DFDA6-A470-4770-9035-64F6BAD39CE7}" + ProjectSection(ProjectDependencies) = postProject + {59197414-421B-457E-A559-F6D875379603} = {59197414-421B-457E-A559-F6D875379603} + {EEFE2438-9F93-4C5C-B85D-6FDD431A1CF1} = {EEFE2438-9F93-4C5C-B85D-6FDD431A1CF1} + EndProjectSection +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug_Internal|Win32 = Debug_Internal|Win32 @@ -1036,6 +1042,14 @@ Global {90045C91-576B-4639-8C2F-A6B5B70EC6A1}.Release_Internal|Win32.Build.0 = Release_Internal|Win32 {90045C91-576B-4639-8C2F-A6B5B70EC6A1}.Release|Win32.ActiveCfg = Release|Win32 {90045C91-576B-4639-8C2F-A6B5B70EC6A1}.Release|Win32.Build.0 = Release|Win32 + {885DFDA6-A470-4770-9035-64F6BAD39CE7}.Debug_Internal|Win32.ActiveCfg = Debug_Internal|Win32 + {885DFDA6-A470-4770-9035-64F6BAD39CE7}.Debug_Internal|Win32.Build.0 = Debug_Internal|Win32 + {885DFDA6-A470-4770-9035-64F6BAD39CE7}.Debug|Win32.ActiveCfg = Debug|Win32 + {885DFDA6-A470-4770-9035-64F6BAD39CE7}.Debug|Win32.Build.0 = Debug|Win32 + {885DFDA6-A470-4770-9035-64F6BAD39CE7}.Release_Internal|Win32.ActiveCfg = Release_Internal|Win32 + {885DFDA6-A470-4770-9035-64F6BAD39CE7}.Release_Internal|Win32.Build.0 = Release_Internal|Win32 + {885DFDA6-A470-4770-9035-64F6BAD39CE7}.Release|Win32.ActiveCfg = Release|Win32 + {885DFDA6-A470-4770-9035-64F6BAD39CE7}.Release|Win32.Build.0 = Release|Win32 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/Build/VS2010/Plasma/Apps/SoundDecompress/SoundDecompress.vcxproj b/Build/VS2010/Plasma/Apps/SoundDecompress/SoundDecompress.vcxproj new file mode 100644 index 00000000..c92da007 --- /dev/null +++ b/Build/VS2010/Plasma/Apps/SoundDecompress/SoundDecompress.vcxproj @@ -0,0 +1,418 @@ + + + + + Debug_Internal + Win32 + + + Debug + Win32 + + + Release_Internal + Win32 + + + Release + Win32 + + + + {885DFDA6-A470-4770-9035-64F6BAD39CE7} + + + + + + Application + false + MultiByte + + + Application + false + MultiByte + + + Application + false + MultiByte + + + Application + false + MultiByte + + + + + + + + + + + + + + + + + + + <_ProjectFileVersion>10.0.40219.1 + $(Configuration)\ + $(Configuration)\ + $(Configuration)\ + $(Configuration)\ + false + false + $(Configuration)\ + $(Configuration)\ + $(Configuration)\ + $(Configuration)\ + false + false + $(ProjectName)_dbg + $(ProjectName)_dbg + + + + Disabled + ../../../../../Sources/Plasma/CoreLib;../../../../../Sources/Plasma/NucleusLib/inc;../../../../../Sources/Plasma/PubUtilLib/inc;../../../StaticSDKs/XPlatform/OpenSSL/include;%(AdditionalIncludeDirectories) + WIN32;_DEBUG;_WINDOWS;_CRT_SECURE_NO_WARNINGS;_CRT_NONSTDC_NO_DEPRECATE;%(PreprocessorDefinitions) + EnableFastChecks + MultiThreadedDebugDLL + true + true + + + $(IntDir) + $(IntDir) + $(IntDir)vc$(PlatformToolsetVersion).pdb + Level3 + true + ProgramDatabase + Default + 4800 + true + + + ws2_32.lib;Rpcrt4.lib;dxerr.lib;libogg_static.lib;libvorbis_static.lib;libvorbisfile_static.lib;zlibd.lib;%(AdditionalDependencies) + $(OutDir)$(TargetName)$(TargetExt) + true + ..\..\..\StaticSDKs\Win32\DX9.0c\Lib\x86;..\..\..\StaticSDKs\XPlatform\oggvorbis\libogg\win32\VS2010\Win32\Debug;..\..\..\StaticSDKs\XPlatform\oggvorbis\libvorbis\win32\VS2010\Win32\Debug;..\..\..\StaticSDKs\XPlatform\zlib\lib;%(AdditionalLibraryDirectories) + libc.lib;libcd.lib;libci.lib;libcid.lib;libcmtd.lib;libcmt.lib;%(IgnoreSpecificDefaultLibraries) + true + true + $(OutDir)$(TargetName).pdb + Console + MachineX86 + true + true + $(OutDir)$(TargetName).map + true + UseLinkTimeCodeGeneration + + + $(OutDir)$(TargetName).tlb + + + + + Copy to Tools directory + xcopy /Y /I "$(TargetPath)" ..\..\..\..\tools\ + + + _DEBUG;%(PreprocessorDefinitions) + 0x0409 + + + + + Disabled + ../../../../../Sources/Plasma/CoreLib;../../../../../Sources/Plasma/NucleusLib/inc;../../../../../Sources/Plasma/PubUtilLib/inc;../../../StaticSDKs/XPlatform/OpenSSL/include;%(AdditionalIncludeDirectories) + WIN32;PLASMA_EXTERNAL_RELEASE;_DEBUG;_WINDOWS;_CRT_SECURE_NO_WARNINGS;_CRT_NONSTDC_NO_DEPRECATE;%(PreprocessorDefinitions) + EnableFastChecks + MultiThreadedDebugDLL + true + true + + + $(IntDir) + $(IntDir) + $(IntDir)vc$(PlatformToolsetVersion).pdb + Level3 + true + ProgramDatabase + Default + 4800 + true + + + ws2_32.lib;Rpcrt4.lib;dxerr.lib;libogg_static.lib;libvorbis_static.lib;libvorbisfile_static.lib;zlibd.lib;%(AdditionalDependencies) + $(OutDir)$(TargetName)$(TargetExt) + true + ..\..\..\StaticSDKs\Win32\DX9.0c\Lib\x86;..\..\..\StaticSDKs\XPlatform\oggvorbis\libogg\win32\VS2010\Win32\Debug;..\..\..\StaticSDKs\XPlatform\oggvorbis\libvorbis\win32\VS2010\Win32\Debug;..\..\..\StaticSDKs\XPlatform\zlib\lib;%(AdditionalLibraryDirectories) + libc.lib;libcd.lib;libci.lib;libcid.lib;libcmtd.lib;libcmt.lib;%(IgnoreSpecificDefaultLibraries) + true + true + $(OutDir)$(TargetName).pdb + Console + MachineX86 + true + true + $(OutDir)$(TargetName).map + true + UseLinkTimeCodeGeneration + + + $(OutDir)$(TargetName).tlb + + + + + Copy to Tools directory + xcopy /Y /I "$(TargetPath)" ..\..\..\..\tools\ + + + _DEBUG;%(PreprocessorDefinitions) + 0x0409 + + + + + Full + OnlyExplicitInline + ../../../../../Sources/Plasma/CoreLib;../../../../../Sources/Plasma/NucleusLib/inc;../../../../../Sources/Plasma/PubUtilLib/inc;../../../StaticSDKs/XPlatform/OpenSSL/include;%(AdditionalIncludeDirectories) + WIN32;NDEBUG;_WINDOWS;_CRT_SECURE_NO_WARNINGS;_CRT_NONSTDC_NO_DEPRECATE;%(PreprocessorDefinitions) + true + MultiThreadedDLL + true + true + + + $(IntDir) + $(IntDir) + $(IntDir)vc$(PlatformToolsetVersion).pdb + false + Level3 + true + + + Default + true + 4800 + true + + + ws2_32.lib;Rpcrt4.lib;dxerr.lib;libogg_static.lib;libvorbis_static.lib;libvorbisfile_static.lib;zlib.lib;%(AdditionalDependencies) + $(OutDir)$(TargetName)$(TargetExt) + true + ..\..\..\StaticSDKs\Win32\DX9.0c\Lib\x86;..\..\..\StaticSDKs\XPlatform\oggvorbis\libogg\win32\VS2010\Win32\Release;..\..\..\StaticSDKs\XPlatform\oggvorbis\libvorbis\win32\VS2010\Win32\Release;..\..\..\StaticSDKs\XPlatform\zlib\lib;%(AdditionalLibraryDirectories) + libc.lib;libci.lib;libcmt.lib;%(IgnoreSpecificDefaultLibraries) + true + false + $(OutDir)$(TargetName).pdb + true + $(OutDir)$(TargetName).map + Console + true + MachineX86 + true + UseLinkTimeCodeGeneration + + + $(OutDir)$(TargetName).tlb + + + + + Copy to Tools directory + xcopy /Y /I "$(TargetPath)" ..\..\..\..\tools\ + + + NDEBUG;%(PreprocessorDefinitions) + 0x0409 + + + + + Full + OnlyExplicitInline + ../../../../../Sources/Plasma/CoreLib;../../../../../Sources/Plasma/NucleusLib/inc;../../../../../Sources/Plasma/PubUtilLib/inc;../../../StaticSDKs/XPlatform/OpenSSL/include;%(AdditionalIncludeDirectories) + WIN32;NDEBUG;_CONSOLE;PLASMA_EXTERNAL_RELEASE;_CRT_SECURE_NO_WARNINGS;_CRT_NONSTDC_NO_DEPRECATE;MS_NO_COREDLL;%(PreprocessorDefinitions) + true + MultiThreadedDLL + + + true + NotUsing + + + $(IntDir) + $(IntDir) + $(IntDir)vc$(PlatformToolsetVersion).pdb + Level3 + true + Default + + + true + + + ws2_32.lib;Rpcrt4.lib;dxerr.lib;libogg_static.lib;libvorbis_static.lib;libvorbisfile_static.lib;zlib.lib;%(AdditionalDependencies) + $(OutDir)$(TargetName)$(TargetExt) + true + ..\..\..\StaticSDKs\Win32\DX9.0c\Lib\x86;..\..\..\StaticSDKs\XPlatform\oggvorbis\libogg\win32\VS2010\Win32\Release;..\..\..\StaticSDKs\XPlatform\oggvorbis\libvorbis\win32\VS2010\Win32\Release;..\..\..\StaticSDKs\XPlatform\zlib\lib;%(AdditionalLibraryDirectories) + libc.lib;libci.lib;libcmt.lib;%(IgnoreSpecificDefaultLibraries) + true + false + $(OutDir)$(TargetName).pdb + true + $(OutDir)$(TargetName).map + Console + true + MachineX86 + true + UseLinkTimeCodeGeneration + + + $(OutDir)$(TargetName).tlb + + + + + Copy to Tools directory + xcopy /Y /I "$(TargetPath)" ..\..\..\..\tools\ + + + NDEBUG;%(PreprocessorDefinitions) + 0x0409 + + + + + Disabled + Disabled + %(AdditionalIncludeDirectories) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + EnableFastChecks + EnableFastChecks + MaxSpeed + MaxSpeed + %(AdditionalIncludeDirectories) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + + + + + {4054c94f-866a-4aa7-874b-2afcfef23a71} + false + + + {83a96477-baef-4db7-8134-aeadf4b2e63f} + false + + + {af37952c-0c38-4057-8d59-eaa18f28da26} + false + + + {e609c4f6-52a0-45c6-958a-8b41680ad809} + false + + + {7c9680f1-6d8c-429d-a3a9-0cd36d9aea0c} + false + + + {4f020dd6-7d46-49e1-bfc1-082d5f979dac} + false + + + {633286c6-e4e8-428f-b1ee-d48cdacc0490} + false + + + {b4752dfb-c7f8-4864-a23b-5f15bc64a7a0} + false + + + {90da3776-6b7c-48a0-8cec-1a60db5be61f} + false + + + {f2635bc2-a8ba-4d43-807a-ea91307dbf93} + false + + + {ca208971-6c77-47f6-aa4b-fb6ecc071132} + false + + + {c0e5499c-1b5b-49a2-9047-95ab6a6c2b13} + false + + + {59197414-421b-457e-a559-f6d875379603} + false + + + {08eb4dcb-75f7-419e-a212-0bead6a10ff1} + false + + + {89316659-f4a9-4e92-8200-c36288a61b9b} + false + + + {7147ce72-97c7-48d9-b3be-e0fca3fba83c} + false + + + {99445121-67ba-4696-8904-f2fc13c928bb} + false + + + {7d696f05-8019-4029-a6e5-1225619ed40a} + false + + + {eefe2438-9f93-4c5c-b85d-6fdd431a1cf1} + false + + + {050ac8c8-a537-46fe-afee-bd3f9cb98f69} + false + + + {05ab7d6b-5c79-4aa2-bee0-b7f9cbfb976a} + false + + + {e157e0e4-ac35-4435-95a6-9179aab66436} + false + + + {21694294-7039-4c2a-b332-08dcad747f05} + false + + + {fe69f407-565e-4c33-a91a-fba622d59c18} + false + + + {bbdf8302-be9c-43ec-aaf8-912e601515b3} + false + + + + + + \ No newline at end of file diff --git a/Build/VS2010/Plasma/Apps/SoundDecompress/SoundDecompress.vcxproj.filters b/Build/VS2010/Plasma/Apps/SoundDecompress/SoundDecompress.vcxproj.filters new file mode 100644 index 00000000..6211973a --- /dev/null +++ b/Build/VS2010/Plasma/Apps/SoundDecompress/SoundDecompress.vcxproj.filters @@ -0,0 +1,22 @@ + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hpp;hxx;hm;inl;inc;xsd + + + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms + + + + + Source Files + + + \ No newline at end of file diff --git a/Sources/Plasma/Apps/SoundDecompress/main.cpp b/Sources/Plasma/Apps/SoundDecompress/main.cpp new file mode 100644 index 00000000..b5dc079f --- /dev/null +++ b/Sources/Plasma/Apps/SoundDecompress/main.cpp @@ -0,0 +1,261 @@ +/*==LICENSE==* + +CyanWorlds.com Engine - MMOG client, server and tools +Copyright (C) 2011 Cyan Worlds, Inc. + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see . + +Additional permissions under GNU GPL version 3 section 7 + +If you modify this Program, or any covered work, by linking or +combining it with any of RAD Game Tools Bink SDK, Autodesk 3ds Max SDK, +NVIDIA PhysX SDK, Microsoft DirectX SDK, OpenSSL library, Independent +JPEG Group JPEG library, Microsoft Windows Media SDK, or Apple QuickTime SDK +(or a modified version of those libraries), +containing parts covered by the terms of the Bink SDK EULA, 3ds Max EULA, +PhysX SDK EULA, DirectX SDK EULA, OpenSSL and SSLeay licenses, IJG +JPEG Library README, Windows Media SDK EULA, or QuickTime SDK EULA, the +licensors of this Program grant you additional +permission to convey the resulting work. Corresponding Source for a +non-source form of such a combination shall include the source code for +the parts of OpenSSL and IJG JPEG Library used as well as that of the covered +work. + +You can contact Cyan Worlds, Inc. by email legal@cyan.com + or by snail mail at: + Cyan Worlds, Inc. + 14617 N Newport Hwy + Mead, WA 99021 + +*==LICENSE==*/ + +#include + +#include "../plResMgr/plResManager.h" +#include "../plResMgr/plResMgrSettings.h" +#include "../plResMgr/plRegistryHelpers.h" +#include "../plResMgr/plRegistryNode.h" + +#include "../plAgeDescription/plAgeManifest.h" + +#include "../plAudioCore/plSoundBuffer.h" + +#include "hsUtils.h" +#include "../plFile/hsFiles.h" +#include "../plFile/plFileUtils.h" + +#define NO_AV_MSGS +#include "pnNucleusCreatables.h" +#include "../pnDispatch/pnDispatchCreatable.h" +#include "../pnKeyedObject/pnKeyedObjectCreatable.h" +#include "../pnMessage/pnMessageCreatable.h" +#include "../pnNetCommon/pnNetCommonCreatable.h" +#include "../pnSceneObject/pnSceneObjectCreatable.h" +#include "../pnTimer/pnTimerCreatable.h" +#include "../plAudioCore/plAudioCoreCreatable.h" +#include "../plNetCommon/plNetCommonCreatable.h" +#include "../plMessage/plMessageCreatable.h" +#include "../plResMgr/plResMgrCreatable.h" + +typedef std::set> SoundSet; + +enum OutputStyle +{ + kSilent, + kProgress, + kVerbose +}; + +//// plSoundBufferCollector ////////////////////////////////////////////////// +// Page iterator that collects all the plSoundBuffers in all of our pages + +class plSoundBufferCollector : public plRegistryPageIterator, public plKeyCollector +{ +public: + plSoundBufferCollector(std::set& keyArray) + : plKeyCollector(keyArray) {} + + hsBool EatPage(plRegistryPageNode* page) + { + if (page->IsValid()) + { + page->LoadKeys(); + return page->IterateKeys(this, plSoundBuffer::Index()); + } + else + { + fprintf(stderr, "INVALID PAGE: %s\n", page->GetPagePath()); + return true; + } + } +}; + + +void PrintHelp() +{ + printf("Plasma Sound Decompressor\n"); + printf("-------------------------\n"); + printf("-s, --silent Run silently, no output\n"); + printf("-v, --verbose Print each filename when decompressing\n"); + printf("-f, --force Force decompressing existing files\n"); +} + +bool CollectSounds(plResManager* rm, SoundSet& sfxArray) +{ + std::set soundKeys; + + plSoundBufferCollector soundCollector(soundKeys); + rm->IterateAllPages(&soundCollector); + + for (auto it = soundKeys.begin(); it != soundKeys.end(); ++it) + { + plSoundBuffer* buffer = plSoundBuffer::ConvertNoRef((*it)->VerifyLoaded()); + if (buffer) + { + // Ref it... + buffer->GetKey()->RefObject(); + + // Get the filename from it and add that file if necessary + const char* filename = buffer->GetFileName(); + if (filename) + { + unsigned short flags = 0; + + if (stricmp(plFileUtils::GetFileExt(filename), "wav") != 0) + { + if (buffer->HasFlag(plSoundBuffer::kOnlyLeftChannel) || + buffer->HasFlag(plSoundBuffer::kOnlyRightChannel)) + hsSetBits(flags, plManifestFile::kSndFlagCacheSplit); + else if (buffer->HasFlag(plSoundBuffer::kStreamCompressed)) + hsSetBits(flags, plManifestFile::kSndFlagStreamCompressed); + else + hsSetBits(flags, plManifestFile::kSndFlagCacheStereo); + } + + std::pair pair = std::make_pair(filename, flags); + sfxArray.insert(pair); + } + + // Unref the object so it goes away + buffer->GetKey()->UnRefObject(); + } + } + + soundKeys.clear(); + + plIndirectUnloadIterator iter; + rm->IterateAllPages(&iter); + + return true; +} + + +void DecompressSounds(SoundSet& sounds, bool overwrite, OutputStyle verbosity) +{ + int total = sounds.size(); + int curr = 0; + + if (verbosity == kVerbose) + { + printf("There are %d sounds\n\n", total); + } + + for (auto it = sounds.begin(); it != sounds.end(); ++it) + { + curr++; + char path[256]; + memset(path, 0, sizeof(path)); + strcat(path, "sfx\\"); + strcat(path, it->first.c_str()); + + if (verbosity == kVerbose) + { + printf("%s\n", path); + } + else if (verbosity == kProgress) + { + int percent = (100 * curr) / total; + int progress = int((float(curr) / total) * 75); + + fprintf(stdout, "\r%3d%% ", percent); + for (int i = 0; i < progress; i++) + { + fprintf(stdout, "="); + } + fflush(stdout); + } + + if (hsCheckBits(it->second, plManifestFile::kSndFlagCacheSplit)) + { + plAudioFileReader::CacheFile(path, true, !overwrite); + } + else if (hsCheckBits(it->second, plManifestFile::kSndFlagCacheStereo)) + { + plAudioFileReader::CacheFile(path, false, !overwrite); + } + } + + + if (verbosity == kProgress) + { + // Hack to ensure we always end with 100% + fprintf(stdout, "\r100%%\n"); + } +} + + +int main(int argc, const char** argv) +{ + bool overwrite = false; + OutputStyle verbosity = kProgress; + + for (int arg = 1; arg < argc; arg++) + { + if (!strcmp(argv[arg], "-h") || !strcmp(argv[arg], "--help")) + { + PrintHelp(); + return 0; + } + else if (!strcmp(argv[arg], "-s") || !strcmp(argv[arg], "--silent")) + { + verbosity = kSilent; + } + else if (!strcmp(argv[arg], "-v") || !strcmp(argv[arg], "--verbose")) + { + verbosity = kVerbose; + } + else if (!strcmp(argv[arg], "-f") || !strcmp(argv[arg], "--force")) + { + overwrite = true; + } + } + + // Init our special resMgr + plResMgrSettings::Get().SetFilterNewerPageVersions(false); + plResMgrSettings::Get().SetFilterOlderPageVersions(false); + plResMgrSettings::Get().SetLoadPagesOnInit(true); + + plResManager* rm = new plResManager(); + rm->SetDataPath("dat"); + hsgResMgr::Init(rm); + + SoundSet sounds; + + CollectSounds(rm, sounds); + DecompressSounds(sounds, overwrite, verbosity); + + hsgResMgr::Shutdown(); + + return 0; +} \ No newline at end of file