From 20d28e80a5c861a9d5f449ea911ab75b4f37ad0d Mon Sep 17 00:00:00 2001 From: Jef Date: Tue, 24 Sep 2024 14:54:57 +0200 Subject: Initial community commit --- .../openmpt-trunk/soundlib/ContainerUMX.cpp | 73 ++++++++++++++++++++++ 1 file changed, 73 insertions(+) create mode 100644 Src/external_dependencies/openmpt-trunk/soundlib/ContainerUMX.cpp (limited to 'Src/external_dependencies/openmpt-trunk/soundlib/ContainerUMX.cpp') diff --git a/Src/external_dependencies/openmpt-trunk/soundlib/ContainerUMX.cpp b/Src/external_dependencies/openmpt-trunk/soundlib/ContainerUMX.cpp new file mode 100644 index 00000000..828bee6c --- /dev/null +++ b/Src/external_dependencies/openmpt-trunk/soundlib/ContainerUMX.cpp @@ -0,0 +1,73 @@ +/* + * ContainerUMX.cpp + * ---------------- + * Purpose: UMX (Unreal Music) module ripper + * Notes : Obviously, this code only rips modules from older Unreal Engine games, such as Unreal 1, Unreal Tournament 1 and Deus Ex. + * Authors: OpenMPT Devs (inspired by code from http://wiki.beyondunreal.com/Legacy:Package_File_Format) + * The OpenMPT source code is released under the BSD license. Read LICENSE for more details. + */ + + +#include "stdafx.h" +#include "Loaders.h" +#include "UMXTools.h" +#include "Container.h" +#include "Sndfile.h" + + +OPENMPT_NAMESPACE_BEGIN + +CSoundFile::ProbeResult CSoundFile::ProbeFileHeaderUMX(MemoryFileReader file, const uint64 *pfilesize) +{ + return UMX::ProbeFileHeader(file, pfilesize, "music"); +} + + +bool UnpackUMX(std::vector &containerItems, FileReader &file, ContainerLoadingFlags loadFlags) +{ + file.Rewind(); + containerItems.clear(); + + UMX::FileHeader fileHeader; + if(!file.ReadStruct(fileHeader) || !fileHeader.IsValid()) + return false; + + // Note that this can be a false positive, e.g. Unreal maps will have music and sound + // in their name table because they usually import such files. However, it spares us + // from wildly seeking through the file, as the name table is usually right at the + // start of the file, so it is hopefully a good enough heuristic for our purposes. + if(!UMX::FindNameTableEntry(file, fileHeader, "music")) + return false; + else if(!file.CanRead(fileHeader.GetMinimumAdditionalFileSize())) + return false; + else if(loadFlags == ContainerOnlyVerifyHeader) + return true; + + const std::vector names = UMX::ReadNameTable(file, fileHeader); + const std::vector classes = UMX::ReadImportTable(file, fileHeader, names); + + // Read export table + file.Seek(fileHeader.exportOffset); + for(uint32 i = 0; i < fileHeader.exportCount && file.CanRead(8); i++) + { + auto [fileChunk, objName] = UMX::ReadExportTableEntry(file, fileHeader, classes, names, "music"); + if(!fileChunk.IsValid()) + continue; + + ContainerItem item; + + if(objName >= 0 && static_cast(objName) < names.size()) + { + item.name = mpt::ToUnicode(mpt::Charset::Windows1252, names[objName]); + } + + item.file = fileChunk; + + containerItems.push_back(std::move(item)); + } + + return !containerItems.empty(); +} + + +OPENMPT_NAMESPACE_END -- cgit