From: <sag...@us...> - 2013-10-21 16:08:43
|
Revision: 2960 http://sourceforge.net/p/modplug/code/2960 Author: saga-games Date: 2013-10-21 16:08:36 +0000 (Mon, 21 Oct 2013) Log Message: ----------- [Fix] Support 16-bit samples in AMS 1.x files. [Fix] Display special characters in AMS 2.x files correctly [Ref] Text converters for SongMessage::Read/etc. are no longer in-place (this should be better when, at some point, these things are supposed to convert to wide chars or something) Modified Paths: -------------- trunk/OpenMPT/common/StringFixer.h trunk/OpenMPT/soundlib/Load_ams.cpp trunk/OpenMPT/soundlib/Message.cpp trunk/OpenMPT/soundlib/Message.h trunk/OpenMPT/soundlib/Tables.cpp Modified: trunk/OpenMPT/common/StringFixer.h =================================================================== --- trunk/OpenMPT/common/StringFixer.h 2013-10-21 14:29:37 UTC (rev 2959) +++ trunk/OpenMPT/common/StringFixer.h 2013-10-21 16:08:36 UTC (rev 2960) @@ -95,8 +95,6 @@ void Read(std::string &dest, const char *srcBuffer, const size_t srcSize) //----------------------------------------------------------------------- { - ASSERT(srcSize > 0); - dest.clear(); if(mode == nullTerminated || mode == maybeNullTerminated) @@ -163,7 +161,6 @@ //---------------------------------------------------------------------------------- { STATIC_ASSERT(destSize > 0); - //ASSERT(srcSize > 0); const size_t maxSize = MIN(destSize, srcSize); char *dst = destBuffer; @@ -389,7 +386,7 @@ // Copy from a fixed size char array to a std::string. template <size_t srcSize> void Copy(std::string &dest, const char (&srcBuffer)[srcSize]) - //---------------------------------------------------------------------------- + //------------------------------------------------------------ { CopyN(dest, srcBuffer, srcSize); } Modified: trunk/OpenMPT/soundlib/Load_ams.cpp =================================================================== --- trunk/OpenMPT/soundlib/Load_ams.cpp 2013-10-21 14:29:37 UTC (rev 2959) +++ trunk/OpenMPT/soundlib/Load_ams.cpp 2013-10-21 16:08:36 UTC (rev 2960) @@ -8,6 +8,8 @@ * While the two programs look rather similiar, the structure of both * programs' "AMS" format is significantly different in some places - * Velvet Studio is a rather advanced tracker in comparison to Extreme's Tracker. + * The source code of Velvet Studio has been released into the + * public domain in 2013: https://github.com/Patosc/VelvetStudio/commits/master * Authors: OpenMPT Devs * The OpenMPT source code is released under the BSD license. Read LICENSE for more details. */ @@ -21,34 +23,35 @@ // Common code for both AMS formats // Callback function for reading text -void ConvertAMSTextChars(char &c) -//------------------------------- +static char ConvertAMSTextChars(char c) +//------------------------------------- { switch((unsigned char)c) { - case 0x00: c = ' '; break; - case 0x14: c = '\xF6'; break; - case 0x19: c = '\xD6'; break; - case 0x04: c = '\xE4'; break; - case 0x0E: c = '\xC4'; break; - case 0x06: c = '\xE5'; break; - case 0x0F: c = '\xC5'; break; + case 0x00: return ' '; + case 0x04: return '\xE4'; // Lower-case ae + case 0x06: return '\xE5'; // Lower-case a-ring + case 0x0E: return '\xC4'; // Upper-case AE + case 0x0F: return '\xC5'; // Upper-case A-ring + case 0x14: return '\xF6'; // Lower-case oe + case 0x19: return '\xD6'; // Upper-case OE } + return c; } // Read variable-length AMS string (we ignore the maximum text length specified by the AMS specs and accept any length). template<size_t destSize> -bool ReadAMSString(char (&destBuffer)[destSize], FileReader &file) -//---------------------------------------------------------------- +static bool ReadAMSString(char (&destBuffer)[destSize], FileReader &file) +//----------------------------------------------------------------------- { const size_t length = file.ReadUint8(); return file.ReadString<mpt::String::spacePadded>(destBuffer, length); } // Read variable-length AMS string (we ignore the maximum text length specified by the AMS specs and accept any length). -bool ReadAMSString(std::string &dest, FileReader &file) -//----------------------------------------------------- +static bool ReadAMSString(std::string &dest, FileReader &file) +//------------------------------------------------------------ { const size_t length = file.ReadUint8(); return file.ReadString<mpt::String::spacePadded>(dest, length); @@ -56,8 +59,8 @@ // Read AMS or AMS2 (newVersion = true) pattern. At least this part of the format is more or less identical between the two trackers... -void ReadAMSPattern(CPattern &pattern, bool newVersion, FileReader &patternChunk, CSoundFile &sndFile) -//---------------------------------------------------------------------------------------------------- +static void ReadAMSPattern(CPattern &pattern, bool newVersion, FileReader &patternChunk, CSoundFile &sndFile) +//----------------------------------------------------------------------------------------------------------- { enum { @@ -324,7 +327,8 @@ { enum SampleFlags { - smp16Bit = 0x80, + smp16BitOld = 0x04, // AMS 1.0 (at least according to docs, I yet have to find such a file) + smp16Bit = 0x80, // AMS 1.1+ smpPacked = 0x03, }; @@ -372,8 +376,13 @@ if(mptSmp.nLoopStart < mptSmp.nLoopEnd) { - mptSmp.uFlags |= CHN_LOOP; + mptSmp.uFlags.set(CHN_LOOP); } + + if((flags & smp16Bit) || (flags & smp16BitOld)) + { + mptSmp.uFlags.set(CHN_16BIT); + } } }; @@ -504,7 +513,7 @@ for(SAMPLEINDEX smp = 1; smp <= GetNumSamples(); smp++) { SampleIO( - (Samples[smp].uFlags & CHN_16BIT) ? SampleIO::_16bit : SampleIO::_8bit, + Samples[smp].uFlags[CHN_16BIT] ? SampleIO::_16bit : SampleIO::_8bit, SampleIO::mono, SampleIO::littleEndian, packSample[smp - 1] ? SampleIO::AMS : SampleIO::signedPCM) @@ -517,9 +526,32 @@ ///////////////////////////////////////////////////////////////////// -// AMS (Velvet Studio) 2.1 / 2.2 loader +// AMS (Velvet Studio) 2.0 - 2.02 loader +// Callback function for reading text - looking at Velvet Studio's bitmap font (TPIC32.PCX), these appear to be the only supported non-ASCII chars. +static char ConvertAMS2TextChars(char c) +//-------------------------------------- +{ + const char controlChars[] = + { + ' ', '\xA9', 'v' /* actually supposed to be a root/check sign */, '\xB7', + '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F', // Small GUI letters + ' ', '\xA7' + }; + const char highChars[] = { '\xE4', ' ', '\xE5', ' ', ' ', ' ', ' ', ' ', ' ', ' ', '\xC4', '\xC5', ' ', ' ', ' ', ' ', '\xF6', ' ', ' ', ' ', ' ', '\xD6' }; + + if(c < CountOf(controlChars)) + { + return controlChars[c]; + } else if((unsigned char)c >= 0x84 && (unsigned char)c < 0x84 + CountOf(highChars)) + { + return highChars[(unsigned char)c - 0x84]; + } + return c; +} + + #ifdef NEEDS_PRAGMA_PACK #pragma pack(push, 1) #endif @@ -532,7 +564,7 @@ linearSlides = 0x40, }; - uint8 versionLow; // Version of format (Hi = MainVer, Low = SubVer e.g. 0202 = 2.2) + uint8 versionLow; // Version of format (Hi = MainVer, Low = SubVer e.g. 0202 = 2.02) uint8 versionHigh; // ditto uint8 numIns; // Nr of Instruments (0-255) uint16 numPats; // Nr of Patterns (1-1024) @@ -553,7 +585,7 @@ // AMS2 Instument Envelope struct PACKED AMS2Envelope { - uint8 speed; // Envelope speed + uint8 speed; // Envelope speed (currently not supported, always the same as current BPM) uint8 sustainPoint; // Envelope sustain point uint8 loopStart; // Envelope loop Start uint8 loopEnd; // Envelope loop End @@ -889,7 +921,7 @@ uint8 composerLength = file.ReadUint8(); if(composerLength) { - songMessage.Read(file, composerLength, SongMessage::leAutodetect, ConvertAMSTextChars); + songMessage.Read(file, composerLength, SongMessage::leAutodetect, ConvertAMS2TextChars); } // Channel names @@ -929,7 +961,7 @@ } } // Packed text doesn't include any line breaks! - songMessage.ReadFixedLineLength(&textOut[0], descriptionHeader.unpackedLen, 74, 0, ConvertAMSTextChars); + songMessage.ReadFixedLineLength(&textOut[0], descriptionHeader.unpackedLen, 74, 0, ConvertAMS2TextChars); } // Read Order List Modified: trunk/OpenMPT/soundlib/Message.cpp =================================================================== --- trunk/OpenMPT/soundlib/Message.cpp 2013-10-21 14:29:37 UTC (rev 2959) +++ trunk/OpenMPT/soundlib/Message.cpp 2013-10-21 16:08:36 UTC (rev 2960) @@ -43,7 +43,7 @@ { char c = str[i]; if(pTextConverter != nullptr) - pTextConverter(c); + c = pTextConverter(c); if(c == '\r') nCR++; else if(c == '\n') nLF++; @@ -68,7 +68,7 @@ { char c = str[i]; if(pTextConverter != nullptr) - pTextConverter(c); + c = pTextConverter(c); if(c != '\n' || lineEnding != leCRLF) finalLength++; @@ -81,7 +81,7 @@ { char c = str[i]; if(pTextConverter != nullptr) - pTextConverter(c); + c = pTextConverter(c); switch(c) { @@ -149,7 +149,7 @@ for(size_t lpos = 0; lpos < lineLength; lpos++) { // Pre-process text - if(pTextConverter != nullptr) pTextConverter(at(cpos + lpos)); + if(pTextConverter != nullptr) at(cpos + lpos) = pTextConverter(at(cpos + lpos)); switch(at(cpos + lpos)) { @@ -215,7 +215,7 @@ { char c = at(i); // Pre-process text - if(pTextConverter != nullptr) pTextConverter(c); + if(pTextConverter != nullptr) c = pTextConverter(c); comments.at(writePos++) = c; } } Modified: trunk/OpenMPT/soundlib/Message.h =================================================================== --- trunk/OpenMPT/soundlib/Message.h 2013-10-21 14:29:37 UTC (rev 2959) +++ trunk/OpenMPT/soundlib/Message.h 2013-10-21 16:08:36 UTC (rev 2960) @@ -20,7 +20,7 @@ { public: - typedef void (*ConverterFunc)(char &); + typedef char (*ConverterFunc)(char); // Line ending types (for reading song messages from module files) enum LineEnding Modified: trunk/OpenMPT/soundlib/Tables.cpp =================================================================== --- trunk/OpenMPT/soundlib/Tables.cpp 2013-10-21 14:29:37 UTC (rev 2959) +++ trunk/OpenMPT/soundlib/Tables.cpp 2013-10-21 16:08:36 UTC (rev 2960) @@ -29,7 +29,8 @@ "F#", "G-", "G#", "A-", "A#", "B-" }; -const LPCSTR szDefaultNoteNames[NOTE_MAX] = { +const LPCSTR szDefaultNoteNames[NOTE_MAX] = +{ "C-0", "C#0", "D-0", "D#0", "E-0", "F-0", "F#0", "G-0", "G#0", "A-0", "A#0", "B-0", "C-1", "C#1", "D-1", "D#1", "E-1", "F-1", "F#1", "G-1", "G#1", "A-1", "A#1", "B-1", "C-2", "C#2", "D-2", "D#2", "E-2", "F-2", "F#2", "G-2", "G#2", "A-2", "A#2", "B-2", @@ -48,8 +49,8 @@ struct ModFormatInfo { - MODTYPE format; // MOD_TYPE_XXXX - const char *name; // "ProTracker" + MODTYPE format; // MOD_TYPE_XXXX + const char *name; // "ProTracker" const char *extension; // "mod" }; @@ -134,7 +135,8 @@ #endif -struct ModCharsetInfo { +struct ModCharsetInfo +{ MODTYPE type; MOD_CHARSET_CERTAINTY certainty; const char *charset; @@ -166,8 +168,8 @@ { MOD_TYPE_J2B , MOD_CHARSET_IS , "cp437" }, { MOD_TYPE_IMF , MOD_CHARSET_IS , "cp437" }, { MOD_TYPE_ULT , MOD_CHARSET_IS , "cp437" }, - { MOD_TYPE_AMS , MOD_CHARSET_IS , "cp437" }, - { MOD_TYPE_AMS2, MOD_CHARSET_IS , "cp437" }, + { MOD_TYPE_AMS , MOD_CHARSET_IS , "Windows-1252"}, // We convert the custom AMS special character set to our own set. + { MOD_TYPE_AMS2, MOD_CHARSET_IS , "Windows-1252"}, // ditto { MOD_TYPE_DSM , MOD_CHARSET_IS , "cp437" }, // Windows { MOD_TYPE_MT2 , MOD_CHARSET_MAYBE , "Windows-1252"}, This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |