Author: sagamusix
Date: Wed May 8 19:53:49 2024
New Revision: 20736
URL: https://source.openmpt.org/browse/openmpt/?op=revision&rev=20736
Log:
[Imp] STK: Allow romantic.stk to load, which has a sample longer than 74KB.
[Imp] STK: Also allow files to load that have garbage in the song title, but whose sample names are properly null-terminated non-empty ASCII strings. Fixes STK.Sharks-NewIntro.
Modified:
trunk/OpenMPT/soundlib/Load_stk.cpp
trunk/OpenMPT/soundlib/MODTools.cpp
trunk/OpenMPT/soundlib/MODTools.h
Modified: trunk/OpenMPT/soundlib/Load_stk.cpp
==============================================================================
--- trunk/OpenMPT/soundlib/Load_stk.cpp Wed May 8 18:52:54 2024 (r20735)
+++ trunk/OpenMPT/soundlib/Load_stk.cpp Wed May 8 19:53:49 2024 (r20736)
@@ -51,7 +51,8 @@
SmpLength totalSampleLen = 0;
uint8 allVolumes = 0;
- uint8 diskNameCount = 0;
+ uint8 validNameCount = 0;
+ bool invalidNames = false;
for(SAMPLEINDEX smp = 0; smp < 15; smp++)
{
@@ -62,13 +63,16 @@
// schmokk.mod has a non-zero value here but it should not be treated as finetune
if(sampleHeader.finetune != 0)
invalidChars += 16;
- if(sampleHeader.HasDiskName())
- diskNameCount++;
+ if(const auto nameType = ClassifyName(sampleHeader.name); nameType == NameClassification::ValidASCII)
+ validNameCount++;
+ else if(nameType == NameClassification::Invalid)
+ invalidNames = true;
// Sanity checks - invalid character count adjusted for ata.mod (MD5 937b79b54026fa73a1a4d3597c26eace, SHA1 3322ca62258adb9e0ae8e9afe6e0c29d39add874)
+ // Sample length adjusted for romantic.stk which has a (valid) sample of length 72222
if(invalidChars > 48
|| sampleHeader.volume > 64
- || sampleHeader.length > 32768)
+ || sampleHeader.length > 37000)
{
return false;
}
@@ -77,8 +81,8 @@
allVolumes |= sampleHeader.volume;
}
- // scramble_2.mod has a lot of garbage in the song title, but it has lots of sample names starting with st-01, so we consider those to be more important than the garbage bytes.
- if(invalidCharsInTitle > 5 && diskNameCount < 4)
+ // scramble_2.mod has a lot of garbage in the song title, but it has lots of properly-formatted sample names, so we consider those to be more important than the garbage bytes.
+ if(invalidCharsInTitle > 5 && (validNameCount < 4 || invalidNames))
{
return false;
}
Modified: trunk/OpenMPT/soundlib/MODTools.cpp
==============================================================================
--- trunk/OpenMPT/soundlib/MODTools.cpp Wed May 8 18:52:54 2024 (r20735)
+++ trunk/OpenMPT/soundlib/MODTools.cpp Wed May 8 19:53:49 2024 (r20736)
@@ -314,7 +314,7 @@
// Check if a name string is valid (i.e. doesn't contain binary garbage data)
-uint32 CountInvalidChars(const mpt::span<const char> name)
+uint32 CountInvalidChars(const mpt::span<const char> name) noexcept
{
uint32 invalidChars = 0;
for(int8 c : name) // char can be signed or unsigned
@@ -327,6 +327,27 @@
}
+// Check if a name is a valid null - terminated ASCII string with no garbage after the null terminator, or if it's empty
+NameClassification ClassifyName(const mpt::span<const char> name) noexcept
+{
+ bool foundNull = false, foundNormal = false;
+ for(auto c : name)
+ {
+ if(c > 0 && c < ' ')
+ return NameClassification::Invalid;
+ if(c == 0)
+ foundNull = true;
+ else if(foundNull)
+ return NameClassification::Invalid;
+ else
+ foundNormal = true;
+ }
+ if(!foundNull)
+ return NameClassification::Invalid;
+ return foundNormal ? NameClassification::ValidASCII : NameClassification::Empty;
+}
+
+
// Count malformed bytes in MOD pattern data
uint32 CountMalformedMODPatternData(const MODPatternData &patternData, const bool extendedFormat)
{
Modified: trunk/OpenMPT/soundlib/MODTools.h
==============================================================================
--- trunk/OpenMPT/soundlib/MODTools.h Wed May 8 18:52:54 2024 (r20735)
+++ trunk/OpenMPT/soundlib/MODTools.h Wed May 8 19:53:49 2024 (r20736)
@@ -108,7 +108,18 @@
// Check if a name string is valid (i.e. doesn't contain binary garbage data)
-uint32 CountInvalidChars(const mpt::span<const char> name);
+uint32 CountInvalidChars(const mpt::span<const char> name) noexcept;
+
+
+enum class NameClassification
+{
+ Empty,
+ ValidASCII,
+ Invalid,
+};
+
+// Check if a name is a valid null-terminated ASCII string with no garbage after the null terminator, or if it's empty
+NameClassification ClassifyName(const mpt::span<const char> name) noexcept;
// Count malformed bytes in MOD pattern data
|