From 6343e117d02a54aa7759156faf101696eb4a3d4b Mon Sep 17 00:00:00 2001 From: Stian Skjelstad Date: Sun, 20 Mar 2022 14:04:46 +0100 Subject: [PATCH 1/3] First byte in a row with value 0xff is special, meaning that the row is empty. --- src/load_ams.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/load_ams.cpp b/src/load_ams.cpp index 6b69b22e..d5f66928 100644 --- a/src/load_ams.cpp +++ b/src/load_ams.cpp @@ -514,6 +514,12 @@ BOOL CSoundFile::ReadAMS2(LPCBYTE lpStream, DWORD dwMemLength) MODCOMMAND *m = Patterns[ipat] + row * m_nChannels; UINT byte1 = psrc[pos++]; UINT ch = byte1 & 0x1F; + if (byte1 == 0xff) + { + row++; + continue; + } + // Read Note + Instr if (!(byte1 & 0x40)) { From b2e8b045b40f04e77f355ea07845f07b620a2d75 Mon Sep 17 00:00:00 2001 From: Stian Skjelstad Date: Tue, 22 Mar 2022 20:57:11 +0100 Subject: [PATCH 2/3] First byte in a row with value 0xff is special for Extreme's Tracker too, meaning that the row is empty. --- src/load_ams.cpp | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/load_ams.cpp b/src/load_ams.cpp index d5f66928..ad4e3bfb 100644 --- a/src/load_ams.cpp +++ b/src/load_ams.cpp @@ -152,6 +152,13 @@ BOOL CSoundFile::ReadAMS(LPCBYTE lpStream, DWORD dwMemLength) while ((row < PatternSize[iPat]) && (i+2 < len)) { BYTE b0 = p[i++]; + + if (b0 == 0xff) + { + row++; + continue; + } + BYTE b1 = p[i++]; BYTE b2 = 0; UINT ch = b0 & 0x3F; From dadf7058372c04ab28ee1fb5475d05e5e191e72e Mon Sep 17 00:00:00 2001 From: Stian Skjelstad Date: Tue, 22 Mar 2022 21:32:44 +0100 Subject: [PATCH 3/3] Velvet Studio files would not parse correct if commands were provided without a note/instrument prefix. (Please note that the current parser only keeps the last command if multiple commands are given at the same channel/row position) --- src/load_ams.cpp | 47 +++++++++++++++++++++++++---------------------- 1 file changed, 25 insertions(+), 22 deletions(-) diff --git a/src/load_ams.cpp b/src/load_ams.cpp index ad4e3bfb..30b20b89 100644 --- a/src/load_ams.cpp +++ b/src/load_ams.cpp @@ -520,6 +520,7 @@ BOOL CSoundFile::ReadAMS2(LPCBYTE lpStream, DWORD dwMemLength) { MODCOMMAND *m = Patterns[ipat] + row * m_nChannels; UINT byte1 = psrc[pos++]; + UINT byte2; UINT ch = byte1 & 0x1F; if (byte1 == 0xff) { @@ -530,36 +531,38 @@ BOOL CSoundFile::ReadAMS2(LPCBYTE lpStream, DWORD dwMemLength) // Read Note + Instr if (!(byte1 & 0x40)) { - UINT byte2 = psrc[pos++]; + byte2 = psrc[pos++]; UINT note = byte2 & 0x7F; if (note) m[ch].note = (note > 1) ? (note-1) : 0xFF; m[ch].instr = psrc[pos++]; - // Read Effect - while (byte2 & 0x80) + } else { + byte2 = 0x80; /* row contains atleast one effect, so trigged the first parse */ + } + // Read Effect + while (byte2 & 0x80) + { + byte2 = psrc[pos++]; + if (byte2 & 0x40) + { + m[ch].volcmd = VOLCMD_VOLUME; + m[ch].vol = byte2 & 0x3F; + } else { - byte2 = psrc[pos++]; - if (byte2 & 0x40) + UINT command = byte2 & 0x3F; + UINT param = psrc[pos++]; + if (command == 0x0C) { m[ch].volcmd = VOLCMD_VOLUME; - m[ch].vol = byte2 & 0x3F; + m[ch].vol = param / 2; } else + if (command < 0x10) { - UINT command = byte2 & 0x3F; - UINT param = psrc[pos++]; - if (command == 0x0C) - { - m[ch].volcmd = VOLCMD_VOLUME; - m[ch].vol = param / 2; - } else - if (command < 0x10) - { - m[ch].command = command; - m[ch].param = param; - ConvertModCommand(&m[ch]); - } else - { - // TODO: AMS effects - } + m[ch].command = command; + m[ch].param = param; + ConvertModCommand(&m[ch]); + } else + { + // TODO: AMS effects } } }