Script 'mail_helper' called by obssrc
Hello community,

here is the log from the commit of package libopenmpt for openSUSE:Factory 
checked in at 2024-07-24 15:32:55
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/libopenmpt (Old)
 and      /work/SRC/openSUSE:Factory/.libopenmpt.new.1869 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "libopenmpt"

Wed Jul 24 15:32:55 2024 rev:49 rq:1188976 version:0.7.9

Changes:
--------
--- /work/SRC/openSUSE:Factory/libopenmpt/libopenmpt.changes    2024-06-10 
17:37:02.805640641 +0200
+++ /work/SRC/openSUSE:Factory/.libopenmpt.new.1869/libopenmpt.changes  
2024-07-25 11:56:03.090727649 +0200
@@ -1,0 +2,57 @@
+Mon Jul 22 09:16:49 UTC 2024 - Mia Herkt <m...@0x0.st>
+
+- Update to 0.7.9:
+  * [Sec] Potential division by 0 when seeking in the module with
+    seek.sync_samples enabled (r21167).
+  * [Change] The work-around for
+    https://gcc.gnu.org/bugzilla/show_bug.cgi?id=115049
+    has been changed from forcing -O1 on GCC 14 to setting
+    -fno-ipa-ra on all GCC versions on non-ELF platforms.
+  * MOD: Allow sample swapping to work when swapping from a
+    non-looping, stopped sample back to a looping sample
+    (fixes MOD.energy).
+  * DBM: Import second sustain point in case the first sustain
+    point is not set, or if it has a lower index than the first.
+  * DBM: When several instruments referenced the same sample with
+    different properties (volume, loop points, etc.), only one set
+    of properties was imported (fixes DBM.Supernova).
+  * DBM: Prioritize effects more correctly when the same effect is
+    encountered in both effect columns of a cell
+    (fixes DBM.143_Gnoj).
+  * DBM: Don’t import offset effects when there’s a tone portmento
+    next to them.
+  * DBM: A few IT-specific playback quirks are disabled for more
+    accurate playback (e.g. in “Are You Flying With Me?” by
+    Jazzcat).
+  * DIGI: Sample play direction was reset if adjacent channel
+    contained a Note Cut note.
+  * AMF: When running out of sample slots, file reading became be
+    misaligned because the sample name was not skipped.
+  * MED: Command 0F was not imported.
+  * MED: Upper frequency limits should be more accurate now.
+  * MED: Channel panning is now only applied in MMD2 files if the
+    free pan flag is set.
+  * MED: Volume command resolution was incorrect for pre-MMD3
+    files.
+  * XM: oggmod does not support stereo samples but keeps the stereo
+    flag when encoding such samples. Such samples are now imported
+    as mono samples instead of not importing them at all.
+  * XM: For files saved with registered MadTracker 2 versions,
+    do not put binary garbage (the user ID) in the tracker metadata
+    field. It is replaced with “registered” instead.
+  * For some truncated files, the used tracker was not identified
+    correctly.
+  * S3M: Identify files saved with early Impulse Tracker versions,
+    Sound Club 2, Liquid Tracker, NESMusa, UNMO3, deMODifier,
+    Kosmic To-S3M, and better tell old ModPlug Tracker versions
+    apart.
+  * S3M: When skipping sample loading, some tracker identifications
+    were not working as intended.
+  * IT: Identify files saved with itwriter.
+  * DTM: Identify files saved with Digital Tracker 2.3.
+  * xmp-openmpt: If there is only one subsong, set the song title
+    to the “global” song title instead of the name of that subsong.
+  * xmp-openmpt: Sample and instrument names were not sanitized,
+    sometimes showing on multiple rows.
+
+-------------------------------------------------------------------

Old:
----
  libopenmpt-0.7.8+release.autotools.tar.gz

New:
----
  libopenmpt-0.7.9+release.autotools.tar.gz

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ libopenmpt.spec ++++++
--- /var/tmp/diff_new_pack.cp4JHW/_old  2024-07-25 11:56:03.734755319 +0200
+++ /var/tmp/diff_new_pack.cp4JHW/_new  2024-07-25 11:56:03.738755491 +0200
@@ -21,7 +21,7 @@
 %define libopenmpt_modplug_version 0.8.9.0
 
 Name:           libopenmpt
-Version:        0.7.8
+Version:        0.7.9
 Release:        0
 Summary:        C++ and C library to decode tracker music files
 License:        BSD-3-Clause

++++++ libopenmpt-0.7.8+release.autotools.tar.gz -> 
libopenmpt-0.7.9+release.autotools.tar.gz ++++++
++++ 2186 lines of diff (skipped)
++++    retrying with extended exclude list
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude 
config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 
--exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh 
old/libopenmpt-0.7.8+release.autotools/Makefile.am 
new/libopenmpt-0.7.9+release.autotools/Makefile.am
--- old/libopenmpt-0.7.8+release.autotools/Makefile.am  2024-04-10 
14:24:33.000000000 +0200
+++ new/libopenmpt-0.7.9+release.autotools/Makefile.am  2024-07-14 
18:10:07.000000000 +0200
@@ -313,6 +313,7 @@
 MPT_FILES_SRC_OPENMPT += src/openmpt/soundbase/SampleFormat.hpp
 MPT_FILES_COMMON = 
 MPT_FILES_COMMON += common/BuildSettings.h
+MPT_FILES_COMMON += common/BuildSettingsCompiler.h
 MPT_FILES_COMMON += common/ComponentManager.cpp
 MPT_FILES_COMMON += common/ComponentManager.h
 MPT_FILES_COMMON += common/Dither.h
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude 
config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 
--exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh 
old/libopenmpt-0.7.8+release.autotools/common/BuildSettings.h 
new/libopenmpt-0.7.9+release.autotools/common/BuildSettings.h
--- old/libopenmpt-0.7.8+release.autotools/common/BuildSettings.h       
2024-05-12 13:07:25.000000000 +0200
+++ new/libopenmpt-0.7.9+release.autotools/common/BuildSettings.h       
2024-07-14 18:10:07.000000000 +0200
@@ -12,6 +12,10 @@
 
 
 
+#include "BuildSettingsCompiler.h"
+
+
+
 #include "mpt/base/detect_compiler.hpp"
 #include "mpt/base/detect_os.hpp"
 #include "mpt/base/detect_quirks.hpp"
@@ -362,57 +366,6 @@
 
 
 
-// compiler configuration
-
-#if MPT_COMPILER_MSVC
-
-#pragma warning(default:4800) // Implicit conversion from 'int' to bool. 
Possible information loss
-
-#pragma warning(disable:4355) // 'this' : used in base member initializer list
-
-// happens for immutable classes (i.e. classes containing const members)
-#pragma warning(disable:4512) // assignment operator could not be generated
-
-#pragma warning(error:4309) // Treat "truncation of constant value"-warning as 
error.
-#pragma warning(error:4463) // Treat overflow; assigning value to bit-field 
that can only hold values from low_value to high_value"-warning as error.
-
-#ifdef MPT_BUILD_ANALYZED
-// Disable Visual Studio static analyzer warnings that generate too many false 
positives in VS2010.
-//#pragma warning(disable:6246)
-//#pragma warning(disable:6262)
-#pragma warning(disable:6297) // 32-bit value is shifted, then cast to 64-bit 
value.  Results might not be an expected value. 
-#pragma warning(disable:6326) // Potential comparison of a constant with 
another constant
-//#pragma warning(disable:6385)
-//#pragma warning(disable:6386)
-#endif // MPT_BUILD_ANALYZED
-
-#endif // MPT_COMPILER_MSVC
-
-#if MPT_COMPILER_GCC
-
-#ifdef MPT_COMPILER_QUIRK_GCC_NO_O2
-// See <https://gcc.gnu.org/bugzilla/show_bug.cgi?id=115049>.
-#if defined(__OPTIMIZE__)
-#pragma GCC optimize("O1")
-#endif
-#endif // MPT_COMPILER_QUIRK_GCC_NO_O2
-
-#endif // MPT_COMPILER_GCC
-
-#if MPT_COMPILER_CLANG
-
-#if defined(MPT_BUILD_MSVC)
-#pragma clang diagnostic warning "-Wimplicit-fallthrough"
-#endif // MPT_BUILD_MSVC
-
-#if defined(MODPLUG_TRACKER)
-#pragma clang diagnostic ignored "-Wunused-local-typedef"
-#endif // MODPLUG_TRACKER
-
-#endif // MPT_COMPILER_CLANG
-
-
-
 // third-party library configuration
 
 #ifdef MPT_WITH_STBVORBIS
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude 
config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 
--exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh 
old/libopenmpt-0.7.8+release.autotools/common/BuildSettingsCompiler.h 
new/libopenmpt-0.7.9+release.autotools/common/BuildSettingsCompiler.h
--- old/libopenmpt-0.7.8+release.autotools/common/BuildSettingsCompiler.h       
1970-01-01 01:00:00.000000000 +0100
+++ new/libopenmpt-0.7.9+release.autotools/common/BuildSettingsCompiler.h       
2024-07-18 20:26:32.000000000 +0200
@@ -0,0 +1,73 @@
+/*
+ * BuildSettingsCompiler.h
+ * -----------------------
+ * Purpose: Global compiler setting overrides
+ * Notes  : (currently none)
+ * Authors: OpenMPT Devs
+ * The OpenMPT source code is released under the BSD license. Read LICENSE for 
more details.
+ */
+
+
+#pragma once
+
+
+
+#include "mpt/base/detect_compiler.hpp"
+
+
+
+// compiler configuration
+
+#if MPT_COMPILER_MSVC
+
+#pragma warning(default:4800) // Implicit conversion from 'int' to bool. 
Possible information loss
+
+#pragma warning(disable:4355) // 'this' : used in base member initializer list
+
+// happens for immutable classes (i.e. classes containing const members)
+#pragma warning(disable:4512) // assignment operator could not be generated
+
+#pragma warning(error:4309) // Treat "truncation of constant value"-warning as 
error.
+#pragma warning(error:4463) // Treat overflow; assigning value to bit-field 
that can only hold values from low_value to high_value"-warning as error.
+
+#ifdef MPT_BUILD_ANALYZED
+// Disable Visual Studio static analyzer warnings that generate too many false 
positives in VS2010.
+//#pragma warning(disable:6246)
+//#pragma warning(disable:6262)
+#pragma warning(disable:6297) // 32-bit value is shifted, then cast to 64-bit 
value.  Results might not be an expected value. 
+#pragma warning(disable:6326) // Potential comparison of a constant with 
another constant
+//#pragma warning(disable:6385)
+//#pragma warning(disable:6386)
+#endif // MPT_BUILD_ANALYZED
+
+#endif // MPT_COMPILER_MSVC
+
+#if MPT_COMPILER_GCC
+
+#ifdef MPT_COMPILER_SETTING_QUIRK_GCC_BROKEN_IPA
+// See <https://gcc.gnu.org/bugzilla/show_bug.cgi?id=115049>.
+#if MPT_GCC_BEFORE(9, 0, 0)
+// Earlier GCC get confused about setting a global function attribute.
+// We need to check for 9.0 instead of 9.1 because of
+// <https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=1028580>.
+// It also gets confused when setting global optimization -O1,
+// so we have no way of fixing GCC 8 or earlier.
+//#pragma GCC optimize("O1")
+#else
+#pragma GCC optimize("no-ipa-ra")
+#endif
+#endif // MPT_COMPILER_SETTING_QUIRK_GCC_BROKEN_IPA
+
+#endif // MPT_COMPILER_GCC
+
+#if MPT_COMPILER_CLANG
+
+#if defined(MPT_BUILD_MSVC)
+#pragma clang diagnostic warning "-Wimplicit-fallthrough"
+#endif // MPT_BUILD_MSVC
+
+#if defined(MODPLUG_TRACKER)
+#pragma clang diagnostic ignored "-Wunused-local-typedef"
+#endif // MODPLUG_TRACKER
+
+#endif // MPT_COMPILER_CLANG
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude 
config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 
--exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh 
old/libopenmpt-0.7.8+release.autotools/common/versionNumber.h 
new/libopenmpt-0.7.9+release.autotools/common/versionNumber.h
--- old/libopenmpt-0.7.8+release.autotools/common/versionNumber.h       
2024-06-09 11:52:49.000000000 +0200
+++ new/libopenmpt-0.7.9+release.autotools/common/versionNumber.h       
2024-07-21 13:55:40.000000000 +0200
@@ -17,7 +17,7 @@
 // Version definitions. The only thing that needs to be changed when changing 
version number.
 #define VER_MAJORMAJOR  1
 #define VER_MAJOR      31
-#define VER_MINOR      08
+#define VER_MINOR      09
 #define VER_MINORMINOR 00
 
 OPENMPT_NAMESPACE_END
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude 
config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 
--exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh 
old/libopenmpt-0.7.8+release.autotools/configure.ac 
new/libopenmpt-0.7.9+release.autotools/configure.ac
--- old/libopenmpt-0.7.8+release.autotools/configure.ac 2024-06-09 
12:58:34.000000000 +0200
+++ new/libopenmpt-0.7.9+release.autotools/configure.ac 2024-07-21 
14:35:14.000000000 +0200
@@ -1,4 +1,4 @@
-AC_INIT([libopenmpt], [0.7.8+release.autotools], [https://bugs.openmpt.org/], 
[libopenmpt], [https://lib.openmpt.org/])
+AC_INIT([libopenmpt], [0.7.9+release.autotools], [https://bugs.openmpt.org/], 
[libopenmpt], [https://lib.openmpt.org/])
 AC_PREREQ([2.69])
 # we do want 2.70, but distributions are not ready yet
 #AC_PREREQ([2.70])
@@ -54,6 +54,18 @@
  []
 )
 
+# work-around <https://gcc.gnu.org/bugzilla/show_bug.cgi?id=115049>
+# This is somewhat pessimistic, but necessary for GCC 8 or earlier,
+# which we still support and where we cannot use #pragma GCC optimize.
+AC_LANG_PUSH([C])
+AX_CHECK_COMPILE_FLAG([-fno-ipa-ra], [CFLAGS="$CFLAGS -fno-ipa-ra"])
+AX_CFLAGS_WARN_ALL
+AC_LANG_POP([C])
+AC_LANG_PUSH([C++])
+AX_CHECK_COMPILE_FLAG([-fno-ipa-ra], [CXXFLAGS="$CXXFLAGS -fno-ipa-ra"])
+AX_CXXFLAGS_WARN_ALL
+AC_LANG_POP([C++])
+
 
 LIBOPENMPT_LTVER_CURRENT=4
 LIBOPENMPT_LTVER_REVISION=4
@@ -62,9 +74,9 @@
 AC_SUBST([LIBOPENMPT_LTVER_REVISION])
 AC_SUBST([LIBOPENMPT_LTVER_AGE])
 
-AC_DEFINE([MPT_SVNURL], 
["https://source.openmpt.org/svn/openmpt/tags/libopenmpt-0.7.8";], [svn version])
-AC_DEFINE([MPT_SVNVERSION], ["20990"], [svn version])
-AC_DEFINE([MPT_SVNDATE], ["2024-06-09T10:46:26.177639Z"], [svn date])
+AC_DEFINE([MPT_SVNURL], 
["https://source.openmpt.org/svn/openmpt/tags/libopenmpt-0.7.9";], [svn version])
+AC_DEFINE([MPT_SVNVERSION], ["21223"], [svn version])
+AC_DEFINE([MPT_SVNDATE], ["2024-07-21T12:01:13.335584Z"], [svn date])
 AC_DEFINE([MPT_PACKAGE], [true], [is package])
 
 
@@ -72,8 +84,15 @@
 
 
 AC_CANONICAL_HOST
-case $host_os in
- mingw32*)
+
+# work-around NetBSD toolchain not understanding transitive shared object 
dependencies at all
+AS_CASE([$host_os],
+ [netbsd*], [LIBS="$LIBS -lstdc++"],
+ []
+)
+
+AS_CASE([$host_os],
+ [mingw32*],[
   LIBOPENMPT_WIN32_LIBS=
   LIBOPENMPT_LIBS_PRIVATE_WIN32=
   LIBOPENMPTTEST_WIN32_LIBS="-lole32 -lrpcrt4"
@@ -83,8 +102,8 @@
   WIN32_CFLAGS="-municode -mthreads"
   WIN32_CONSOLE_CXXFLAGS=-mconsole
   WIN32_CONSOLE_CFLAGS=-mconsole
-  ;;
- *)
+ ],
+ [
   LIBOPENMPT_WIN32_LIBS=
   LIBOPENMPT_LIBS_PRIVATE_WIN32=
   LIBOPENMPTTEST_WIN32_LIBS=
@@ -94,8 +113,8 @@
   WIN32_CFLAGS=
   WIN32_CONSOLE_CXXFLAGS=
   WIN32_CONSOLE_CFLAGS=
-  ;;
-esac
+ ]
+)
 AC_SUBST([LIBOPENMPT_WIN32_LIBS])
 AC_SUBST([LIBOPENMPTTEST_WIN32_LIBS])
 AC_SUBST([OPENMPT123_WIN32_LIBS])
@@ -198,8 +217,8 @@
 # Optional openmpt123 dependency
 AC_ARG_WITH([pulseaudio], AS_HELP_STRING([--with-pulseaudio], [Enable use of 
libpulse and libpulse-simple (enabled by default on Linux).]))
 AS_IF([test "x$enable_openmpt123" != "xno"],[
-case $host_os in
- linux*)
+AS_CASE([$host_os],
+ [linux*],[
 AS_IF([test "x$with_pulseaudio" != "xno"],
  [
   PKG_CHECK_MODULES([PULSEAUDIO], [libpulse libpulse-simple],
@@ -236,8 +255,9 @@
   have_pulseaudio=0
  ]
 )
- ;;
-esac
+ ],
+ []
+)
 ],[have_pulseaudio=0])
 
 # Optional openmpt123 and examples dependency
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude 
config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 
--exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh 
old/libopenmpt-0.7.8+release.autotools/doc/libopenmpt/changelog.md 
new/libopenmpt-0.7.9+release.autotools/doc/libopenmpt/changelog.md
--- old/libopenmpt-0.7.8+release.autotools/doc/libopenmpt/changelog.md  
2024-06-09 12:46:24.000000000 +0200
+++ new/libopenmpt-0.7.9+release.autotools/doc/libopenmpt/changelog.md  
2024-07-21 14:01:11.000000000 +0200
@@ -5,6 +5,61 @@
 For fully detailed change log, please see the source repository directly. This
 is just a high-level summary.
 
+### libopenmpt 0.7.9 (2024-07-21)
+
+ *  [**Sec**] Potential division by 0 when seeking in the module with
+    `seek.sync_samples` enabled (r21167).
+
+ *  [**Change**] The work-around for
+    <https://gcc.gnu.org/bugzilla/show_bug.cgi?id=115049> has been changed from
+    forcing `-O1` on GCC 14 to setting `-fno-ipa-ra` on all GCC versions on
+    non-ELF platforms. We are still not 100% sure if this work-around is
+    sufficient in all circumstances. If you are using a non-ELF platform, it is
+    strongly recommended to update GCC to versions 12.5.0, 13.4.0, 14.2.0, or
+    15.1.0 as soon as they are released, or to apply the patch from the linked
+    GCC issues.
+
+ *  MOD: Allow sample swapping to work when swapping from a non-looping, 
stopped
+    sample back to a looping sample (fixes MOD.energy).
+ *  DBM: Import second sustain point in case the first sustain point is not 
set,
+    or if it has a lower index than the first.
+ *  DBM: When several instruments referenced the same sample with different
+    properties (volume, loop points, etc.), only one set of properties was
+    imported (fixes DBM.Supernova).
+ *  DBM: Prioritize effects more correctly when the same effect is encountered
+    in both effect columns of a cell (fixes DBM.143_Gnoj).
+ *  DBM: Don't import offset effects when there's a tone portmento next to 
them.
+ *  DBM: A few IT-specific playback quirks are disabled for more accurate
+    playback (e.g. in "Are You Flying With Me?" by Jazzcat).
+ *  DIGI: Sample play direction was reset if adjacent channel contained a
+    Note Cut note.
+ *  AMF: When running out of sample slots, file reading became be misaligned
+    because the sample name was not skipped.
+ *  MED: Command 0F was not imported.
+ *  MED: Upper frequency limits should be more accurate now.
+ *  MED: Channel panning is now only applied in MMD2 files if the free pan flag
+    is set.
+ *  MED: Volume command resolution was incorrect for pre-MMD3 files.
+ *  XM: oggmod does not support stereo samples but keeps the stereo flag when
+    encoding such samples. Such samples are now imported as mono samples 
instead
+    of not importing them at all.
+ *  XM: For files saved with registered MadTracker 2 versions, do not put
+    binary garbage (the user ID) in the tracker metadata field. It is replaced
+    with "registered" instead.
+ *  For some truncated files, the used tracker was not identified correctly. 
+ *  S3M: Identify files saved with early Impulse Tracker versions, Sound Club 
2,
+    Liquid Tracker, NESMusa, UNMO3, deMODifier, Kosmic To-S3M, and better tell
+    old ModPlug Tracker versions apart.
+ *  S3M: When skipping sample loading, some tracker identifications were not
+    working as intended.
+ *  IT: Identify files saved with itwriter.
+ *  DTM: Identify files saved with Digital Tracker 2.3.
+
+ *  xmp-openmpt: If there is only one subsong, set the song title to the
+    "global" song title instead of the name of that subsong.
+ *  xmp-openmpt: Sample and instrument names were not sanitized, sometimes
+    showing on multiple rows.
+
 ### libopenmpt 0.7.8 (2024-06-09)
 
  *  [**Sec**] Potential heap out-of-bounds read with malformed Dynamic Studio
@@ -43,7 +98,7 @@
 
  *  IT: Disable a few more compatibility flags for older SchismTracker builds.
  *  IT: Halve the output volume of files saved with ChibiTracker, as its mixer
- *  is about half as loud as ours.
+    is about half as loud as ours.
  *  S3M: In mono mode, the ratio between sample and OPL volume was incorrect.
  *  S3M: Detect files saved with PlayerPRO.
  *  XM: Detect files saved with PlayerPRO. Improved detection of files saved
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude 
config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 
--exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh 
old/libopenmpt-0.7.8+release.autotools/libopenmpt/libopenmpt_version.h 
new/libopenmpt-0.7.9+release.autotools/libopenmpt/libopenmpt_version.h
--- old/libopenmpt-0.7.8+release.autotools/libopenmpt/libopenmpt_version.h      
2024-06-09 12:46:24.000000000 +0200
+++ new/libopenmpt-0.7.9+release.autotools/libopenmpt/libopenmpt_version.h      
2024-07-21 14:01:11.000000000 +0200
@@ -21,7 +21,7 @@
 /*! \brief libopenmpt minor version number */
 #define OPENMPT_API_VERSION_MINOR 7
 /*! \brief libopenmpt patch version number */
-#define OPENMPT_API_VERSION_PATCH 8
+#define OPENMPT_API_VERSION_PATCH 9
 /*! \brief libopenmpt pre-release tag */
 #define OPENMPT_API_VERSION_PREREL ""
 /*! \brief libopenmpt pre-release flag */
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude 
config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 
--exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh 
old/libopenmpt-0.7.8+release.autotools/libopenmpt/libopenmpt_version.mk 
new/libopenmpt-0.7.9+release.autotools/libopenmpt/libopenmpt_version.mk
--- old/libopenmpt-0.7.8+release.autotools/libopenmpt/libopenmpt_version.mk     
2024-06-09 12:46:24.000000000 +0200
+++ new/libopenmpt-0.7.9+release.autotools/libopenmpt/libopenmpt_version.mk     
2024-07-21 14:01:11.000000000 +0200
@@ -1,8 +1,8 @@
 LIBOPENMPT_VERSION_MAJOR=0
 LIBOPENMPT_VERSION_MINOR=7
-LIBOPENMPT_VERSION_PATCH=8
+LIBOPENMPT_VERSION_PATCH=9
 LIBOPENMPT_VERSION_PREREL=
 
 LIBOPENMPT_LTVER_CURRENT=4
-LIBOPENMPT_LTVER_REVISION=8
+LIBOPENMPT_LTVER_REVISION=9
 LIBOPENMPT_LTVER_AGE=4
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude 
config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 
--exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh 
old/libopenmpt-0.7.8+release.autotools/man/openmpt123.1 
new/libopenmpt-0.7.9+release.autotools/man/openmpt123.1
--- old/libopenmpt-0.7.8+release.autotools/man/openmpt123.1     2024-06-09 
12:58:33.000000000 +0200
+++ new/libopenmpt-0.7.9+release.autotools/man/openmpt123.1     2024-07-21 
14:35:13.000000000 +0200
@@ -1,12 +1,12 @@
 .\" DO NOT MODIFY THIS FILE!  It was generated by help2man 1.49.3.
-.TH OPENMPT123 "1" "June 2024" "openmpt123 v0.7.8" "User Commands"
+.TH OPENMPT123 "1" "July 2024" "openmpt123 v0.7.9" "User Commands"
 .SH NAME
 openmpt123 - command line module music player based on libopenmpt
 .SH SYNOPSIS
 .B openmpt123
 [\fI\,options\/\fR] [\fI\,--\/\fR] \fI\,file1 \/\fR[\fI\,file2\/\fR] ...
 .SH DESCRIPTION
-openmpt123 v0.7.8, libopenmpt 0.7.8+r20990 (OpenMPT 1.31.08.00 
https://source.openmpt.org/svn/openmpt/tags/libopenmpt\-0.7.8@20990 
(2024\-06\-09T10:46:26.177639Z) clean)
+openmpt123 v0.7.9, libopenmpt 0.7.9+r21223 (OpenMPT 1.31.09.00 
https://source.openmpt.org/svn/openmpt/tags/libopenmpt\-0.7.9@21223 
(2024\-07\-21T12:01:13.335584Z) clean)
 Copyright \(co 2013\-2024 OpenMPT Project Developers and Contributors 
<https://lib.openmpt.org/>
 .PP
 openmpt123 plays module music files.
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude 
config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 
--exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh 
old/libopenmpt-0.7.8+release.autotools/soundlib/Load_ams.cpp 
new/libopenmpt-0.7.9+release.autotools/soundlib/Load_ams.cpp
--- old/libopenmpt-0.7.8+release.autotools/soundlib/Load_ams.cpp        
2024-06-01 15:58:00.000000000 +0200
+++ new/libopenmpt-0.7.9+release.autotools/soundlib/Load_ams.cpp        
2024-06-14 23:11:55.000000000 +0200
@@ -826,12 +826,12 @@
                }
 
                uint8 numSamples = file.ReadUint8();
-               uint8 sampleAssignment[120];
-               MemsetZero(sampleAssignment);   // Only really needed for v2.0, 
where the lowest and highest octave aren't cleared.
+               std::array<uint8, 120> sampleAssignment;
+               sampleAssignment.fill(0);  // Only really needed for v2.0, 
where the lowest and highest octave aren't cleared.
 
                if(numSamples == 0
-                       || (fileHeader.versionLow > 0 && 
!file.ReadArray(sampleAssignment))     // v2.01+: 120 Notes
-                       || (fileHeader.versionLow == 0 && 
!file.ReadRaw(mpt::span(sampleAssignment + 12, 96)).size()))  // v2.0: 96 Notes
+                       || (fileHeader.versionLow > 0 && 
!file.ReadArray(sampleAssignment))  // v2.01+: 120 Notes
+                       || (fileHeader.versionLow == 0 && 
!file.ReadRaw(mpt::as_span(sampleAssignment).subspan(12, 96)).size()))  // 
v2.0: 96 Notes
                {
                        continue;
                }
@@ -878,18 +878,17 @@
                // Sample headers - we will have to read them even for shadow 
samples, and we will have to load them several times,
                // as it is possible that shadow samples use different sample 
settings like base frequency or panning.
                const SAMPLEINDEX firstSmp = GetNumSamples() + 1;
+               std::string sampleName;
                for(SAMPLEINDEX smp = 0; smp < numSamples; smp++)
                {
-                       if(firstSmp + smp >= MAX_SAMPLES)
-                       {
-                               file.Skip(sizeof(AMS2SampleHeader));
-                               break;
-                       }
-                       file.ReadSizedString<uint8le, 
mpt::String::spacePadded>(m_szNames[firstSmp + smp]);
-
+                       file.ReadSizedString<uint8le, 
mpt::String::spacePadded>(sampleName);
                        AMS2SampleHeader sampleHeader;
                        file.ReadStruct(sampleHeader);
+                       if(firstSmp + smp >= MAX_SAMPLES)
+                               continue;
+
                        sampleHeader.ConvertToMPT(Samples[firstSmp + smp]);
+                       m_szNames[firstSmp + smp] = sampleName;
 
                        uint16 settings = (instrHeader.shadowInstr & 
instrIndexMask)
                                | ((smp << sampleIndexShift) & sampleIndexMask)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude 
config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 
--exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh 
old/libopenmpt-0.7.8+release.autotools/soundlib/Load_dbm.cpp 
new/libopenmpt-0.7.9+release.autotools/soundlib/Load_dbm.cpp
--- old/libopenmpt-0.7.8+release.autotools/soundlib/Load_dbm.cpp        
2023-02-25 15:41:10.000000000 +0100
+++ new/libopenmpt-0.7.9+release.autotools/soundlib/Load_dbm.cpp        
2024-06-25 23:35:15.000000000 +0200
@@ -38,17 +38,17 @@
        // 32-Bit chunk identifiers
        enum ChunkIdentifiers
        {
-               idNAME  = MagicBE("NAME"),
-               idINFO  = MagicBE("INFO"),
-               idSONG  = MagicBE("SONG"),
-               idINST  = MagicBE("INST"),
-               idVENV  = MagicBE("VENV"),
-               idPENV  = MagicBE("PENV"),
-               idPATT  = MagicBE("PATT"),
-               idPNAM  = MagicBE("PNAM"),
-               idSMPL  = MagicBE("SMPL"),
-               idDSPE  = MagicBE("DSPE"),
-               idMPEG  = MagicBE("MPEG"),
+               idNAME = MagicBE("NAME"),
+               idINFO = MagicBE("INFO"),
+               idSONG = MagicBE("SONG"),
+               idINST = MagicBE("INST"),
+               idVENV = MagicBE("VENV"),
+               idPENV = MagicBE("PENV"),
+               idPATT = MagicBE("PATT"),
+               idPNAM = MagicBE("PNAM"),
+               idSMPL = MagicBE("SMPL"),
+               idDSPE = MagicBE("DSPE"),
+               idMPEG = MagicBE("MPEG"),
        };
 
        uint32be id;
@@ -85,18 +85,43 @@
 {
        enum DBMInstrFlags
        {
-               smpLoop                 = 0x01,
-               smpPingPongLoop = 0x02,
+               smpLoop         = 0x01,
+               smpPingPongLoop = 0x02,
        };
 
        char     name[30];
-       uint16be sample;                // Sample reference
-       uint16be volume;                // 0...64
+       uint16be sample;  // Sample reference
+       uint16be volume;  // 0...64
        uint32be sampleRate;
        uint32be loopStart;
        uint32be loopLength;
-       int16be  panning;               // -128...128
-       uint16be flags;                 // See DBMInstrFlags
+       int16be  panning;  // -128...128
+       uint16be flags;    // See DBMInstrFlags
+
+       void ConvertToMPT(ModInstrument &mptIns) const
+       {
+               mptIns.name = 
mpt::String::ReadBuf(mpt::String::maybeNullTerminated, name);
+               mptIns.nFadeOut = 0;
+               mptIns.nPan = static_cast<uint16>(panning + 128);
+               LimitMax(mptIns.nPan, uint32(256));
+               mptIns.dwFlags.set(INS_SETPANNING);
+       }
+
+       void ConvertToMPT(ModSample &mptSmp) const
+       {
+               mptSmp.Initialize();
+               mptSmp.nVolume = std::min(static_cast<uint16>(volume), 
uint16(64)) * 4u;
+               mptSmp.nC5Speed = Util::muldivr(sampleRate, 8303, 8363);
+               
+               if(loopLength && (flags & (smpLoop | smpPingPongLoop)))
+               {
+                       mptSmp.nLoopStart = loopStart;
+                       mptSmp.nLoopEnd = mptSmp.nLoopStart + loopLength;
+                       mptSmp.uFlags.set(CHN_LOOP);
+                       if(flags & smpPingPongLoop)
+                               mptSmp.uFlags.set(CHN_PINGPONGLOOP);
+               }
+       }
 };
 
 MPT_BINARY_STRUCT(DBMInstrument, 50)
@@ -107,19 +132,55 @@
 {
        enum DBMEnvelopeFlags
        {
-               envEnabled      = 0x01,
-               envSustain      = 0x02,
-               envLoop         = 0x04,
+               envEnabled  = 0x01,
+               envSustain1 = 0x02,
+               envLoop     = 0x04,
+               envSustain2 = 0x08,
        };
 
        uint16be instrument;
-       uint8be  flags;                 // See DBMEnvelopeFlags
-       uint8be  numSegments;   // Number of envelope points - 1
+       uint8be  flags;        // See DBMEnvelopeFlags
+       uint8be  numSegments;  // Number of envelope points - 1
        uint8be  sustain1;
        uint8be  loopBegin;
        uint8be  loopEnd;
-       uint8be  sustain2;              // Second sustain point
+       uint8be  sustain2;  // Second sustain point
        uint16be data[2 * 32];
+
+       void ConvertToMPT(InstrumentEnvelope &mptEnv, bool scaleEnv) const
+       {
+               if(numSegments)
+               {
+                       if(flags & envEnabled) mptEnv.dwFlags.set(ENV_ENABLED);
+                       if(flags & (envSustain1 | envSustain2)) 
mptEnv.dwFlags.set(ENV_SUSTAIN);
+                       if(flags & envLoop) mptEnv.dwFlags.set(ENV_LOOP);
+               }
+
+               uint8 numPoints = std::min(numSegments.get(), uint8(31)) + 1;
+               mptEnv.resize(numPoints);
+
+               mptEnv.nLoopStart = loopBegin;
+               mptEnv.nLoopEnd = loopEnd;
+               if((flags & (envSustain1 | envSustain2)) == envSustain1)
+                       mptEnv.nSustainStart = mptEnv.nSustainEnd = sustain1;
+               else if((flags & (envSustain1 | envSustain2)) == envSustain2)
+                       mptEnv.nSustainStart = mptEnv.nSustainEnd = sustain2;
+               else
+                       mptEnv.nSustainStart = mptEnv.nSustainEnd = 
std::min(sustain1, sustain2);
+
+               for(uint8 i = 0; i < numPoints; i++)
+               {
+                       mptEnv[i].tick = data[i * 2];
+                       uint16 val = data[i * 2 + 1];
+                       if(scaleEnv)
+                       {
+                               // Panning envelopes are -128...128 in 
DigiBooster Pro 3.x
+                               val = static_cast<uint16>((val + 128) / 4);
+                       }
+                       LimitMax(val, uint16(64));
+                       mptEnv[i].value = static_cast<uint8>(val);
+               }
+       }
 };
 
 MPT_BINARY_STRUCT(DBMEnvelope, 136)
@@ -137,11 +198,11 @@
        CMD_NONE, CMD_PANNINGSLIDE, CMD_NONE, CMD_NONE,
        CMD_NONE, CMD_NONE, CMD_NONE,
 #ifndef NO_PLUGINS
-       CMD_DBMECHO,    // Toggle DSP
-       CMD_MIDI,               // Wxx Echo Delay
-       CMD_MIDI,               // Xxx Echo Feedback
-       CMD_MIDI,               // Yxx Echo Mix
-       CMD_MIDI,               // Zxx Echo Cross
+       CMD_DBMECHO,  // Toggle DSP
+       CMD_MIDI,     // Wxx Echo Delay
+       CMD_MIDI,     // Xxx Echo Feedback
+       CMD_MIDI,     // Yxx Echo Mix
+       CMD_MIDI,     // Zxx Echo Cross
 #endif // NO_PLUGINS
 };
 
@@ -197,15 +258,15 @@
        case CMD_MODCMDEX:
                switch(param & 0xF0)
                {
-               case 0x30:      // Play backwards
+               case 0x30:  // Play backwards
                        command = CMD_S3MCMDEX;
                        param = 0x9F;
                        break;
-               case 0x40:      // Turn off sound in channel (volume / 
portamento commands after this can't pick up the note anymore)
+               case 0x40:  // Turn off sound in channel (volume / portamento 
commands after this can't pick up the note anymore)
                        command = CMD_S3MCMDEX;
                        param = 0xC0;
                        break;
-               case 0x50:      // Turn on/off channel
+               case 0x50:  // Turn on/off channel
                        // TODO: Apparently this should also kill the playing 
note.
                        if((param & 0x0F) <= 0x01)
                        {
@@ -213,7 +274,7 @@
                                param = (param == 0x50) ? 0x00 : 0x40;
                        }
                        break;
-               case 0x70:      // Coarse offset
+               case 0x70:  // Coarse offset
                        command = CMD_S3MCMDEX;
                        param = 0xA0 | (param & 0x0F);
                        break;
@@ -258,35 +319,7 @@
                uint16 dbmIns = dbmEnv.instrument;
                if(dbmIns > 0 && dbmIns <= sndFile.GetNumInstruments() && 
(sndFile.Instruments[dbmIns] != nullptr))
                {
-                       ModInstrument *mptIns = sndFile.Instruments[dbmIns];
-                       InstrumentEnvelope &mptEnv = 
mptIns->GetEnvelope(envType);
-
-                       if(dbmEnv.numSegments)
-                       {
-                               if(dbmEnv.flags & DBMEnvelope::envEnabled) 
mptEnv.dwFlags.set(ENV_ENABLED);
-                               if(dbmEnv.flags & DBMEnvelope::envSustain) 
mptEnv.dwFlags.set(ENV_SUSTAIN);
-                               if(dbmEnv.flags & DBMEnvelope::envLoop) 
mptEnv.dwFlags.set(ENV_LOOP);
-                       }
-
-                       uint8 numPoints = std::min(dbmEnv.numSegments.get(), 
uint8(31)) + 1;
-                       mptEnv.resize(numPoints);
-
-                       mptEnv.nLoopStart = dbmEnv.loopBegin;
-                       mptEnv.nLoopEnd = dbmEnv.loopEnd;
-                       mptEnv.nSustainStart = mptEnv.nSustainEnd = 
dbmEnv.sustain1;
-
-                       for(uint8 i = 0; i < numPoints; i++)
-                       {
-                               mptEnv[i].tick = dbmEnv.data[i * 2];
-                               uint16 val = dbmEnv.data[i * 2 + 1];
-                               if(scaleEnv)
-                               {
-                                       // Panning envelopes are -128...128 in 
DigiBooster Pro 3.x
-                                       val = (val + 128) / 4;
-                               }
-                               LimitMax(val, uint16(64));
-                               mptEnv[i].value = static_cast<uint8>(val);
-                       }
+                       
dbmEnv.ConvertToMPT(sndFile.Instruments[dbmIns]->GetEnvelope(envType), 
scaleEnv);
                }
        }
 }
@@ -356,6 +389,8 @@
        m_playBehaviour.set(kSlidesAtSpeed1);
        m_playBehaviour.reset(kITVibratoTremoloPanbrello);
        m_playBehaviour.reset(kITArpeggio);
+       m_playBehaviour.reset(kITInstrWithNoteOff);
+       m_playBehaviour.reset(kITInstrWithNoteOffOldEffects);
 
        m_modFormat.formatName = U_("DigiBooster Pro");
        m_modFormat.type = U_("dbm");
@@ -407,41 +442,41 @@
 #endif // MPT_DBM_USE_REAL_SUBSONGS
 
        // Read instruments
+       std::map<SAMPLEINDEX, SAMPLEINDEX> copySample;
        if(FileReader instChunk = chunks.GetChunk(DBMChunk::idINST))
        {
+               std::set<SAMPLEINDEX> sampleUsed;
                for(INSTRUMENTINDEX i = 1; i <= GetNumInstruments(); i++)
                {
                        DBMInstrument instrHeader;
                        instChunk.ReadStruct(instrHeader);
 
-                       ModInstrument *mptIns = AllocateInstrument(i, 
instrHeader.sample);
-                       if(mptIns == nullptr || instrHeader.sample >= 
MAX_SAMPLES)
+                       SAMPLEINDEX mappedSample = instrHeader.sample;
+                       if(sampleUsed.count(mappedSample) && 
CanAddMoreSamples())
                        {
-                               continue;
+                               ModSample mptSmp;
+                               instrHeader.ConvertToMPT(mptSmp);
+                               const ModSample &origSmp = 
Samples[mappedSample];
+                               if(mptSmp.nVolume != origSmp.nVolume
+                                       || mptSmp.uFlags != origSmp.uFlags
+                                       || mptSmp.nLoopStart != 
origSmp.nLoopStart
+                                       || mptSmp.nLoopEnd != origSmp.nLoopEnd
+                                       || mptSmp.nC5Speed != origSmp.nC5Speed)
+                               {
+                                       // Need to duplicate
+                                       mappedSample = ++m_nSamples;
+                                       copySample.emplace(mappedSample, 
instrHeader.sample);
+                               }
                        }
+                       ModInstrument *mptIns = AllocateInstrument(i, 
mappedSample);
+                       if(mptIns == nullptr || mappedSample >= MAX_SAMPLES)
+                               continue;
 
-                       mptIns->name = 
mpt::String::ReadBuf(mpt::String::maybeNullTerminated, instrHeader.name);
-                       m_szNames[instrHeader.sample] = 
mpt::String::ReadBuf(mpt::String::maybeNullTerminated, instrHeader.name);
-
-                       mptIns->nFadeOut = 0;
-                       mptIns->nPan = static_cast<uint16>(instrHeader.panning 
+ 128);
-                       LimitMax(mptIns->nPan, uint32(256));
-                       mptIns->dwFlags.set(INS_SETPANNING);
-
+                       instrHeader.ConvertToMPT(*mptIns);
                        // Sample Info
-                       ModSample &mptSmp = Samples[instrHeader.sample];
-                       mptSmp.Initialize();
-                       mptSmp.nVolume = 
std::min(static_cast<uint16>(instrHeader.volume), uint16(64)) * 4u;
-                       mptSmp.nC5Speed = Util::muldivr(instrHeader.sampleRate, 
8303, 8363);
-
-                       if(instrHeader.loopLength && (instrHeader.flags & 
(DBMInstrument::smpLoop | DBMInstrument::smpPingPongLoop)))
-                       {
-                               mptSmp.nLoopStart = instrHeader.loopStart;
-                               mptSmp.nLoopEnd = mptSmp.nLoopStart + 
instrHeader.loopLength;
-                               mptSmp.uFlags.set(CHN_LOOP);
-                               if(instrHeader.flags & 
DBMInstrument::smpPingPongLoop)
-                                       mptSmp.uFlags.set(CHN_PINGPONGLOOP);
-                       }
+                       instrHeader.ConvertToMPT(Samples[mappedSample]);
+                       m_szNames[mappedSample] = mptIns->name;
+                       sampleUsed.insert(mappedSample);
                }
 
                // Read envelopes
@@ -466,7 +501,7 @@
        if(patternChunk.IsValid() && (loadFlags & loadPatternData))
        {
                FileReader patternNameChunk = chunks.GetChunk(DBMChunk::idPNAM);
-               patternNameChunk.Skip(1);       // Encoding, should be UTF-8 or 
ASCII
+               patternNameChunk.Skip(1);  // Encoding (0 = unspecified 
ASCII-compatible 8-bit encoding, 106 = UTF-8)
 
                Patterns.ResizeArray(infoData.patterns);
                std::vector<std::pair<EffectCommand, ModCommand::PARAM>> 
lostGlobalCommands;
@@ -538,6 +573,14 @@
                                        {
                                                std::swap(cmd1, cmd2);
                                                std::swap(param1, param2);
+                                       } else if(cmd1 == CMD_TONEPORTAMENTO && 
cmd2 == CMD_OFFSET && param2 == 0)
+                                       {
+                                               // Offset + Portmaneto: Ignore 
portamento. If the offset command has a non-zero parameter, keep it for effect 
memory.
+                                               cmd2 = CMD_NONE;
+                                       } else if(cmd2 == CMD_TONEPORTAMENTO && 
cmd1 == CMD_OFFSET && param1 == 0)
+                                       {
+                                               // Ditto
+                                               cmd1 = CMD_NONE;
                                        }
 
                                        const auto lostCommand = 
m.FillInTwoCommands(cmd1, param1, cmd2, param2);
@@ -641,6 +684,13 @@
        {
                for(SAMPLEINDEX smp = 1; smp <= GetNumSamples(); smp++)
                {
+                       if(auto copyFrom = copySample.find(smp); copyFrom != 
copySample.end())
+                       {
+                               Samples[smp].nLength = 
Samples[copyFrom->second].nLength;
+                               
Samples[smp].CopyWaveform(Samples[copyFrom->second]);
+                               continue;
+                       }
+
                        uint32 sampleFlags = sampleChunk.ReadUint32BE();
                        uint32 sampleLength = sampleChunk.ReadUint32BE();
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude 
config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 
--exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh 
old/libopenmpt-0.7.8+release.autotools/soundlib/Load_dtm.cpp 
new/libopenmpt-0.7.9+release.autotools/soundlib/Load_dtm.cpp
--- old/libopenmpt-0.7.8+release.autotools/soundlib/Load_dtm.cpp        
2024-06-08 15:44:28.000000000 +0200
+++ new/libopenmpt-0.7.9+release.autotools/soundlib/Load_dtm.cpp        
2024-06-14 23:11:55.000000000 +0200
@@ -576,6 +576,9 @@
        if(patternFormat == DTM_206_PATTERN_FORMAT)
        {
                tracker = U_("Digital Home Studio");
+       } else if(patternFormat == DTM_PT_PATTERN_FORMAT)
+       {
+               tracker = U_("Digital Tracker 2.3");
        } else if(FileReader chunk = chunks.GetChunk(DTMChunk::idVERS))
        {
                uint32 version = chunk.ReadUint32BE();
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude 
config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 
--exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh 
old/libopenmpt-0.7.8+release.autotools/soundlib/Load_it.cpp 
new/libopenmpt-0.7.9+release.autotools/soundlib/Load_it.cpp
--- old/libopenmpt-0.7.8+release.autotools/soundlib/Load_it.cpp 2024-05-06 
21:58:26.000000000 +0200
+++ new/libopenmpt-0.7.9+release.autotools/soundlib/Load_it.cpp 2024-06-14 
23:11:55.000000000 +0200
@@ -1320,7 +1320,12 @@
                                madeWithTracker = MPT_UFORMAT("ITMCK 
{}.{}.{}")((fileHeader.cwtv >> 8) & 0x0F, (fileHeader.cwtv >> 4) & 0x0F, 
fileHeader.cwtv & 0x0F);
                        break;
                case 0xD:
-                       madeWithTracker = U_("spc2it");
+                       if(fileHeader.cwtv == 0xDAEB)
+                               madeWithTracker = U_("spc2it");
+                       else if(fileHeader.cwtv == 0xD1CE)
+                               madeWithTracker = U_("itwriter");
+                       else
+                               madeWithTracker = U_("Unknown");
                        break;
                }
        }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude 
config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 
--exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh 
old/libopenmpt-0.7.8+release.autotools/soundlib/Load_med.cpp 
new/libopenmpt-0.7.9+release.autotools/soundlib/Load_med.cpp
--- old/libopenmpt-0.7.8+release.autotools/soundlib/Load_med.cpp        
2024-06-06 22:31:37.000000000 +0200
+++ new/libopenmpt-0.7.9+release.autotools/soundlib/Load_med.cpp        
2024-07-20 16:22:36.000000000 +0200
@@ -419,9 +419,11 @@
                if(param > 0 && param <= 20)
                        m.SetEffectCommand(CMD_SPEED, param);
                break;
-       case 0x0C:  // Set Volume
+       case 0x0C:  // Set Volume (note: parameters >= 0x80 (only in hex mode?) 
should set the default instrument volume, which we don't support)
                if(!ctx.volHex && param < 0x99)
                        m.SetEffectCommand(CMD_VOLUME, 
static_cast<ModCommand::PARAM>((param >> 4) * 10 + (param & 0x0F)));
+               else if(ctx.volHex && ctx.version < 3)
+                       m.SetEffectCommand(CMD_VOLUME, 
static_cast<ModCommand::PARAM>(std::min(param & 0x7F, 64)));
                else if(ctx.volHex)
                        m.SetEffectCommand(CMD_VOLUME, 
static_cast<ModCommand::PARAM>(((param & 0x7F) + 1) / 2));
                break;
@@ -458,7 +460,7 @@
                        if(m.param < 0x20)
                                m.param = 0x20;
 #endif  // MODPLUG_TRACKER
-               } else switch(command)
+               } else switch(param)
                {
                        case 0xF1:  // Play note twice
                                m.SetEffectCommand(CMD_MODCMDEX, 0x93);
@@ -603,7 +605,7 @@
                                cmd = command;
                                param1 = param;
                        }
-                       // Octave wrapping for 4-channel modules (TODO: this 
should not be set because of synth instruments)
+                       // Octave wrapping for 4-channel modules
                        if(ctx.hardwareMixSamples && note >= NOTE_MIDDLEC + 2 * 
12)
                                needInstruments = true;
 
@@ -794,6 +796,7 @@
        // - starkelsesirap.mmd0 (synth instruments) on the other hand don't 
need it
        // In MMD2 / MMD3, the mix flag is used instead.
        const bool hardwareMixSamples = (version < 2) || (version >= 2 && 
!(songHeader.flags2 & MMDSong::FLAG2_MIX));
+       m_nMinPeriod = hardwareMixSamples ? (113 * 4) : (55 * 4);
 
        bool needInstruments = false;
        bool anySynthInstrs = false;
@@ -1153,7 +1156,7 @@
                                        ChnSettings[chn].nVolume = 
std::min<uint8>(file.ReadUint8(), 64);
                                }
                        }
-                       if(header.trackPanOffset && 
file.Seek(header.trackPanOffset))
+                       if((freePan || version > 2) && header.trackPanOffset && 
file.Seek(header.trackPanOffset))
                        {
                                for(CHANNELINDEX chn = 0; chn < m_nChannels; 
chn++)
                                {
@@ -1183,11 +1186,11 @@
                                mixPlug.Info.szLibraryName = "Echo";
 
                                std::array<float32le, 6> params{};
-                               params[1] = 1.0f;                               
    // WetDryMix
-                               params[2] = feedback;                           
    // Feedback
-                               params[3] = delay;                              
    // LeftDelay
-                               params[4] = delay;                              
    // RightDelay
-                               params[5] = header.mixEchoType == 2 ? 1.0f : 
0.0f;  // PanDelay
+                               params[1] = 1.0f;                       // 
WetDryMix
+                               params[2] = feedback;                   // 
Feedback
+                               params[3] = delay;                      // 
LeftDelay
+                               params[4] = delay;                      // 
RightDelay
+                               params[5] = header.mixEchoType - 1.0f;  // 
PanDelay
                                mixPlug.pluginData.resize(sizeof(params));
                                memcpy(mixPlug.pluginData.data(), 
params.data(), sizeof(params));
                        }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude 
config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 
--exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh 
old/libopenmpt-0.7.8+release.autotools/soundlib/Load_mid.cpp 
new/libopenmpt-0.7.9+release.autotools/soundlib/Load_mid.cpp
--- old/libopenmpt-0.7.8+release.autotools/soundlib/Load_mid.cpp        
2023-04-29 21:43:40.000000000 +0200
+++ new/libopenmpt-0.7.9+release.autotools/soundlib/Load_mid.cpp        
2024-06-22 20:45:37.000000000 +0200
@@ -270,9 +270,12 @@
 };
 
 
+static constexpr uint8 NUM_MIDI_CHANNELS = 32;
+
+
 
////////////////////////////////////////////////////////////////////////////////
 // Maps a midi instrument - returns the instrument number in the file
-uint32 CSoundFile::MapMidiInstrument(uint8 program, uint16 bank, uint8 
midiChannel, uint8 note, bool isXG, std::bitset<16> drumChns)
+uint32 CSoundFile::MapMidiInstrument(uint8 program, uint16 bank, uint8 
midiChannel, uint8 note, bool isXG, std::bitset<NUM_MIDI_CHANNELS> drumChns)
 {
        ModInstrument *pIns;
        program &= 0x7F;
@@ -361,6 +364,7 @@
        FileReader track;
        tick_t nextEvent = 0;
        uint8 command = 0;
+       uint8 midiBaseChannel = 0;
        bool finished = false;
 };
 
@@ -506,7 +510,7 @@
 }
 
 
-static void MIDINoteOff(MidiChannelState &midiChn, 
std::vector<ModChannelState> &modChnStatus, uint8 note, uint8 delay, 
mpt::span<ModCommand> patRow, std::bitset<16> drumChns)
+static void MIDINoteOff(MidiChannelState &midiChn, 
std::vector<ModChannelState> &modChnStatus, uint8 note, uint8 delay, 
mpt::span<ModCommand> patRow, std::bitset<NUM_MIDI_CHANNELS> drumChns)
 {
        CHANNELINDEX chn = midiChn.noteOn[note];
        if(chn == CHANNELINDEX_INVALID)
@@ -666,13 +670,14 @@
                ppqn = 96;
        Order().clear();
 
-       MidiChannelState midiChnStatus[16];
+       std::array<MidiChannelState, NUM_MIDI_CHANNELS> midiChnStatus;
        const CHANNELINDEX tempoChannel = m_nChannels - 2, globalVolChannel = 
m_nChannels - 1;
        const uint16 numTracks = fileHeader.numTracks;
        std::vector<TrackState> tracks(numTracks);
        std::vector<ModChannelState> modChnStatus(m_nChannels);
-       std::bitset<16> drumChns;
+       std::bitset<NUM_MIDI_CHANNELS> drumChns;
        drumChns.set(MIDI_DRUMCHANNEL - 1);
+       drumChns.set(MIDI_DRUMCHANNEL + 15);
 
        tick_t timeShift = 0;
        for(auto &track : tracks)
@@ -820,6 +825,9 @@
                        case 8: // Patch name
                        case 9: // Port name
                                break;
+                       case 0x21: // MIDI port
+                               tracks[t].midiBaseChannel = chunk.ReadUint8() * 
16u;
+                               break;
                        case 0x2F: // End Of Track
                                tracks[t].finished = true;
                                break;
@@ -840,6 +848,14 @@
                                        tempo = newTempo;
                                }
                                break;
+                       case 0x7F: // Sequencer specific
+                               {
+                                       // Yamaha MIDI port selection
+                                       uint32 data = chunk.ReadUint32BE();
+                                       if(chunk.LengthIs(4) && (data & 
0xFFFFFF00) == 0x43000100)
+                                               tracks[t].midiBaseChannel = 
static_cast<uint8>((data & 0xFF) * 16u);
+                               }
+                               break;
 
                        default:
                                break;
@@ -857,7 +873,7 @@
                                        data1 = track.ReadUint8();
                                }
                        }
-                       uint8 midiCh = command & 0x0F;
+                       const uint8 midiCh = ((command & 0x0F) + 
tracks[t].midiBaseChannel) % NUM_MIDI_CHANNELS;
 
                        switch(command & 0xF0)
                        {
@@ -1079,7 +1095,7 @@
                                midiChnStatus[midiCh].SetPitchbend(data1 | 
(track.ReadUint8() << 7));
                                break;
                        case 0xF0: // General / Immediate
-                               switch(midiCh)
+                               switch(command & 0x0F)
                                {
                                case MIDIEvents::sysExStart: // SysEx
                                case MIDIEvents::sysExEnd: // SysEx (continued)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude 
config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 
--exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh 
old/libopenmpt-0.7.8+release.autotools/soundlib/Load_s3m.cpp 
new/libopenmpt-0.7.9+release.autotools/soundlib/Load_s3m.cpp
--- old/libopenmpt-0.7.8+release.autotools/soundlib/Load_s3m.cpp        
2024-05-11 17:30:11.000000000 +0200
+++ new/libopenmpt-0.7.9+release.autotools/soundlib/Load_s3m.cpp        
2024-07-13 19:37:24.000000000 +0200
@@ -35,7 +35,7 @@
        case '@': m.command = (m.param ? CMD_DUMMY : CMD_NONE); break;
        case 'A': m.command = CMD_SPEED; break;
        case 'B': m.command = CMD_POSITIONJUMP; break;
-       case 'C': m.command = CMD_PATTERNBREAK; if (!fromIT) m.param = (m.param 
>> 4) * 10 + (m.param & 0x0F); break;
+       case 'C': m.command = CMD_PATTERNBREAK; if(!fromIT) m.param = 
static_cast<uint8>((m.param >> 4) * 10 + (m.param & 0x0F)); break;
        case 'D': m.command = CMD_VOLUMESLIDE; break;
        case 'E': m.command = CMD_PORTAMENTODOWN; break;
        case 'F': m.command = CMD_PORTAMENTOUP; break;
@@ -86,8 +86,8 @@
        case CMD_POSITIONJUMP:    command = 'B'; break;
        case CMD_PATTERNBREAK:    command = 'C'; if(!toIT) param = ((param / 
10) << 4) + (param % 10); break;
        case CMD_VOLUMESLIDE:     command = 'D'; break;
-       case CMD_PORTAMENTODOWN:  command = 'E'; if (param >= 0xE0 && 
(GetType() & (MOD_TYPE_MOD | MOD_TYPE_XM))) param = 0xDF; break;
-       case CMD_PORTAMENTOUP:    command = 'F'; if (param >= 0xE0 && 
(GetType() & (MOD_TYPE_MOD | MOD_TYPE_XM))) param = 0xDF; break;
+       case CMD_PORTAMENTODOWN:  command = 'E'; if(param >= 0xE0 && (GetType() 
& (MOD_TYPE_MOD | MOD_TYPE_XM))) param = 0xDF; break;
+       case CMD_PORTAMENTOUP:    command = 'F'; if(param >= 0xE0 && (GetType() 
& (MOD_TYPE_MOD | MOD_TYPE_XM))) param = 0xDF; break;
        case CMD_TONEPORTAMENTO:  command = 'G'; break;
        case CMD_VIBRATO:         command = 'H'; break;
        case CMD_TREMOR:          command = 'I'; break;
@@ -110,11 +110,11 @@
                command = 'X';
                if(toIT && !(GetType() & (MOD_TYPE_IT | MOD_TYPE_MPT | 
MOD_TYPE_XM | MOD_TYPE_MOD)))
                {
-                       if (param == 0xA4) { command = 'S'; param = 0x91; }
-                       else if (param == 0x80) { param = 0xFF; }
-                       else if (param < 0x80) { param <<= 1; }
+                       if(param == 0xA4) { command = 'S'; param = 0x91; }
+                       else if(param == 0x80) { param = 0xFF; }
+                       else if(param < 0x80) { param <<= 1; }
                        else command = 0;
-               } else if (!toIT && (GetType() & (MOD_TYPE_IT | MOD_TYPE_MPT | 
MOD_TYPE_XM | MOD_TYPE_MOD)))
+               } else if(!toIT && (GetType() & (MOD_TYPE_IT | MOD_TYPE_MPT | 
MOD_TYPE_XM | MOD_TYPE_MOD)))
                {
                        param >>= 1;
                }
@@ -240,43 +240,50 @@
        bool nonCompatTracker = false;
        bool isST3 = false;
        bool isSchism = false;
+       const bool usePanningTable = fileHeader.usePanningTable == 
S3MFileHeader::idPanning;
        const int32 schismDateVersion = SchismTrackerEpoch + ((fileHeader.cwtv 
== 0x4FFF) ? fileHeader.reserved2 : (fileHeader.cwtv - 0x4050));
        switch(fileHeader.cwtv & S3MFileHeader::trackerMask)
        {
        case S3MFileHeader::trkAkord & S3MFileHeader::trackerMask:
                if(fileHeader.cwtv == S3MFileHeader::trkAkord)
-                       madeWithTracker = U_("Akord");
+                       madeWithTracker = UL_("Akord");
                break;
        case S3MFileHeader::trkScreamTracker:
-               if(fileHeader.cwtv == S3MFileHeader::trkST3_20 && 
fileHeader.special == 0 && (fileHeader.ordNum & 0x0F) == 0 && 
fileHeader.ultraClicks == 0 && (fileHeader.flags & ~0x50) == 0 && 
fileHeader.usePanningTable == S3MFileHeader::idPanning)
+               if(!memcmp(&fileHeader.reserved2, "SCLUB2.0", 8))
+               {
+                       madeWithTracker = UL_("Sound Club 2");
+               } else if(fileHeader.cwtv == S3MFileHeader::trkST3_20 && 
fileHeader.special == 0 && (fileHeader.ordNum & 0x0F) == 0 && 
fileHeader.ultraClicks == 0 && (fileHeader.flags & ~0x50) == 0 && 
usePanningTable)
                {
                        // MPT and OpenMPT before 1.17.03.02 - Simply keep 
default (filter) MIDI macros
                        if((fileHeader.masterVolume & 0x80) != 0)
                        {
-                               m_dwLastSavedWithVersion = MPT_V("1.16.00.00");
-                               madeWithTracker = U_("ModPlug Tracker / OpenMPT 
1.17");
+                               m_dwLastSavedWithVersion = MPT_V("1.16");
+                               madeWithTracker = UL_("ModPlug Tracker / 
OpenMPT 1.17");
                        } else
                        {
-                               // MPT 1.0 alpha5 doesn't set the stereo flag, 
but MPT 1.0 beta1 does.
-                               m_dwLastSavedWithVersion = MPT_V("1.00.00.00");
-                               madeWithTracker = U_("ModPlug Tracker 1.0 
alpha");
+                               // MPT 1.0 alpha5 doesn't set the stereo flag, 
but MPT 1.0 alpha6 does.
+                               m_dwLastSavedWithVersion = MPT_V("1.00.00.A0");
+                               madeWithTracker = UL_("ModPlug Tracker 1.0 
alpha");
                        }
                        keepMidiMacros = true;
                        nonCompatTracker = true;
                        m_playBehaviour.set(kST3LimitPeriod);
-               } else if(fileHeader.cwtv == S3MFileHeader::trkST3_20 && 
fileHeader.special == 0 && fileHeader.ultraClicks == 0 && fileHeader.flags == 0 
&& fileHeader.usePanningTable == 0)
+               } else if(fileHeader.cwtv == S3MFileHeader::trkST3_20 && 
fileHeader.special == 0 && fileHeader.ultraClicks == 0 && fileHeader.flags == 0 
&& !usePanningTable)
                {
                        if(fileHeader.globalVol == 64 && 
fileHeader.masterVolume == 48)
-                               madeWithTracker = U_("PlayerPRO");
+                               madeWithTracker = UL_("PlayerPRO");
                        else  // Always stereo
-                               madeWithTracker = U_("Velvet Studio");
+                               madeWithTracker = UL_("Velvet Studio");
+               } else if(fileHeader.cwtv == S3MFileHeader::trkST3_20 && 
fileHeader.special == 0 && fileHeader.ultraClicks == 0 && fileHeader.flags == 8 
&& !usePanningTable)
+               {
+                       madeWithTracker = UL_("Impulse Tracker < 1.03");  // 
Not sure if 1.02 saves like this as I don't have it
                } else
                {
                        // ST3.20 should only ever write ultra-click values 16, 
24 and 32 (corresponding to 8, 12 and 16 in the GUI), ST3.01/3.03 should only 
write 0,
                        // though several ST3.01/3.03 files with ultra-click 
values of 16 have been found as well.
                        // However, we won't fingerprint these values here as 
it's unlikely that there is any other tracker out there disguising as ST3 and 
using a strange ultra-click value.
                        // Also, re-saving a file with a strange ultra-click 
value in ST3 doesn't fix this value unless the user manually changes it, or if 
it's below 16.
-                       madeWithTracker = U_("Scream Tracker");
+                       madeWithTracker = UL_("Scream Tracker");
                        formatTrackerStr = true;
                        isST3 = true;
                }
@@ -284,16 +291,19 @@
        case S3MFileHeader::trkImagoOrpheus:
                formatTrackerStr = (fileHeader.cwtv != 
S3MFileHeader::trkPlayerPRO);
                if(formatTrackerStr)
-                       madeWithTracker = U_("Imago Orpheus");
+                       madeWithTracker = UL_("Imago Orpheus");
                else
-                       madeWithTracker = U_("PlayerPRO");
+                       madeWithTracker = UL_("PlayerPRO");
                nonCompatTracker = true;
                break;
        case S3MFileHeader::trkImpulseTracker:
                if(fileHeader.cwtv <= S3MFileHeader::trkIT2_14)
                {
-                       madeWithTracker = U_("Impulse Tracker");
+                       madeWithTracker = UL_("Impulse Tracker");
                        formatTrackerStr = true;
+               } else if(fileHeader.cwtv == S3MFileHeader::trkIT1_old)
+               {
+                       madeWithTracker = UL_("Impulse Tracker 1.03");  // 
Could also be 1.02, maybe? I don't have that one
                } else
                {
                        madeWithTracker = MPT_UFORMAT("Impulse Tracker 
2.14p{}")(fileHeader.cwtv - S3MFileHeader::trkIT2_14);
@@ -317,7 +327,7 @@
        case S3MFileHeader::trkSchismTracker:
                if(fileHeader.cwtv == S3MFileHeader::trkBeRoTrackerOld)
                {
-                       madeWithTracker = U_("BeRoTracker");
+                       madeWithTracker = UL_("BeRoTracker");
                        m_playBehaviour.set(kST3LimitPeriod);
                } else
                {
@@ -333,28 +343,40 @@
                nonCompatTracker = true;
                break;
        case S3MFileHeader::trkOpenMPT:
-               if(fileHeader.cwtv != S3MFileHeader::trkGraoumfTracker)
+               if((fileHeader.cwtv & 0xFF00) == S3MFileHeader::trkNESMusa)
+               {
+                       madeWithTracker = UL_("NESMusa");
+                       formatTrackerStr = true;
+               } else if(fileHeader.reserved2 == 0 && fileHeader.ultraClicks 
== 16 && fileHeader.channels[1] != 1)
+               {
+                       // Liquid Tracker's ID clashes with OpenMPT's.
+                       // OpenMPT started writing full version information 
with OpenMPT 1.29 and later changed the ultraClicks value from 8 to 16.
+                       // Liquid Tracker writes an ultraClicks value of 16.
+                       // So we assume that a file was saved with Liquid 
Tracker if the reserved fields are 0 and ultraClicks is 16.
+                       madeWithTracker = UL_("Liquid Tracker");
+                       formatTrackerStr = true;
+               } else if(fileHeader.cwtv != S3MFileHeader::trkGraoumfTracker)
                {
                        uint32 mptVersion = (fileHeader.cwtv & 
S3MFileHeader::versionMask) << 16;
                        if(mptVersion >= 0x01'29'00'00)
                                mptVersion |= fileHeader.reserved2;
                        m_dwLastSavedWithVersion = Version(mptVersion);
-                       madeWithTracker = U_("OpenMPT ") + 
mpt::ufmt::val(m_dwLastSavedWithVersion);
+                       madeWithTracker = UL_("OpenMPT ") + 
mpt::ufmt::val(m_dwLastSavedWithVersion);
                } else
                {
-                       madeWithTracker = U_("Graoumf Tracker");
+                       madeWithTracker = UL_("Graoumf Tracker");
                }
                break; 
        case S3MFileHeader::trkBeRoTracker:
-               madeWithTracker = U_("BeRoTracker");
+               madeWithTracker = UL_("BeRoTracker");
                m_playBehaviour.set(kST3LimitPeriod);
                break;
        case S3MFileHeader::trkCreamTracker:
-               madeWithTracker = U_("CreamTracker");
+               madeWithTracker = UL_("CreamTracker");
                break;
        default:
                if(fileHeader.cwtv == S3MFileHeader::trkCamoto)
-                       madeWithTracker = U_("Camoto");
+                       madeWithTracker = UL_("Camoto");
                break;
        }
        if(formatTrackerStr)
@@ -362,8 +384,8 @@
                madeWithTracker = MPT_UFORMAT("{} {}.{}")(madeWithTracker, 
(fileHeader.cwtv & 0xF00) >> 8, mpt::ufmt::hex0<2>(fileHeader.cwtv & 0xFF));
        }
 
-       m_modFormat.formatName = U_("Scream Tracker 3");
-       m_modFormat.type = U_("s3m");
+       m_modFormat.formatName = UL_("Scream Tracker 3");
+       m_modFormat.type = UL_("s3m");
        m_modFormat.madeWithTracker = std::move(madeWithTracker);
        m_modFormat.charset = m_dwLastSavedWithVersion ? 
mpt::Charset::Windows1252 : mpt::Charset::CP437;
 
@@ -377,7 +399,7 @@
                m_playBehaviour.reset(kST3OffsetWithoutInstrument);
                m_playBehaviour.reset(kApplyUpperPeriodLimit);
        }
-       if (fileHeader.cwtv <= S3MFileHeader::trkST3_01)
+       if(fileHeader.cwtv <= S3MFileHeader::trkST3_01)
        {
                // This broken behaviour is not present in ST3.01
                m_playBehaviour.reset(kST3TonePortaWithAdlibNote);
@@ -498,16 +520,28 @@
        file.ReadVector(patternOffsets, fileHeader.patNum);
 
        // Read extended channel panning
-       if(fileHeader.usePanningTable == S3MFileHeader::idPanning)
+       if(usePanningTable)
        {
+               bool hasChannelsWithoutPanning = false;
                const auto pan = file.ReadArray<uint8, 32>();
                for(CHANNELINDEX i = 0; i < 32; i++)
                {
                        if((pan[i] & 0x20) != 0 && (!isST3 || 
!isAdlibChannel[i]))
                        {
                                ChnSettings[i].nPan = 
(static_cast<uint16>(pan[i] & 0x0F) * 256 + 8) / 15;
+                       } else if(pan[i] < 0x10)
+                       {
+                               hasChannelsWithoutPanning = true;
                        }
                }
+               if(m_nChannels < 32 && m_dwLastSavedWithVersion == 
MPT_V("1.16"))
+               {
+                       // MPT 1.0 alpha 6 up to 1.16.203 set ths panning bit 
for all channels, regardless of whether they are used or not.
+                       if(hasChannelsWithoutPanning)
+                               m_modFormat.madeWithTracker = UL_("ModPlug 
Tracker 1.16 / OpenMPT 1.17");
+                       else
+                               m_modFormat.madeWithTracker = UL_("ModPlug 
Tracker");
+               }
        }
 
        // Reading sample headers
@@ -528,11 +562,11 @@
 
                if(sampleHeader.sampleType < S3MSampleHeader::typeAdMel)
                {
-                       const uint32 sampleOffset = 
sampleHeader.GetSampleOffset();
-                       if((loadFlags & loadSampleData) && sampleHeader.length 
!= 0 && file.Seek(sampleOffset))
+                       if(sampleHeader.length != 0)
                        {
                                SampleIO sampleIO = 
sampleHeader.GetSampleFormat((fileHeader.formatVersion == 
S3MFileHeader::oldVersion));
-                               sampleIO.ReadSample(Samples[smp + 1], file);
+                               if((loadFlags & loadSampleData) && 
file.Seek(sampleHeader.GetSampleOffset()))
+                                       sampleIO.ReadSample(Samples[smp + 1], 
file);
                                anySamples = true;
                                if(sampleIO.GetEncoding() == SampleIO::ADPCM)
                                        anyADPCM = true;
@@ -548,7 +582,17 @@
                // Hence if a file claims to be written with ST3 (but not 
ST3.00), but has no GUS addresses, we deduce that it must be written by some 
other software (e.g. some PSM -> S3M conversions)
                isST3 = false;
                MPT_UNUSED(isST3);
-               m_modFormat.madeWithTracker = U_("Unknown");
+               m_modFormat.madeWithTracker = UL_("Unknown");
+               // Check these only after we are certain that it can't be 
ST3.01 because that version doesn't sanitize the ultraClicks value yet
+               if(fileHeader.cwtv == S3MFileHeader::trkST3_01 && 
fileHeader.ultraClicks == 0)
+               {
+                       if(!(fileHeader.flags & 
~(S3MFileHeader::fastVolumeSlides | S3MFileHeader::amigaLimits)) && 
(fileHeader.masterVolume & 0x80) && usePanningTable)
+                               m_modFormat.madeWithTracker = UL_("UNMO3");
+                       else if(!fileHeader.flags && fileHeader.globalVol == 48 
&& fileHeader.masterVolume == 176 && fileHeader.tempo == 150 && 
!usePanningTable)
+                               m_modFormat.madeWithTracker = 
UL_("deMODifier");  // SoundSmith to S3M converter
+                       else if(!fileHeader.flags && fileHeader.globalVol == 64 
&& (fileHeader.masterVolume & 0x7F) == 48 && fileHeader.speed == 6 && 
fileHeader.tempo == 125 && !usePanningTable)
+                               m_modFormat.madeWithTracker = UL_("Kosmic 
To-S3M");  // MTM to S3M converter by Zab/Kosmic
+               }
        } else if(isST3)
        {
                // Saving an S3M file in ST3 with the Gravis Ultrasound driver 
loaded will write a unique GUS memory address for each non-empty sample slot 
(and 0 for unused slots).
@@ -565,7 +609,7 @@
        }
 
        if(anyADPCM)
-               m_modFormat.madeWithTracker += U_(" (ADPCM packed)");
+               m_modFormat.madeWithTracker += UL_(" (ADPCM packed)");
 
        // Try to find out if Zxx commands are supposed to be panning commands 
(PixPlay).
        // Actually I am only aware of one module that uses this panning style, 
namely "Crawling Despair" by $volkraq
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude 
config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 
--exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh 
old/libopenmpt-0.7.8+release.autotools/soundlib/Load_xm.cpp 
new/libopenmpt-0.7.9+release.autotools/soundlib/Load_xm.cpp
--- old/libopenmpt-0.7.8+release.autotools/soundlib/Load_xm.cpp 2024-05-11 
21:51:49.000000000 +0200
+++ new/libopenmpt-0.7.9+release.autotools/soundlib/Load_xm.cpp 2024-07-13 
19:29:22.000000000 +0200
@@ -480,6 +480,13 @@
                                                {
                                                        decodedSamples = ret;
                                                        
LimitMax(decodedSamples, mpt::saturate_cast<long>(sample.nLength - offset));
+                                                       if(offset == 0 && 
channels == 1 && sample.GetNumChannels() == 2)
+                                                       {
+                                                               // oggmod 
doesn't know what stereo samples are, so it treats them as mono samples, but 
doesn't clear the unknown stereo flag.
+                                                               // We just take 
the left channel in this case, as it is difficult (if possible at all) to 
properly reconstruct the waveform of the right channel.
+                                                               // Due to XM's 
delta-encoding and Vorbis being a lossless codec, samples could distort easily 
even when the delta encoding was off by a very small amount.
+                                                               
sample.uFlags.reset(CHN_STEREO);
+                                                       }
                                                        if(decodedSamples > 0 
&& channels == sample.GetNumChannels())
                                                        {
                                                                
if(sample.uFlags[CHN_16BIT])
@@ -663,6 +670,10 @@
                        // Fix arpeggios in kragle_-_happy_day.xm
                        m_playBehaviour.reset(kFT2Arpeggio);
                        isMadTracker = true;
+                       if(memcmp(fileHeader.trackerName + 15, "\0\0\0\0", 4))
+                               madeWithTracker = UL_("MadTracker 2 
(registered)");
+                       else
+                               madeWithTracker = UL_("MadTracker 2");
                } else if(!memcmp(fileHeader.trackerName, "Skale Tracker\0", 
14) || !memcmp(fileHeader.trackerName, "Sk@le Tracker\0", 14))
                {
                        m_playBehaviour.reset(kFT2ST3OffsetOutOfRange);
@@ -720,6 +731,11 @@
        // Reading instruments
        for(INSTRUMENTINDEX instr = 1; instr <= m_nInstruments; instr++)
        {
+               if(!AllocateInstrument(instr))
+                       return false;
+               if(!file.CanRead(4))
+                       continue;
+
                // First, try to read instrument header length...
                uint32 headerSize = file.ReadUint32LE();
                if(headerSize == 0)
@@ -782,11 +798,6 @@
                        }
                }
 
-               if(AllocateInstrument(instr) == nullptr)
-               {
-                       continue;
-               }
-
                instrHeader.ConvertToMPT(*Instruments[instr]);
 
                if(lastInstrType == -1)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude 
config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 
--exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh 
old/libopenmpt-0.7.8+release.autotools/soundlib/S3MTools.h 
new/libopenmpt-0.7.9+release.autotools/soundlib/S3MTools.h
--- old/libopenmpt-0.7.8+release.autotools/soundlib/S3MTools.h  2024-05-11 
17:30:11.000000000 +0200
+++ new/libopenmpt-0.7.9+release.autotools/soundlib/S3MTools.h  2024-07-13 
19:37:24.000000000 +0200
@@ -46,14 +46,16 @@
 
                trkAkord          = 0x0208,
                trkST3_00         = 0x1300,
-               trkST3_20         = 0x1320,
                trkST3_01         = 0x1301,
+               trkST3_20         = 0x1320,
+               trkIT1_old        = 0x3320,
                trkIT2_07         = 0x3207,
                trkIT2_14         = 0x3214,
                trkBeRoTrackerOld = 0x4100,  // Used from 2004 to 2012
                trkGraoumfTracker = 0x5447,
+               trkNESMusa        = 0x5700,
                trkCamoto         = 0xCA00,
-               trkPlayerPRO      = 0x2013  // PlayerPRO on Intel doesn't 
byte-swap the tracker ID bytes
+               trkPlayerPRO      = 0x2013,  // PlayerPRO on Intel doesn't 
byte-swap the tracker ID bytes
        };
 
        // Flags
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude 
config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 
--exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh 
old/libopenmpt-0.7.8+release.autotools/soundlib/Snd_fx.cpp 
new/libopenmpt-0.7.9+release.autotools/soundlib/Snd_fx.cpp
--- old/libopenmpt-0.7.8+release.autotools/soundlib/Snd_fx.cpp  2024-06-08 
15:44:28.000000000 +0200
+++ new/libopenmpt-0.7.9+release.autotools/soundlib/Snd_fx.cpp  2024-07-14 
15:28:14.000000000 +0200
@@ -220,7 +220,7 @@
 
                        if(chn.position >= sampleEnd || (chn.position < 
loopStart && inc.IsNegative()))
                        {
-                               if(!chn.dwFlags[CHN_LOOP])
+                               if(!chn.dwFlags[CHN_LOOP] || !loopLength)
                                {
                                        // Past sample end.
                                        stopNote = true;
@@ -1064,7 +1064,8 @@
                                {
                                        if(m.command == CMD_OFFSET)
                                        {
-                                               ProcessSampleOffset(chn, nChn, 
playState);
+                                               if(!porta || !(GetType() & 
(MOD_TYPE_XM | MOD_TYPE_DBM)))
+                                                       
ProcessSampleOffset(chn, nChn, playState);
                                        } else if(m.command == 
CMD_OFFSETPERCENTAGE)
                                        {
                                                SampleOffset(chn, 
Util::muldiv_unsigned(chn.nLength, m.param, 256));
@@ -1365,7 +1366,7 @@
 void CSoundFile::InstrumentChange(ModChannel &chn, uint32 instr, bool bPorta, 
bool bUpdVol, bool bResetEnv) const
 {
        const ModInstrument *pIns = instr <= GetNumInstruments() ? 
Instruments[instr] : nullptr;
-       const ModSample *pSmp = &Samples[instr];
+       const ModSample *pSmp = &Samples[instr <= GetNumSamples() ? instr : 0];
        const auto oldInsVol = chn.nInsVol;
        ModCommand::NOTE note = chn.nNewNote;
 
@@ -2707,8 +2708,8 @@
                        if(m_playBehaviour[kMODSampleSwap])
                        {
                                // ProTracker Compatibility: If a sample was 
stopped before, lone instrument numbers can retrigger it
-                               // Test case: PTSwapEmpty.mod, 
PTInstrVolume.mod, SampleSwap.s3m
-                               if(!chn.IsSamplePlaying() && (chn.pModSample == 
nullptr || !chn.pModSample->HasSampleData()))
+                               // Test cases: PTSwapEmpty.mod, 
PTInstrVolume.mod, PTStoppedSwap.mod
+                               if(!chn.IsSamplePlaying() && instr <= 
GetNumSamples() && Samples[instr].uFlags[CHN_LOOP])
                                        keepInstr = true;
                        }
 
@@ -2951,7 +2952,8 @@
                                }
 
                                NoteChange(chn, note, bPorta, !(GetType() & 
(MOD_TYPE_XM | MOD_TYPE_MT2)), false, nChn);
-                               HandleDigiSamplePlayDirection(m_PlayState, 
nChn);
+                               if(ModCommand::IsNote(note))
+                                       
HandleDigiSamplePlayDirection(m_PlayState, nChn);
                                if ((bPorta) && (GetType() & 
(MOD_TYPE_XM|MOD_TYPE_MT2)) && (instr))
                                {
                                        chn.dwFlags.set(CHN_FASTVOLRAMP);
@@ -3229,7 +3231,7 @@
                        {
                                // FT2 compatibility: Portamento + Offset = 
Ignore offset
                                // Test case: porta-offset.xm
-                               if(bPorta && GetType() == MOD_TYPE_XM)
+                               if(bPorta && (GetType() & (MOD_TYPE_XM | 
MOD_TYPE_DBM)))
                                        break;
 
                                ProcessSampleOffset(chn, nChn, m_PlayState);
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude 
config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 
--exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh 
old/libopenmpt-0.7.8+release.autotools/soundlib/Sndfile.h 
new/libopenmpt-0.7.9+release.autotools/soundlib/Sndfile.h
--- old/libopenmpt-0.7.8+release.autotools/soundlib/Sndfile.h   2024-01-10 
21:33:43.000000000 +0100
+++ new/libopenmpt-0.7.9+release.autotools/soundlib/Sndfile.h   2024-06-22 
20:45:37.000000000 +0200
@@ -1285,7 +1285,7 @@
        // Resolve note/instrument combination to real sample index. Return 
value is guaranteed to be in [0, GetNumSamples()].
        SAMPLEINDEX GetSampleIndex(ModCommand::NOTE note, uint32 instr) const 
noexcept;
 
-       uint32 MapMidiInstrument(uint8 program, uint16 bank, uint8 midiChannel, 
uint8 note, bool isXG, std::bitset<16> drumChns);
+       uint32 MapMidiInstrument(uint8 program, uint16 bank, uint8 midiChannel, 
uint8 note, bool isXG, std::bitset<32> drumChns);
        size_t ITInstrToMPT(FileReader &file, ModInstrument &ins, uint16 
trkvers);
        std::pair<bool, bool> LoadMixPlugins(FileReader &file);
 #ifndef NO_PLUGINS
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude 
config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 
--exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh 
old/libopenmpt-0.7.8+release.autotools/soundlib/modcommand.cpp 
new/libopenmpt-0.7.9+release.autotools/soundlib/modcommand.cpp
--- old/libopenmpt-0.7.8+release.autotools/soundlib/modcommand.cpp      
2024-06-01 15:58:00.000000000 +0200
+++ new/libopenmpt-0.7.9+release.autotools/soundlib/modcommand.cpp      
2024-06-25 20:47:51.000000000 +0200
@@ -1348,6 +1348,41 @@
 
 std::pair<EffectCommand, ModCommand::PARAM> 
ModCommand::FillInTwoCommands(EffectCommand effect1, uint8 param1, 
EffectCommand effect2, uint8 param2)
 {
+       if(effect1 == effect2)
+       {
+               // For non-sliding, absolute effects, it doesn't make sense to 
keep both commands
+               switch(effect1)
+               {
+               case CMD_ARPEGGIO:
+               case CMD_PANNING8:
+               case CMD_OFFSET:
+               case CMD_POSITIONJUMP:
+               case CMD_VOLUME:
+               case CMD_PATTERNBREAK:
+               case CMD_SPEED:
+               case CMD_TEMPO:
+               case CMD_CHANNELVOLUME:
+               case CMD_GLOBALVOLUME:
+               case CMD_KEYOFF:
+               case CMD_SETENVPOSITION:
+               case CMD_MIDI:
+               case CMD_SMOOTHMIDI:
+               case CMD_DELAYCUT:
+               case CMD_FINETUNE:
+               case CMD_FINETUNE_SMOOTH:
+               case CMD_DUMMY:
+               case CMD_REVERSEOFFSET:
+               case CMD_DBMECHO:
+               case CMD_OFFSETPERCENTAGE:
+               case CMD_DIGIREVERSESAMPLE:
+               case CMD_VOLUME8:
+                       effect2 = CMD_NONE;
+                       break;
+               default:
+                       break;
+               }
+       }
+
        for(uint8 n = 0; n < 4; n++)
        {
                if(auto volCmd = ModCommand::ConvertToVolCommand(effect1, 
param1, (n > 1)); effect1 == CMD_NONE || volCmd.first != VOLCMD_NONE)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude 
config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 
--exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh 
old/libopenmpt-0.7.8+release.autotools/soundlib/plugins/PluginManager.cpp 
new/libopenmpt-0.7.9+release.autotools/soundlib/plugins/PluginManager.cpp
--- old/libopenmpt-0.7.8+release.autotools/soundlib/plugins/PluginManager.cpp   
2023-02-11 15:52:59.000000000 +0100
+++ new/libopenmpt-0.7.9+release.autotools/soundlib/plugins/PluginManager.cpp   
2024-07-03 19:09:44.000000000 +0200
@@ -779,7 +779,11 @@
        }
 
 #ifdef MPT_WITH_VST
-       if(pFound && mixPlugin.Info.dwPluginId1 == Vst::kEffectMagic)
+       // Note: we don't check if dwPluginId1 matches Vst::kEffectMagic here, 
even if it should.
+       // I have an old file I made with OpenMPT 1.17 where the primary plugin 
ID has an unexpected value.
+       // No idea how that could happen, apart from some plugin.cache 
corruption (back then, the IDs were not re-checked
+       // after instantiating a plugin and the cached plugin ID was blindly 
written to the module file)
+       if(pFound)
        {
                Vst::AEffect *pEffect = nullptr;
                HINSTANCE hLibrary = nullptr;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude 
config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 
--exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh 
old/libopenmpt-0.7.8+release.autotools/src/mpt/base/detect_compiler.hpp 
new/libopenmpt-0.7.9+release.autotools/src/mpt/base/detect_compiler.hpp
--- old/libopenmpt-0.7.8+release.autotools/src/mpt/base/detect_compiler.hpp     
2024-05-22 11:10:28.000000000 +0200
+++ new/libopenmpt-0.7.9+release.autotools/src/mpt/base/detect_compiler.hpp     
2024-07-19 12:42:56.000000000 +0200
@@ -204,4 +204,30 @@
 
 
 
+// detect compiler setting quirks
+
+#if MPT_COMPILER_GCC
+#if (MPT_GCC_AT_LEAST(14, 0, 0) && MPT_GCC_BEFORE(14, 2, 0)) || 
(MPT_GCC_AT_LEAST(13, 0, 0) && MPT_GCC_BEFORE(13, 4, 0)) || 
(MPT_GCC_AT_LEAST(12, 0, 0) && MPT_GCC_BEFORE(12, 5, 0)) || MPT_GCC_BEFORE(12, 
0, 0)
+// GCC 14 causes severe miscompilation of inline functions on MinGW.
+// See <https://gcc.gnu.org/bugzilla/show_bug.cgi?id=115049>.
+// Current investigation suggests a general problem with -fipa-ra on non-ELF
+// platforms.
+// As far as we understand the issue, it could possibly also manifest with
+// other inter-procedure-optimizations and with older GCC versions.
+// Fixed in GCC 15
+// 
(<https://gcc.gnu.org/git/?p=gcc.git;h=5080840d8fbf25a321dd27543a1462d393d338bc>),
+// GCC 14.2
+// 
(<https://gcc.gnu.org/git/?p=gcc.git;h=747c4b58573ea00419f64293a61537eb69f43307>).
+// GCC 13.4
+// 
(<https://gcc.gnu.org/git/?p=gcc.git;h=953bf37690d22de956d75c6aef7a9690ad55b9a7>).
+// and GCC 12.5
+// 
(<https://gcc.gnu.org/git/?p=gcc.git;h=2c5f48a43f26223cb8603b826d7c0d52cdbcfb46>).
+#if !defined(__ELF__)
+#define MPT_COMPILER_SETTING_QUIRK_GCC_BROKEN_IPA
+#endif
+#endif
+#endif
+
+
+
 #endif // MPT_BASE_DETECT_COMPILER_HPP
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude 
config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 
--exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh 
old/libopenmpt-0.7.8+release.autotools/src/mpt/base/detect_quirks.hpp 
new/libopenmpt-0.7.9+release.autotools/src/mpt/base/detect_quirks.hpp
--- old/libopenmpt-0.7.8+release.autotools/src/mpt/base/detect_quirks.hpp       
2024-05-12 13:07:25.000000000 +0200
+++ new/libopenmpt-0.7.9+release.autotools/src/mpt/base/detect_quirks.hpp       
2024-07-14 18:10:07.000000000 +0200
@@ -19,16 +19,6 @@
 
 
 
-#if MPT_GCC_AT_LEAST(14, 0, 0) && MPT_GCC_BEFORE(15, 0, 0)
-// GCC 14 causes severe miscompilation of inline functions.
-// See <https://gcc.gnu.org/bugzilla/show_bug.cgi?id=115049>.
-#if defined(__OPTIMIZE__)
-#define MPT_COMPILER_QUIRK_GCC_NO_O2
-#endif
-#endif
-
-
-
 #if MPT_COMPILER_MSVC
 #if !defined(_MSVC_TRADITIONAL)
 #define MPT_COMPILER_QUIRK_MSVC_OLD_PREPROCESSOR
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude 
config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 
--exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh 
old/libopenmpt-0.7.8+release.autotools/src/mpt/check/compiler.hpp 
new/libopenmpt-0.7.9+release.autotools/src/mpt/check/compiler.hpp
--- old/libopenmpt-0.7.8+release.autotools/src/mpt/check/compiler.hpp   
2024-05-12 13:07:25.000000000 +0200
+++ new/libopenmpt-0.7.9+release.autotools/src/mpt/check/compiler.hpp   
2024-07-14 15:00:00.000000000 +0200
@@ -7,13 +7,6 @@
 #include "mpt/base/detect_quirks.hpp"
 #include "mpt/base/compiletime_warning.hpp"
 
-#ifndef MPT_CHECK_CXX_IGNORE_WARNING_O2
-#if defined(MPT_COMPILER_QUIRK_GCC_NO_O2)
-// See <https://gcc.gnu.org/bugzilla/show_bug.cgi?id=115049>.
-MPT_WARNING("GCC 14 is known to cause severe miscompilation of inline 
functions. OpenMPT has forced optimization settings down to -O1. This comes at 
a roughly 15% performance cost. It is strongly recommended to stay with GCC 13 
for the time being. You will need to edit the source to opt-out of this safety 
guard.")
-#endif
-#endif
-
 #ifndef MPT_CHECK_CXX_IGNORE_PREPROCESSOR
 #if defined(MPT_COMPILER_QUIRK_MSVC_OLD_PREPROCESSOR)
 MPT_WARNING("C++ preprocessor is not standard conformings.")
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude 
config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 
--exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh 
old/libopenmpt-0.7.8+release.autotools/src/mpt/string_transcode/transcode.hpp 
new/libopenmpt-0.7.9+release.autotools/src/mpt/string_transcode/transcode.hpp
--- 
old/libopenmpt-0.7.8+release.autotools/src/mpt/string_transcode/transcode.hpp   
    2023-04-11 11:17:44.000000000 +0200
+++ 
new/libopenmpt-0.7.9+release.autotools/src/mpt/string_transcode/transcode.hpp   
    2024-06-25 16:04:01.000000000 +0200
@@ -678,6 +678,7 @@
                                                out.push_back(replacement);
                                                ucs4 = 0;
                                                charsleft = 0;
+                                               continue;
                                        }
                                        if (ucs4 <= 0xffff) {
                                                
out.push_back(static_cast<mpt::widechar>(ucs4));
@@ -817,7 +818,7 @@
                char32_t ucs4 = 
static_cast<char32_t>(static_cast<uint32>(in[i]));
                if (ucs4 > 0x1fffff) {
                        out.push_back(static_cast<typename 
Tdststring::value_type>(static_cast<uint16>(replacement)));
-                       ucs4 = 0;
+                       continue;
                }
                if (ucs4 <= 0xffff) {
                        out.push_back(static_cast<typename 
Tdststring::value_type>(static_cast<uint16>(ucs4)));
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude 
config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 
--exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh 
old/libopenmpt-0.7.8+release.autotools/src/openmpt/all/BuildSettings.hpp 
new/libopenmpt-0.7.9+release.autotools/src/openmpt/all/BuildSettings.hpp
--- old/libopenmpt-0.7.8+release.autotools/src/openmpt/all/BuildSettings.hpp    
2021-05-24 11:10:03.000000000 +0200
+++ new/libopenmpt-0.7.9+release.autotools/src/openmpt/all/BuildSettings.hpp    
2024-07-14 18:10:07.000000000 +0200
@@ -6,6 +6,12 @@
 
 
 
+#if defined(MODPLUG_TRACKER) || defined(LIBOPENMPT_BUILD)
+#include "BuildSettingsCompiler.h"
+#endif
+
+
+
 #include "mpt/base/detect_compiler.hpp"
 #include "mpt/base/detect_os.hpp"
 #include "mpt/base/detect_quirks.hpp"

Reply via email to