Updated libopenmpt to version 0.4.3
parent
d484ed47e0
commit
947ec7f691
|
@ -56,7 +56,7 @@ void* align(std::size_t alignment, std::size_t size, void* &ptr, std::size_t &sp
|
|||
|
||||
aligned_raw_memory aligned_alloc_impl(std::size_t size, std::size_t count, std::size_t alignment)
|
||||
{
|
||||
#if MPT_CXX_AT_LEAST(17) && (!MPT_COMPILER_MSVC && !MPT_GCC_BEFORE(8,1,0) && !MPT_CLANG_BEFORE(5,0,0)) && !(MPT_COMPILER_CLANG && defined(__GLIBCXX__)) && !MPT_OS_EMSCRIPTEN
|
||||
#if MPT_CXX_AT_LEAST(17) && (!MPT_COMPILER_MSVC && !MPT_GCC_BEFORE(8,1,0) && !MPT_CLANG_BEFORE(5,0,0)) && !(MPT_COMPILER_CLANG && defined(__GLIBCXX__)) && !(MPT_COMPILER_CLANG && MPT_OS_MACOSX_OR_IOS) && !MPT_OS_EMSCRIPTEN
|
||||
std::size_t space = count * size;
|
||||
void* mem = std::aligned_alloc(alignment, space);
|
||||
if(!mem)
|
||||
|
@ -103,7 +103,7 @@ aligned_raw_memory aligned_alloc_impl(std::size_t size, std::size_t count, std::
|
|||
|
||||
void aligned_free(aligned_raw_memory raw)
|
||||
{
|
||||
#if MPT_CXX_AT_LEAST(17) && (!MPT_COMPILER_MSVC && !MPT_GCC_BEFORE(8,1,0) && !MPT_CLANG_BEFORE(5,0,0)) && !(MPT_COMPILER_CLANG && defined(__GLIBCXX__)) && !MPT_OS_EMSCRIPTEN
|
||||
#if MPT_CXX_AT_LEAST(17) && (!MPT_COMPILER_MSVC && !MPT_GCC_BEFORE(8,1,0) && !MPT_CLANG_BEFORE(5,0,0)) && !(MPT_COMPILER_CLANG && defined(__GLIBCXX__)) && !(MPT_COMPILER_CLANG && MPT_OS_MACOSX_OR_IOS) && !MPT_OS_EMSCRIPTEN
|
||||
std::free(raw.mem);
|
||||
#elif MPT_COMPILER_MSVC
|
||||
_aligned_free(raw.mem);
|
||||
|
|
|
@ -100,7 +100,7 @@ namespace mpt
|
|||
|
||||
|
||||
|
||||
#if MPT_CXX_AT_LEAST(17) && !(MPT_COMPILER_CLANG && defined(__GLIBCXX__))
|
||||
#if MPT_CXX_AT_LEAST(17) && !(MPT_COMPILER_CLANG && defined(__GLIBCXX__)) && !(MPT_COMPILER_CLANG && MPT_OS_MACOSX_OR_IOS)
|
||||
using std::launder;
|
||||
#else
|
||||
template <class T>
|
||||
|
|
|
@ -20,8 +20,8 @@ OPENMPT_NAMESPACE_BEGIN
|
|||
//Version definitions. The only thing that needs to be changed when changing version number.
|
||||
#define VER_MAJORMAJOR 1
|
||||
#define VER_MAJOR 28
|
||||
#define VER_MINOR 02
|
||||
#define VER_MINORMINOR 04
|
||||
#define VER_MINOR 03
|
||||
#define VER_MINORMINOR 00
|
||||
|
||||
//Numerical value of the version.
|
||||
#define MPT_VERSION_CURRENT MAKE_VERSION_NUMERIC(VER_MAJORMAJOR,VER_MAJOR,VER_MINOR,VER_MINORMINOR)
|
||||
|
|
|
@ -0,0 +1,22 @@
|
|||
Copyright 2013-2014 RAD Game Tools and Valve Software
|
||||
Copyright 2010-2014 Rich Geldreich and Tenacious Software LLC
|
||||
|
||||
All Rights Reserved.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
|
@ -1,6 +1,6 @@
|
|||
miniz DEFLATE implementation.
|
||||
https://github.com/richgel999/miniz
|
||||
2.0.7
|
||||
2.0.8
|
||||
Modifications for OpenMPT:
|
||||
* #define MINIZ_NO_STDIO has been set because OpenMPT does not need stdio
|
||||
functionality and miniz relies on secure-CRT file i/o functions in windows
|
||||
|
|
|
@ -2709,18 +2709,19 @@ tinfl_status tinfl_decompress(tinfl_decompressor *r, const mz_uint8 *pIn_buf_nex
|
|||
}
|
||||
}
|
||||
#endif
|
||||
do
|
||||
while(counter>2)
|
||||
{
|
||||
pOut_buf_cur[0] = pSrc[0];
|
||||
pOut_buf_cur[1] = pSrc[1];
|
||||
pOut_buf_cur[2] = pSrc[2];
|
||||
pOut_buf_cur += 3;
|
||||
pSrc += 3;
|
||||
} while ((int)(counter -= 3) > 2);
|
||||
if ((int)counter > 0)
|
||||
counter -= 3;
|
||||
}
|
||||
if (counter > 0)
|
||||
{
|
||||
pOut_buf_cur[0] = pSrc[0];
|
||||
if ((int)counter > 1)
|
||||
if (counter > 1)
|
||||
pOut_buf_cur[1] = pSrc[1];
|
||||
pOut_buf_cur += counter;
|
||||
}
|
||||
|
@ -6092,6 +6093,17 @@ mz_bool mz_zip_writer_add_mem_ex_v2(mz_zip_archive *pZip, const char *pArchive_n
|
|||
}
|
||||
#endif /* #ifndef MINIZ_NO_TIME */
|
||||
|
||||
if (!(level_and_flags & MZ_ZIP_FLAG_COMPRESSED_DATA))
|
||||
{
|
||||
uncomp_crc32 = (mz_uint32)mz_crc32(MZ_CRC32_INIT, (const mz_uint8 *)pBuf, buf_size);
|
||||
uncomp_size = buf_size;
|
||||
if (uncomp_size <= 3)
|
||||
{
|
||||
level = 0;
|
||||
store_data_uncompressed = MZ_TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
archive_name_size = strlen(pArchive_name);
|
||||
if (archive_name_size > MZ_UINT16_MAX)
|
||||
return mz_zip_set_error(pZip, MZ_ZIP_INVALID_FILENAME);
|
||||
|
@ -6207,24 +6219,13 @@ mz_bool mz_zip_writer_add_mem_ex_v2(mz_zip_archive *pZip, const char *pArchive_n
|
|||
cur_archive_file_ofs += archive_name_size;
|
||||
}
|
||||
|
||||
if (user_extra_data_len > 0)
|
||||
{
|
||||
if (pZip->m_pWrite(pZip->m_pIO_opaque, cur_archive_file_ofs, user_extra_data, user_extra_data_len) != user_extra_data_len)
|
||||
return mz_zip_set_error(pZip, MZ_ZIP_FILE_WRITE_FAILED);
|
||||
if (user_extra_data_len > 0)
|
||||
{
|
||||
if (pZip->m_pWrite(pZip->m_pIO_opaque, cur_archive_file_ofs, user_extra_data, user_extra_data_len) != user_extra_data_len)
|
||||
return mz_zip_set_error(pZip, MZ_ZIP_FILE_WRITE_FAILED);
|
||||
|
||||
cur_archive_file_ofs += user_extra_data_len;
|
||||
}
|
||||
|
||||
if (!(level_and_flags & MZ_ZIP_FLAG_COMPRESSED_DATA))
|
||||
{
|
||||
uncomp_crc32 = (mz_uint32)mz_crc32(MZ_CRC32_INIT, (const mz_uint8 *)pBuf, buf_size);
|
||||
uncomp_size = buf_size;
|
||||
if (uncomp_size <= 3)
|
||||
{
|
||||
level = 0;
|
||||
store_data_uncompressed = MZ_TRUE;
|
||||
}
|
||||
}
|
||||
cur_archive_file_ofs += user_extra_data_len;
|
||||
}
|
||||
|
||||
if (store_data_uncompressed)
|
||||
{
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* miniz.c 2.0.7 - public domain deflate/inflate, zlib-subset, ZIP reading/writing/appending, PNG writing
|
||||
/* miniz.c 2.0.8 - public domain deflate/inflate, zlib-subset, ZIP reading/writing/appending, PNG writing
|
||||
See "unlicense" statement at the end of this file.
|
||||
Rich Geldreich <richgel99@gmail.com>, last updated Oct. 13, 2013
|
||||
Implements RFC 1950: http://www.ietf.org/rfc/rfc1950.txt and RFC 1951: http://www.ietf.org/rfc/rfc1951.txt
|
||||
|
@ -247,11 +247,11 @@ enum
|
|||
MZ_DEFAULT_COMPRESSION = -1
|
||||
};
|
||||
|
||||
#define MZ_VERSION "10.0.2"
|
||||
#define MZ_VERNUM 0xA020
|
||||
#define MZ_VERSION "10.0.3"
|
||||
#define MZ_VERNUM 0xA030
|
||||
#define MZ_VER_MAJOR 10
|
||||
#define MZ_VER_MINOR 0
|
||||
#define MZ_VER_REVISION 2
|
||||
#define MZ_VER_REVISION 3
|
||||
#define MZ_VER_SUBREVISION 0
|
||||
|
||||
#ifndef MINIZ_NO_ZLIB_APIS
|
||||
|
@ -1149,13 +1149,6 @@ MZ_FILE *mz_zip_get_cfile(mz_zip_archive *pZip);
|
|||
/* Reads n bytes of raw archive data, starting at file offset file_ofs, to pBuf. */
|
||||
size_t mz_zip_read_archive_data(mz_zip_archive *pZip, mz_uint64 file_ofs, void *pBuf, size_t n);
|
||||
|
||||
/* Attempts to locates a file in the archive's central directory. */
|
||||
/* Valid flags: MZ_ZIP_FLAG_CASE_SENSITIVE, MZ_ZIP_FLAG_IGNORE_PATH */
|
||||
/* Returns -1 if the file cannot be found. */
|
||||
int mz_zip_locate_file(mz_zip_archive *pZip, const char *pName, const char *pComment, mz_uint flags);
|
||||
/* Returns MZ_FALSE if the file cannot be found. */
|
||||
mz_bool mz_zip_locate_file_v2(mz_zip_archive *pZip, const char *pName, const char *pComment, mz_uint flags, mz_uint32 *pIndex);
|
||||
|
||||
/* All mz_zip funcs set the m_last_error field in the mz_zip_archive struct. These functions retrieve/manipulate this field. */
|
||||
/* Note that the m_last_error functionality is not thread safe. */
|
||||
mz_zip_error mz_zip_set_last_error(mz_zip_archive *pZip, mz_zip_error err_num);
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
This folder contains the stb_vorbis library from
|
||||
https://github.com/nothings/stb/blob/master/stb_vorbis.c v1.14
|
||||
commit e6afb9cbae4064da8c3e69af3ff5c4629579c1d2 (2018-02-11)
|
||||
https://github.com/nothings/stb/blob/master/stb_vorbis.c v1.15
|
||||
commit 59e9702be5bfc0061e756c7beab7dcd3d363400d (2019-02-07)
|
||||
|
||||
Modifications:
|
||||
* Use of alloca has been replaced with malloc, as alloca is not in C99 and
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
// Ogg Vorbis audio decoder - v1.14 - public domain
|
||||
// Ogg Vorbis audio decoder - v1.15 - public domain
|
||||
// http://nothings.org/stb_vorbis/
|
||||
//
|
||||
// Original version written by Sean Barrett in 2007.
|
||||
|
@ -33,6 +33,7 @@
|
|||
// Timur Gagiev
|
||||
//
|
||||
// Partial history:
|
||||
// 1.15 - 2019-02-07 - explicit failure if Ogg Skeleton data is found
|
||||
// 1.14 - 2018-02-11 - delete bogus dealloca usage
|
||||
// 1.13 - 2018-01-29 - fix truncation of last frame (hopefully)
|
||||
// 1.12 - 2017-11-21 - limit residue begin/end to blocksize/2 to avoid large temp allocs in bad/corrupt files
|
||||
|
@ -253,7 +254,7 @@ extern stb_vorbis * stb_vorbis_open_file(FILE *f, int close_handle_on_close,
|
|||
// create an ogg vorbis decoder from an open FILE *, looking for a stream at
|
||||
// the _current_ seek point (ftell). on failure, returns NULL and sets *error.
|
||||
// note that stb_vorbis must "own" this stream; if you seek it in between
|
||||
// calls to stb_vorbis, it will become confused. Morever, if you attempt to
|
||||
// calls to stb_vorbis, it will become confused. Moreover, if you attempt to
|
||||
// perform stb_vorbis_seek_*() operations on this file, it will assume it
|
||||
// owns the _entire_ rest of the file after the start point. Use the next
|
||||
// function, stb_vorbis_open_file_section(), to limit it.
|
||||
|
@ -374,7 +375,8 @@ enum STBVorbisError
|
|||
VORBIS_invalid_first_page,
|
||||
VORBIS_bad_packet_type,
|
||||
VORBIS_cant_find_last_page,
|
||||
VORBIS_seek_failed
|
||||
VORBIS_seek_failed,
|
||||
VORBIS_ogg_skeleton_not_supported
|
||||
};
|
||||
|
||||
|
||||
|
@ -1082,7 +1084,7 @@ static int compute_codewords(Codebook *c, uint8 *len, int n, uint32 *values)
|
|||
assert(z >= 0 && z < 32);
|
||||
available[z] = 0;
|
||||
add_entry(c, bit_reverse(res), i, m++, len[i], values);
|
||||
// propogate availability up the tree
|
||||
// propagate availability up the tree
|
||||
if (z != len[i]) {
|
||||
assert(len[i] >= 0 && len[i] < 32);
|
||||
for (y=len[i]; y > z; --y) {
|
||||
|
@ -2646,7 +2648,7 @@ static void inverse_mdct(float *buffer, int n, vorb *f, int blocktype)
|
|||
// once I combined the passes.
|
||||
|
||||
// so there's a missing 'times 2' here (for adding X to itself).
|
||||
// this propogates through linearly to the end, where the numbers
|
||||
// this propagates through linearly to the end, where the numbers
|
||||
// are 1/2 too small, and need to be compensated for.
|
||||
|
||||
{
|
||||
|
@ -3587,7 +3589,22 @@ static int start_decoder(vorb *f)
|
|||
if (f->page_flag & PAGEFLAG_continued_packet) return error(f, VORBIS_invalid_first_page);
|
||||
// check for expected packet length
|
||||
if (f->segment_count != 1) return error(f, VORBIS_invalid_first_page);
|
||||
if (f->segments[0] != 30) return error(f, VORBIS_invalid_first_page);
|
||||
if (f->segments[0] != 30) {
|
||||
// check for the Ogg skeleton fishead identifying header to refine our error
|
||||
if (f->segments[0] == 64 &&
|
||||
getn(f, header, 6) &&
|
||||
header[0] == 'f' &&
|
||||
header[1] == 'i' &&
|
||||
header[2] == 's' &&
|
||||
header[3] == 'h' &&
|
||||
header[4] == 'e' &&
|
||||
header[5] == 'a' &&
|
||||
get8(f) == 'd' &&
|
||||
get8(f) == '\0') return error(f, VORBIS_ogg_skeleton_not_supported);
|
||||
else
|
||||
return error(f, VORBIS_invalid_first_page);
|
||||
}
|
||||
|
||||
// read packet
|
||||
// check packet header
|
||||
if (get8(f) != VORBIS_packet_id) return error(f, VORBIS_invalid_first_page);
|
||||
|
@ -4580,7 +4597,7 @@ static int get_seek_page_info(stb_vorbis *f, ProbedPage *z)
|
|||
return 1;
|
||||
}
|
||||
|
||||
// rarely used function to seek back to the preceeding page while finding the
|
||||
// rarely used function to seek back to the preceding page while finding the
|
||||
// start of a packet
|
||||
static int go_to_page_before(stb_vorbis *f, unsigned int limit_offset)
|
||||
{
|
||||
|
|
|
@ -5,6 +5,20 @@ Changelog {#changelog}
|
|||
For fully detailed change log, please see the source repository directly. This
|
||||
is just a high-level summary.
|
||||
|
||||
### libopenmpt 0.4.3 (2019-02-11)
|
||||
|
||||
* [**Sec**] Possible crash due to null-pointer access when doing a portamento
|
||||
from an OPL instrument to an empty instrument note map slot (r11348).
|
||||
|
||||
* [**Bug**] libopenmpt did not compile on Apple platforms in C++17 mode.
|
||||
|
||||
* IT: Various fixes for note-off + instrument number in Old Effects mode.
|
||||
* MO3: Import IT row highlights as written by MO3 2.4.1.2 or newer. Required
|
||||
for modules using modern tempo mode.
|
||||
|
||||
* miniz: Update to v2.0.8 (2018-09-19).
|
||||
* stb_vorbis: Update to v1.15 (2019-02-07).
|
||||
|
||||
### libopenmpt 0.4.2 (2019-01-22)
|
||||
|
||||
* [**Sec**] DSM: Assertion failure during file parsing with debug STLs
|
||||
|
|
|
@ -19,7 +19,7 @@
|
|||
/*! \brief libopenmpt minor version number */
|
||||
#define OPENMPT_API_VERSION_MINOR 4
|
||||
/*! \brief libopenmpt patch version number */
|
||||
#define OPENMPT_API_VERSION_PATCH 2
|
||||
#define OPENMPT_API_VERSION_PATCH 3
|
||||
/*! \brief libopenmpt pre-release tag */
|
||||
#define OPENMPT_API_VERSION_PREREL ""
|
||||
/*! \brief libopenmpt pre-release flag */
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
LIBOPENMPT_VERSION_MAJOR=0
|
||||
LIBOPENMPT_VERSION_MINOR=4
|
||||
LIBOPENMPT_VERSION_PATCH=2
|
||||
LIBOPENMPT_VERSION_PATCH=3
|
||||
LIBOPENMPT_VERSION_PREREL=
|
||||
|
||||
LIBOPENMPT_LTVER_CURRENT=1
|
||||
LIBOPENMPT_LTVER_REVISION=2
|
||||
LIBOPENMPT_LTVER_REVISION=3
|
||||
LIBOPENMPT_LTVER_AGE=1
|
||||
|
|
|
@ -63,7 +63,7 @@ struct MixLoopState
|
|||
// If there is no interpolation happening, there is no lookahead happening the sample read-out is exact.
|
||||
if(chn.dwFlags[CHN_LOOP] && chn.resamplingMode != SRCMODE_NEAREST)
|
||||
{
|
||||
const bool inSustainLoop = chn.InSustainLoop();
|
||||
const bool inSustainLoop = chn.InSustainLoop() && chn.nLoopStart == chn.pModSample->nSustainStart && chn.nLoopEnd == chn.pModSample->nSustainEnd;
|
||||
|
||||
// Do not enable wraparound magic if we're previewing a custom loop!
|
||||
if(inSustainLoop || chn.nLoopEnd == chn.pModSample->nLoopEnd)
|
||||
|
|
|
@ -1415,7 +1415,7 @@ bool CSoundFile::SaveIT(std::ostream &f, const mpt::PathString &filename, bool c
|
|||
|
||||
if(!compatibilityExport)
|
||||
{
|
||||
// This way, we indicate that the file will most likely contain OpenMPT hacks. Compatibility export puts 0 here.
|
||||
// This way, we indicate that the file might contain OpenMPT hacks. Compatibility export puts 0 here.
|
||||
memcpy(&itHeader.reserved, "OMPT", 4);
|
||||
}
|
||||
}
|
||||
|
@ -1428,17 +1428,17 @@ bool CSoundFile::SaveIT(std::ostream &f, const mpt::PathString &filename, bool c
|
|||
if(m_SongFlags[SONG_ITCOMPATGXX]) itHeader.flags |= ITFileHeader::itCompatGxx;
|
||||
if(m_SongFlags[SONG_EXFILTERRANGE] && !compatibilityExport) itHeader.flags |= ITFileHeader::extendedFilterRange;
|
||||
|
||||
itHeader.globalvol = (uint8)(m_nDefaultGlobalVolume >> 1);
|
||||
itHeader.mv = (uint8)MIN(m_nSamplePreAmp, 128u);
|
||||
itHeader.speed = (uint8)MIN(m_nDefaultSpeed, 255u);
|
||||
itHeader.tempo = (uint8)MIN(m_nDefaultTempo.GetInt(), 255u); //Limit this one to 255, we save the real one as an extension below.
|
||||
itHeader.globalvol = static_cast<uint8>(m_nDefaultGlobalVolume / 2u);
|
||||
itHeader.mv = static_cast<uint8>(std::min(m_nSamplePreAmp, uint32(128)));
|
||||
itHeader.speed = mpt::saturate_cast<uint8>(m_nDefaultSpeed);
|
||||
itHeader.tempo = mpt::saturate_cast<uint8>(m_nDefaultTempo.GetInt()); // We save the real tempo in an extension below if it exceeds 255.
|
||||
itHeader.sep = 128; // pan separation
|
||||
// IT doesn't have a per-instrument Pitch Wheel Depth setting, so we just store the first non-zero PWD setting in the header.
|
||||
for(INSTRUMENTINDEX ins = 1; ins < GetNumInstruments(); ins++)
|
||||
for(INSTRUMENTINDEX ins = 1; ins <= GetNumInstruments(); ins++)
|
||||
{
|
||||
if(Instruments[ins] != nullptr && Instruments[ins]->midiPWD != 0)
|
||||
{
|
||||
itHeader.pwd = (uint8)mpt::abs(Instruments[ins]->midiPWD);
|
||||
itHeader.pwd = static_cast<uint8>(mpt::abs(Instruments[ins]->midiPWD));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -1613,7 +1613,7 @@ bool CSoundFile::SaveIT(std::ostream &f, const mpt::PathString &filename, bool c
|
|||
uint16 writeSize = 0;
|
||||
uint16le patinfo[4];
|
||||
patinfo[0] = 0;
|
||||
patinfo[1] = (uint16)writeRows;
|
||||
patinfo[1] = static_cast<uint16>(writeRows);
|
||||
patinfo[2] = 0;
|
||||
patinfo[3] = 0;
|
||||
|
||||
|
@ -1744,11 +1744,11 @@ bool CSoundFile::SaveIT(std::ostream &f, const mpt::PathString &filename, bool c
|
|||
if (b != chnmask[ch])
|
||||
{
|
||||
chnmask[ch] = b;
|
||||
buf[len++] = uint8((ch + 1) | IT_bitmask_patternChanEnabled_c);
|
||||
buf[len++] = static_cast<uint8>((ch + 1) | IT_bitmask_patternChanEnabled_c);
|
||||
buf[len++] = b;
|
||||
} else
|
||||
{
|
||||
buf[len++] = uint8(ch + 1);
|
||||
buf[len++] = static_cast<uint8>(ch + 1);
|
||||
}
|
||||
if (b & 1) buf[len++] = note;
|
||||
if (b & 2) buf[len++] = m->instr;
|
||||
|
@ -1790,7 +1790,7 @@ bool CSoundFile::SaveIT(std::ostream &f, const mpt::PathString &filename, bool c
|
|||
bool compress = false;
|
||||
#endif // MODPLUG_TRACKER
|
||||
// Old MPT, DUMB and probably other libraries will only consider the IT2.15 compression flag if the header version also indicates IT2.15.
|
||||
// MilkyTracker <= 0.90.85 will only assume IT2.15 compression with cmwt == 0x215, ignoring the delta flag completely.
|
||||
// MilkyTracker <= 0.90.85 assumes IT2.15 compression with cmwt == 0x215, ignoring the delta flag completely.
|
||||
itss.ConvertToIT(sample, GetType(), compress, itHeader.cmwt >= 0x215, GetType() == MOD_TYPE_MPT);
|
||||
const bool isExternal = itss.cvt == ITSample::cvtExternalSample;
|
||||
|
||||
|
|
|
@ -194,22 +194,29 @@ struct MO3Instrument
|
|||
panEnv.ConvertToMPT(mptIns.PanEnv, 0);
|
||||
pitchEnv.ConvertToMPT(mptIns.PitchEnv, 5);
|
||||
mptIns.nFadeOut = fadeOut;
|
||||
|
||||
if(midiChannel >= 128)
|
||||
{
|
||||
// Plugin
|
||||
mptIns.nMixPlug = midiChannel - 127;
|
||||
} else if(midiChannel < 17 && (flags & playOnMIDI))
|
||||
{
|
||||
// XM / IT with recent encoder
|
||||
// XM, or IT with recent encoder
|
||||
mptIns.nMidiChannel = midiChannel + MidiFirstChannel;
|
||||
} else if(midiChannel > 0 && midiChannel < 17)
|
||||
{
|
||||
// IT encoded with MO3 version prior to 2.4.1 (yes, channel 0 is represented the same way as "no channel")
|
||||
mptIns.nMidiChannel = midiChannel + MidiFirstChannel;
|
||||
}
|
||||
mptIns.wMidiBank = midiBank;
|
||||
mptIns.nMidiProgram = midiPatch;
|
||||
mptIns.midiPWD = midiBend;
|
||||
if(mptIns.nMidiChannel != MidiNoChannel)
|
||||
{
|
||||
if(mptIns.wMidiBank < 128)
|
||||
mptIns.wMidiBank = midiBank + 1;
|
||||
if(mptIns.nMidiProgram < 128)
|
||||
mptIns.nMidiProgram = midiPatch + 1;
|
||||
mptIns.midiPWD = midiBend;
|
||||
}
|
||||
|
||||
if(type == MOD_TYPE_IT)
|
||||
mptIns.nGlobalVol = std::min<uint8>(globalVol, 128) / 2u;
|
||||
if(panning <= 256)
|
||||
|
@ -1811,6 +1818,10 @@ bool CSoundFile::ReadMO3(FileReader &file, ModLoadingFlags loadFlags)
|
|||
break;
|
||||
}
|
||||
break;
|
||||
case MagicLE("PRHI"):
|
||||
m_nDefaultRowsPerBeat = chunk.ReadUint8();
|
||||
m_nDefaultRowsPerMeasure = chunk.ReadUint8();
|
||||
break;
|
||||
case MagicLE("MIDI"):
|
||||
// Full MIDI config
|
||||
chunk.ReadStruct<MIDIMacroConfigData>(m_MidiCfg);
|
||||
|
|
|
@ -513,6 +513,7 @@ enum PlayBehaviour
|
|||
kReleaseNodePastSustainBug, // OpenMPT 1.23.01.02 / r4009 broke release nodes past the sustain point, fixed in OpenMPT 1.28
|
||||
kFT2NoteDelayWithoutInstr, // Sometime between OpenMPT 1.18.03.00 and 1.19.01.00, delayed instrument-less notes in XM started recalling the default sample volume and panning
|
||||
kOPLFlexibleNoteOff, // Full control after note-off over OPL voices, ^^^ sends note cut instead of just note-off
|
||||
kITInstrWithNoteOffOldEffects, // Instrument number with note-off recalls default volume - special cases with Old Effects enabled
|
||||
|
||||
// Add new play behaviours here.
|
||||
|
||||
|
|
|
@ -1327,6 +1327,7 @@ void CSoundFile::InstrumentChange(ModChannel &chn, uint32 instr, bool bPorta, bo
|
|||
{
|
||||
const ModInstrument *pIns = instr <= GetNumInstruments() ? Instruments[instr] : nullptr;
|
||||
const ModSample *pSmp = &Samples[instr];
|
||||
const auto oldInsVol = chn.nInsVol;
|
||||
ModCommand::NOTE note = chn.nNewNote;
|
||||
|
||||
if(note == NOTE_NONE && m_playBehaviour[kITInstrWithoutNote]) return;
|
||||
|
@ -1491,9 +1492,12 @@ void CSoundFile::InstrumentChange(ModChannel &chn, uint32 instr, bool bPorta, bo
|
|||
if(m_playBehaviour[kITEnvelopeReset])
|
||||
{
|
||||
const bool insNumber = (instr != 0);
|
||||
// IT compatibility: Note-off with instrument number + Old Effects retriggers envelopes.
|
||||
// Test case: ResetEnvNoteOffOldFx.it
|
||||
const bool isKeyOff = chn.dwFlags[CHN_NOTEFADE | CHN_KEYOFF] || (chn.rowCommand.note == NOTE_KEYOFF && m_playBehaviour[kITInstrWithNoteOffOldEffects]);
|
||||
reset = (!chn.nLength
|
||||
|| (insNumber && bPorta && m_SongFlags[SONG_ITCOMPATGXX])
|
||||
|| (insNumber && !bPorta && chn.dwFlags[CHN_NOTEFADE | CHN_KEYOFF] && m_SongFlags[SONG_ITOLDEFFECTS]));
|
||||
|| (insNumber && !bPorta && isKeyOff && m_SongFlags[SONG_ITOLDEFFECTS]));
|
||||
// NOTE: IT2.14 with SB/GUS/etc. output is different. We are going after IT's WAV writer here.
|
||||
// For SB/GUS/etc. emulation, envelope carry should only apply when the NNA isn't set to "Note Cut".
|
||||
// Test case: CarryNNA.it
|
||||
|
@ -1597,6 +1601,21 @@ void CSoundFile::InstrumentChange(ModChannel &chn, uint32 instr, bool bPorta, bo
|
|||
chn.increment.Set(0);
|
||||
}
|
||||
|
||||
// IT compatibility: Note-off with instrument number + Old Effects retriggers envelopes.
|
||||
// If the instrument changes, keep playing the previous sample, but load the new instrument's envelopes.
|
||||
// Test case: ResetEnvNoteOffOldFx.it
|
||||
if(chn.rowCommand.note == NOTE_KEYOFF && m_playBehaviour[kITInstrWithNoteOffOldEffects] && m_SongFlags[SONG_ITOLDEFFECTS] && sampleChanged)
|
||||
{
|
||||
if(chn.pModSample)
|
||||
{
|
||||
chn.dwFlags |= (chn.pModSample->uFlags & CHN_SAMPLEFLAGS);
|
||||
}
|
||||
chn.nInsVol = oldInsVol;
|
||||
chn.nVolume = pSmp->nVolume;
|
||||
if(pSmp->uFlags[CHN_PANNING]) chn.nPan = pSmp->nPan;
|
||||
return;
|
||||
}
|
||||
|
||||
chn.pModSample = pSmp;
|
||||
chn.nLength = pSmp->nLength;
|
||||
chn.nLoopStart = pSmp->nLoopStart;
|
||||
|
@ -1622,13 +1641,11 @@ void CSoundFile::InstrumentChange(ModChannel &chn, uint32 instr, bool bPorta, bo
|
|||
// Don't reset finetune changed by "set finetune" command.
|
||||
// Test case: finetune.xm, finetune.mod
|
||||
// But *do* change the finetune if we switch to a different sample, to fix
|
||||
// Miranda`s axe by Jamson (jam007.xm) - this file doesn't use compatible play mode,
|
||||
// so we may want to use IsCompatibleMode instead if further problems arise.
|
||||
// Miranda`s axe by Jamson (jam007.xm).
|
||||
chn.nC5Speed = pSmp->nC5Speed;
|
||||
chn.nFineTune = pSmp->nFineTune;
|
||||
}
|
||||
|
||||
|
||||
chn.nTranspose = pSmp->RelativeTone;
|
||||
|
||||
// FT2 compatibility: Don't reset portamento target with new instrument numbers.
|
||||
|
@ -1694,6 +1711,10 @@ void CSoundFile::NoteChange(ModChannel &chn, int note, bool bPorta, bool bResetE
|
|||
if(note == NOTE_KEYOFF || !(GetType() & (MOD_TYPE_IT|MOD_TYPE_MPT)))
|
||||
{
|
||||
KeyOff(chn);
|
||||
// IT compatibility: Note-off + instrument releases sample sustain but does not release envelopes or fade the instrument
|
||||
// Test case: noteoff3.it, ResetEnvNoteOffOldFx2.it
|
||||
if(!bPorta && m_playBehaviour[kITInstrWithNoteOffOldEffects] && m_SongFlags[SONG_ITOLDEFFECTS] && chn.rowCommand.instr)
|
||||
chn.dwFlags.reset(CHN_NOTEFADE | CHN_KEYOFF);
|
||||
} else // Invalid Note -> Note Fade
|
||||
{
|
||||
if(/*note == NOTE_FADE && */ GetNumInstruments())
|
||||
|
@ -2783,7 +2804,10 @@ bool CSoundFile::ProcessEffects()
|
|||
if(smp > 0 && smp <= GetNumSamples() && !Samples[smp].uFlags[SMP_NODEFAULTVOLUME])
|
||||
chn.nVolume = Samples[smp].nVolume;
|
||||
}
|
||||
instr = 0;
|
||||
// IT compatibility: Note-off with instrument number + Old Effects retriggers envelopes.
|
||||
// Test case: ResetEnvNoteOffOldFx.it
|
||||
if(!m_playBehaviour[kITInstrWithNoteOffOldEffects] || !m_SongFlags[SONG_ITOLDEFFECTS])
|
||||
instr = 0;
|
||||
}
|
||||
|
||||
if(ModCommand::IsNote(note))
|
||||
|
|
|
@ -1038,6 +1038,7 @@ PlayBehaviourSet CSoundFile::GetSupportedPlaybackBehaviour(MODTYPE type)
|
|||
playBehaviour.set(kITInstrWithNoteOff);
|
||||
playBehaviour.set(kITMultiSampleInstrumentNumber);
|
||||
playBehaviour.set(kRowDelayWithNoteDelay);
|
||||
playBehaviour.set(kITInstrWithNoteOffOldEffects);
|
||||
if(type == MOD_TYPE_MPT)
|
||||
{
|
||||
playBehaviour.set(kOPLFlexibleNoteOff);
|
||||
|
|
|
@ -2235,7 +2235,7 @@ bool CSoundFile::ReadNote()
|
|||
period = m_nMinPeriod;
|
||||
}
|
||||
|
||||
if((chn.dwFlags & (CHN_ADLIB | CHN_MUTE | CHN_SYNCMUTE)) == CHN_ADLIB && !chn.pModSample->uFlags[CHN_MUTE] && m_opl)
|
||||
if((chn.dwFlags & (CHN_ADLIB | CHN_MUTE | CHN_SYNCMUTE)) == CHN_ADLIB && m_opl)
|
||||
{
|
||||
const bool doProcess = m_playBehaviour[kOPLFlexibleNoteOff] || !chn.dwFlags[CHN_NOTEFADE] || GetType() == MOD_TYPE_S3M;
|
||||
if(doProcess && !(GetType() == MOD_TYPE_S3M && chn.dwFlags[CHN_KEYOFF]))
|
||||
|
|
|
@ -430,49 +430,49 @@ void CSoundFile::UpgradeModule()
|
|||
// Pre-1.26: Detailed compatibility flags did not exist.
|
||||
static constexpr PlayBehaviourVersion behaviours[] =
|
||||
{
|
||||
{ kTempoClamp, MAKE_VERSION_NUMERIC(1, 17, 03, 02) },
|
||||
{ kPerChannelGlobalVolSlide, MAKE_VERSION_NUMERIC(1, 17, 03, 02) },
|
||||
{ kPanOverride, MAKE_VERSION_NUMERIC(1, 17, 03, 02) },
|
||||
{ kITInstrWithoutNote, MAKE_VERSION_NUMERIC(1, 17, 02, 46) },
|
||||
{ kITVolColFinePortamento, MAKE_VERSION_NUMERIC(1, 17, 02, 49) },
|
||||
{ kITArpeggio, MAKE_VERSION_NUMERIC(1, 17, 02, 49) },
|
||||
{ kITOutOfRangeDelay, MAKE_VERSION_NUMERIC(1, 17, 02, 49) },
|
||||
{ kITPortaMemoryShare, MAKE_VERSION_NUMERIC(1, 17, 02, 49) },
|
||||
{ kITPatternLoopTargetReset, MAKE_VERSION_NUMERIC(1, 17, 02, 49) },
|
||||
{ kITFT2PatternLoop, MAKE_VERSION_NUMERIC(1, 17, 02, 49) },
|
||||
{ kITPingPongNoReset, MAKE_VERSION_NUMERIC(1, 17, 02, 51) },
|
||||
{ kITEnvelopeReset, MAKE_VERSION_NUMERIC(1, 17, 02, 51) },
|
||||
{ kITClearOldNoteAfterCut, MAKE_VERSION_NUMERIC(1, 17, 02, 52) },
|
||||
{ kITVibratoTremoloPanbrello, MAKE_VERSION_NUMERIC(1, 17, 03, 02) },
|
||||
{ kITTremor, MAKE_VERSION_NUMERIC(1, 17, 03, 02) },
|
||||
{ kITRetrigger, MAKE_VERSION_NUMERIC(1, 17, 03, 02) },
|
||||
{ kITMultiSampleBehaviour, MAKE_VERSION_NUMERIC(1, 17, 03, 02) },
|
||||
{ kITPortaTargetReached, MAKE_VERSION_NUMERIC(1, 17, 03, 02) },
|
||||
{ kITPatternLoopBreak, MAKE_VERSION_NUMERIC(1, 17, 03, 02) },
|
||||
{ kITOffset, MAKE_VERSION_NUMERIC(1, 17, 03, 02) },
|
||||
{ kITSwingBehaviour, MAKE_VERSION_NUMERIC(1, 18, 00, 00) },
|
||||
{ kITNNAReset, MAKE_VERSION_NUMERIC(1, 18, 00, 00) },
|
||||
{ kITSCxStopsSample, MAKE_VERSION_NUMERIC(1, 18, 00, 01) },
|
||||
{ kITEnvelopePositionHandling, MAKE_VERSION_NUMERIC(1, 18, 01, 00) },
|
||||
{ kITPortamentoInstrument, MAKE_VERSION_NUMERIC(1, 19, 00, 01) },
|
||||
{ kITPingPongMode, MAKE_VERSION_NUMERIC(1, 19, 00, 21) },
|
||||
{ kITRealNoteMapping, MAKE_VERSION_NUMERIC(1, 19, 00, 30) },
|
||||
{ kITHighOffsetNoRetrig, MAKE_VERSION_NUMERIC(1, 20, 00, 14) },
|
||||
{ kITFilterBehaviour, MAKE_VERSION_NUMERIC(1, 20, 00, 35) },
|
||||
{ kITNoSurroundPan, MAKE_VERSION_NUMERIC(1, 20, 00, 53) },
|
||||
{ kITShortSampleRetrig, MAKE_VERSION_NUMERIC(1, 20, 00, 54) },
|
||||
{ kITPortaNoNote, MAKE_VERSION_NUMERIC(1, 20, 00, 56) },
|
||||
{ kRowDelayWithNoteDelay, MAKE_VERSION_NUMERIC(1, 20, 00, 76) },
|
||||
{ kITDontResetNoteOffOnPorta, MAKE_VERSION_NUMERIC(1, 20, 02, 06) },
|
||||
{ kITVolColMemory, MAKE_VERSION_NUMERIC(1, 21, 01, 16) },
|
||||
{ kITPortamentoSwapResetsPos, MAKE_VERSION_NUMERIC(1, 21, 01, 25) },
|
||||
{ kITEmptyNoteMapSlot, MAKE_VERSION_NUMERIC(1, 21, 01, 25) },
|
||||
{ kITFirstTickHandling, MAKE_VERSION_NUMERIC(1, 22, 07, 09) },
|
||||
{ kITSampleAndHoldPanbrello, MAKE_VERSION_NUMERIC(1, 22, 07, 19) },
|
||||
{ kITClearPortaTarget, MAKE_VERSION_NUMERIC(1, 23, 04, 03) },
|
||||
{ kITPanbrelloHold, MAKE_VERSION_NUMERIC(1, 24, 01, 06) },
|
||||
{ kITPanningReset, MAKE_VERSION_NUMERIC(1, 24, 01, 06) },
|
||||
{ kITPatternLoopWithJumps, MAKE_VERSION_NUMERIC(1, 25, 00, 19) },
|
||||
{ kTempoClamp, MAKE_VERSION_NUMERIC(1, 17, 03, 02) },
|
||||
{ kPerChannelGlobalVolSlide, MAKE_VERSION_NUMERIC(1, 17, 03, 02) },
|
||||
{ kPanOverride, MAKE_VERSION_NUMERIC(1, 17, 03, 02) },
|
||||
{ kITInstrWithoutNote, MAKE_VERSION_NUMERIC(1, 17, 02, 46) },
|
||||
{ kITVolColFinePortamento, MAKE_VERSION_NUMERIC(1, 17, 02, 49) },
|
||||
{ kITArpeggio, MAKE_VERSION_NUMERIC(1, 17, 02, 49) },
|
||||
{ kITOutOfRangeDelay, MAKE_VERSION_NUMERIC(1, 17, 02, 49) },
|
||||
{ kITPortaMemoryShare, MAKE_VERSION_NUMERIC(1, 17, 02, 49) },
|
||||
{ kITPatternLoopTargetReset, MAKE_VERSION_NUMERIC(1, 17, 02, 49) },
|
||||
{ kITFT2PatternLoop, MAKE_VERSION_NUMERIC(1, 17, 02, 49) },
|
||||
{ kITPingPongNoReset, MAKE_VERSION_NUMERIC(1, 17, 02, 51) },
|
||||
{ kITEnvelopeReset, MAKE_VERSION_NUMERIC(1, 17, 02, 51) },
|
||||
{ kITClearOldNoteAfterCut, MAKE_VERSION_NUMERIC(1, 17, 02, 52) },
|
||||
{ kITVibratoTremoloPanbrello, MAKE_VERSION_NUMERIC(1, 17, 03, 02) },
|
||||
{ kITTremor, MAKE_VERSION_NUMERIC(1, 17, 03, 02) },
|
||||
{ kITRetrigger, MAKE_VERSION_NUMERIC(1, 17, 03, 02) },
|
||||
{ kITMultiSampleBehaviour, MAKE_VERSION_NUMERIC(1, 17, 03, 02) },
|
||||
{ kITPortaTargetReached, MAKE_VERSION_NUMERIC(1, 17, 03, 02) },
|
||||
{ kITPatternLoopBreak, MAKE_VERSION_NUMERIC(1, 17, 03, 02) },
|
||||
{ kITOffset, MAKE_VERSION_NUMERIC(1, 17, 03, 02) },
|
||||
{ kITSwingBehaviour, MAKE_VERSION_NUMERIC(1, 18, 00, 00) },
|
||||
{ kITNNAReset, MAKE_VERSION_NUMERIC(1, 18, 00, 00) },
|
||||
{ kITSCxStopsSample, MAKE_VERSION_NUMERIC(1, 18, 00, 01) },
|
||||
{ kITEnvelopePositionHandling, MAKE_VERSION_NUMERIC(1, 18, 01, 00) },
|
||||
{ kITPortamentoInstrument, MAKE_VERSION_NUMERIC(1, 19, 00, 01) },
|
||||
{ kITPingPongMode, MAKE_VERSION_NUMERIC(1, 19, 00, 21) },
|
||||
{ kITRealNoteMapping, MAKE_VERSION_NUMERIC(1, 19, 00, 30) },
|
||||
{ kITHighOffsetNoRetrig, MAKE_VERSION_NUMERIC(1, 20, 00, 14) },
|
||||
{ kITFilterBehaviour, MAKE_VERSION_NUMERIC(1, 20, 00, 35) },
|
||||
{ kITNoSurroundPan, MAKE_VERSION_NUMERIC(1, 20, 00, 53) },
|
||||
{ kITShortSampleRetrig, MAKE_VERSION_NUMERIC(1, 20, 00, 54) },
|
||||
{ kITPortaNoNote, MAKE_VERSION_NUMERIC(1, 20, 00, 56) },
|
||||
{ kRowDelayWithNoteDelay, MAKE_VERSION_NUMERIC(1, 20, 00, 76) },
|
||||
{ kITDontResetNoteOffOnPorta, MAKE_VERSION_NUMERIC(1, 20, 02, 06) },
|
||||
{ kITVolColMemory, MAKE_VERSION_NUMERIC(1, 21, 01, 16) },
|
||||
{ kITPortamentoSwapResetsPos, MAKE_VERSION_NUMERIC(1, 21, 01, 25) },
|
||||
{ kITEmptyNoteMapSlot, MAKE_VERSION_NUMERIC(1, 21, 01, 25) },
|
||||
{ kITFirstTickHandling, MAKE_VERSION_NUMERIC(1, 22, 07, 09) },
|
||||
{ kITSampleAndHoldPanbrello, MAKE_VERSION_NUMERIC(1, 22, 07, 19) },
|
||||
{ kITClearPortaTarget, MAKE_VERSION_NUMERIC(1, 23, 04, 03) },
|
||||
{ kITPanbrelloHold, MAKE_VERSION_NUMERIC(1, 24, 01, 06) },
|
||||
{ kITPanningReset, MAKE_VERSION_NUMERIC(1, 24, 01, 06) },
|
||||
{ kITPatternLoopWithJumps, MAKE_VERSION_NUMERIC(1, 25, 00, 19) },
|
||||
};
|
||||
|
||||
for(const auto &b : behaviours)
|
||||
|
@ -484,36 +484,36 @@ void CSoundFile::UpgradeModule()
|
|||
// Pre-1.26: Detailed compatibility flags did not exist.
|
||||
static constexpr PlayBehaviourVersion behaviours[] =
|
||||
{
|
||||
{ kTempoClamp, MAKE_VERSION_NUMERIC(1, 17, 03, 02) },
|
||||
{ kPerChannelGlobalVolSlide, MAKE_VERSION_NUMERIC(1, 17, 03, 02) },
|
||||
{ kPanOverride, MAKE_VERSION_NUMERIC(1, 17, 03, 02) },
|
||||
{ kITFT2PatternLoop, MAKE_VERSION_NUMERIC(1, 17, 03, 02) },
|
||||
{ kFT2Arpeggio, MAKE_VERSION_NUMERIC(1, 17, 03, 02) },
|
||||
{ kFT2Retrigger, MAKE_VERSION_NUMERIC(1, 17, 03, 02) },
|
||||
{ kFT2VolColVibrato, MAKE_VERSION_NUMERIC(1, 17, 03, 02) },
|
||||
{ kFT2PortaNoNote, MAKE_VERSION_NUMERIC(1, 17, 03, 02) },
|
||||
{ kFT2KeyOff, MAKE_VERSION_NUMERIC(1, 17, 03, 02) },
|
||||
{ kFT2PanSlide, MAKE_VERSION_NUMERIC(1, 17, 03, 02) },
|
||||
{ kFT2OffsetOutOfRange, MAKE_VERSION_NUMERIC(1, 17, 03, 02) },
|
||||
{ kFT2RestrictXCommand, MAKE_VERSION_NUMERIC(1, 18, 00, 00) },
|
||||
{ kFT2RetrigWithNoteDelay, MAKE_VERSION_NUMERIC(1, 18, 00, 00) },
|
||||
{ kFT2SetPanEnvPos, MAKE_VERSION_NUMERIC(1, 18, 00, 00) },
|
||||
{ kFT2PortaIgnoreInstr, MAKE_VERSION_NUMERIC(1, 18, 00, 01) },
|
||||
{ kFT2VolColMemory, MAKE_VERSION_NUMERIC(1, 18, 01, 00) },
|
||||
{ kFT2LoopE60Restart, MAKE_VERSION_NUMERIC(1, 18, 02, 01) },
|
||||
{ kFT2ProcessSilentChannels, MAKE_VERSION_NUMERIC(1, 18, 02, 01) },
|
||||
{ kFT2ReloadSampleSettings, MAKE_VERSION_NUMERIC(1, 20, 00, 36) },
|
||||
{ kFT2PortaDelay, MAKE_VERSION_NUMERIC(1, 20, 00, 40) },
|
||||
{ kFT2Transpose, MAKE_VERSION_NUMERIC(1, 20, 00, 62) },
|
||||
{ kFT2PatternLoopWithJumps, MAKE_VERSION_NUMERIC(1, 20, 00, 69) },
|
||||
{ kFT2PortaTargetNoReset, MAKE_VERSION_NUMERIC(1, 20, 00, 69) },
|
||||
{ kFT2EnvelopeEscape, MAKE_VERSION_NUMERIC(1, 20, 00, 77) },
|
||||
{ kFT2Tremor, MAKE_VERSION_NUMERIC(1, 20, 01, 11) },
|
||||
{ kFT2OutOfRangeDelay, MAKE_VERSION_NUMERIC(1, 20, 02, 02) },
|
||||
{ kFT2Periods, MAKE_VERSION_NUMERIC(1, 22, 03, 01) },
|
||||
{ kFT2PanWithDelayedNoteOff, MAKE_VERSION_NUMERIC(1, 22, 03, 02) },
|
||||
{ kFT2VolColDelay, MAKE_VERSION_NUMERIC(1, 22, 07, 19) },
|
||||
{ kFT2FinetunePrecision, MAKE_VERSION_NUMERIC(1, 22, 07, 19) },
|
||||
{ kTempoClamp, MAKE_VERSION_NUMERIC(1, 17, 03, 02) },
|
||||
{ kPerChannelGlobalVolSlide, MAKE_VERSION_NUMERIC(1, 17, 03, 02) },
|
||||
{ kPanOverride, MAKE_VERSION_NUMERIC(1, 17, 03, 02) },
|
||||
{ kITFT2PatternLoop, MAKE_VERSION_NUMERIC(1, 17, 03, 02) },
|
||||
{ kFT2Arpeggio, MAKE_VERSION_NUMERIC(1, 17, 03, 02) },
|
||||
{ kFT2Retrigger, MAKE_VERSION_NUMERIC(1, 17, 03, 02) },
|
||||
{ kFT2VolColVibrato, MAKE_VERSION_NUMERIC(1, 17, 03, 02) },
|
||||
{ kFT2PortaNoNote, MAKE_VERSION_NUMERIC(1, 17, 03, 02) },
|
||||
{ kFT2KeyOff, MAKE_VERSION_NUMERIC(1, 17, 03, 02) },
|
||||
{ kFT2PanSlide, MAKE_VERSION_NUMERIC(1, 17, 03, 02) },
|
||||
{ kFT2OffsetOutOfRange, MAKE_VERSION_NUMERIC(1, 17, 03, 02) },
|
||||
{ kFT2RestrictXCommand, MAKE_VERSION_NUMERIC(1, 18, 00, 00) },
|
||||
{ kFT2RetrigWithNoteDelay, MAKE_VERSION_NUMERIC(1, 18, 00, 00) },
|
||||
{ kFT2SetPanEnvPos, MAKE_VERSION_NUMERIC(1, 18, 00, 00) },
|
||||
{ kFT2PortaIgnoreInstr, MAKE_VERSION_NUMERIC(1, 18, 00, 01) },
|
||||
{ kFT2VolColMemory, MAKE_VERSION_NUMERIC(1, 18, 01, 00) },
|
||||
{ kFT2LoopE60Restart, MAKE_VERSION_NUMERIC(1, 18, 02, 01) },
|
||||
{ kFT2ProcessSilentChannels, MAKE_VERSION_NUMERIC(1, 18, 02, 01) },
|
||||
{ kFT2ReloadSampleSettings, MAKE_VERSION_NUMERIC(1, 20, 00, 36) },
|
||||
{ kFT2PortaDelay, MAKE_VERSION_NUMERIC(1, 20, 00, 40) },
|
||||
{ kFT2Transpose, MAKE_VERSION_NUMERIC(1, 20, 00, 62) },
|
||||
{ kFT2PatternLoopWithJumps, MAKE_VERSION_NUMERIC(1, 20, 00, 69) },
|
||||
{ kFT2PortaTargetNoReset, MAKE_VERSION_NUMERIC(1, 20, 00, 69) },
|
||||
{ kFT2EnvelopeEscape, MAKE_VERSION_NUMERIC(1, 20, 00, 77) },
|
||||
{ kFT2Tremor, MAKE_VERSION_NUMERIC(1, 20, 01, 11) },
|
||||
{ kFT2OutOfRangeDelay, MAKE_VERSION_NUMERIC(1, 20, 02, 02) },
|
||||
{ kFT2Periods, MAKE_VERSION_NUMERIC(1, 22, 03, 01) },
|
||||
{ kFT2PanWithDelayedNoteOff, MAKE_VERSION_NUMERIC(1, 22, 03, 02) },
|
||||
{ kFT2VolColDelay, MAKE_VERSION_NUMERIC(1, 22, 07, 19) },
|
||||
{ kFT2FinetunePrecision, MAKE_VERSION_NUMERIC(1, 22, 07, 19) },
|
||||
};
|
||||
|
||||
for(const auto &b : behaviours)
|
||||
|
@ -527,8 +527,9 @@ void CSoundFile::UpgradeModule()
|
|||
// The following behaviours were added in/after OpenMPT 1.26, so are not affected by the upgrade mechanism above.
|
||||
static constexpr PlayBehaviourVersion behaviours[] =
|
||||
{
|
||||
{ kITInstrWithNoteOff, MAKE_VERSION_NUMERIC(1, 26, 00, 01) },
|
||||
{ kITMultiSampleInstrumentNumber, MAKE_VERSION_NUMERIC(1, 27, 00, 27) },
|
||||
{ kITInstrWithNoteOff, MAKE_VERSION_NUMERIC(1, 26, 00, 01) },
|
||||
{ kITMultiSampleInstrumentNumber, MAKE_VERSION_NUMERIC(1, 27, 00, 27) },
|
||||
{ kITInstrWithNoteOffOldEffects, MAKE_VERSION_NUMERIC(1, 28, 02, 06) },
|
||||
};
|
||||
|
||||
for(const auto &b : behaviours)
|
||||
|
@ -544,12 +545,12 @@ void CSoundFile::UpgradeModule()
|
|||
// The following behaviours were added after OpenMPT 1.26, so are not affected by the upgrade mechanism above.
|
||||
static constexpr PlayBehaviourVersion behaviours[] =
|
||||
{
|
||||
{ kFT2NoteOffFlags, MAKE_VERSION_NUMERIC(1, 27, 00, 27) },
|
||||
{ kRowDelayWithNoteDelay, MAKE_VERSION_NUMERIC(1, 27, 00, 37) },
|
||||
{ kFT2TremoloRampWaveform, MAKE_VERSION_NUMERIC(1, 27, 00, 37) },
|
||||
{ kFT2PortaUpDownMemory, MAKE_VERSION_NUMERIC(1, 27, 00, 37) },
|
||||
{ kFT2PanSustainRelease, MAKE_VERSION_NUMERIC(1, 28, 00, 09) },
|
||||
{ kFT2NoteDelayWithoutInstr, MAKE_VERSION_NUMERIC(1, 28, 00, 44) },
|
||||
{ kFT2NoteOffFlags, MAKE_VERSION_NUMERIC(1, 27, 00, 27) },
|
||||
{ kRowDelayWithNoteDelay, MAKE_VERSION_NUMERIC(1, 27, 00, 37) },
|
||||
{ kFT2TremoloRampWaveform, MAKE_VERSION_NUMERIC(1, 27, 00, 37) },
|
||||
{ kFT2PortaUpDownMemory, MAKE_VERSION_NUMERIC(1, 27, 00, 37) },
|
||||
{ kFT2PanSustainRelease, MAKE_VERSION_NUMERIC(1, 28, 00, 09) },
|
||||
{ kFT2NoteDelayWithoutInstr, MAKE_VERSION_NUMERIC(1, 28, 00, 44) },
|
||||
};
|
||||
|
||||
for(const auto &b : behaviours)
|
||||
|
|
Loading…
Reference in New Issue