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/Loaders.h | 90 ++++++++++++++++++++++ 1 file changed, 90 insertions(+) create mode 100644 Src/external_dependencies/openmpt-trunk/soundlib/Loaders.h (limited to 'Src/external_dependencies/openmpt-trunk/soundlib/Loaders.h') 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((static_cast(id[3]) << 24) | (static_cast(id[2]) << 16) | (static_cast(id[1]) << 8) | static_cast(id[0])); +} +constexpr uint16 MagicLE(const char(&id)[3]) +{ + return static_cast((static_cast(id[1]) << 8) | static_cast(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((static_cast(id[0]) << 24) | (static_cast(id[1]) << 16) | (static_cast(id[2]) << 8) | static_cast(id[3])); +} +constexpr uint16 MagicBE(const char(&id)[3]) +{ + return static_cast((static_cast(id[0]) << 8) | static_cast(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 +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::value); + LimitMax(howMany, arraySize); + LimitMax(howMany, MAX_ORDERS); + ORDERINDEX readEntries = static_cast(howMany); + + order.resize(readEntries); + for(int i = 0; i < readEntries; i++) + { + PATTERNINDEX pat = static_cast(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 +bool ReadOrderFromFile(ModSequence &order, FileReader &file, size_t howMany, uint16 stopIndex = uint16_max, uint16 ignoreIndex = uint16_max) +{ + static_assert(mpt::is_binary_safe::value); + if(!file.CanRead(howMany * sizeof(T))) + return false; + LimitMax(howMany, MAX_ORDERS); + ORDERINDEX readEntries = static_cast(howMany); + + order.resize(readEntries); + T patF; + for(auto &pat : order) + { + file.ReadStruct(patF); + pat = static_cast(patF); + if(pat == stopIndex) pat = order.GetInvalidPatIndex(); + else if(pat == ignoreIndex) pat = order.GetIgnoreIndex(); + } + return true; +} + +OPENMPT_NAMESPACE_END -- cgit