aboutsummaryrefslogtreecommitdiff
path: root/Src/external_dependencies/openmpt-trunk/soundlib/Loaders.h
diff options
context:
space:
mode:
authorJef <jef@targetspot.com>2024-09-24 08:54:57 -0400
committerJef <jef@targetspot.com>2024-09-24 08:54:57 -0400
commit20d28e80a5c861a9d5f449ea911ab75b4f37ad0d (patch)
tree12f17f78986871dd2cfb0a56e5e93b545c1ae0d0 /Src/external_dependencies/openmpt-trunk/soundlib/Loaders.h
parent537bcbc86291b32fc04ae4133ce4d7cac8ebe9a7 (diff)
downloadwinamp-20d28e80a5c861a9d5f449ea911ab75b4f37ad0d.tar.gz
Initial community commit
Diffstat (limited to 'Src/external_dependencies/openmpt-trunk/soundlib/Loaders.h')
-rw-r--r--Src/external_dependencies/openmpt-trunk/soundlib/Loaders.h90
1 files changed, 90 insertions, 0 deletions
diff --git a/Src/external_dependencies/openmpt-trunk/soundlib/Loaders.h b/Src/external_dependencies/openmpt-trunk/soundlib/Loaders.h
new file mode 100644
index 00000000..4b9b6504
--- /dev/null
+++ b/Src/external_dependencies/openmpt-trunk/soundlib/Loaders.h
@@ -0,0 +1,90 @@
+/*
+ * Loaders.h
+ * ---------
+ * Purpose: Common functions for module loaders
+ * Notes : (currently none)
+ * Authors: OpenMPT Devs
+ * The OpenMPT source code is released under the BSD license. Read LICENSE for more details.
+ */
+
+#pragma once
+
+#include "openmpt/all/BuildSettings.hpp"
+
+#include "../common/misc_util.h"
+#include "../common/FileReader.h"
+#include "Sndfile.h"
+#include "SampleIO.h"
+
+OPENMPT_NAMESPACE_BEGIN
+
+// Functions to create 4-byte and 2-byte magic byte identifiers in little-endian format
+// Use this together with uint32le/uint16le file members.
+constexpr uint32 MagicLE(const char(&id)[5])
+{
+ return static_cast<uint32>((static_cast<uint8>(id[3]) << 24) | (static_cast<uint8>(id[2]) << 16) | (static_cast<uint8>(id[1]) << 8) | static_cast<uint8>(id[0]));
+}
+constexpr uint16 MagicLE(const char(&id)[3])
+{
+ return static_cast<uint16>((static_cast<uint8>(id[1]) << 8) | static_cast<uint8>(id[0]));
+}
+// Functions to create 4-byte and 2-byte magic byte identifiers in big-endian format
+// Use this together with uint32be/uint16be file members.
+// Note: Historically, some magic bytes in MPT-specific fields are reversed (due to the use of multi-char literals).
+// Such fields turned up reversed in files, so MagicBE is used to keep them readable in the code.
+constexpr uint32 MagicBE(const char(&id)[5])
+{
+ return static_cast<uint32>((static_cast<uint8>(id[0]) << 24) | (static_cast<uint8>(id[1]) << 16) | (static_cast<uint8>(id[2]) << 8) | static_cast<uint8>(id[3]));
+}
+constexpr uint16 MagicBE(const char(&id)[3])
+{
+ return static_cast<uint16>((static_cast<uint8>(id[0]) << 8) | static_cast<uint8>(id[1]));
+}
+
+
+// Read 'howMany' order items from an array.
+// 'stopIndex' is treated as '---', 'ignoreIndex' is treated as '+++'. If the format doesn't support such indices, just pass uint16_max.
+template<typename T, size_t arraySize>
+bool ReadOrderFromArray(ModSequence &order, const T(&orders)[arraySize], size_t howMany = arraySize, uint16 stopIndex = uint16_max, uint16 ignoreIndex = uint16_max)
+{
+ static_assert(mpt::is_binary_safe<T>::value);
+ LimitMax(howMany, arraySize);
+ LimitMax(howMany, MAX_ORDERS);
+ ORDERINDEX readEntries = static_cast<ORDERINDEX>(howMany);
+
+ order.resize(readEntries);
+ for(int i = 0; i < readEntries; i++)
+ {
+ PATTERNINDEX pat = static_cast<PATTERNINDEX>(orders[i]);
+ if(pat == stopIndex) pat = order.GetInvalidPatIndex();
+ else if(pat == ignoreIndex) pat = order.GetIgnoreIndex();
+ order.at(i) = pat;
+ }
+ return true;
+}
+
+
+// Read 'howMany' order items as integers with defined endianness from a file.
+// 'stopIndex' is treated as '---', 'ignoreIndex' is treated as '+++'. If the format doesn't support such indices, just pass uint16_max.
+template<typename T>
+bool ReadOrderFromFile(ModSequence &order, FileReader &file, size_t howMany, uint16 stopIndex = uint16_max, uint16 ignoreIndex = uint16_max)
+{
+ static_assert(mpt::is_binary_safe<T>::value);
+ if(!file.CanRead(howMany * sizeof(T)))
+ return false;
+ LimitMax(howMany, MAX_ORDERS);
+ ORDERINDEX readEntries = static_cast<ORDERINDEX>(howMany);
+
+ order.resize(readEntries);
+ T patF;
+ for(auto &pat : order)
+ {
+ file.ReadStruct(patF);
+ pat = static_cast<PATTERNINDEX>(patF);
+ if(pat == stopIndex) pat = order.GetInvalidPatIndex();
+ else if(pat == ignoreIndex) pat = order.GetIgnoreIndex();
+ }
+ return true;
+}
+
+OPENMPT_NAMESPACE_END