Răsfoiți Sursa

Moved to audio.mod.

woollybah 5 ani în urmă
părinte
comite
85b492b13c
100 a modificat fișierele cu 0 adăugiri și 34209 ștergeri
  1. 0 178
      libopenmpt.mod/libopenmpt.bmx
  2. 0 26
      libopenmpt.mod/openmpt/LICENSE
  3. 0 296
      libopenmpt.mod/openmpt/README.md
  4. 0 21
      libopenmpt.mod/openmpt/build/svn_version/svn_version.h
  5. 0 14
      libopenmpt.mod/openmpt/build/svn_version/svn_version.template.subwcrev.h
  6. 0 6
      libopenmpt.mod/openmpt/build/svn_version/update_svn_version_vs_premake.cmd
  7. 0 718
      libopenmpt.mod/openmpt/common/BuildSettings.h
  8. 0 358
      libopenmpt.mod/openmpt/common/CompilerDetect.h
  9. 0 469
      libopenmpt.mod/openmpt/common/ComponentManager.cpp
  10. 0 519
      libopenmpt.mod/openmpt/common/ComponentManager.h
  11. 0 1178
      libopenmpt.mod/openmpt/common/Endianness.h
  12. 0 152
      libopenmpt.mod/openmpt/common/FileReader.cpp
  13. 0 1443
      libopenmpt.mod/openmpt/common/FileReader.h
  14. 0 35
      libopenmpt.mod/openmpt/common/FileReaderFwd.h
  15. 0 415
      libopenmpt.mod/openmpt/common/FlagSet.h
  16. 0 433
      libopenmpt.mod/openmpt/common/Logging.cpp
  17. 0 254
      libopenmpt.mod/openmpt/common/Logging.h
  18. 0 221
      libopenmpt.mod/openmpt/common/Profiler.cpp
  19. 0 127
      libopenmpt.mod/openmpt/common/Profiler.h
  20. 0 118
      libopenmpt.mod/openmpt/common/misc_util.cpp
  21. 0 233
      libopenmpt.mod/openmpt/common/misc_util.h
  22. 0 36
      libopenmpt.mod/openmpt/common/mptAlloc.cpp
  23. 0 125
      libopenmpt.mod/openmpt/common/mptAlloc.h
  24. 0 145
      libopenmpt.mod/openmpt/common/mptAssert.h
  25. 0 234
      libopenmpt.mod/openmpt/common/mptBaseMacros.h
  26. 0 290
      libopenmpt.mod/openmpt/common/mptBaseTypes.h
  27. 0 640
      libopenmpt.mod/openmpt/common/mptBaseUtils.h
  28. 0 292
      libopenmpt.mod/openmpt/common/mptCPU.cpp
  29. 0 76
      libopenmpt.mod/openmpt/common/mptCPU.h
  30. 0 259
      libopenmpt.mod/openmpt/common/mptCRC.h
  31. 0 56
      libopenmpt.mod/openmpt/common/mptException.h
  32. 0 76
      libopenmpt.mod/openmpt/common/mptExceptionText.h
  33. 0 433
      libopenmpt.mod/openmpt/common/mptFileIO.cpp
  34. 0 289
      libopenmpt.mod/openmpt/common/mptFileIO.h
  35. 0 671
      libopenmpt.mod/openmpt/common/mptIO.cpp
  36. 0 1097
      libopenmpt.mod/openmpt/common/mptIO.h
  37. 0 556
      libopenmpt.mod/openmpt/common/mptLibrary.cpp
  38. 0 120
      libopenmpt.mod/openmpt/common/mptLibrary.h
  39. 0 334
      libopenmpt.mod/openmpt/common/mptMemory.h
  40. 0 239
      libopenmpt.mod/openmpt/common/mptMutex.h
  41. 0 958
      libopenmpt.mod/openmpt/common/mptOS.cpp
  42. 0 304
      libopenmpt.mod/openmpt/common/mptOS.h
  43. 0 80
      libopenmpt.mod/openmpt/common/mptOSException.h
  44. 0 870
      libopenmpt.mod/openmpt/common/mptPathString.cpp
  45. 0 504
      libopenmpt.mod/openmpt/common/mptPathString.h
  46. 0 301
      libopenmpt.mod/openmpt/common/mptRandom.cpp
  47. 0 668
      libopenmpt.mod/openmpt/common/mptRandom.h
  48. 0 139
      libopenmpt.mod/openmpt/common/mptSpan.h
  49. 0 1605
      libopenmpt.mod/openmpt/common/mptString.cpp
  50. 0 700
      libopenmpt.mod/openmpt/common/mptString.h
  51. 0 117
      libopenmpt.mod/openmpt/common/mptStringBuffer.cpp
  52. 0 565
      libopenmpt.mod/openmpt/common/mptStringBuffer.h
  53. 0 522
      libopenmpt.mod/openmpt/common/mptStringFormat.cpp
  54. 0 737
      libopenmpt.mod/openmpt/common/mptStringFormat.h
  55. 0 120
      libopenmpt.mod/openmpt/common/mptStringParse.cpp
  56. 0 250
      libopenmpt.mod/openmpt/common/mptStringParse.h
  57. 0 140
      libopenmpt.mod/openmpt/common/mptThread.h
  58. 0 309
      libopenmpt.mod/openmpt/common/mptTime.cpp
  59. 0 116
      libopenmpt.mod/openmpt/common/mptTime.h
  60. 0 559
      libopenmpt.mod/openmpt/common/mptUUID.cpp
  61. 0 207
      libopenmpt.mod/openmpt/common/mptUUID.h
  62. 0 755
      libopenmpt.mod/openmpt/common/mptWine.cpp
  63. 0 129
      libopenmpt.mod/openmpt/common/mptWine.h
  64. 0 731
      libopenmpt.mod/openmpt/common/serialization_utils.cpp
  65. 0 553
      libopenmpt.mod/openmpt/common/serialization_utils.h
  66. 0 145
      libopenmpt.mod/openmpt/common/stdafx.h
  67. 0 808
      libopenmpt.mod/openmpt/common/version.cpp
  68. 0 308
      libopenmpt.mod/openmpt/common/version.h
  69. 0 32
      libopenmpt.mod/openmpt/common/versionNumber.h
  70. 0 36
      libopenmpt.mod/openmpt/doc/backporting_patches.md
  71. 0 43
      libopenmpt.mod/openmpt/doc/contributing.md
  72. 0 41
      libopenmpt.mod/openmpt/doc/libopenmpt_release.md
  73. 0 104
      libopenmpt.mod/openmpt/doc/libopenmpt_styleguide.md
  74. 0 106
      libopenmpt.mod/openmpt/doc/module_formats.md
  75. 0 70
      libopenmpt.mod/openmpt/doc/openmpt_release.md
  76. 0 35
      libopenmpt.mod/openmpt/doc/openmpt_styleguide.md
  77. 0 24
      libopenmpt.mod/openmpt/doc/release_branches.md
  78. 0 14
      libopenmpt.mod/openmpt/doc/year_changed.md
  79. 0 63
      libopenmpt.mod/openmpt/examples/.clang-format
  80. 0 203
      libopenmpt.mod/openmpt/examples/libopenmpt_example_c.c
  81. 0 292
      libopenmpt.mod/openmpt/examples/libopenmpt_example_c_mem.c
  82. 0 152
      libopenmpt.mod/openmpt/examples/libopenmpt_example_c_pipe.c
  83. 0 181
      libopenmpt.mod/openmpt/examples/libopenmpt_example_c_probe.c
  84. 0 176
      libopenmpt.mod/openmpt/examples/libopenmpt_example_c_stdout.c
  85. 0 65
      libopenmpt.mod/openmpt/examples/libopenmpt_example_c_unsafe.c
  86. 0 85
      libopenmpt.mod/openmpt/examples/libopenmpt_example_cxx.cpp
  87. 0 45
      libopenmpt.mod/openmpt/libopenmpt/.clang-format
  88. 0 2469
      libopenmpt.mod/openmpt/libopenmpt/Doxyfile
  89. 0 1622
      libopenmpt.mod/openmpt/libopenmpt/bindings/freebasic/libopenmpt.bi
  90. 0 332
      libopenmpt.mod/openmpt/libopenmpt/bindings/freebasic/libopenmpt_ext.bi
  91. 0 17
      libopenmpt.mod/openmpt/libopenmpt/doc/in_openmpt.txt
  92. 0 16
      libopenmpt.mod/openmpt/libopenmpt/doc/xmp-openmpt.txt
  93. 0 780
      libopenmpt.mod/openmpt/libopenmpt/dox/changelog.md
  94. 0 122
      libopenmpt.mod/openmpt/libopenmpt/dox/dependencies.md
  95. 0 42
      libopenmpt.mod/openmpt/libopenmpt/dox/index.dox
  96. 0 38
      libopenmpt.mod/openmpt/libopenmpt/dox/packaging.md
  97. 0 70
      libopenmpt.mod/openmpt/libopenmpt/dox/quickstart.md
  98. 0 44
      libopenmpt.mod/openmpt/libopenmpt/dox/tests.md
  99. 0 8
      libopenmpt.mod/openmpt/libopenmpt/dox/todo.md
  100. 0 500
      libopenmpt.mod/openmpt/libopenmpt/in_openmpt.cpp

+ 0 - 178
libopenmpt.mod/libopenmpt.bmx

@@ -1,178 +0,0 @@
-' Copyright (c) 2019 Bruce A Henderson
-' All rights reserved.
-' 
-' Redistribution and use in source and binary forms, with or without
-' modification, are permitted provided that the following conditions are met:
-'     * Redistributions of source code must retain the above copyright
-'       notice, this list of conditions and the following disclaimer.
-'     * Redistributions in binary form must reproduce the above copyright
-'       notice, this list of conditions and the following disclaimer in the
-'       documentation and/or other materials provided with the distribution.
-'     * Neither the name of the project nor the
-'       names of its contributors may be used to endorse or promote products
-'       derived from this software without specific prior written permission.
-' 
-' THIS SOFTWARE IS PROVIDED BY THE CONTRIBUTORS ``AS IS'' AND ANY
-' EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-' WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
-' DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
-' DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
-' (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
-' LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
-' ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-' (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
-' SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-' 
-SuperStrict
-
-Module Pub.libopenmpt
-
-
-ModuleInfo "CC_OPTS: -DLIBOPENMPT_BUILD"
-ModuleInfo "CPP_OPTS: -std=c++17 -fexceptions"
-
-Import "openmpt/*.h"
-Import "openmpt/common/*.h"
-Import "openmpt/build/svn_version/*.h"
-
-' common
-Import "openmpt/common/ComponentManager.cpp"
-Import "openmpt/common/FileReader.cpp"
-Import "openmpt/common/Logging.cpp"
-Import "openmpt/common/misc_util.cpp"
-Import "openmpt/common/mptAlloc.cpp"
-Import "openmpt/common/mptCPU.cpp"
-Import "openmpt/common/mptFileIO.cpp"
-Import "openmpt/common/mptIO.cpp"
-Import "openmpt/common/mptLibrary.cpp"
-Import "openmpt/common/mptOS.cpp"
-Import "openmpt/common/mptPathString.cpp"
-Import "openmpt/common/mptRandom.cpp"
-Import "openmpt/common/mptString.cpp"
-Import "openmpt/common/mptStringBuffer.cpp"
-Import "openmpt/common/mptStringFormat.cpp"
-Import "openmpt/common/mptStringParse.cpp"
-Import "openmpt/common/mptTime.cpp"
-Import "openmpt/common/mptUUID.cpp"
-Import "openmpt/common/mptWine.cpp"
-Import "openmpt/common/Profiler.cpp"
-Import "openmpt/common/serialization_utils.cpp"
-Import "openmpt/common/version.cpp"
-
-' libopenmpt
-Import "openmpt/libopenmpt/*.h"
-Import "openmpt/libopenmpt/libopenmpt_c.cpp"
-Import "openmpt/libopenmpt/libopenmpt_cxx.cpp"
-Import "openmpt/libopenmpt/libopenmpt_ext_impl.cpp"
-Import "openmpt/libopenmpt/libopenmpt_impl.cpp"
-
-' sounddsp
-Import "openmpt/sounddsp/AGC.cpp"
-Import "openmpt/sounddsp/DSP.cpp"
-Import "openmpt/sounddsp/EQ.cpp"
-Import "openmpt/sounddsp/Reverb.cpp"
-
-' soundlib
-Import "openmpt/soundlib/AudioCriticalSection.cpp"
-Import "openmpt/soundlib/ContainerMMCMP.cpp"
-Import "openmpt/soundlib/ContainerPP20.cpp"
-Import "openmpt/soundlib/ContainerUMX.cpp"
-Import "openmpt/soundlib/ContainerXPK.cpp"
-Import "openmpt/soundlib/Dlsbank.cpp"
-Import "openmpt/soundlib/Fastmix.cpp"
-Import "openmpt/soundlib/InstrumentExtensions.cpp"
-Import "openmpt/soundlib/ITCompression.cpp"
-Import "openmpt/soundlib/ITTools.cpp"
-Import "openmpt/soundlib/Load_669.cpp"
-Import "openmpt/soundlib/Load_amf.cpp"
-Import "openmpt/soundlib/Load_ams.cpp"
-Import "openmpt/soundlib/Load_c67.cpp"
-Import "openmpt/soundlib/Load_dbm.cpp"
-Import "openmpt/soundlib/Load_digi.cpp"
-Import "openmpt/soundlib/Load_dmf.cpp"
-Import "openmpt/soundlib/Load_dsm.cpp"
-Import "openmpt/soundlib/Load_dtm.cpp"
-Import "openmpt/soundlib/Load_far.cpp"
-Import "openmpt/soundlib/Load_gdm.cpp"
-Import "openmpt/soundlib/Load_imf.cpp"
-Import "openmpt/soundlib/Load_it.cpp"
-Import "openmpt/soundlib/Load_itp.cpp"
-Import "openmpt/soundlib/load_j2b.cpp"
-Import "openmpt/soundlib/Load_mdl.cpp"
-Import "openmpt/soundlib/Load_med.cpp"
-Import "openmpt/soundlib/Load_mid.cpp"
-Import "openmpt/soundlib/Load_mo3.cpp"
-Import "openmpt/soundlib/Load_mod.cpp"
-Import "openmpt/soundlib/Load_mt2.cpp"
-Import "openmpt/soundlib/Load_mtm.cpp"
-Import "openmpt/soundlib/Load_okt.cpp"
-Import "openmpt/soundlib/Load_plm.cpp"
-Import "openmpt/soundlib/Load_psm.cpp"
-Import "openmpt/soundlib/Load_ptm.cpp"
-Import "openmpt/soundlib/Load_s3m.cpp"
-Import "openmpt/soundlib/Load_sfx.cpp"
-Import "openmpt/soundlib/Load_stm.cpp"
-Import "openmpt/soundlib/Load_stp.cpp"
-Import "openmpt/soundlib/Load_uax.cpp"
-Import "openmpt/soundlib/Load_ult.cpp"
-Import "openmpt/soundlib/Load_wav.cpp"
-Import "openmpt/soundlib/Load_xm.cpp"
-Import "openmpt/soundlib/Message.cpp"
-Import "openmpt/soundlib/MIDIEvents.cpp"
-Import "openmpt/soundlib/MIDIMacros.cpp"
-Import "openmpt/soundlib/MixerLoops.cpp"
-Import "openmpt/soundlib/MixerSettings.cpp"
-Import "openmpt/soundlib/MixFuncTable.cpp"
-Import "openmpt/soundlib/mod_specifications.cpp"
-Import "openmpt/soundlib/ModChannel.cpp"
-Import "openmpt/soundlib/modcommand.cpp"
-Import "openmpt/soundlib/ModInstrument.cpp"
-Import "openmpt/soundlib/ModSample.cpp"
-Import "openmpt/soundlib/ModSequence.cpp"
-Import "openmpt/soundlib/modsmp_ctrl.cpp"
-Import "openmpt/soundlib/MPEGFrame.cpp"
-Import "openmpt/soundlib/OggStream.cpp"
-Import "openmpt/soundlib/OPL.cpp"
-Import "openmpt/soundlib/pattern.cpp"
-Import "openmpt/soundlib/patternContainer.cpp"
-Import "openmpt/soundlib/Paula.cpp"
-Import "openmpt/soundlib/RowVisitor.cpp"
-Import "openmpt/soundlib/S3MTools.cpp"
-Import "openmpt/soundlib/SampleFormatFLAC.cpp"
-Import "openmpt/soundlib/SampleFormatMediaFoundation.cpp"
-Import "openmpt/soundlib/SampleFormatMP3.cpp"
-Import "openmpt/soundlib/SampleFormatOpus.cpp"
-Import "openmpt/soundlib/SampleFormats.cpp"
-Import "openmpt/soundlib/SampleFormatVorbis.cpp"
-Import "openmpt/soundlib/SampleIO.cpp"
-Import "openmpt/soundlib/Snd_flt.cpp"
-Import "openmpt/soundlib/Snd_fx.cpp"
-Import "openmpt/soundlib/Sndfile.cpp"
-Import "openmpt/soundlib/Sndmix.cpp"
-Import "openmpt/soundlib/SoundFilePlayConfig.cpp"
-Import "openmpt/soundlib/Tables.cpp"
-Import "openmpt/soundlib/Tagging.cpp"
-Import "openmpt/soundlib/tuning.cpp"
-Import "openmpt/soundlib/tuningbase.cpp"
-Import "openmpt/soundlib/tuningCollection.cpp"
-Import "openmpt/soundlib/UMXTools.cpp"
-Import "openmpt/soundlib/UpgradeModule.cpp"
-Import "openmpt/soundlib/WAVTools.cpp"
-Import "openmpt/soundlib/WindowedFIR.cpp"
-Import "openmpt/soundlib/XMTools.cpp"
-
-Import "openmpt/soundlib/plugins/DigiBoosterEcho.cpp"
-Import "openmpt/soundlib/plugins/LFOPlugin.cpp"
-Import "openmpt/soundlib/plugins/PluginManager.cpp"
-Import "openmpt/soundlib/plugins/PlugInterface.cpp"
-
-Import "openmpt/soundlib/plugins/dmo/Chorus.cpp"
-Import "openmpt/soundlib/plugins/dmo/Compressor.cpp"
-Import "openmpt/soundlib/plugins/dmo/Distortion.cpp"
-Import "openmpt/soundlib/plugins/dmo/DMOPlugin.cpp"
-Import "openmpt/soundlib/plugins/dmo/Echo.cpp"
-Import "openmpt/soundlib/plugins/dmo/Flanger.cpp"
-Import "openmpt/soundlib/plugins/dmo/Gargle.cpp"
-Import "openmpt/soundlib/plugins/dmo/I3DL2Reverb.cpp"
-Import "openmpt/soundlib/plugins/dmo/ParamEq.cpp"
-Import "openmpt/soundlib/plugins/dmo/WavesReverb.cpp"

+ 0 - 26
libopenmpt.mod/openmpt/LICENSE

@@ -1,26 +0,0 @@
-Copyright (c) 2004-2019, OpenMPT contributors
-Copyright (c) 1997-2003, Olivier Lapicque
-All rights reserved.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are met:
-    * Redistributions of source code must retain the above copyright
-      notice, this list of conditions and the following disclaimer.
-    * Redistributions in binary form must reproduce the above copyright
-      notice, this list of conditions and the following disclaimer in the
-      documentation and/or other materials provided with the distribution.
-    * Neither the name of the OpenMPT project nor the
-      names of its contributors may be used to endorse or promote products
-      derived from this software without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE CONTRIBUTORS ``AS IS'' AND ANY
-EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
-DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
-DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
-(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
-LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
-ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
-SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-

+ 0 - 296
libopenmpt.mod/openmpt/README.md

@@ -1,296 +0,0 @@
-
-README
-======
-
-
-OpenMPT and libopenmpt
-======================
-
-This repository contains OpenMPT, a free Windows/Wine-based
-[tracker](https://en.wikipedia.org/wiki/Music_tracker) and libopenmpt,
-a library to render tracker music (MOD, XM, S3M, IT MPTM and dozens of other
-legacy formats) to a PCM audio stream. libopenmpt is directly based on OpenMPT,
-offering the same playback quality and format support, and development of the
-two happens in parallel.
-
-
-License
--------
-
-The OpenMPT/libopenmpt project is distributed under the *BSD-3-Clause* License.
-See [LICENSE](LICENSE) for the full license text.
-
-Files below the `include/` (external projects) and `contrib/` (related assets
-not directly considered integral part of the project) folders may be subject to
-other licenses. See the respective subfolders for license information. These
-folders are not distributed in all source packages, and in particular they are
-not distributed in the Autotools packages.
-
-
-How to compile
---------------
-
-
-### OpenMPT
-
- -  Supported Visual Studio versions:
-
-     -  Visual Studio 2017 and 2019 Community/Professional/Enterprise
-
-        To compile the project, open `build/vsVERSIONwin7/OpenMPT.sln` (VERSION
-        being 2017 or 2019) and hit the compile button. Other target systems can
-        be found in the `vs2017*` and `vs2019*` sibling folders.
-
- -  OpenMPT requires the compile host system to be 64bit x86-64.
-
- -  The Windows 8.1 SDK is required to build OpenMPT with Visual Studio 2017
-    (this is included with Visual Studio, however may need to be selected
-    explicitly during setup).
-
- -  Microsoft Foundation Classes (MFC) are required to build OpenMPT.
-
- -  The ASIO SDK is needed for compiling with ASIO support.
-
-    If you don't want this, comment out `#define MPT_WITH_ASIO` in the file
-    `common/BuildSettings.h`.
-
-    The ASIO SDK can be downloaded automatically on Windows 7 or later by just
-    running the `build/download_externals.cmd` script.
-
-    If you do not want to or cannot use this script, you may follow these manual
-    steps instead:
-
-     -  Visit
-        [steinberg.net](https://www.steinberg.net/en/company/developers.html) to
-        download the SDK.
-
-     -  Put the ASIO SDK in the `include/ASIOSDK2` folder. The top level
-        directory of the SDK is already named `ASIOSDK2`, so simply move that
-        directory in the include folder.
-
-    If you need further help with the ASIO SDK, get in touch with the
-    main OpenMPT developers. 
-
-
-### libopenmpt and openmpt123
-
-For detailed requirements, see `libopenmpt/dox/quickstart.md`.
-
- -  Autotools
-
-    Grab a `libopenmpt-VERSION-autotools.tar.gz` tarball.
-
-        ./configure
-        make
-        make check
-        sudo make install
-
-    Cross-compilation is generally supported (although only tested for
-    targetting MinGW-w64).
-
-    Note that some MinGW-w64 distributions come with the `win32` threading model
-    enabled by default instead of the `posix` threading model. The `win32`
-    threading model lacks proper support for C++11 `<thread>` and `<mutex>` as
-    well as thread-safe magic statics. It is recommended to use the `posix`
-    threading model for libopenmpt for this reason. On Debian, the appropriate
-    configure command is
-    `./configure --host=x86_64-w64-mingw32 CC=x86_64-w64-mingw32-gcc-posix CXX=x86_64-w64-mingw32-g++-posix`
-    for 64bit, or
-    `./configure --host=i686-w64-mingw32 CC=i686-w64-mingw32-gcc-posix CXX=i686-w64-mingw32-g++-posix`
-    for 32bit. Other MinGW-w64 distributions may differ.
-
- -  Visual Studio:
-
-     -  You will find solutions for Visual Studio 2017 and 2019 in the
-        corresponding `build/vsVERSIONwin7/` folder.
-        Projects that target Windows versions before Windows 7 are available in
-        `build/vsVERSIONwinxp/`.
-        Projects that target Windows 10 1709 Desktop (10.0.16299.0, including
-        ARM and ARM64) or later versions are available in
-        `build/vsVERSIONwin10/`.
-        Minimal projects that target Windows 10 UWP are available in
-        `build/vsVERSIONuwp/`.
-        Most projects are supported with any of the mentioned Visual Studio
-        verions, with the following exceptions:
-
-         -  in_openmpt: Requires Visual Studio with MFC.
-
-         -  xmp-openmpt: Requires Visual Studio with MFC.
-
-     -  libopenmpt requires the compile host system to be 64bit x86-64 when
-        building with Visual Studio.
-
-     -  You will need the Winamp 5 SDK and the XMPlay SDK if you want to
-        compile the plugins for these 2 players. They can be downloaded
-        automatically on Windows 7 or later by just running the
-        `build/download_externals.cmd` script.
-
-        If you do not want to or cannot use this script, you may follow these
-        manual steps instead:
-
-         -  Winamp 5 SDK:
-
-            To build libopenmpt as a winamp input plugin, copy the contents of
-            `WA5.55_SDK.exe` to include/winamp/.
-
-            Please visit
-            [winamp.com](http://wiki.winamp.com/wiki/Plug-in_Developer) to
-            download the SDK.
-            You can disable in_openmpt in the solution configuration.
-
-         -  XMPlay SDK:
-
-            To build libopenmpt with XMPlay input plugin support, copy the
-            contents of xmp-sdk.zip into include/xmplay/.
-
-            Please visit [un4seen.com](https://www.un4seen.com/xmplay.html) to
-            download the SDK.
-            You can disable xmp-openmpt in the solution configuration.
-
- -  Makefile
-
-    The makefile supports different build environments and targets via the
-    `CONFIG=` parameter directly to the make invocation.
-    Use `make CONFIG=$newconfig clean` when switching between different configs
-    because the makefile cleans only intermediates and target that are active
-    for the current config and no configuration state is kept around across
-    invocations.
-
-     -  mingw-w64:
-
-        The required compiler version is at least GCC 5.
-
-            make CONFIG=mingw64-win32    # for win32
-
-            make CONFIG=mingw64-win64    # for win64
-
-     -  gcc or clang (on Unix-like systems, including Mac OS X with MacPorts,
-        and Haiku (32-bit Hybrid and 64-bit)):
-
-        The minimum required compiler versions are:
-
-         -  gcc 7
-
-         -  clang 5
-
-        The Makefile requires pkg-config for native builds.
-        For sound output in openmpt123, PortAudio or SDL is required.
-        openmpt123 can optionally use libflac and libsndfile to render PCM
-        files to disk.
-
-        When using gcc, run:
-
-            make CONFIG=gcc
-
-        When using clang, it is recommended to do:
-
-            make CONFIG=clang
-
-        Otherwise, simply run
-
-            make
-
-        which will try to guess the compiler based on your operating system.
-
-     -  emscripten (on Unix-like systems):
-
-        libopenmpt has been tested and verified to work with emscripten 1.38.5
-        or later. Earlier versions are not supported.
-
-        Run:
-
-            # generates WebAssembly with dynamic heap growth
-            make CONFIG=emscripten EMSCRIPTEN_TARGET=wasm
-
-        or
-
-            # generates asm.js with a fixed size 128MB heap
-            make CONFIG=emscripten EMSCRIPTEN_TARGET=asmjs128m
-
-        or
-
-            # generates asm.js with a fixed default size heap (as of Emscripten
-            # 1.38.11, this amounts to 16MB)
-            make CONFIG=emscripten EMSCRIPTEN_TARGET=asmjs
-
-        or
-
-            # generates JavaScript with dynamic heap growth and with
-            # compatibility for older VMs
-            make CONFIG=emscripten EMSCRIPTEN_TARGET=js
-
-        Running the test suite on the command line is also supported by using
-        node.js. Version 8.9.1 or greater has been tested. Earlier versions
-        might or might not work. Depending on how your distribution calls the
-        `node.js` binary, you might have to edit
-        `build/make/config-emscripten.mk`.
-
-     -  DJGPP / DOS
-
-        Cross-compilation from Linux systems is supported with DJGPP GCC 7.2 or
-        later via
-
-            make CONFIG=djgpp
-
-        `openmpt123` can use liballegro 4.2 for sound output on DJGPP/DOS.
-        liballegro can either be installed system-wide in the DJGPP environment
-        or downloaded into the `libopenmpt` source tree.
-
-            make CONFIG=djgpp USE_ALLEGRO42=1    # use installed liballegro
-
-        or
-
-            ./build/download_externals.sh    # download liballegro binaries
-            make CONFIG=djgpp USE_ALLEGRO42=1 BUNDLED_ALLEGRO42=1
-
-     -  American Fuzzy Lop:
-
-        To compile libopenmpt with fuzzing instrumentation for afl-fuzz, run:
-        
-            make CONFIG=afl
-        
-        For more detailed instructions, read `contrib/fuzzing/readme.md`.
-
-     -  other compilers:
-
-        To compile libopenmpt with other C++14 compliant compilers, run:
-        
-            make CONFIG=generic
-        
-    
-    The `Makefile` supports some customizations. You might want to read the top
-    which should get you some possible make settings, like e.g.
-    `make DYNLINK=0` or similar. Cross compiling or different compiler would
-    best be implemented via new `config-*.mk` files.
-
-    The `Makefile` also supports building doxygen documentation by using
-
-        make doc
-
-    Binaries and documentation can be installed systen-wide with
-
-        make PREFIX=/yourprefix install
-        make PREFIX=/yourprefix install-doc
-
-    Some systems (i.e. Linux) require running
-
-        sudo ldconfig
-
-    in order for the system linker to be able to pick up newly installed
-    libraries.
-
-    `PREFIX` defaults to `/usr/local`. A `DESTDIR=` parameter is also
-    supported.
-
- -  Android NDK
-
-    See `build/android_ndk/README.AndroidNDK.txt`.
-
-
-
-Contributing to OpenMPT/libopenmpt
-----------------------------------
-
-
-See [contributing](doc/contributing.md).
-

+ 0 - 21
libopenmpt.mod/openmpt/build/svn_version/svn_version.h

@@ -1,21 +0,0 @@
-
-#pragma once
-
-#if defined(MPT_PACKAGE)
-#define OPENMPT_VERSION_IS_PACKAGE 1
-#else
-#define OPENMPT_VERSION_IS_PACKAGE 0
-#endif
-
-#if defined(MPT_SVNURL)
-#define OPENMPT_VERSION_URL MPT_SVNURL
-#endif
-
-#if defined(MPT_SVNVERSION)
-#define OPENMPT_VERSION_SVNVERSION MPT_SVNVERSION
-#endif
-
-#if defined(MPT_SVNDATE)
-#define OPENMPT_VERSION_DATE MPT_SVNDATE
-#endif
-

+ 0 - 14
libopenmpt.mod/openmpt/build/svn_version/svn_version.template.subwcrev.h

@@ -1,14 +0,0 @@
-
-#pragma once
-
-#define OPENMPT_VERSION_URL "$WCURL$"
-#define OPENMPT_VERSION_SVNVERSION "$WCRANGE$$WCMODS?M:$"
-#define OPENMPT_VERSION_DATE "$WCDATEUTC=%Y-%m-%dT%H:%M:%S$Z"
-
-#define OPENMPT_VERSION_REVISION $WCREV$
-#define OPENMPT_VERSION_DIRTY $WCMODS?1:0$
-#define OPENMPT_VERSION_MIXEDREVISIONS $WCMIXED?1:0$
-
-#define OPENMPT_VERSION_IS_PACKAGE 0
-
-#define OPENMPT_BUILD_DATE "$WCNOW=%Y-%m-%d %H:%M:%S$"

+ 0 - 6
libopenmpt.mod/openmpt/build/svn_version/update_svn_version_vs_premake.cmd

@@ -1,6 +0,0 @@
-@echo off
-set INTDIR=%1%
-if not exist %INTDIR% mkdir %INTDIR%
-if not exist %INTDIR%\svn_version mkdir %INTDIR%\svn_version
-subwcrev ..\.. ..\..\build\svn_version\svn_version.template.subwcrev.h %INTDIR%\svn_version\svn_version.h || del %INTDIR%\svn_version\svn_version.h || exit 0
-exit 0

+ 0 - 718
libopenmpt.mod/openmpt/common/BuildSettings.h

@@ -1,718 +0,0 @@
-/*
- * BuildSettings.h
- * ---------------
- * Purpose: Global, user settable compile time flags (and some global system header configuration)
- * Notes  : (currently none)
- * Authors: OpenMPT Devs
- * The OpenMPT source code is released under the BSD license. Read LICENSE for more details.
- */
-
-
-#pragma once
-
-
-
-#include "CompilerDetect.h"
-
-
-
-// set windows version early so that we can deduce dependencies from SDK version
-
-#if MPT_OS_WINDOWS
-
-#ifndef _WIN32_WINNT
-#define _WIN32_WINNT 0x0601 // _WIN32_WINNT_WIN7
-#endif
-
-#ifndef WINVER
-#define WINVER       _WIN32_WINNT
-#endif
-
-#endif // MPT_OS_WINDOWS
-
-
-
-#if defined(MODPLUG_TRACKER) && defined(LIBOPENMPT_BUILD)
-#error "either MODPLUG_TRACKER or LIBOPENMPT_BUILD has to be defined"
-#elif defined(MODPLUG_TRACKER)
-// nothing
-#elif defined(LIBOPENMPT_BUILD)
-// nothing
-#else
-#error "either MODPLUG_TRACKER or LIBOPENMPT_BUILD has to be defined"
-#endif // MODPLUG_TRACKER || LIBOPENMPT_BUILD
-
-
-
-// wrapper for autoconf macros
-
-#if defined(HAVE_CONFIG_H)
-
-#include "config.h"
-
-// Fixup dependencies which are currently not used in libopenmpt itself
-#ifdef MPT_WITH_FLAC
-#undef MPT_WITH_FLAC
-#endif
-
-#endif // HAVE_CONFIG_H
-
-
-
-// Dependencies from the MSVC build system
-#if defined(MPT_BUILD_MSVC)
-
-// This section defines which dependencies are available when building with
-// MSVC. Other build systems provide MPT_WITH_* macros via command-line or other
-// means.
-// OpenMPT and libopenmpt should compile and run successfully (albeit with
-// reduced functionality) with any or all dependencies missing/disabled.
-// The defaults match the bundled third-party libraries with the addition of
-// ASIO and VST SDKs.
-
-#if defined(MODPLUG_TRACKER)
-
-// OpenMPT-only dependencies
-#define MPT_WITH_ASIO
-#define MPT_WITH_DMO
-#define MPT_WITH_LAME
-#define MPT_WITH_LHASA
-#define MPT_WITH_MINIZIP
-#define MPT_WITH_NLOHMANNJSON
-#define MPT_WITH_OPUS
-#define MPT_WITH_OPUSENC
-#define MPT_WITH_OPUSFILE
-#define MPT_WITH_PORTAUDIO
-//#define MPT_WITH_PULSEAUDIO
-//#define MPT_WITH_PULSEAUDIOSIMPLE
-#define MPT_WITH_RTAUDIO
-#define MPT_WITH_SMBPITCHSHIFT
-#define MPT_WITH_UNRAR
-#define MPT_WITH_VORBISENC
-
-// OpenMPT and libopenmpt dependencies (not for openmp123, player plugins or examples)
-//#define MPT_WITH_DL
-#define MPT_WITH_FLAC
-//#define MPT_WITH_LTDL
-#if MPT_OS_WINDOWS
-#define MPT_WITH_MEDIAFOUNDATION
-#endif
-//#define MPT_WITH_MINIMP3
-//#define MPT_WITH_MINIZ
-#define MPT_WITH_MPG123
-#define MPT_WITH_OGG
-//#define MPT_WITH_STBVORBIS
-#define MPT_WITH_VORBIS
-#define MPT_WITH_VORBISFILE
-#if MPT_OS_WINDOWS
-#if (_WIN32_WINNT >= 0x0A00)
-#define MPT_WITH_WINDOWS10
-#endif
-#endif
-#define MPT_WITH_ZLIB
-
-#endif // MODPLUG_TRACKER
-
-#if defined(LIBOPENMPT_BUILD)
-
-// OpenMPT and libopenmpt dependencies (not for openmp123, player plugins or examples)
-#if defined(LIBOPENMPT_BUILD_FULL) && defined(LIBOPENMPT_BUILD_SMALL)
-#error "only one of LIBOPENMPT_BUILD_FULL or LIBOPENMPT_BUILD_SMALL can be defined"
-#endif // LIBOPENMPT_BUILD_FULL && LIBOPENMPT_BUILD_SMALL
-
-#if defined(LIBOPENMPT_BUILD_SMALL)
-
-//#define MPT_WITH_DL
-//#define MPT_WITH_FLAC
-//#define MPT_WITH_LTDL
-//#define MPT_WITH_MEDIAFOUNDATION
-#define MPT_WITH_MINIMP3
-#define MPT_WITH_MINIZ
-//#define MPT_WITH_MPG123
-//#define MPT_WITH_OGG
-#define MPT_WITH_STBVORBIS
-//#define MPT_WITH_VORBIS
-//#define MPT_WITH_VORBISFILE
-//#define MPT_WITH_ZLIB
-
-#else // !LIBOPENMPT_BUILD_SMALL
-
-//#define MPT_WITH_DL
-//#define MPT_WITH_FLAC
-//#define MPT_WITH_LTDL
-//#define MPT_WITH_MEDIAFOUNDATION
-//#define MPT_WITH_MINIMP3
-//#define MPT_WITH_MINIZ
-#define MPT_WITH_MPG123
-#define MPT_WITH_OGG
-//#define MPT_WITH_STBVORBIS
-#define MPT_WITH_VORBIS
-#define MPT_WITH_VORBISFILE
-#define MPT_WITH_ZLIB
-
-#endif // LIBOPENMPT_BUILD_SMALL
-
-#endif // LIBOPENMPT_BUILD
-
-#endif // MPT_BUILD_MSVC
-
-
-#if defined(MPT_BUILD_XCODE)
-
-#if defined(MODPLUG_TRACKER)
-
-// n/a
-
-#endif // MODPLUG_TRACKER
-
-#if defined(LIBOPENMPT_BUILD)
-
-//#define MPT_WITH_DL
-//#define MPT_WITH_FLAC
-//#define MPT_WITH_LTDL
-//#define MPT_WITH_MEDIAFOUNDATION
-//#define MPT_WITH_MINIMP3
-//#define MPT_WITH_MINIZ
-#define MPT_WITH_MPG123
-#define MPT_WITH_OGG
-//#define MPT_WITH_STBVORBIS
-#define MPT_WITH_VORBIS
-#define MPT_WITH_VORBISFILE
-#define MPT_WITH_ZLIB
-
-#endif // LIBOPENMPT_BUILD
-
-#endif // MPT_BUILD_XCODE
-
-
-
-#if defined(MODPLUG_TRACKER)
-
-// Enable built-in test suite.
-#if defined(MPT_BUILD_DEBUG) || defined(MPT_BUILD_CHECKED)
-#define ENABLE_TESTS
-#endif
-
-// Disable any file saving functionality (not really useful except for the player library)
-//#define MODPLUG_NO_FILESAVE
-
-// Disable any debug logging
-//#define NO_LOGGING
-#if !defined(MPT_BUILD_DEBUG) && !defined(MPT_BUILD_CHECKED) && !defined(MPT_BUILD_WINESUPPORT)
-#define MPT_LOG_GLOBAL_LEVEL_STATIC
-#define MPT_LOG_GLOBAL_LEVEL 0
-#endif
-
-// Enable all individual logging macros and MPT_LOG calls
-//#define MPT_ALL_LOGGING
-
-// Disable all runtime asserts
-#if !defined(MPT_BUILD_DEBUG) && !defined(MPT_BUILD_CHECKED) && !defined(MPT_BUILD_WINESUPPORT)
-#define NO_ASSERTS
-#endif
-
-// Enable callback stream wrapper for FileReader (required by libopenmpt C API).
-//#define MPT_FILEREADER_CALLBACK_STREAM
-
-// Support for externally linked samples e.g. in MPTM files
-#define MPT_EXTERNAL_SAMPLES
-
-// Support mpt::ChartsetLocale
-#define MPT_ENABLE_CHARSET_LOCALE
-
-// Use inline assembly
-#define ENABLE_ASM
-
-// Disable unarchiving support
-//#define NO_ARCHIVE_SUPPORT
-
-// Disable the built-in reverb effect
-//#define NO_REVERB
-
-// Disable built-in miscellaneous DSP effects (surround, mega bass, noise reduction)
-//#define NO_DSP
-
-// Disable the built-in equalizer.
-//#define NO_EQ
-
-// Disable the built-in automatic gain control
-//#define NO_AGC
-
-// Define to build without VST plugin support; makes build possible without VST SDK.
-//#define NO_VST
-
-// (HACK) Define to build without any plugin support
-//#define NO_PLUGINS
-
-// Do not build libopenmpt C api
-#define NO_LIBOPENMPT_C
-
-// Do not build libopenmpt C++ api
-#define NO_LIBOPENMPT_CXX
-
-#endif // MODPLUG_TRACKER
-
-
-
-#if defined(LIBOPENMPT_BUILD)
-
-#if (defined(_DEBUG) || defined(DEBUG)) && !defined(MPT_BUILD_DEBUG)
-#define MPT_BUILD_DEBUG
-#endif
-
-#if defined(LIBOPENMPT_BUILD_TEST)
-#define ENABLE_TESTS
-#else
-#define MODPLUG_NO_FILESAVE
-#endif
-#if defined(MPT_BUILD_ANALZYED) || defined(MPT_BUILD_DEBUG) || defined(MPT_BUILD_CHECKED) || defined(ENABLE_TESTS)
-// enable asserts
-#else
-#define NO_ASSERTS
-#endif
-//#define NO_LOGGING
-//#define MPT_ALL_LOGGING
-#define MPT_FILEREADER_CALLBACK_STREAM
-//#define MPT_EXTERNAL_SAMPLES
-#if defined(ENABLE_TESTS) || defined(MPT_BUILD_HACK_ARCHIVE_SUPPORT)
-#define MPT_ENABLE_CHARSET_LOCALE
-#else
-//#define MPT_ENABLE_CHARSET_LOCALE
-#endif
-// Do not use inline asm in library builds. There is just about no codepath which would use it anyway.
-//#define ENABLE_ASM
-#if defined(MPT_BUILD_HACK_ARCHIVE_SUPPORT)
-//#define NO_ARCHIVE_SUPPORT
-#else
-#define NO_ARCHIVE_SUPPORT
-#endif
-//#define NO_REVERB
-#define NO_DSP
-#define NO_EQ
-#define NO_AGC
-#define NO_VST
-//#define NO_PLUGINS
-//#define NO_LIBOPENMPT_C
-//#define NO_LIBOPENMPT_CXX
-
-#endif // LIBOPENMPT_BUILD
-
-
-
-#if MPT_OS_WINDOWS
-
-	#ifndef MPT_ENABLE_CHARSET_LOCALE
-	#define MPT_ENABLE_CHARSET_LOCALE
-	#endif
-
-#elif MPT_OS_LINUX
-
-#elif MPT_OS_ANDROID
-
-#elif MPT_OS_EMSCRIPTEN
-
-	#ifndef MPT_LOCALE_ASSUME_CHARSET
-	#define MPT_LOCALE_ASSUME_CHARSET Charset::UTF8
-	#endif
-
-#elif MPT_OS_MACOSX_OR_IOS
-
-#elif MPT_OS_DJGPP
-
-	#ifndef MPT_LOCALE_ASSUME_CHARSET
-	#define MPT_LOCALE_ASSUME_CHARSET Charset::CP437
-	#endif
-
-#endif
-
-
-
-#if MPT_COMPILER_MSVC && !defined(MPT_USTRING_MODE_UTF8_FORCE)
-
-	// Use wide strings for MSVC because this is the native encoding on 
-	// microsoft platforms.
-	#define MPT_USTRING_MODE_WIDE 1
-	#define MPT_USTRING_MODE_UTF8 0
-
-#else // !MPT_COMPILER_MSVC
-
-	#define MPT_USTRING_MODE_WIDE 0
-	#define MPT_USTRING_MODE_UTF8 1
-
-#endif // MPT_COMPILER_MSVC
-
-#if MPT_USTRING_MODE_UTF8
-
-	// MPT_USTRING_MODE_UTF8 mpt::ustring is implemented via mpt::u8string
-	#define MPT_ENABLE_U8STRING 1
-
-#else
-
-	#define MPT_ENABLE_U8STRING 0
-
-#endif
-
-#if defined(MODPLUG_TRACKER) || MPT_USTRING_MODE_WIDE
-
-	// mpt::ToWString, mpt::wfmt, ConvertStrTo<std::wstring>
-	// Required by the tracker to ease interfacing with WinAPI.
-	// Required by MPT_USTRING_MODE_WIDE to ease type tunneling in mpt::format.
-	#define MPT_WSTRING_FORMAT 1
-
-#else
-
-	#define MPT_WSTRING_FORMAT 0
-
-#endif
-
-#if MPT_OS_WINDOWS || MPT_USTRING_MODE_WIDE || MPT_WSTRING_FORMAT
-
-	// mpt::ToWide
-	// Required on Windows by mpt::PathString.
-	// Required by MPT_USTRING_MODE_WIDE as they share the conversion functions.
-	// Required by MPT_WSTRING_FORMAT because of std::string<->std::wstring conversion in mpt::ToString and mpt::ToWString.
-	#define MPT_WSTRING_CONVERT 1
-
-#else
-
-	#define MPT_WSTRING_CONVERT 0
-
-#endif
-
-
-
-// fixing stuff up
-
-#if defined(MPT_BUILD_ANALYZED) || defined(MPT_BUILD_CHECKED) 
-#ifdef NO_ASSERTS
-#undef NO_ASSERTS // static or dynamic analyzers want assertions on
-#endif
-#endif
-
-#if defined(MPT_BUILD_FUZZER)
-#ifndef MPT_FUZZ_TRACKER
-#define MPT_FUZZ_TRACKER
-#endif
-#endif
-
-#if !MPT_COMPILER_MSVC && defined(ENABLE_ASM)
-#undef ENABLE_ASM // inline assembly requires MSVC compiler
-#endif
-
-#if defined(ENABLE_ASM)
-#if MPT_COMPILER_MSVC && defined(_M_IX86)
-
-#define ENABLE_CPUID
-// Generate general x86 inline assembly and intrinsics.
-#define ENABLE_X86
-// Generate MMX instructions (only used when the CPU supports it).
-#define ENABLE_MMX
-// Generate SSE instructions (only used when the CPU supports it).
-#define ENABLE_SSE
-// Generate SSE2 instructions (only used when the CPU supports it).
-#define ENABLE_SSE2
-// Generate SSE3 instructions (only used when the CPU supports it).
-#define ENABLE_SSE3
-// Generate SSE4 instructions (only used when the CPU supports it).
-#define ENABLE_SSE4
-// Generate AVX instructions (only used when the CPU supports it).
-#define ENABLE_AVX
-// Generate AVX2 instructions (only used when the CPU supports it).
-#define ENABLE_AVX2
-
-#elif MPT_COMPILER_MSVC && defined(_M_X64)
-
-#define ENABLE_CPUID
-// Generate general x64 intrinsics.
-#define ENABLE_X64
-// Generate SSE instructions (only used when the CPU supports it).
-#define ENABLE_SSE
-// Generate SSE2 instructions (only used when the CPU supports it).
-#define ENABLE_SSE2
-// Generate SSE3 instructions (only used when the CPU supports it).
-#define ENABLE_SSE3
-// Generate SSE4 instructions (only used when the CPU supports it).
-#define ENABLE_SSE4
-// Generate AVX instructions (only used when the CPU supports it).
-#define ENABLE_AVX
-// Generate AVX2 instructions (only used when the CPU supports it).
-#define ENABLE_AVX2
-
-#endif // arch
-#endif // ENABLE_ASM
-
-#if defined(ENABLE_TESTS) && defined(MODPLUG_NO_FILESAVE)
-#undef MODPLUG_NO_FILESAVE // tests recommend file saving
-#endif
-
-#if defined(MPT_WITH_ZLIB) && defined(MPT_WITH_MINIZ)
-// Only one deflate implementation should be used. Prefer zlib.
-#undef MPT_WITH_MINIZ
-#endif
-
-#if !MPT_OS_WINDOWS && defined(MPT_WITH_MEDIAFOUNDATION)
-#undef MPT_WITH_MEDIAFOUNDATION // MediaFoundation requires Windows
-#endif
-
-#if !MPT_COMPILER_MSVC && !MPT_COMPILER_CLANG && defined(MPT_WITH_MEDIAFOUNDATION)
-#undef MPT_WITH_MEDIAFOUNDATION // MediaFoundation requires MSVC or Clang due to ATL (no MinGW support)
-#endif
-
-#if defined(MPT_WITH_MEDIAFOUNDATION) && !defined(MPT_ENABLE_TEMPFILE)
-#define MPT_ENABLE_TEMPFILE
-#endif
-
-#if defined(MODPLUG_TRACKER) && !defined(MPT_ENABLE_TEMPFILE)
-#define MPT_ENABLE_TEMPFILE
-#endif
-
-#if defined(MODPLUG_TRACKER) && !defined(MPT_ENABLE_DYNBIND)
-#define MPT_ENABLE_DYNBIND // Tracker requires dynamic library loading for export codecs
-#endif
-
-#if defined(MPT_WITH_MEDIAFOUNDATION) && !defined(MPT_ENABLE_DYNBIND)
-#define MPT_ENABLE_DYNBIND // MediaFoundation needs dynamic loading in order to test availability of delay loaded libs
-#endif
-
-#if (defined(MPT_WITH_MPG123) || defined(MPT_WITH_MINIMP3)) && !defined(MPT_ENABLE_MP3_SAMPLES)
-#define MPT_ENABLE_MP3_SAMPLES
-#endif
-
-#if defined(ENABLE_TESTS)
-#define MPT_ENABLE_FILEIO // Test suite requires PathString for file loading.
-#endif
-
-#if defined(MODPLUG_TRACKER) && !defined(MPT_ENABLE_FILEIO)
-#define MPT_ENABLE_FILEIO // Tracker requires disk file io
-#endif
-
-#if defined(MODPLUG_TRACKER) && !defined(MPT_ENABLE_THREAD)
-#define MPT_ENABLE_THREAD // Tracker requires threads
-#endif
-
-#if defined(MPT_EXTERNAL_SAMPLES) && !defined(MPT_ENABLE_FILEIO)
-#define MPT_ENABLE_FILEIO // External samples require disk file io
-#endif
-
-#if defined(NO_PLUGINS)
-// Any plugin type requires NO_PLUGINS to not be defined.
-#define NO_VST
-#endif
-
-#if defined(ENABLE_ASM) || !defined(NO_VST)
-#define MPT_ENABLE_ALIGNED_ALLOC
-#endif
-
-
-
-#if defined(MODPLUG_TRACKER) && !defined(MPT_BUILD_WINESUPPORT) && !defined(MPT_BUILD_WINESUPPORT_WRAPPER)
-#ifndef MPT_NO_NAMESPACE
-#define MPT_NO_NAMESPACE
-#endif
-#endif
-
-#if defined(MPT_NO_NAMESPACE)
-
-#ifdef OPENMPT_NAMESPACE
-#undef OPENMPT_NAMESPACE
-#endif
-#define OPENMPT_NAMESPACE
-
-#ifdef OPENMPT_NAMESPACE_BEGIN
-#undef OPENMPT_NAMESPACE_BEGIN
-#endif
-#define OPENMPT_NAMESPACE_BEGIN
-
-#ifdef OPENMPT_NAMESPACE_END
-#undef OPENMPT_NAMESPACE_END
-#endif
-#define OPENMPT_NAMESPACE_END
-
-#else
-
-#ifndef OPENMPT_NAMESPACE
-#define OPENMPT_NAMESPACE OpenMPT
-#endif
-
-#ifndef OPENMPT_NAMESPACE_BEGIN
-#define OPENMPT_NAMESPACE_BEGIN namespace OPENMPT_NAMESPACE {
-#endif
-#ifndef OPENMPT_NAMESPACE_END
-#define OPENMPT_NAMESPACE_END   }
-#endif
-
-#endif
-
-
-
-// platform configuration
-
-#if defined(MODPLUG_TRACKER)
-#if MPT_OS_WINDOWS
-#if !defined(MPT_BUILD_WINESUPPORT)
-#ifndef MPT_MFC_FULL
-#define _AFX_NO_MFC_CONTROLS_IN_DIALOGS	// Do not include support for MFC controls in dialogs (reduces binary bloat; remove this #define if you want to use MFC controls)
-#endif // !MPT_MFC_FULL
-#endif // !MPT_BUILD_WINESUPPORT
-#endif // MPT_OS_WINDOWS
-#endif // MODPLUG_TRACKER
-
-#if MPT_OS_WINDOWS
-
-#define WIN32_LEAN_AND_MEAN
-
-// windows.h excludes
-#define NOMEMMGR          // GMEM_*, LMEM_*, GHND, LHND, associated routines
-#define NOMINMAX          // Macros min(a,b) and max(a,b)
-#define NOSERVICE         // All Service Controller routines, SERVICE_ equates, etc.
-#define NOCOMM            // COMM driver routines
-#define NOKANJI           // Kanji support stuff.
-#define NOPROFILER        // Profiler interface.
-#define NOMCX             // Modem Configuration Extensions
-
-// mmsystem.h excludes
-#define MMNODRV
-//#define MMNOSOUND
-//#define MMNOWAVE
-//#define MMNOMIDI
-#define MMNOAUX
-#define MMNOMIXER
-//#define MMNOTIMER
-#define MMNOJOY
-#define MMNOMCI
-//#define MMNOMMIO
-//#define MMNOMMSYSTEM
-
-// mmreg.h excludes
-#define NOMMIDS
-//#define NONEWWAVE
-#define NONEWRIFF
-#define NOJPEGDIB
-#define NONEWIC
-#define NOBITMAP
-
-#endif // MPT_OS_WINDOWS
-
-
-
-// stdlib configuration
-
-#if MPT_COMPILER_CLANG
-#pragma clang diagnostic push
-#pragma clang diagnostic ignored "-Wreserved-id-macro"
-#endif
-
-#define __STDC_CONSTANT_MACROS
-#define __STDC_LIMIT_MACROS
-
-#define _USE_MATH_DEFINES
-
-#ifndef _FILE_OFFSET_BITS
-#define _FILE_OFFSET_BITS 64
-#endif
-
-#if MPT_COMPILER_CLANG
-#pragma clang diagnostic pop
-#endif
-
-
-
-// compiler configuration
-
-#if MPT_COMPILER_MSVC
-
-#define VC_EXTRALEAN		// Exclude rarely-used stuff from Windows headers
-
-#ifndef _CRT_SECURE_NO_WARNINGS
-#define _CRT_SECURE_NO_WARNINGS		// Define to disable the "This function or variable may be unsafe" warnings.
-#endif
-#define _CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES			1
-#define _CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES_COUNT	1
-#ifndef _SCL_SECURE_NO_WARNINGS
-#define _SCL_SECURE_NO_WARNINGS
-#endif
-
-#ifndef NO_WARN_MBCS_MFC_DEPRECATION
-#define NO_WARN_MBCS_MFC_DEPRECATION
-#endif
-
-#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.
-
-#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: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_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
-
-
-
-
-
-// standard library quirks
-
-
-
-
-
-// third-party library configuration
-
-#if defined(MODPLUG_TRACKER)
-//#define MPT_MFC_FULL  // use full MFC, including MFC controls
-#endif
-
-#ifdef MPT_WITH_FLAC
-#ifdef MPT_BUILD_MSVC_STATIC
-#define FLAC__NO_DLL
-#endif
-#endif
-
-#ifdef MPT_WITH_SMBPITCHSHIFT
-#ifdef MPT_BUILD_MSVC_SHARED
-#define SMBPITCHSHIFT_USE_DLL
-#endif
-#endif
-
-#ifdef MPT_WITH_STBVORBIS
-#define STB_VORBIS_HEADER_ONLY
-#ifndef STB_VORBIS_NO_PULLDATA_API
-#define STB_VORBIS_NO_PULLDATA_API
-#endif
-#ifndef STB_VORBIS_NO_STDIO
-#define STB_VORBIS_NO_STDIO
-#endif
-#endif
-
-#ifdef MPT_WITH_VORBISFILE
-#ifndef OV_EXCLUDE_STATIC_CALLBACKS
-#define OV_EXCLUDE_STATIC_CALLBACKS
-#endif
-#endif
-
-#ifdef MPT_WITH_ZLIB
-#ifdef MPT_BUILD_MSVC_SHARED
-#define ZLIB_DLL
-#endif
-#endif
-

+ 0 - 358
libopenmpt.mod/openmpt/common/CompilerDetect.h

@@ -1,358 +0,0 @@
-/*
- * CompilerDetect.h
- * ----------------
- * Purpose: Detect current compiler and provide readable version test macros.
- * Notes  : (currently none)
- * Authors: OpenMPT Devs
- * The OpenMPT source code is released under the BSD license. Read LICENSE for more details.
- */
-
-
-#pragma once
-
-
-
-#define MPT_COMPILER_MAKE_VERSION2(version,sp)              ((version) * 100 + (sp))
-#define MPT_COMPILER_MAKE_VERSION3(major,minor,patch)       ((major) * 10000 + (minor) * 100 + (patch))
-#define MPT_COMPILER_MAKE_VERSION3_BUILD(major,minor,build) ((major) * 10000000 + (minor) * 100000 + (patch))
-
-
-
-#if defined(MPT_COMPILER_GENERIC)
-
-#undef MPT_COMPILER_GENERIC
-#define MPT_COMPILER_GENERIC                         1
-
-#elif defined(__clang__) && defined(_MSC_VER) && defined(__c2__)
-
-#error "Clang/C2 is not supported. Please use Clang/LLVM for Windows instead."
-
-#elif defined(__clang__)
-
-#define MPT_COMPILER_CLANG                           1
-#define MPT_COMPILER_CLANG_VERSION                   MPT_COMPILER_MAKE_VERSION3(__clang_major__,__clang_minor__,__clang_patchlevel__)
-#define MPT_CLANG_AT_LEAST(major,minor,patch)        (MPT_COMPILER_CLANG_VERSION >= MPT_COMPILER_MAKE_VERSION3((major),(minor),(patch)))
-#define MPT_CLANG_BEFORE(major,minor,patch)          (MPT_COMPILER_CLANG_VERSION <  MPT_COMPILER_MAKE_VERSION3((major),(minor),(patch)))
-
-#if MPT_CLANG_BEFORE(5,0,0)
-#error "clang version 5 required"
-#endif
-
-#if defined(__clang_analyzer__)
-#ifndef MPT_BUILD_ANALYZED
-#define MPT_BUILD_ANALYZED
-#endif
-#endif
-
-#elif defined(__GNUC__)
-
-#define MPT_COMPILER_GCC                             1
-#define MPT_COMPILER_GCC_VERSION                     MPT_COMPILER_MAKE_VERSION3(__GNUC__,__GNUC_MINOR__,__GNUC_PATCHLEVEL__)
-#define MPT_GCC_AT_LEAST(major,minor,patch)          (MPT_COMPILER_GCC_VERSION >= MPT_COMPILER_MAKE_VERSION3((major),(minor),(patch)))
-#define MPT_GCC_BEFORE(major,minor,patch)            (MPT_COMPILER_GCC_VERSION <  MPT_COMPILER_MAKE_VERSION3((major),(minor),(patch)))
-
-#if MPT_GCC_BEFORE(7,1,0)
-#error "GCC version 7.1 required"
-#endif
-
-#elif defined(_MSC_VER)
-
-#define MPT_COMPILER_MSVC                            1
-#if (_MSC_VER >= 1923)
-#define MPT_COMPILER_MSVC_VERSION                    MPT_COMPILER_MAKE_VERSION2(2019,3)
-#elif (_MSC_VER >= 1922)
-#define MPT_COMPILER_MSVC_VERSION                    MPT_COMPILER_MAKE_VERSION2(2019,2)
-#elif (_MSC_VER >= 1921)
-#define MPT_COMPILER_MSVC_VERSION                    MPT_COMPILER_MAKE_VERSION2(2019,1)
-#elif (_MSC_VER >= 1920)
-#define MPT_COMPILER_MSVC_VERSION                    MPT_COMPILER_MAKE_VERSION2(2019,0)
-#elif (_MSC_VER >= 1916)
-#define MPT_COMPILER_MSVC_VERSION                    MPT_COMPILER_MAKE_VERSION2(2017,9)
-#elif (_MSC_VER >= 1915)
-#define MPT_COMPILER_MSVC_VERSION                    MPT_COMPILER_MAKE_VERSION2(2017,8)
-#elif (_MSC_VER >= 1914)
-#define MPT_COMPILER_MSVC_VERSION                    MPT_COMPILER_MAKE_VERSION2(2017,7)
-#elif (_MSC_VER >= 1913)
-#define MPT_COMPILER_MSVC_VERSION                    MPT_COMPILER_MAKE_VERSION2(2017,6)
-#elif (_MSC_VER >= 1912)
-#define MPT_COMPILER_MSVC_VERSION                    MPT_COMPILER_MAKE_VERSION2(2017,5)
-#elif (_MSC_VER >= 1911)
-#define MPT_COMPILER_MSVC_VERSION                    MPT_COMPILER_MAKE_VERSION2(2017,3)
-#elif (_MSC_VER >= 1910)
-#define MPT_COMPILER_MSVC_VERSION                    MPT_COMPILER_MAKE_VERSION2(2017,0)
-#elif (_MSC_VER >= 1900) && defined(_MSVC_LANG)
-#define MPT_COMPILER_MSVC_VERSION                    MPT_COMPILER_MAKE_VERSION2(2015,3)
-#elif (_MSC_VER >= 1900)
-#define MPT_COMPILER_MSVC_VERSION                    MPT_COMPILER_MAKE_VERSION2(2015,0)
-#elif (_MSC_VER >= 1800)
-#define MPT_COMPILER_MSVC_VERSION                    MPT_COMPILER_MAKE_VERSION2(2013,0)
-#elif (_MSC_VER >= 1700)
-#define MPT_COMPILER_MSVC_VERSION                    MPT_COMPILER_MAKE_VERSION2(2012,0)
-#elif (_MSC_VER >= 1600)
-#define MPT_COMPILER_MSVC_VERSION                    MPT_COMPILER_MAKE_VERSION2(2010,0)
-#elif (_MSC_VER >= 1500)
-#define MPT_COMPILER_MSVC_VERSION                    MPT_COMPILER_MAKE_VERSION2(2008,0)
-#else
-#define MPT_COMPILER_MSVC_VERSION                    MPT_COMPILER_MAKE_VERSION2(2005,0)
-#endif
-#define MPT_MSVC_AT_LEAST(version,sp)                (MPT_COMPILER_MSVC_VERSION >= MPT_COMPILER_MAKE_VERSION2((version),(sp)))
-#define MPT_MSVC_BEFORE(version,sp)                  (MPT_COMPILER_MSVC_VERSION <  MPT_COMPILER_MAKE_VERSION2((version),(sp)))
-
-#if MPT_MSVC_BEFORE(2017,9)
-#error "MSVC version 2017 15.9 required"
-#endif
-
-#if defined(_PREFAST_)
-#ifndef MPT_BUILD_ANALYZED
-#define MPT_BUILD_ANALYZED
-#endif
-#endif
-
-#else
-
-#define MPT_COMPILER_GENERIC                         1
-
-#endif
-
-
-
-#ifndef MPT_COMPILER_GENERIC
-#define MPT_COMPILER_GENERIC                  0
-#endif
-#ifndef MPT_COMPILER_CLANG
-#define MPT_COMPILER_CLANG                    0
-#define MPT_CLANG_AT_LEAST(major,minor,patch) 0
-#define MPT_CLANG_BEFORE(major,minor,patch)   0
-#endif
-#ifndef MPT_COMPILER_GCC
-#define MPT_COMPILER_GCC                      0
-#define MPT_GCC_AT_LEAST(major,minor,patch)   0
-#define MPT_GCC_BEFORE(major,minor,patch)     0
-#endif
-#ifndef MPT_COMPILER_MSVC
-#define MPT_COMPILER_MSVC                     0
-#define MPT_MSVC_AT_LEAST(version,sp)         0
-#define MPT_MSVC_BEFORE(version,sp)           0
-#endif
-
-
-
-#if MPT_COMPILER_GENERIC || MPT_COMPILER_GCC || MPT_COMPILER_CLANG
-
-#if (__cplusplus >= 201703)
-#define MPT_CXX 17
-#else
-#define MPT_CXX 17
-#endif
-
-#elif MPT_COMPILER_MSVC
-
-#if (_MSVC_LANG >= 201703)
-#define MPT_CXX 17
-#else
-#define MPT_CXX 17
-#endif
-
-#else
-
-#define MPT_CXX 17
-
-#endif
-
-// MPT_CXX is stricter than just using __cplusplus directly.
-// We will only claim a language version as supported IFF all core language and
-// library fatures that we need are actually supported AND working correctly
-// (to our needs).
-
-#define MPT_CXX_AT_LEAST(version) (MPT_CXX >= (version))
-#define MPT_CXX_BEFORE(version)   (MPT_CXX <  (version))
-
-
-
-// This should really be based on __STDCPP_THREADS__, but that is not defined by
-// GCC or clang. Stupid.
-// Just assume multithreaded and disable for platforms we know are
-// singlethreaded later on.
-#define MPT_PLATFORM_MULTITHREADED 1
-
-
-
-// specific C++ features
-
-
-
-#if MPT_COMPILER_MSVC
-// Compiler has multiplication/division semantics when shifting signed integers.
-#define MPT_COMPILER_SHIFT_SIGNED 1
-#endif
-
-#ifndef MPT_COMPILER_SHIFT_SIGNED
-#define MPT_COMPILER_SHIFT_SIGNED 0
-#endif
-
-
-
-// The order of the checks matters!
-#if defined(__DJGPP__)
-	#define MPT_OS_DJGPP 1
-#elif defined(__EMSCRIPTEN__)
-	#define MPT_OS_EMSCRIPTEN 1
-	#if defined(__EMSCRIPTEN_major__) && defined(__EMSCRIPTEN_minor__)
-		#if (__EMSCRIPTEN_major__ > 1)
-			// ok 
-		#elif (__EMSCRIPTEN_major__ == 1) && (__EMSCRIPTEN_minor__ >= 38)
-			// ok 		
-		#else
-			#error "Emscripten >= 1.38 is required."
-		#endif
-	#endif
-#elif defined(_WIN32)
-	#define MPT_OS_WINDOWS 1
-	#if defined(WINAPI_FAMILY)
-		#include <winapifamily.h>
-		#if (WINAPI_FAMILY == WINAPI_FAMILY_DESKTOP_APP)
-			#define MPT_OS_WINDOWS_WINRT 0
-		#else
-			#define MPT_OS_WINDOWS_WINRT 1
-		#endif
-	#else // !WINAPI_FAMILY
-		#define MPT_OS_WINDOWS_WINRT 0
-	#endif // WINAPI_FAMILY
-#elif defined(__APPLE__)
-	#define MPT_OS_MACOSX_OR_IOS 1
-	//#include "TargetConditionals.h"
-	//#if TARGET_IPHONE_SIMULATOR
-	//#elif TARGET_OS_IPHONE
-	//#elif TARGET_OS_MAC
-	//#else
-	//#endif
-#elif defined(__HAIKU__)
-	#define MPT_OS_HAIKU 1
-#elif defined(__ANDROID__) || defined(ANDROID)
-	#define MPT_OS_ANDROID 1
-#elif defined(__linux__)
-	#define MPT_OS_LINUX 1
-#elif defined(__DragonFly__)
-	#define MPT_OS_DRAGONFLYBSD 1
-#elif defined(__FreeBSD__)
-	#define MPT_OS_FREEBSD 1
-#elif defined(__OpenBSD__)
-	#define MPT_OS_OPENBSD 1
-#elif defined(__NetBSD__)
-	#define MPT_OS_NETBSD 1
-#elif defined(__unix__)
-	#define MPT_OS_GENERIC_UNIX 1
-#else
-	#define MPT_OS_UNKNOWN 1
-#endif
-
-#ifndef MPT_OS_DJGPP
-#define MPT_OS_DJGPP 0
-#endif
-#ifndef MPT_OS_EMSCRIPTEN
-#define MPT_OS_EMSCRIPTEN 0
-#endif
-#ifndef MPT_OS_WINDOWS
-#define MPT_OS_WINDOWS 0
-#endif
-#ifndef MPT_OS_WINDOWS_WINRT
-#define MPT_OS_WINDOWS_WINRT 0
-#endif
-#ifndef MPT_OS_MACOSX_OR_IOS
-#define MPT_OS_MACOSX_OR_IOS 0
-#endif
-#ifndef MPT_OS_HAIKU
-#define MPT_OS_HAIKU 0
-#endif
-#ifndef MPT_OS_ANDROID
-#define MPT_OS_ANDROID 0
-#endif
-#ifndef MPT_OS_LINUX
-#define MPT_OS_LINUX 0
-#endif
-#ifndef MPT_OS_DRAGONFLYBSD
-#define MPT_OS_DRAGONFLYBSD 0
-#endif
-#ifndef MPT_OS_FREEBSD
-#define MPT_OS_FREEBSD 0
-#endif
-#ifndef MPT_OS_OPENBSD
-#define MPT_OS_OPENBSD 0
-#endif
-#ifndef MPT_OS_NETBSD
-#define MPT_OS_NETBSD 0
-#endif
-#ifndef MPT_OS_GENERIC_UNIX
-#define MPT_OS_GENERIC_UNIX 0
-#endif
-#ifndef MPT_OS_UNKNOWN
-#define MPT_OS_UNKNOWN 0
-#endif
-
-#ifndef MPT_OS_EMSCRIPTEN_ANCIENT
-#define MPT_OS_EMSCRIPTEN_ANCIENT 0
-#endif
-
-
-
-#if (MPT_OS_DJGPP || MPT_OS_EMSCRIPTEN)
-#undef MPT_PLATFORM_MULTITHREADED
-#define MPT_PLATFORM_MULTITHREADED 0
-#endif
-
-
-#if MPT_OS_DJGPP
-#define MPT_COMPILER_QUIRK_NO_WCHAR
-#endif
-
-
-#if defined(__arm__)
-
-#if defined(__SOFTFP__)
-#define MPT_COMPILER_QUIRK_FLOAT_EMULATED 1
-#else
-#define MPT_COMPILER_QUIRK_FLOAT_EMULATED 0
-#endif
-#if defined(__VFP_FP__)
-// native-endian IEEE754
-#define MPT_COMPILER_QUIRK_FLOAT_NOTNATIVEENDIAN 0
-#define MPT_COMPILER_QUIRK_FLOAT_NOTIEEE754 0
-#elif defined(__MAVERICK__)
-// little-endian IEEE754, we assume native-endian though
-#define MPT_COMPILER_QUIRK_FLOAT_NOTNATIVEENDIAN 1
-#define MPT_COMPILER_QUIRK_FLOAT_NOTIEEE754 0
-#else
-// not IEEE754
-#define MPT_COMPILER_QUIRK_FLOAT_NOTNATIVEENDIAN 1
-#define MPT_COMPILER_QUIRK_FLOAT_NOTIEEE754 1
-#endif
-
-#elif defined(__mips__)
-
-#if defined(__mips_soft_float)
-#define MPT_COMPILER_QUIRK_FLOAT_EMULATED 1
-#else
-#define MPT_COMPILER_QUIRK_FLOAT_EMULATED 0
-#endif
-
-#endif
-
-#if MPT_OS_EMSCRIPTEN
-#define MPT_COMPILER_QUIRK_FLOAT_PREFER64 1
-#endif
-
-#ifndef MPT_COMPILER_QUIRK_FLOAT_PREFER32
-#define MPT_COMPILER_QUIRK_FLOAT_PREFER32 0
-#endif
-#ifndef MPT_COMPILER_QUIRK_FLOAT_PREFER64
-#define MPT_COMPILER_QUIRK_FLOAT_PREFER64 0
-#endif
-#ifndef MPT_COMPILER_QUIRK_FLOAT_EMULATED
-#define MPT_COMPILER_QUIRK_FLOAT_EMULATED 0
-#endif
-#ifndef MPT_COMPILER_QUIRK_FLOAT_NOTNATIVEENDIAN
-#define MPT_COMPILER_QUIRK_FLOAT_NOTNATIVEENDIAN 0
-#endif
-#ifndef MPT_COMPILER_QUIRK_FLOAT_NOTIEEE754
-#define MPT_COMPILER_QUIRK_FLOAT_NOTIEEE754 0
-#endif

+ 0 - 469
libopenmpt.mod/openmpt/common/ComponentManager.cpp

@@ -1,469 +0,0 @@
-/*
- * ComponentManager.cpp
- * --------------------
- * Purpose: Manages loading of optional components.
- * Notes  : (currently none)
- * Authors: Joern Heusipp
- *          OpenMPT Devs
- * The OpenMPT source code is released under the BSD license. Read LICENSE for more details.
- */
-
-#include "stdafx.h"
-#include "ComponentManager.h"
-
-#include "Logging.h"
-
-#include "mptMutex.h"
-
-OPENMPT_NAMESPACE_BEGIN
-
-
-#if defined(MPT_ENABLE_COMPONENTS)
-
-
-ComponentBase::ComponentBase(ComponentType type)
-	: m_Type(type)
-	, m_Initialized(false)
-	, m_Available(false)
-{
-	return;
-}
-
-
-ComponentBase::~ComponentBase()
-{
-	return;
-}
-
-
-void ComponentBase::SetInitialized()
-{
-	m_Initialized = true;
-}
-
-
-void ComponentBase::SetAvailable()
-{
-	m_Available = true;
-}
-
-
-ComponentType ComponentBase::GetType() const
-{
-	return m_Type;
-}
-
-
-bool ComponentBase::IsInitialized() const
-{
-	return m_Initialized;
-}
-
-
-bool ComponentBase::IsAvailable() const
-{
-	return m_Initialized && m_Available;
-}
-
-
-mpt::ustring ComponentBase::GetVersion() const
-{
-	return mpt::ustring();
-}
-
-
-void ComponentBase::Initialize()
-{
-	if(IsInitialized())
-	{
-		return;
-	}
-	if(DoInitialize())
-	{
-		SetAvailable();
-	}
-	SetInitialized();
-}
-
-
-#if defined(MPT_ENABLE_DYNBIND)
-
-
-ComponentLibrary::ComponentLibrary(ComponentType type)
-	: ComponentBase(type)
-	, m_BindFailed(false)
-{
-	return;
-}
-
-
-ComponentLibrary::~ComponentLibrary()
-{
-	return;
-}
-
-
-bool ComponentLibrary::AddLibrary(const std::string &libName, const mpt::LibraryPath &libPath)
-{
-	if(m_Libraries[libName].IsValid())
-	{
-		// prefer previous
-		return true;
-	}
-	mpt::Library lib(libPath);
-	if(!lib.IsValid())
-	{
-		return false;
-	}
-	m_Libraries[libName] = lib;
-	return true;
-}
-
-
-void ComponentLibrary::ClearLibraries()
-{
-	m_Libraries.clear();
-}
-
-
-void ComponentLibrary::SetBindFailed()
-{
-	m_BindFailed = true;
-}
-
-
-void ComponentLibrary::ClearBindFailed()
-{
-	m_BindFailed = false;
-}
-
-
-bool ComponentLibrary::HasBindFailed() const
-{
-	return m_BindFailed;
-}
-
-
-mpt::Library ComponentLibrary::GetLibrary(const std::string &libName) const
-{
-	const auto it = m_Libraries.find(libName);
-	if(it == m_Libraries.end())
-	{
-		return mpt::Library();
-	}
-	return it->second;
-}
-
-
-#endif // MPT_ENABLE_DYNBIND
-
-
-#if MPT_COMPONENT_MANAGER
-
-
-ComponentFactoryBase::ComponentFactoryBase(const std::string &id, const std::string &settingsKey)
-	: m_ID(id)
-	, m_SettingsKey(settingsKey)
-{
-	return;
-}
-
-
-ComponentFactoryBase::~ComponentFactoryBase()
-{
-	return;
-}
-
-
-std::string ComponentFactoryBase::GetID() const
-{
-	return m_ID;
-}
-
-
-std::string ComponentFactoryBase::GetSettingsKey() const
-{
-	return m_SettingsKey;
-}
-
-
-void ComponentFactoryBase::PreConstruct() const
-{
-	MPT_LOG(LogInformation, "Components", 
-		mpt::format(U_("Constructing Component %1"))
-			( mpt::ToUnicode(mpt::Charset::ASCII, m_ID)
-			)
-		);
-}
-
-
-void ComponentFactoryBase::Initialize(ComponentManager &componentManager, std::shared_ptr<IComponent> component) const
-{
-	if(componentManager.IsComponentBlocked(GetSettingsKey()))
-	{
-		return;
-	}
-	componentManager.InitializeComponent(component);
-}
-
-
-// Global list of component register functions.
-// We do not use a global scope static list head because the corresponding
-//  mutex would be no POD type and would thus not be safe to be usable in
-//  zero-initialized state.
-// Function scope static initialization is guaranteed to be thread safe
-//  in C++11.
-// We use this implementation to be future-proof.
-// MSVC currently does not exploit the possibility of using multiple threads
-//  for global lifetime object's initialization.
-// An implementation with a simple global list head and no mutex at all would
-//  thus work fine for MSVC (currently).
-
-static mpt::mutex & ComponentListMutex()
-{
-	static mpt::mutex g_ComponentListMutex;
-	return g_ComponentListMutex;
-}
-
-static ComponentListEntry * & ComponentListHead()
-{
-	static ComponentListEntry *g_ComponentListHead = nullptr;
-	return g_ComponentListHead;
-}
-
-bool ComponentListPush(ComponentListEntry *entry)
-{
-	MPT_LOCK_GUARD<mpt::mutex> guard(ComponentListMutex());
-	entry->next = ComponentListHead();
-	ComponentListHead() = entry;
-	return true;
-}
-
-
-static std::shared_ptr<ComponentManager> g_ComponentManager;
-
-
-void ComponentManager::Init(const IComponentManagerSettings &settings)
-{
-	MPT_LOG(LogInformation, "Components", U_("Init"));
-	// cannot use make_shared because the constructor is private
-	g_ComponentManager = std::shared_ptr<ComponentManager>(new ComponentManager(settings));
-}
-
-
-void ComponentManager::Release()
-{
-	MPT_LOG(LogInformation, "Components", U_("Release"));
-	g_ComponentManager = nullptr;
-}
-
-
-std::shared_ptr<ComponentManager> ComponentManager::Instance()
-{
-	return g_ComponentManager;
-}
-
-
-ComponentManager::ComponentManager(const IComponentManagerSettings &settings)
-	: m_Settings(settings)
-{
-	MPT_LOCK_GUARD<mpt::mutex> guard(ComponentListMutex());
-	for(ComponentListEntry *entry = ComponentListHead(); entry; entry = entry->next)
-	{
-		entry->reg(*this);
-	}
-}
-
-
-void ComponentManager::Register(const IComponentFactory &componentFactory)
-{
-	if(m_Components.find(componentFactory.GetID()) != m_Components.end())
-	{
-		return;
-	}
-	RegisteredComponent registeredComponent;
-	registeredComponent.settingsKey = componentFactory.GetSettingsKey();
-	registeredComponent.factoryMethod = componentFactory.GetStaticConstructor();
-	registeredComponent.instance = nullptr;
-	registeredComponent.weakInstance = std::weak_ptr<IComponent>();
-	m_Components.insert(std::make_pair(componentFactory.GetID(), registeredComponent));
-}
-
-
-void ComponentManager::Startup()
-{
-	MPT_LOG(LogDebug, "Components", U_("Startup"));
-	if(m_Settings.LoadOnStartup())
-	{
-		for(auto &it : m_Components)
-		{
-			it.second.instance = it.second.factoryMethod(*this);
-			it.second.weakInstance = it.second.instance;
-		}
-	}
-	if(!m_Settings.KeepLoaded())
-	{
-		for(auto &it : m_Components)
-		{
-			it.second.instance = nullptr;
-		}
-	}
-}
-
-
-bool ComponentManager::IsComponentBlocked(const std::string &settingsKey) const
-{
-	if(settingsKey.empty())
-	{
-		return false;
-	}
-	return m_Settings.IsBlocked(settingsKey);
-}
-
-
-void ComponentManager::InitializeComponent(std::shared_ptr<IComponent> component) const
-{
-	if(!component)
-	{
-		return;
-	}
-	if(component->IsInitialized())
-	{
-		return;
-	}
-	component->Initialize();
-}
-
-
-std::shared_ptr<const IComponent> ComponentManager::GetComponent(const IComponentFactory &componentFactory)
-{
-	std::shared_ptr<IComponent> component = nullptr;
-	auto it = m_Components.find(componentFactory.GetID());
-	if(it != m_Components.end())
-	{ // registered component
-		if((*it).second.instance)
-		{ // loaded
-			component = (*it).second.instance;
-		} else
-		{ // not loaded
-			component = (*it).second.weakInstance.lock();
-			if(!component)
-			{
-				component = (*it).second.factoryMethod(*this);
-			}
-			if(m_Settings.KeepLoaded())
-			{ // keep the component loaded
-				(*it).second.instance = component;
-			}
-			(*it).second.weakInstance = component;
-		}
-	} else
-	{ // unregistered component
-		component = componentFactory.Construct(*this);
-	}
-	MPT_ASSERT(component);
-	return component;
-}
-
-
-std::shared_ptr<const IComponent> ComponentManager::ReloadComponent(const IComponentFactory &componentFactory)
-{
-	std::shared_ptr<IComponent> component = nullptr;
-	auto it = m_Components.find(componentFactory.GetID());
-	if(it != m_Components.end())
-	{ // registered component
-		if((*it).second.instance)
-		{ // loaded
-			(*it).second.instance = nullptr;
-			if(!(*it).second.weakInstance.expired())
-			{
-				throw std::runtime_error("Component not completely unloaded. Cannot reload.");
-			}
-			(*it).second.weakInstance = std::weak_ptr<IComponent>();
-		}
-		// not loaded
-		component = (*it).second.factoryMethod(*this);
-		if(m_Settings.KeepLoaded())
-		{ // keep the component loaded
-			(*it).second.instance = component;
-		}
-		(*it).second.weakInstance = component;
-	} else
-	{ // unregistered component
-		component = componentFactory.Construct(*this);
-	}
-	MPT_ASSERT(component);
-	return component;
-}
-
-
-std::vector<std::string> ComponentManager::GetRegisteredComponents() const
-{
-	std::vector<std::string> result;
-	result.reserve(m_Components.size());
-	for(const auto &it : m_Components)
-	{
-		result.push_back(it.first);
-	}
-	return result;
-}
-
-
-ComponentInfo ComponentManager::GetComponentInfo(std::string name) const
-{
-	ComponentInfo result;
-	result.name = name;
-	result.state = ComponentStateUnregistered;
-	result.settingsKey = "";
-	result.type = ComponentTypeUnknown;
-	const auto it = m_Components.find(name);
-	if(it == m_Components.end())
-	{
-		result.state = ComponentStateUnregistered;
-		return result;
-	}
-	result.settingsKey = it->second.settingsKey;
-	if(IsComponentBlocked(it->second.settingsKey))
-	{
-		result.state = ComponentStateBlocked;
-		return result;
-	}
-	std::shared_ptr<IComponent> component = it->second.instance;
-	if(!component)
-	{
-		component = it->second.weakInstance.lock();
-	}
-	if(!component)
-	{
-		result.state = ComponentStateUnintialized;
-		return result;
-	}
-	result.type = component->GetType();
-	if(!component->IsInitialized())
-	{
-		result.state = ComponentStateUnintialized;
-		return result;
-	}
-	if(!component->IsAvailable())
-	{
-		result.state = ComponentStateUnavailable;
-		return result;
-	}
-	result.state = ComponentStateAvailable;
-	return result;
-}
-
-
-mpt::PathString ComponentManager::GetComponentPath() const
-{
-	return m_Settings.Path();
-}
-
-
-#endif // MPT_COMPONENT_MANAGER
-
-
-#endif // MPT_ENABLE_COMPONENTS
-
-
-OPENMPT_NAMESPACE_END

+ 0 - 519
libopenmpt.mod/openmpt/common/ComponentManager.h

@@ -1,519 +0,0 @@
-/*
- * ComponentManager.h
- * ------------------
- * Purpose: Manages loading of optional components.
- * Notes  : (currently none)
- * Authors: Joern Heusipp
- *          OpenMPT Devs
- * The OpenMPT source code is released under the BSD license. Read LICENSE for more details.
- */
-
-#pragma once
-
-#include "BuildSettings.h"
-
-#include <map>
-#include <vector>
-#include "../common/misc_util.h"
-#include "../common/mptMutex.h"
-
-
-OPENMPT_NAMESPACE_BEGIN
-
-
-#define MPT_ENABLE_COMPONENTS
-
-
-#if defined(MPT_ENABLE_COMPONENTS)
-
-
-#if defined(MODPLUG_TRACKER)
-#define MPT_COMPONENT_MANAGER 1
-#else
-#define MPT_COMPONENT_MANAGER 0
-#endif
-
-
-enum ComponentType
-{
-	ComponentTypeUnknown = 0,
-	ComponentTypeBuiltin,            // PortAudio
-	ComponentTypeSystem,             // mf.dll
-	ComponentTypeSystemInstallable,  // acm mp3 codec
-	ComponentTypeBundled,            // libsoundtouch
-	ComponentTypeForeign,            // libmp3lame
-};
-
-
-class ComponentFactoryBase;
-
-
-class IComponent
-{
-
-	friend class ComponentFactoryBase;
-
-protected:
-
-	IComponent() = default;
-
-public:
-
-	virtual ~IComponent() = default;
-
-public:
-
-	virtual ComponentType GetType() const = 0;
-	
-	virtual bool IsInitialized() const = 0;  // Initialize() has been called
-	virtual bool IsAvailable() const = 0;  // Initialize() has been successfull
-	virtual mpt::ustring GetVersion() const = 0;
-
-	virtual void Initialize() = 0;  // try to load the component
-
-};
-
-
-class ComponentBase
-	: public IComponent
-{
-
-private:
-
-	ComponentType m_Type;
-
-	bool m_Initialized;
-	bool m_Available;
-
-protected:
-
-	ComponentBase(ComponentType type);
-
-public:
-
-	virtual ~ComponentBase();
-
-protected:
-
-	void SetInitialized();
-	void SetAvailable();
-
-public:
-
-	ComponentType GetType() const override;
-	bool IsInitialized() const override;
-	bool IsAvailable() const override;
-
-	mpt::ustring GetVersion() const override;
-
-public:
-
-	void Initialize() override;
-
-protected:
-
-	virtual bool DoInitialize() = 0;
-
-};
-
-
-class ComponentBuiltin : public ComponentBase
-{
-public:
-	ComponentBuiltin()
-		: ComponentBase(ComponentTypeBuiltin)
-	{
-		return;
-	}
-	bool DoInitialize() override
-	{
-		return true;
-	}
-};
-
-
-#define MPT_GLOBAL_BIND(lib, name) name = &::name;
-
-
-#if defined(MPT_ENABLE_DYNBIND)
-
-
-class ComponentLibrary
-	: public ComponentBase
-{
-
-private:
-	
-	typedef std::map<std::string, mpt::Library> TLibraryMap;
-	TLibraryMap m_Libraries;
-	
-	bool m_BindFailed;
-
-protected:
-
-	ComponentLibrary(ComponentType type);
-
-public:
-
-	virtual ~ComponentLibrary();
-
-protected:
-
-	bool AddLibrary(const std::string &libName, const mpt::LibraryPath &libPath);
-	void ClearLibraries();
-	void SetBindFailed();
-	void ClearBindFailed();
-	bool HasBindFailed() const;
-
-public:
-	
-	virtual mpt::Library GetLibrary(const std::string &libName) const;
-	
-	template <typename Tfunc>
-	bool Bind(Tfunc * & f, const std::string &libName, const std::string &symbol) const
-	{
-		return GetLibrary(libName).Bind(f, symbol);
-	}
-
-protected:
-
-	bool DoInitialize() override = 0;
-
-};
-
-
-#define MPT_COMPONENT_BIND(libName, func) MPT_DO { if(!Bind( func , libName , #func )) { SetBindFailed(); } } MPT_WHILE_0
-#define MPT_COMPONENT_BIND_OPTIONAL(libName, func) Bind( func , libName , #func )
-#define MPT_COMPONENT_BIND_SYMBOL(libName, symbol, func) MPT_DO { if(!Bind( func , libName , symbol )) { SetBindFailed(); } } MPT_WHILE_0
-#define MPT_COMPONENT_BIND_SYMBOL_OPTIONAL(libName, symbol, func) Bind( func , libName , symbol )
-
-#if MPT_OS_WINDOWS
-#ifdef UNICODE
-#define MPT_COMPONENT_BINDWIN_SUFFIX "W"
-#else
-#define MPT_COMPONENT_BINDWIN_SUFFIX "A"
-#endif
-#define MPT_COMPONENT_BINDWIN(libName, func) MPT_DO { if(!Bind( func , libName , #func MPT_COMPONENT_BINDWIN_SUFFIX )) { SetBindFailed(); } } MPT_WHILE_0
-#define MPT_COMPONENT_BINDWIN_OPTIONAL(libName, func) Bind( func , libName , #func MPT_COMPONENT_BINDWIN_SUFFIX )
-#define MPT_COMPONENT_BINDWIN_SYMBOL(libName, symbol, func) MPT_DO { if(!Bind( func , libName , symbol MPT_COMPONENT_BINDWIN_SUFFIX )) { SetBindFailed(); } } MPT_WHILE_0
-#define MPT_COMPONENT_BINDWIN_SYMBOL_OPTIONAL(libName, symbol, func) Bind( func , libName , symbol MPT_COMPONENT_BINDWIN_SUFFIX )
-#endif
-
-
-class ComponentSystemDLL : public ComponentLibrary
-{
-private:
-	mpt::PathString m_BaseName;
-public:
-	ComponentSystemDLL(const mpt::PathString &baseName)
-		: ComponentLibrary(ComponentTypeSystem)
-		, m_BaseName(baseName)
-	{
-		return;
-	}
-	bool DoInitialize() override
-	{
-		AddLibrary(m_BaseName.ToUTF8(), mpt::LibraryPath::System(m_BaseName));
-		return GetLibrary(m_BaseName.ToUTF8()).IsValid();
-	}
-};
-
-
-class ComponentBundledDLL : public ComponentLibrary
-{
-private:
-	mpt::PathString m_FullName;
-public:
-	ComponentBundledDLL(const mpt::PathString &fullName)
-		: ComponentLibrary(ComponentTypeBundled)
-		, m_FullName(fullName)
-	{
-		return;
-	}
-	bool DoInitialize() override
-	{
-		AddLibrary(m_FullName.ToUTF8(), mpt::LibraryPath::AppFullName(m_FullName));
-		return GetLibrary(m_FullName.ToUTF8()).IsValid();
-	}
-};
-
-
-#endif // MPT_ENABLE_DYNBIND
-
-
-#if MPT_COMPONENT_MANAGER
-
-
-class ComponentManager;
-
-typedef std::shared_ptr<IComponent> (*ComponentFactoryMethod)(ComponentManager &componentManager);
-
-
-class IComponentFactory
-{
-protected:
-	IComponentFactory() = default;
-public:
-	virtual ~IComponentFactory() = default;
-public:
-	virtual std::string GetID() const = 0;
-	virtual std::string GetSettingsKey() const = 0;
-	virtual std::shared_ptr<IComponent> Construct(ComponentManager &componentManager) const = 0;
-	virtual ComponentFactoryMethod GetStaticConstructor() const = 0;
-};
-
-
-class ComponentFactoryBase
-	: public IComponentFactory
-{
-private:
-	std::string m_ID;
-	std::string m_SettingsKey;
-protected:
-	ComponentFactoryBase(const std::string &id, const std::string &settingsKey);
-	void PreConstruct() const;
-	void Initialize(ComponentManager &componentManager, std::shared_ptr<IComponent> component) const;
-public:
-	virtual ~ComponentFactoryBase();
-	std::string GetID() const override;
-	std::string GetSettingsKey() const override;
-	std::shared_ptr<IComponent> Construct(ComponentManager &componentManager) const override = 0;
-	ComponentFactoryMethod GetStaticConstructor() const override = 0;
-};
-
-
-template <typename T>
-class ComponentFactory
-	: public ComponentFactoryBase
-{
-public:
-	ComponentFactory()
-		: ComponentFactoryBase(T::g_ID, T::g_SettingsKey)
-	{
-		return;
-	}
-public:
-	std::shared_ptr<IComponent> Construct(ComponentManager &componentManager) const override
-	{
-		PreConstruct();
-		std::shared_ptr<IComponent> component = std::make_shared<T>();
-		Initialize(componentManager, component);
-		return component;
-	}
-	static std::shared_ptr<IComponent> StaticConstruct(ComponentManager &componentManager)
-	{
-		return ComponentFactory().Construct(componentManager);
-	}
-	virtual ComponentFactoryMethod GetStaticConstructor() const override
-	{
-		return &StaticConstruct;
-	}
-};
-
-
-class IComponentManagerSettings
-{
-public:
-	virtual bool LoadOnStartup() const = 0;
-	virtual bool KeepLoaded() const = 0;
-	virtual bool IsBlocked(const std::string &key) const = 0;
-	virtual mpt::PathString Path() const = 0;
-protected:
-	virtual ~IComponentManagerSettings() = default;
-};
-
-
-class ComponentManagerSettingsDefault
-	: public IComponentManagerSettings
-{
-public:
-	bool LoadOnStartup() const override { return false; }
-	bool KeepLoaded() const override { return true; }
-	bool IsBlocked(const std::string & /*key*/ ) const override { return false; }
-	mpt::PathString Path() const override { return mpt::PathString(); }
-};
-
-
-enum ComponentState
-{
-	ComponentStateUnregistered,
-	ComponentStateBlocked,
-	ComponentStateUnintialized,
-	ComponentStateUnavailable,
-	ComponentStateAvailable,
-};
-
-
-struct ComponentInfo
-{
-	std::string name;
-	ComponentState state;
-	std::string settingsKey;
-	ComponentType type;
-};
-
-
-class ComponentManager
-{
-	friend class ComponentFactoryBase;
-public:
-	static void Init(const IComponentManagerSettings &settings);
-	static void Release();
-	static std::shared_ptr<ComponentManager> Instance();
-private:
-	ComponentManager(const IComponentManagerSettings &settings);
-private:
-	struct RegisteredComponent
-	{
-		std::string settingsKey;
-		ComponentFactoryMethod factoryMethod;
-		std::shared_ptr<IComponent> instance;
-		std::weak_ptr<IComponent> weakInstance;
-	};
-	typedef std::map<std::string, RegisteredComponent> TComponentMap;
-	const IComponentManagerSettings &m_Settings;
-	TComponentMap m_Components;
-private:
-	bool IsComponentBlocked(const std::string &settingsKey) const;
-	void InitializeComponent(std::shared_ptr<IComponent> component) const;
-public:
-	void Register(const IComponentFactory &componentFactory);
-	void Startup();
-	std::shared_ptr<const IComponent> GetComponent(const IComponentFactory &componentFactory);
-	std::shared_ptr<const IComponent> ReloadComponent(const IComponentFactory &componentFactory);
-	std::vector<std::string> GetRegisteredComponents() const;
-	ComponentInfo GetComponentInfo(std::string name) const;
-	mpt::PathString GetComponentPath() const;
-};
-
-
-struct ComponentListEntry
-{
-	ComponentListEntry *next;
-	void (*reg)(ComponentManager &componentManager);
-};
-		
-bool ComponentListPush(ComponentListEntry *entry);
-
-#define MPT_DECLARE_COMPONENT_MEMBERS public: static const char * const g_ID; static const char * const g_SettingsKey;
-		
-#define MPT_REGISTERED_COMPONENT(name, settingsKey) \
-	static void RegisterComponent ## name (ComponentManager &componentManager) \
-	{ \
-		componentManager.Register(ComponentFactory< name >()); \
-	} \
-	static ComponentListEntry Component ## name ## ListEntry = { nullptr, & RegisterComponent ## name }; \
-	bool Component ## name ## Registered = ComponentListPush(& Component ## name ## ListEntry ); \
-	const char * const name :: g_ID = #name ; \
-	const char * const name :: g_SettingsKey = settingsKey ; \
-/**/
-
-
-template <typename type>
-std::shared_ptr<const type> GetComponent()
-{
-	return std::dynamic_pointer_cast<const type>(ComponentManager::Instance()->GetComponent(ComponentFactory<type>()));
-}
-
-
-template <typename type>
-std::shared_ptr<const type> ReloadComponent()
-{
-	return std::dynamic_pointer_cast<const type>(ComponentManager::Instance()->ReloadComponent(ComponentFactory<type>()));
-}
-
-
-static inline mpt::PathString GetComponentPath()
-{
-	return ComponentManager::Instance()->GetComponentPath();
-}
-
-
-#else // !MPT_COMPONENT_MANAGER
-
-
-#define MPT_DECLARE_COMPONENT_MEMBERS
-
-#define MPT_REGISTERED_COMPONENT(name, settingsKey)
-
-
-template <typename type>
-std::shared_ptr<const type> GetComponent()
-{
-	static std::weak_ptr<type> cache;
-	static mpt::mutex m;
-	MPT_LOCK_GUARD<mpt::mutex> l(m);
-	std::shared_ptr<type> component = cache.lock();
-	if(!component)
-	{
-		component = std::make_shared<type>();
-		component->Initialize();
-		cache = component;
-	}
-	return component;
-}
-
-
-static inline mpt::PathString GetComponentPath()
-{
-	return mpt::PathString();
-}
-
-
-#endif // MPT_COMPONENT_MANAGER
-
-
-// Simple wrapper around std::shared_ptr<ComponentType> which automatically
-// gets a reference to the component (or constructs it) on initialization.
-template <typename T>
-class ComponentHandle
-{
-private:
-	std::shared_ptr<const T> component;
-public:
-	ComponentHandle()
-		: component(GetComponent<T>())
-	{
-		return;
-	}
-	~ComponentHandle()
-	{
-		return;
-	}
-	bool IsAvailable() const
-	{
-		return component && component->IsAvailable();
-	}
-	const T *get() const
-	{
-		return component.get();
-	}
-	const T &operator*() const
-	{
-		return *component;
-	}
-	const T *operator->() const
-	{
-		return &*component;
-	}
-#if MPT_COMPONENT_MANAGER
-	void Reload()
-	{
-		component = nullptr;
-		component = ReloadComponent<T>();
-	}
-#endif
-};
-
-
-template <typename T>
-bool IsComponentAvailable(const ComponentHandle<T> &handle)
-{
-	return handle.IsAvailable();
-}
-
-
-#endif // MPT_ENABLE_COMPONENTS
-
-
-OPENMPT_NAMESPACE_END

+ 0 - 1178
libopenmpt.mod/openmpt/common/Endianness.h

@@ -1,1178 +0,0 @@
-/*
- * Endianness.h
- * ------------
- * Purpose: Code for deadling with endianness.
- * Notes  : (currently none)
- * Authors: OpenMPT Devs
- * The OpenMPT source code is released under the BSD license. Read LICENSE for more details.
- */
-
-
-#pragma once
-
-#include "BuildSettings.h"
-
-#include <array>
-#if MPT_CXX_AT_LEAST(20)
-#include <bit>
-#endif // C++20
-#include <limits>
-
-#include <cmath>
-#include <cstdlib>
-
-#include <math.h>
-#include <stdlib.h>
-
-#if MPT_COMPILER_MSVC
-#include <intrin.h>
-#endif
-
-
-
-OPENMPT_NAMESPACE_BEGIN
-
-
-
-namespace mpt {
-
-
-
-#if MPT_CXX_AT_LEAST(20)
-
-using std::endian;
-
-static_assert(mpt::endian::big != mpt::endian::little, "platform with all scalar types having size 1 is not supported");
-
-static constexpr mpt::endian get_endian() noexcept
-{
-	return mpt::endian::native;
-}
-
-static constexpr bool endian_is_little() noexcept
-{
-	return get_endian() == mpt::endian::little;
-}
-
-static constexpr bool endian_is_big() noexcept
-{
-	return get_endian() == mpt::endian::big;
-}
-
-static constexpr bool endian_is_weird() noexcept
-{
-	return !endian_is_little() && !endian_is_big();
-}
-
-#else // !C++20
-
-#if !MPT_COMPILER_GENERIC
-
-#if MPT_COMPILER_MSVC
-	#define MPT_PLATFORM_LITTLE_ENDIAN
-#elif MPT_COMPILER_GCC || MPT_COMPILER_CLANG
-	#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
-		#define MPT_PLATFORM_BIG_ENDIAN
-	#elif __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
-		#define MPT_PLATFORM_LITTLE_ENDIAN
-	#endif
-#endif
-
-// fallback:
-#if !defined(MPT_PLATFORM_BIG_ENDIAN) && !defined(MPT_PLATFORM_LITTLE_ENDIAN)
-	// taken from boost/detail/endian.hpp
-	#if (defined(_BIG_ENDIAN) && !defined(_LITTLE_ENDIAN)) \
-		|| (defined(__BIG_ENDIAN__) && !defined(__LITTLE_ENDIAN__)) \
-		|| (defined(_STLP_BIG_ENDIAN) && !defined(_STLP_LITTLE_ENDIAN))
-			#define MPT_PLATFORM_BIG_ENDIAN
-	#elif (defined(_LITTLE_ENDIAN) && !defined(_BIG_ENDIAN)) \
-		|| (defined(__LITTLE_ENDIAN__) && !defined(__BIG_ENDIAN__)) \
-		|| (defined(_STLP_LITTLE_ENDIAN) && !defined(_STLP_BIG_ENDIAN))
-			#define MPT_PLATFORM_LITTLE_ENDIAN
-	#elif defined(__sparc) || defined(__sparc__) \
-		|| defined(_POWER) || defined(__powerpc__) \
-		|| defined(__ppc__) || defined(__hpux) || defined(__hppa) \
-		|| defined(_MIPSEB) || defined(_POWER) \
-		|| defined(__s390__)
-			#define MPT_PLATFORM_BIG_ENDIAN
-	#elif defined(__i386__) || defined(__alpha__) \
-		|| defined(__ia64) || defined(__ia64__) \
-		|| defined(_M_IX86) || defined(_M_IA64) \
-		|| defined(_M_ALPHA) || defined(__amd64) \
-		|| defined(__amd64__) || defined(_M_AMD64) \
-		|| defined(__x86_64) || defined(__x86_64__) \
-		|| defined(_M_X64) || defined(__bfin__)
-			#define MPT_PLATFORM_LITTLE_ENDIAN
-	#endif
-#endif
-
-#endif // !MPT_COMPILER_GENERIC
-
-enum class endian
-{
-	little = 0x78563412u,
-	big    = 0x12345678u,
-	weird  = 1u,
-#if MPT_COMPILER_GENERIC
-	native = 0u,
-#elif defined(MPT_PLATFORM_LITTLE_ENDIAN)
-	native = little,
-#elif defined(MPT_PLATFORM_BIG_ENDIAN)
-	native = big,
-#else
-	native = 0u,
-#endif
-};
-
-static_assert(mpt::endian::big != mpt::endian::little, "platform with all scalar types having size 1 is not supported");
-
-namespace detail {
-
-	static MPT_FORCEINLINE mpt::endian endian_probe() noexcept
-	{
-		using endian_probe_type = uint32;
-		static_assert(sizeof(endian_probe_type) == 4);
-		constexpr endian_probe_type endian_probe_big    = 0x12345678u;
-		constexpr endian_probe_type endian_probe_little = 0x78563412u;
-		const std::array<std::byte, sizeof(endian_probe_type)> probe{ {mpt::as_byte(0x12), mpt::as_byte(0x34), mpt::as_byte(0x56), mpt::as_byte(0x78)} };
-		const endian_probe_type test = mpt::bit_cast<endian_probe_type>(probe);
-		mpt::endian result = mpt::endian::native;
-		switch(test)
-		{
-			case endian_probe_big:
-				result = mpt::endian::big;
-				break;
-			case endian_probe_little:
-				result = mpt::endian::little;
-				break;
-			default:
-				result = mpt::endian::weird;
-				break;
-		}
-		return result;
-	}
-
-} // namespace detail
-
-static MPT_FORCEINLINE mpt::endian get_endian() noexcept
-{
-	if constexpr((mpt::endian::native == mpt::endian::little) || (mpt::endian::native == mpt::endian::big))
-	{
-		return mpt::endian::native;
-	} else
-	{
-		return detail::endian_probe();
-	}
-}
-
-static MPT_FORCEINLINE bool endian_is_little() noexcept
-{
-	return get_endian() == mpt::endian::little;
-}
-
-static MPT_FORCEINLINE bool endian_is_big() noexcept
-{
-	return get_endian() == mpt::endian::big;
-}
-
-static MPT_FORCEINLINE bool endian_is_weird() noexcept
-{
-	return !endian_is_little() && !endian_is_big();
-}
-
-#endif // C++20
-
-
-
-} // namespace mpt
-
-
-
-struct BigEndian_tag
-{
-	static MPT_CONSTEXPR11_VAR mpt::endian endian = mpt::endian::big;
-};
-
-struct LittleEndian_tag
-{
-	static MPT_CONSTEXPR11_VAR mpt::endian endian = mpt::endian::little;
-};
-
-
-
-namespace mpt {
-
-template <typename Tbyte>
-inline void SwapBufferEndian(std::size_t elementSize, Tbyte * buffer, std::size_t elements)
-{
-	static_assert(sizeof(Tbyte) == 1);
-	for(std::size_t element = 0; element < elements; ++element)
-	{
-		std::reverse(&buffer[0], &buffer[elementSize]);
-		buffer += elementSize;
-	}
-}
-
-} // namespace mpt
-
-
-
-#define MPT_constexpr_bswap16(x) \
-	( uint16(0) \
-		| ((static_cast<uint16>(x) >> 8) & 0x00FFu) \
-		| ((static_cast<uint16>(x) << 8) & 0xFF00u) \
-	) \
-/**/
-#define MPT_constexpr_bswap32(x) \
-	( uint32(0) \
-		| ((static_cast<uint32>(x) & 0x000000FFu) << 24) \
-		| ((static_cast<uint32>(x) & 0x0000FF00u) <<  8) \
-		| ((static_cast<uint32>(x) & 0x00FF0000u) >>  8) \
-		| ((static_cast<uint32>(x) & 0xFF000000u) >> 24) \
-	) \
-/**/
-#define MPT_constexpr_bswap64(x) \
-	( uint64(0) \
-		| (((static_cast<uint64>(x) >>  0) & 0xffull) << 56) \
-		| (((static_cast<uint64>(x) >>  8) & 0xffull) << 48) \
-		| (((static_cast<uint64>(x) >> 16) & 0xffull) << 40) \
-		| (((static_cast<uint64>(x) >> 24) & 0xffull) << 32) \
-		| (((static_cast<uint64>(x) >> 32) & 0xffull) << 24) \
-		| (((static_cast<uint64>(x) >> 40) & 0xffull) << 16) \
-		| (((static_cast<uint64>(x) >> 48) & 0xffull) <<  8) \
-		| (((static_cast<uint64>(x) >> 56) & 0xffull) <<  0) \
-	) \
-/**/
-
-#if MPT_COMPILER_GCC
-#define MPT_bswap16 __builtin_bswap16
-#define MPT_bswap32 __builtin_bswap32
-#define MPT_bswap64 __builtin_bswap64
-#elif MPT_COMPILER_MSVC
-#define MPT_bswap16 _byteswap_ushort
-#define MPT_bswap32 _byteswap_ulong
-#define MPT_bswap64 _byteswap_uint64
-#endif
-
-namespace mpt { namespace detail {
-// catch system macros
-#ifndef MPT_bswap16
-#ifdef bswap16
-static MPT_FORCEINLINE uint16 mpt_bswap16(uint16 x) { return bswap16(x); }
-#define MPT_bswap16 mpt::detail::mpt_bswap16
-#endif
-#endif
-#ifndef MPT_bswap32
-#ifdef bswap32
-static MPT_FORCEINLINE uint32 mpt_bswap32(uint32 x) { return bswap32(x); }
-#define MPT_bswap32 mpt::detail::mpt_bswap32
-#endif
-#endif
-#ifndef MPT_bswap64
-#ifdef bswap64
-static MPT_FORCEINLINE uint64 mpt_bswap64(uint64 x) { return bswap64(x); }
-#define MPT_bswap64 mpt::detail::mpt_bswap64
-#endif
-#endif
-} } // namespace mpt::detail
-
-// No intrinsics available
-#ifndef MPT_bswap16
-#define MPT_bswap16(x) MPT_constexpr_bswap16(x)
-#endif
-#ifndef MPT_bswap32
-#define MPT_bswap32(x) MPT_constexpr_bswap32(x)
-#endif
-#ifndef MPT_bswap64
-#define MPT_bswap64(x) MPT_constexpr_bswap64(x)
-#endif
-
-
-
-template <typename T, typename Tendian, std::size_t size>
-static MPT_CONSTEXPR17_FUN std::array<std::byte, size> EndianEncode(T val) noexcept
-{
-	static_assert(Tendian::endian == mpt::endian::little || Tendian::endian == mpt::endian::big);
-	static_assert(std::numeric_limits<T>::is_integer);
-	static_assert(!std::numeric_limits<T>::is_signed);
-	static_assert(sizeof(T) == size);
-	using base_type = T;
-	using unsigned_base_type = typename std::make_unsigned<base_type>::type;
-	using endian_type = Tendian;
-	unsigned_base_type uval = static_cast<unsigned_base_type>(val);
-	std::array<std::byte, size> data{};
-	if constexpr(endian_type::endian == mpt::endian::little)
-	{
-		for(std::size_t i = 0; i < sizeof(base_type); ++i)
-		{
-			data[i] = static_cast<std::byte>(static_cast<uint8>((uval >> (i*8)) & 0xffu));
-		}
-	} else
-	{
-		for(std::size_t i = 0; i < sizeof(base_type); ++i)
-		{
-			data[(sizeof(base_type)-1) - i] = static_cast<std::byte>(static_cast<uint8>((uval >> (i*8)) & 0xffu));
-		}
-	}
-	return data;
-}
-
-template <typename T, typename Tendian, std::size_t size>
-static MPT_CONSTEXPR17_FUN T EndianDecode(std::array<std::byte, size> data) noexcept
-{
-	static_assert(Tendian::endian == mpt::endian::little || Tendian::endian == mpt::endian::big);
-	static_assert(std::numeric_limits<T>::is_integer);
-	static_assert(!std::numeric_limits<T>::is_signed);
-	static_assert(sizeof(T) == size);
-	using base_type = T;
-	using unsigned_base_type = typename std::make_unsigned<base_type>::type;
-	using endian_type = Tendian;
-	base_type val = base_type();
-	unsigned_base_type uval = unsigned_base_type();
-	if constexpr(endian_type::endian == mpt::endian::little)
-	{
-		for(std::size_t i = 0; i < sizeof(base_type); ++i)
-		{
-			uval |= static_cast<unsigned_base_type>(static_cast<uint8>(data[i])) << (i*8);
-		}
-	} else
-	{
-		for(std::size_t i = 0; i < sizeof(base_type); ++i)
-		{
-			uval |= static_cast<unsigned_base_type>(static_cast<uint8>(data[(sizeof(base_type)-1) - i])) << (i*8);
-		}
-	}
-	val = static_cast<base_type>(uval);
-	return val;
-}
-
-
-namespace mpt
-{
-namespace detail
-{
-
-static MPT_CONSTEXPR20_FUN uint64 SwapBytes(uint64 value) noexcept { MPT_MAYBE_CONSTANT_IF(MPT_IS_CONSTANT_EVALUATED20()) { return MPT_constexpr_bswap64(value); } else { return MPT_bswap64(value); } }
-static MPT_CONSTEXPR20_FUN uint32 SwapBytes(uint32 value) noexcept { MPT_MAYBE_CONSTANT_IF(MPT_IS_CONSTANT_EVALUATED20()) { return MPT_constexpr_bswap32(value); } else { return MPT_bswap32(value); } }
-static MPT_CONSTEXPR20_FUN uint16 SwapBytes(uint16 value) noexcept { MPT_MAYBE_CONSTANT_IF(MPT_IS_CONSTANT_EVALUATED20()) { return MPT_constexpr_bswap16(value); } else { return MPT_bswap16(value); } }
-static MPT_CONSTEXPR20_FUN int64  SwapBytes(int64  value) noexcept { MPT_MAYBE_CONSTANT_IF(MPT_IS_CONSTANT_EVALUATED20()) { return MPT_constexpr_bswap64(value); } else { return MPT_bswap64(value); } }
-static MPT_CONSTEXPR20_FUN int32  SwapBytes(int32  value) noexcept { MPT_MAYBE_CONSTANT_IF(MPT_IS_CONSTANT_EVALUATED20()) { return MPT_constexpr_bswap32(value); } else { return MPT_bswap32(value); } }
-static MPT_CONSTEXPR20_FUN int16  SwapBytes(int16  value) noexcept { MPT_MAYBE_CONSTANT_IF(MPT_IS_CONSTANT_EVALUATED20()) { return MPT_constexpr_bswap16(value); } else { return MPT_bswap16(value); } }
-
-// Do NOT remove these overloads, even if they seem useless.
-// We do not want risking to extend 8bit integers to int and then
-// endian-converting and casting back to int.
-// Thus these overloads.
-static MPT_CONSTEXPR20_FUN uint8  SwapBytes(uint8  value) noexcept { return value; }
-static MPT_CONSTEXPR20_FUN int8   SwapBytes(int8   value) noexcept { return value; }
-static MPT_CONSTEXPR20_FUN char   SwapBytes(char   value) noexcept { return value; }
-
-} // namespace detail
-} // namespace mpt
-
-#undef MPT_constexpr_bswap16
-#undef MPT_constexpr_bswap32
-#undef MPT_constexpr_bswap64
-
-#undef MPT_bswap16
-#undef MPT_bswap32
-#undef MPT_bswap64
-
-
-// 1.0f --> 0x3f800000u
-static MPT_FORCEINLINE uint32 EncodeIEEE754binary32(float32 f)
-{
-	if constexpr(mpt::float_traits<float32>::is_ieee754_binary32ne)
-	{
-		return mpt::bit_cast<uint32>(f);
-	} else
-	{
-		int e = 0;
-		float m = std::frexp(f, &e);
-		if(e == 0 && std::fabs(m) == 0.0f)
-		{
-			uint32 expo = 0u;
-			uint32 sign = std::signbit(m) ? 0x01u : 0x00u;
-			uint32 mant = 0u;
-			uint32 i = 0u;
-			i |= (mant <<  0) & 0x007fffffu;
-			i |= (expo << 23) & 0x7f800000u;
-			i |= (sign << 31) & 0x80000000u;
-			return i;
-		} else
-		{
-			uint32 expo = e + 127 - 1;
-			uint32 sign = std::signbit(m) ? 0x01u : 0x00u;
-			uint32 mant = static_cast<uint32>(std::fabs(std::ldexp(m, 24)));
-			uint32 i = 0u;
-			i |= (mant <<  0) & 0x007fffffu;
-			i |= (expo << 23) & 0x7f800000u;
-			i |= (sign << 31) & 0x80000000u;
-			return i;
-		}
-	}
-}
-static MPT_FORCEINLINE uint64 EncodeIEEE754binary64(float64 f)
-{
-	if constexpr(mpt::float_traits<float64>::is_ieee754_binary64ne)
-	{
-		return mpt::bit_cast<uint64>(f);
-	} else
-	{
-		int e = 0;
-		double m = std::frexp(f, &e);
-		if(e == 0 && std::fabs(m) == 0.0)
-		{
-			uint64 expo = 0u;
-			uint64 sign = std::signbit(m) ? 0x01u : 0x00u;
-			uint64 mant = 0u;
-			uint64 i = 0u;
-			i |= (mant <<  0) & 0x000fffffffffffffull;
-			i |= (expo << 52) & 0x7ff0000000000000ull;
-			i |= (sign << 63) & 0x8000000000000000ull;
-			return i;
-		} else
-		{
-			uint64 expo = e + 1023 - 1;
-			uint64 sign = std::signbit(m) ? 0x01u : 0x00u;
-			uint64 mant = static_cast<uint64>(std::fabs(std::ldexp(m, 53)));
-			uint64 i = 0u;
-			i |= (mant <<  0) & 0x000fffffffffffffull;
-			i |= (expo << 52) & 0x7ff0000000000000ull;
-			i |= (sign << 63) & 0x8000000000000000ull;
-			return i;
-		}
-	}
-}
-
-// 0x3f800000u --> 1.0f
-static MPT_FORCEINLINE float32 DecodeIEEE754binary32(uint32 i)
-{
-	if constexpr(mpt::float_traits<float32>::is_ieee754_binary32ne)
-	{
-		return mpt::bit_cast<float32>(i);
-	} else
-	{
-		uint32 mant = (i & 0x007fffffu) >>  0;
-		uint32 expo = (i & 0x7f800000u) >> 23;
-		uint32 sign = (i & 0x80000000u) >> 31;
-		if(expo == 0)
-		{
-			float m = sign ? -static_cast<float>(mant) : static_cast<float>(mant);
-			int e = static_cast<int>(expo) - 127 + 1 - 24;
-			float f = std::ldexp(m, e);
-			return static_cast<float32>(f);
-		} else
-		{
-			mant |= 0x00800000u;
-			float m = sign ? -static_cast<float>(mant) : static_cast<float>(mant);
-			int e = static_cast<int>(expo) - 127 + 1 - 24;
-			float f = std::ldexp(m, e);
-			return static_cast<float32>(f);
-		}
-	}
-}
-static MPT_FORCEINLINE float64 DecodeIEEE754binary64(uint64 i)
-{
-	if constexpr(mpt::float_traits<float64>::is_ieee754_binary64ne)
-	{
-		return mpt::bit_cast<float64>(i);
-	} else
-	{
-		uint64 mant = (i & 0x000fffffffffffffull) >>  0;
-		uint64 expo = (i & 0x7ff0000000000000ull) >> 52;
-		uint64 sign = (i & 0x8000000000000000ull) >> 63;
-		if(expo == 0)
-		{
-			double m = sign ? -static_cast<double>(mant) : static_cast<double>(mant);
-			int e = static_cast<int>(expo) - 1023 + 1 - 53;
-			double f = std::ldexp(m, e);
-			return static_cast<float64>(f);
-		} else
-		{
-			mant |= 0x0010000000000000ull;
-			double m = sign ? -static_cast<double>(mant) : static_cast<double>(mant);
-			int e = static_cast<int>(expo) - 1023 + 1 - 53;
-			double f = std::ldexp(m, e);
-			return static_cast<float64>(f);
-		}
-	}
-}
-
-
-// template parameters are byte indices corresponding to the individual bytes of iee754 in memory
-template<std::size_t hihi, std::size_t hilo, std::size_t lohi, std::size_t lolo>
-struct IEEE754binary32Emulated
-{
-public:
-	using self_t = IEEE754binary32Emulated<hihi,hilo,lohi,lolo>;
-	std::byte bytes[4];
-public:
-	MPT_FORCEINLINE std::byte GetByte(std::size_t i) const
-	{
-		return bytes[i];
-	}
-	IEEE754binary32Emulated() = default;
-	MPT_FORCEINLINE explicit IEEE754binary32Emulated(float32 f)
-	{
-		SetInt32(EncodeIEEE754binary32(f));
-	}
-	// b0...b3 are in memory order, i.e. depend on the endianness of this type
-	// little endian: (0x00,0x00,0x80,0x3f)
-	// big endian:    (0x3f,0x80,0x00,0x00)
-	MPT_FORCEINLINE explicit IEEE754binary32Emulated(std::byte b0, std::byte b1, std::byte b2, std::byte b3)
-	{
-		bytes[0] = b0;
-		bytes[1] = b1;
-		bytes[2] = b2;
-		bytes[3] = b3;
-	}
-	MPT_FORCEINLINE operator float32 () const
-	{
-		return DecodeIEEE754binary32(GetInt32());
-	}
-	MPT_FORCEINLINE self_t & SetInt32(uint32 i)
-	{
-		bytes[hihi] = static_cast<std::byte>(i >> 24);
-		bytes[hilo] = static_cast<std::byte>(i >> 16);
-		bytes[lohi] = static_cast<std::byte>(i >>  8);
-		bytes[lolo] = static_cast<std::byte>(i >>  0);
-		return *this;
-	}
-	MPT_FORCEINLINE uint32 GetInt32() const
-	{
-		return 0u
-			| (static_cast<uint32>(bytes[hihi]) << 24)
-			| (static_cast<uint32>(bytes[hilo]) << 16)
-			| (static_cast<uint32>(bytes[lohi]) <<  8)
-			| (static_cast<uint32>(bytes[lolo]) <<  0)
-			;
-	}
-	MPT_FORCEINLINE bool operator == (const self_t &cmp) const
-	{
-		return true
-			&& bytes[0] == cmp.bytes[0]
-			&& bytes[1] == cmp.bytes[1]
-			&& bytes[2] == cmp.bytes[2]
-			&& bytes[3] == cmp.bytes[3]
-			;
-	}
-	MPT_FORCEINLINE bool operator != (const self_t &cmp) const
-	{
-		return !(*this == cmp);
-	}
-};
-template<std::size_t hihihi, std::size_t hihilo, std::size_t hilohi, std::size_t hilolo, std::size_t lohihi, std::size_t lohilo, std::size_t lolohi, std::size_t lololo>
-struct IEEE754binary64Emulated
-{
-public:
-	using self_t = IEEE754binary64Emulated<hihihi,hihilo,hilohi,hilolo,lohihi,lohilo,lolohi,lololo>;
-	std::byte bytes[8];
-public:
-	MPT_FORCEINLINE std::byte GetByte(std::size_t i) const
-	{
-		return bytes[i];
-	}
-	IEEE754binary64Emulated() = default;
-	MPT_FORCEINLINE explicit IEEE754binary64Emulated(float64 f)
-	{
-		SetInt64(EncodeIEEE754binary64(f));
-	}
-	MPT_FORCEINLINE explicit IEEE754binary64Emulated(std::byte b0, std::byte b1, std::byte b2, std::byte b3, std::byte b4, std::byte b5, std::byte b6, std::byte b7)
-	{
-		bytes[0] = b0;
-		bytes[1] = b1;
-		bytes[2] = b2;
-		bytes[3] = b3;
-		bytes[4] = b4;
-		bytes[5] = b5;
-		bytes[6] = b6;
-		bytes[7] = b7;
-	}
-	MPT_FORCEINLINE operator float64 () const
-	{
-		return DecodeIEEE754binary64(GetInt64());
-	}
-	MPT_FORCEINLINE self_t & SetInt64(uint64 i)
-	{
-		bytes[hihihi] = static_cast<std::byte>(i >> 56);
-		bytes[hihilo] = static_cast<std::byte>(i >> 48);
-		bytes[hilohi] = static_cast<std::byte>(i >> 40);
-		bytes[hilolo] = static_cast<std::byte>(i >> 32);
-		bytes[lohihi] = static_cast<std::byte>(i >> 24);
-		bytes[lohilo] = static_cast<std::byte>(i >> 16);
-		bytes[lolohi] = static_cast<std::byte>(i >>  8);
-		bytes[lololo] = static_cast<std::byte>(i >>  0);
-		return *this;
-	}
-	MPT_FORCEINLINE uint64 GetInt64() const
-	{
-		return 0u
-			| (static_cast<uint64>(bytes[hihihi]) << 56)
-			| (static_cast<uint64>(bytes[hihilo]) << 48)
-			| (static_cast<uint64>(bytes[hilohi]) << 40)
-			| (static_cast<uint64>(bytes[hilolo]) << 32)
-			| (static_cast<uint64>(bytes[lohihi]) << 24)
-			| (static_cast<uint64>(bytes[lohilo]) << 16)
-			| (static_cast<uint64>(bytes[lolohi]) <<  8)
-			| (static_cast<uint64>(bytes[lololo]) <<  0)
-			;
-	}
-	MPT_FORCEINLINE bool operator == (const self_t &cmp) const
-	{
-		return true
-			&& bytes[0] == cmp.bytes[0]
-			&& bytes[1] == cmp.bytes[1]
-			&& bytes[2] == cmp.bytes[2]
-			&& bytes[3] == cmp.bytes[3]
-			&& bytes[4] == cmp.bytes[4]
-			&& bytes[5] == cmp.bytes[5]
-			&& bytes[6] == cmp.bytes[6]
-			&& bytes[7] == cmp.bytes[7]
-			;
-	}
-	MPT_FORCEINLINE bool operator != (const self_t &cmp) const
-	{
-		return !(*this == cmp);
-	}
-};
-
-using IEEE754binary32EmulatedBE = IEEE754binary32Emulated<0,1,2,3>;
-using IEEE754binary32EmulatedLE = IEEE754binary32Emulated<3,2,1,0>;
-using IEEE754binary64EmulatedBE = IEEE754binary64Emulated<0,1,2,3,4,5,6,7>;
-using IEEE754binary64EmulatedLE = IEEE754binary64Emulated<7,6,5,4,3,2,1,0>;
-
-MPT_BINARY_STRUCT(IEEE754binary32EmulatedBE, 4)
-MPT_BINARY_STRUCT(IEEE754binary32EmulatedLE, 4)
-MPT_BINARY_STRUCT(IEEE754binary64EmulatedBE, 8)
-MPT_BINARY_STRUCT(IEEE754binary64EmulatedLE, 8)
-
-template <mpt::endian endian = mpt::endian::native>
-struct IEEE754binary32Native
-{
-public:
-	float32 value;
-public:
-	MPT_FORCEINLINE std::byte GetByte(std::size_t i) const
-	{
-		static_assert(endian == mpt::endian::little || endian == mpt::endian::big);
-		if constexpr(endian == mpt::endian::little)
-		{
-			return static_cast<std::byte>(EncodeIEEE754binary32(value) >> (i*8));
-		}
-		if constexpr(endian == mpt::endian::big)
-		{
-			return static_cast<std::byte>(EncodeIEEE754binary32(value) >> ((4-1-i)*8));
-		}
-	}
-	IEEE754binary32Native() = default;
-	MPT_FORCEINLINE explicit IEEE754binary32Native(float32 f)
-	{
-		value = f;
-	}
-	// b0...b3 are in memory order, i.e. depend on the endianness of this type
-	// little endian: (0x00,0x00,0x80,0x3f)
-	// big endian:    (0x3f,0x80,0x00,0x00)
-	MPT_FORCEINLINE explicit IEEE754binary32Native(std::byte b0, std::byte b1, std::byte b2, std::byte b3)
-	{
-		static_assert(endian == mpt::endian::little || endian == mpt::endian::big);
-		if constexpr(endian == mpt::endian::little)
-		{
-			value = DecodeIEEE754binary32(0u
-				| (static_cast<uint32>(b0) <<  0)
-				| (static_cast<uint32>(b1) <<  8)
-				| (static_cast<uint32>(b2) << 16)
-				| (static_cast<uint32>(b3) << 24)
-				);
-		}
-		if constexpr(endian == mpt::endian::big)
-		{
-			value = DecodeIEEE754binary32(0u
-				| (static_cast<uint32>(b0) << 24)
-				| (static_cast<uint32>(b1) << 16)
-				| (static_cast<uint32>(b2) <<  8)
-				| (static_cast<uint32>(b3) <<  0)
-				);
-		}
-	}
-	MPT_FORCEINLINE operator float32 () const
-	{
-		return value;
-	}
-	MPT_FORCEINLINE IEEE754binary32Native & SetInt32(uint32 i)
-	{
-		value = DecodeIEEE754binary32(i);
-		return *this;
-	}
-	MPT_FORCEINLINE uint32 GetInt32() const
-	{
-		return EncodeIEEE754binary32(value);
-	}
-	MPT_FORCEINLINE bool operator == (const IEEE754binary32Native &cmp) const
-	{
-		return value == cmp.value;
-	}
-	MPT_FORCEINLINE bool operator != (const IEEE754binary32Native &cmp) const
-	{
-		return value != cmp.value;
-	}
-};
-
-template <mpt::endian endian = mpt::endian::native>
-struct IEEE754binary64Native
-{
-public:
-	float64 value;
-public:
-	MPT_FORCEINLINE std::byte GetByte(std::size_t i) const
-	{
-		static_assert(endian == mpt::endian::little || endian == mpt::endian::big);
-		if constexpr(endian == mpt::endian::little)
-		{
-			return mpt::byte_cast<std::byte>(static_cast<uint8>(EncodeIEEE754binary64(value) >> (i*8)));
-		}
-		if constexpr(endian == mpt::endian::big)
-		{
-			return mpt::byte_cast<std::byte>(static_cast<uint8>(EncodeIEEE754binary64(value) >> ((8-1-i)*8)));
-		}
-	}
-	IEEE754binary64Native() = default;
-	MPT_FORCEINLINE explicit IEEE754binary64Native(float64 f)
-	{
-		value = f;
-	}
-	MPT_FORCEINLINE explicit IEEE754binary64Native(std::byte b0, std::byte b1, std::byte b2, std::byte b3, std::byte b4, std::byte b5, std::byte b6, std::byte b7)
-	{
-		static_assert(endian == mpt::endian::little || endian == mpt::endian::big);
-		if constexpr(endian == mpt::endian::little)
-		{
-			value = DecodeIEEE754binary64(0ull
-				| (static_cast<uint64>(b0) <<  0)
-				| (static_cast<uint64>(b1) <<  8)
-				| (static_cast<uint64>(b2) << 16)
-				| (static_cast<uint64>(b3) << 24)
-				| (static_cast<uint64>(b4) << 32)
-				| (static_cast<uint64>(b5) << 40)
-				| (static_cast<uint64>(b6) << 48)
-				| (static_cast<uint64>(b7) << 56)
-				);
-		}
-		if constexpr(endian == mpt::endian::big)
-		{
-			value = DecodeIEEE754binary64(0ull
-				| (static_cast<uint64>(b0) << 56)
-				| (static_cast<uint64>(b1) << 48)
-				| (static_cast<uint64>(b2) << 40)
-				| (static_cast<uint64>(b3) << 32)
-				| (static_cast<uint64>(b4) << 24)
-				| (static_cast<uint64>(b5) << 16)
-				| (static_cast<uint64>(b6) <<  8)
-				| (static_cast<uint64>(b7) <<  0)
-				);
-		}
-	}
-	MPT_FORCEINLINE operator float64 () const
-	{
-		return value;
-	}
-	MPT_FORCEINLINE IEEE754binary64Native & SetInt64(uint64 i)
-	{
-		value = DecodeIEEE754binary64(i);
-		return *this;
-	}
-	MPT_FORCEINLINE uint64 GetInt64() const
-	{
-		return EncodeIEEE754binary64(value);
-	}
-	MPT_FORCEINLINE bool operator == (const IEEE754binary64Native &cmp) const
-	{
-		return value == cmp.value;
-	}
-	MPT_FORCEINLINE bool operator != (const IEEE754binary64Native &cmp) const
-	{
-		return value != cmp.value;
-	}
-};
-
-static_assert((sizeof(IEEE754binary32Native<>) == 4));
-static_assert((sizeof(IEEE754binary64Native<>) == 8));
-
-namespace mpt {
-template <> struct is_binary_safe< IEEE754binary32Native<> > : public std::true_type { };
-template <> struct is_binary_safe< IEEE754binary64Native<> > : public std::true_type { };
-}
-
-template <bool is_ieee754, mpt::endian endian = mpt::endian::native> struct IEEE754binary_types {
-	using IEEE754binary32LE = IEEE754binary32EmulatedLE;
-	using IEEE754binary32BE = IEEE754binary32EmulatedBE;
-	using IEEE754binary64LE = IEEE754binary64EmulatedLE;
-	using IEEE754binary64BE = IEEE754binary64EmulatedBE;
-};
-template <> struct IEEE754binary_types<true, mpt::endian::little> {
-	using IEEE754binary32LE = IEEE754binary32Native<>;
-	using IEEE754binary32BE = IEEE754binary32EmulatedBE;
-	using IEEE754binary64LE = IEEE754binary64Native<>;
-	using IEEE754binary64BE = IEEE754binary64EmulatedBE;
-};
-template <> struct IEEE754binary_types<true, mpt::endian::big> {
-	using IEEE754binary32LE = IEEE754binary32EmulatedLE;
-	using IEEE754binary32BE = IEEE754binary32Native<>;
-	using IEEE754binary64LE = IEEE754binary64EmulatedLE;
-	using IEEE754binary64BE = IEEE754binary64Native<>;
-};
-
-using IEEE754binary32LE = IEEE754binary_types<mpt::float_traits<float32>::is_ieee754_binary32ne, mpt::endian::native>::IEEE754binary32LE;
-using IEEE754binary32BE = IEEE754binary_types<mpt::float_traits<float32>::is_ieee754_binary32ne, mpt::endian::native>::IEEE754binary32BE;
-using IEEE754binary64LE = IEEE754binary_types<mpt::float_traits<float64>::is_ieee754_binary64ne, mpt::endian::native>::IEEE754binary64LE;
-using IEEE754binary64BE = IEEE754binary_types<mpt::float_traits<float64>::is_ieee754_binary64ne, mpt::endian::native>::IEEE754binary64BE;
-
-static_assert(sizeof(IEEE754binary32LE) == 4);
-static_assert(sizeof(IEEE754binary32BE) == 4);
-static_assert(sizeof(IEEE754binary64LE) == 8);
-static_assert(sizeof(IEEE754binary64BE) == 8);
-
-
-// unaligned
-
-using float32le = IEEE754binary32EmulatedLE;
-using float32be = IEEE754binary32EmulatedBE;
-using float64le = IEEE754binary64EmulatedLE;
-using float64be = IEEE754binary64EmulatedBE;
-
-static_assert(sizeof(float32le) == 4);
-static_assert(sizeof(float32be) == 4);
-static_assert(sizeof(float64le) == 8);
-static_assert(sizeof(float64be) == 8);
-
-
-// potentially aligned
-
-using float32le_fast = IEEE754binary32LE;
-using float32be_fast = IEEE754binary32BE;
-using float64le_fast = IEEE754binary64LE;
-using float64be_fast = IEEE754binary64BE;
-
-static_assert(sizeof(float32le_fast) == 4);
-static_assert(sizeof(float32be_fast) == 4);
-static_assert(sizeof(float64le_fast) == 8);
-static_assert(sizeof(float64be_fast) == 8);
-
-
-
-// On-disk integer types with defined endianness and no alignemnt requirements
-// Note: To easily debug module loaders (and anything else that uses this
-// wrapper struct), you can use the Debugger Visualizers available in
-// build/vs/debug/ to conveniently view the wrapped contents.
-
-template<typename T, typename Tendian>
-struct packed
-{
-public:
-	using base_type = T;
-	using endian_type = Tendian;
-public:
-	std::array<std::byte, sizeof(base_type)> data;
-public:
-	MPT_CONSTEXPR20_FUN void set(base_type val) noexcept
-	{
-		static_assert(std::numeric_limits<T>::is_integer);
-		MPT_MAYBE_CONSTANT_IF(MPT_IS_CONSTANT_EVALUATED20())
-		{
-			if constexpr(endian_type::endian == mpt::endian::big)
-			{
-				typename std::make_unsigned<base_type>::type uval = val;
-				for(std::size_t i = 0; i < sizeof(base_type); ++i)
-				{
-					data[i] = static_cast<std::byte>((uval >> (8*(sizeof(base_type)-1-i))) & 0xffu);
-				}
-			} else
-			{
-				typename std::make_unsigned<base_type>::type uval = val;
-				for(std::size_t i = 0; i < sizeof(base_type); ++i)
-				{
-					data[i] = static_cast<std::byte>((uval >> (8*i)) & 0xffu);
-				}
-			}
-		} else
-		{
-			if constexpr(mpt::endian::native == mpt::endian::little || mpt::endian::native == mpt::endian::big)
-			{
-				if constexpr(mpt::endian::native != endian_type::endian)
-				{
-					val = mpt::detail::SwapBytes(val);
-				}
-				std::memcpy(data.data(), &val, sizeof(val));
-			} else
-			{
-				using unsigned_base_type = typename std::make_unsigned<base_type>::type;
-				data = EndianEncode<unsigned_base_type, Tendian, sizeof(T)>(val);
-			}
-		}
-	}
-	MPT_CONSTEXPR20_FUN base_type get() const noexcept
-	{
-		static_assert(std::numeric_limits<T>::is_integer);
-		MPT_MAYBE_CONSTANT_IF(MPT_IS_CONSTANT_EVALUATED20())
-		{
-			if constexpr(endian_type::endian == mpt::endian::big)
-			{
-				typename std::make_unsigned<base_type>::type uval = 0;
-				for(std::size_t i = 0; i < sizeof(base_type); ++i)
-				{
-					uval |= static_cast<typename std::make_unsigned<base_type>::type>(data[i]) << (8*(sizeof(base_type)-1-i));
-				}
-				return static_cast<base_type>(uval);
-			} else
-			{
-				typename std::make_unsigned<base_type>::type uval = 0;
-				for(std::size_t i = 0; i < sizeof(base_type); ++i)
-				{
-					uval |= static_cast<typename std::make_unsigned<base_type>::type>(data[i]) << (8*i);
-				}
-				return static_cast<base_type>(uval);
-			}
-		} else
-		{
-			if constexpr(mpt::endian::native == mpt::endian::little || mpt::endian::native == mpt::endian::big)
-			{
-				base_type val = base_type();
-				std::memcpy(&val, data.data(), sizeof(val));
-				if constexpr(mpt::endian::native != endian_type::endian)
-				{
-					val = mpt::detail::SwapBytes(val);
-				}
-				return val;
-			} else
-			{
-				using unsigned_base_type = typename std::make_unsigned<base_type>::type;
-				return EndianDecode<unsigned_base_type, Tendian, sizeof(T)>(data);
-			}
-		}
-	}
-	MPT_CONSTEXPR20_FUN packed & operator = (const base_type & val) noexcept { set(val); return *this; }
-	MPT_CONSTEXPR20_FUN operator base_type () const noexcept { return get(); }
-public:
-	MPT_CONSTEXPR20_FUN packed & operator &= (base_type val) noexcept { set(get() & val); return *this; }
-	MPT_CONSTEXPR20_FUN packed & operator |= (base_type val) noexcept { set(get() | val); return *this; }
-	MPT_CONSTEXPR20_FUN packed & operator ^= (base_type val) noexcept { set(get() ^ val); return *this; }
-	MPT_CONSTEXPR20_FUN packed & operator += (base_type val) noexcept { set(get() + val); return *this; }
-	MPT_CONSTEXPR20_FUN packed & operator -= (base_type val) noexcept { set(get() - val); return *this; }
-	MPT_CONSTEXPR20_FUN packed & operator *= (base_type val) noexcept { set(get() * val); return *this; }
-	MPT_CONSTEXPR20_FUN packed & operator /= (base_type val) noexcept { set(get() / val); return *this; }
-	MPT_CONSTEXPR20_FUN packed & operator %= (base_type val) noexcept { set(get() % val); return *this; }
-	MPT_CONSTEXPR20_FUN packed & operator ++ () noexcept { set(get() + 1); return *this; } // prefix
-	MPT_CONSTEXPR20_FUN packed & operator -- () noexcept { set(get() - 1); return *this; } // prefix
-	MPT_CONSTEXPR20_FUN base_type operator ++ (int) noexcept { base_type old = get(); set(old + 1); return old; } // postfix
-	MPT_CONSTEXPR20_FUN base_type operator -- (int) noexcept { base_type old = get(); set(old - 1); return old; } // postfix
-};
-
-using int64le  = packed< int64, LittleEndian_tag>;
-using int32le  = packed< int32, LittleEndian_tag>;
-using int16le  = packed< int16, LittleEndian_tag>;
-using int8le   = packed< int8 , LittleEndian_tag>;
-using uint64le = packed<uint64, LittleEndian_tag>;
-using uint32le = packed<uint32, LittleEndian_tag>;
-using uint16le = packed<uint16, LittleEndian_tag>;
-using uint8le  = packed<uint8 , LittleEndian_tag>;
-
-using int64be  = packed< int64, BigEndian_tag>;
-using int32be  = packed< int32, BigEndian_tag>;
-using int16be  = packed< int16, BigEndian_tag>;
-using int8be   = packed< int8 , BigEndian_tag>;
-using uint64be = packed<uint64, BigEndian_tag>;
-using uint32be = packed<uint32, BigEndian_tag>;
-using uint16be = packed<uint16, BigEndian_tag>;
-using uint8be  = packed<uint8 , BigEndian_tag>;
-
-namespace mpt {
-template <typename T, typename Tendian> struct limits<packed<T, Tendian>> : mpt::limits<T> {};
-} // namespace mpt
-
-MPT_BINARY_STRUCT(int64le, 8)
-MPT_BINARY_STRUCT(int32le, 4)
-MPT_BINARY_STRUCT(int16le, 2)
-MPT_BINARY_STRUCT(int8le , 1)
-MPT_BINARY_STRUCT(uint64le, 8)
-MPT_BINARY_STRUCT(uint32le, 4)
-MPT_BINARY_STRUCT(uint16le, 2)
-MPT_BINARY_STRUCT(uint8le , 1)
-
-MPT_BINARY_STRUCT(int64be, 8)
-MPT_BINARY_STRUCT(int32be, 4)
-MPT_BINARY_STRUCT(int16be, 2)
-MPT_BINARY_STRUCT(int8be , 1)
-MPT_BINARY_STRUCT(uint64be, 8)
-MPT_BINARY_STRUCT(uint32be, 4)
-MPT_BINARY_STRUCT(uint16be, 2)
-MPT_BINARY_STRUCT(uint8be , 1)
-
-namespace mpt {
-
-template <typename T> struct make_le { using type = packed<typename std::remove_const<T>::type, LittleEndian_tag>; };
-template <typename T> struct make_be { using type = packed<typename std::remove_const<T>::type, BigEndian_tag>; };
-
-template <typename T>
-MPT_CONSTEXPR20_FUN auto as_le(T v) noexcept -> typename mpt::make_le<typename std::remove_const<T>::type>::type
-{
-	typename mpt::make_le<typename std::remove_const<T>::type>::type res{};
-	res = v;
-	return res;
-}
-template <typename T>
-MPT_CONSTEXPR20_FUN auto as_be(T v) noexcept -> typename mpt::make_be<typename std::remove_const<T>::type>::type
-{
-	typename mpt::make_be<typename std::remove_const<T>::type>::type res{};
-	res = v;
-	return res;
-}
-
-template <typename Tpacked>
-MPT_CONSTEXPR20_FUN Tpacked as_endian(typename Tpacked::base_type v) noexcept
-{
-	Tpacked res{};
-	res = v;
-	return res;
-}
-
-} // namespace mpt
-
-
-
-// 24-bit integer wrapper (for 24-bit PCM)
-struct int24
-{
-	uint8 bytes[3];
-	int24() noexcept
-	{
-		bytes[0] = bytes[1] = bytes[2] = 0;
-	}
-	explicit int24(int other) noexcept
-	{
-		MPT_MAYBE_CONSTANT_IF(mpt::endian_is_big())
-		{
-			bytes[0] = (static_cast<unsigned int>(other)>>16)&0xff;
-			bytes[1] = (static_cast<unsigned int>(other)>> 8)&0xff;
-			bytes[2] = (static_cast<unsigned int>(other)>> 0)&0xff;
-		} else
-		{
-			bytes[0] = (static_cast<unsigned int>(other)>> 0)&0xff;
-			bytes[1] = (static_cast<unsigned int>(other)>> 8)&0xff;
-			bytes[2] = (static_cast<unsigned int>(other)>>16)&0xff;
-		}
-	}
-	operator int() const noexcept
-	{
-		MPT_MAYBE_CONSTANT_IF(mpt::endian_is_big())
-		{
-			return (static_cast<int8>(bytes[0]) * 65536) + (bytes[1] * 256) + bytes[2];
-		} else
-		{
-			return (static_cast<int8>(bytes[2]) * 65536) + (bytes[1] * 256) + bytes[0];
-		}
-	}
-};
-static_assert(sizeof(int24) == 3);
-#define int24_min (0-0x00800000)
-#define int24_max (0+0x007fffff)
-
-
-
-// Small helper class to support unaligned memory access on all platforms.
-// This is only used to make old module loaders work everywhere.
-// Do not use in new code.
-template <typename T>
-class const_unaligned_ptr_le
-{
-public:
-	using value_type = T;
-private:
-	const std::byte *mem;
-	value_type Read() const
-	{
-		typename mpt::make_le<T>::type val;
-		std::memcpy(&val, mem, sizeof(value_type));
-		return val;
-	}
-public:
-	const_unaligned_ptr_le() : mem(nullptr) {}
-	const_unaligned_ptr_le(const const_unaligned_ptr_le<value_type> & other) : mem(other.mem) {}
-	const_unaligned_ptr_le & operator = (const const_unaligned_ptr_le<value_type> & other) { mem = other.mem; return *this; }
-	template <typename Tbyte> explicit const_unaligned_ptr_le(const Tbyte *mem) : mem(mpt::byte_cast<const std::byte*>(mem)) {}
-	const_unaligned_ptr_le & operator += (std::size_t count) { mem += count * sizeof(value_type); return *this; }
-	const_unaligned_ptr_le & operator -= (std::size_t count) { mem -= count * sizeof(value_type); return *this; }
-	const_unaligned_ptr_le & operator ++ () { mem += sizeof(value_type); return *this; }
-	const_unaligned_ptr_le & operator -- () { mem -= sizeof(value_type); return *this; }
-	const_unaligned_ptr_le operator ++ (int) { const_unaligned_ptr_le<value_type> result = *this; ++result; return result; }
-	const_unaligned_ptr_le operator -- (int) { const_unaligned_ptr_le<value_type> result = *this; --result; return result; }
-	const_unaligned_ptr_le operator + (std::size_t count) const { const_unaligned_ptr_le<value_type> result = *this; result += count; return result; }
-	const_unaligned_ptr_le operator - (std::size_t count) const { const_unaligned_ptr_le<value_type> result = *this; result -= count; return result; }
-	const value_type operator * () const { return Read(); }
-	const value_type operator [] (std::size_t i) const { return *((*this) + i); }
-	operator bool () const { return mem != nullptr; }
-};
-
-template <typename T>
-class const_unaligned_ptr_be
-{
-public:
-	using value_type = T;
-private:
-	const std::byte *mem;
-	value_type Read() const
-	{
-		typename mpt::make_be<T>::type val;
-		std::memcpy(&val, mem, sizeof(value_type));
-		return val;
-	}
-public:
-	const_unaligned_ptr_be() : mem(nullptr) {}
-	const_unaligned_ptr_be(const const_unaligned_ptr_be<value_type> & other) : mem(other.mem) {}
-	const_unaligned_ptr_be & operator = (const const_unaligned_ptr_be<value_type> & other) { mem = other.mem; return *this; }
-	template <typename Tbyte> explicit const_unaligned_ptr_be(const Tbyte *mem) : mem(mpt::byte_cast<const std::byte*>(mem)) {}
-	const_unaligned_ptr_be & operator += (std::size_t count) { mem += count * sizeof(value_type); return *this; }
-	const_unaligned_ptr_be & operator -= (std::size_t count) { mem -= count * sizeof(value_type); return *this; }
-	const_unaligned_ptr_be & operator ++ () { mem += sizeof(value_type); return *this; }
-	const_unaligned_ptr_be & operator -- () { mem -= sizeof(value_type); return *this; }
-	const_unaligned_ptr_be operator ++ (int) { const_unaligned_ptr_be<value_type> result = *this; ++result; return result; }
-	const_unaligned_ptr_be operator -- (int) { const_unaligned_ptr_be<value_type> result = *this; --result; return result; }
-	const_unaligned_ptr_be operator + (std::size_t count) const { const_unaligned_ptr_be<value_type> result = *this; result += count; return result; }
-	const_unaligned_ptr_be operator - (std::size_t count) const { const_unaligned_ptr_be<value_type> result = *this; result -= count; return result; }
-	const value_type operator * () const { return Read(); }
-	const value_type operator [] (std::size_t i) const { return *((*this) + i); }
-	operator bool () const { return mem != nullptr; }
-};
-
-template <typename T>
-class const_unaligned_ptr
-{
-public:
-	using value_type = T;
-private:
-	const std::byte *mem;
-	value_type Read() const
-	{
-		value_type val = value_type();
-		std::memcpy(&val, mem, sizeof(value_type));
-		return val;
-	}
-public:
-	const_unaligned_ptr() : mem(nullptr) {}
-	const_unaligned_ptr(const const_unaligned_ptr<value_type> & other) : mem(other.mem) {}
-	const_unaligned_ptr & operator = (const const_unaligned_ptr<value_type> & other) { mem = other.mem; return *this; }
-	template <typename Tbyte> explicit const_unaligned_ptr(const Tbyte *mem) : mem(mpt::byte_cast<const std::byte*>(mem)) {}
-	const_unaligned_ptr & operator += (std::size_t count) { mem += count * sizeof(value_type); return *this; }
-	const_unaligned_ptr & operator -= (std::size_t count) { mem -= count * sizeof(value_type); return *this; }
-	const_unaligned_ptr & operator ++ () { mem += sizeof(value_type); return *this; }
-	const_unaligned_ptr & operator -- () { mem -= sizeof(value_type); return *this; }
-	const_unaligned_ptr operator ++ (int) { const_unaligned_ptr<value_type> result = *this; ++result; return result; }
-	const_unaligned_ptr operator -- (int) { const_unaligned_ptr<value_type> result = *this; --result; return result; }
-	const_unaligned_ptr operator + (std::size_t count) const { const_unaligned_ptr<value_type> result = *this; result += count; return result; }
-	const_unaligned_ptr operator - (std::size_t count) const { const_unaligned_ptr<value_type> result = *this; result -= count; return result; }
-	const value_type operator * () const { return Read(); }
-	const value_type operator [] (std::size_t i) const { return *((*this) + i); }
-	operator bool () const { return mem != nullptr; }
-};
-
-
-OPENMPT_NAMESPACE_END
-

+ 0 - 152
libopenmpt.mod/openmpt/common/FileReader.cpp

@@ -1,152 +0,0 @@
-/*
- * FileReader.cpp
- * --------------
- * Purpose: A basic class for transparent reading of memory-based files.
- * Notes  : (currently none)
- * Authors: OpenMPT Devs
- * The OpenMPT source code is released under the BSD license. Read LICENSE for more details.
- */
-
-
-#include "stdafx.h"
-#include "FileReader.h"
-
-#if defined(MPT_ENABLE_TEMPFILE) && MPT_OS_WINDOWS
-#include <windows.h>
-#include "mptFileIO.h"
-#endif // MPT_ENABLE_TEMPFILE && MPT_OS_WINDOWS
-
-
-OPENMPT_NAMESPACE_BEGIN
-
-
-#if defined(MPT_ENABLE_TEMPFILE) && MPT_OS_WINDOWS
-
-
-OnDiskFileWrapper::OnDiskFileWrapper(FileReader &file, const mpt::PathString &fileNameExtension)
-	: m_IsTempFile(false)
-{
-	try
-	{
-		file.Rewind();
-		if(file.GetFileName().empty())
-		{
-			const mpt::PathString tempName = mpt::CreateTempFileName(P_("OpenMPT"), fileNameExtension);
-
-#if MPT_OS_WINDOWS && MPT_OS_WINDOWS_WINRT
-#if (_WIN32_WINNT < 0x0602)
-#define MPT_ONDISKFILEWRAPPER_NO_CREATEFILE
-#endif
-#endif
-
-#ifdef MPT_ONDISKFILEWRAPPER_NO_CREATEFILE
-
-			mpt::ofstream f(tempName, std::ios::binary);
-			if(!f)
-			{
-				throw std::runtime_error("");
-			}
-			while(!file.EndOfFile())
-			{
-				FileReader::PinnedRawDataView view = file.ReadPinnedRawDataView(mpt::IO::BUFFERSIZE_NORMAL);
-				std::size_t towrite = view.size();
-				std::size_t written = 0;
-				do
-				{
-					std::size_t chunkSize = mpt::saturate_cast<std::size_t>(towrite);
-					bool chunkOk = false;
-					chunkOk = mpt::IO::WriteRaw(f, mpt::const_byte_span(view.data() + written, chunkSize));
-					if(!chunkOk)
-					{
-						throw std::runtime_error("");
-					}
-					towrite -= chunkSize;
-					written += chunkSize;
-				} while(towrite > 0);
-			}
-			f.close();
-
-#else // !MPT_ONDISKFILEWRAPPER_NO_CREATEFILE
-
-			HANDLE hFile = NULL;
-			#if MPT_OS_WINDOWS_WINRT
-				hFile = CreateFile2(tempName.AsNative().c_str(), GENERIC_WRITE, FILE_SHARE_READ, CREATE_ALWAYS, NULL);
-			#else
-				hFile = CreateFile(tempName.AsNative().c_str(), GENERIC_WRITE, FILE_SHARE_READ, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_TEMPORARY, NULL);
-			#endif
-			if(hFile == NULL || hFile == INVALID_HANDLE_VALUE)
-			{
-				throw std::runtime_error("");
-			}
-			while(!file.EndOfFile())
-			{
-				FileReader::PinnedRawDataView view = file.ReadPinnedRawDataView(mpt::IO::BUFFERSIZE_NORMAL);
-				std::size_t towrite = view.size();
-				std::size_t written = 0;
-				do
-				{
-					DWORD chunkSize = mpt::saturate_cast<DWORD>(towrite);
-					DWORD chunkDone = 0;
-					WriteFile(hFile, view.data() + written, chunkSize, &chunkDone, NULL);
-					if(chunkDone != chunkSize)
-					{
-						CloseHandle(hFile);
-						hFile = NULL;
-						throw std::runtime_error("");
-					}
-					towrite -= chunkDone;
-					written += chunkDone;
-				} while(towrite > 0);
-			}
-			CloseHandle(hFile);
-			hFile = NULL;
-
-#endif // MPT_ONDISKFILEWRAPPER_NO_CREATEFILE
-
-			m_Filename = tempName;
-			m_IsTempFile = true;
-		} else
-		{
-			m_Filename = file.GetFileName();
-		}
-	} catch (const std::runtime_error &)
-	{
-		m_IsTempFile = false;
-		m_Filename = mpt::PathString();
-	}
-}
-
-
-OnDiskFileWrapper::~OnDiskFileWrapper()
-{
-	if(m_IsTempFile)
-	{
-		DeleteFile(m_Filename.AsNative().c_str());
-		m_IsTempFile = false;
-	}
-	m_Filename = mpt::PathString();
-}
-
-
-bool OnDiskFileWrapper::IsValid() const
-{
-	return !m_Filename.empty();
-}
-
-
-mpt::PathString OnDiskFileWrapper::GetFilename() const
-{
-	return m_Filename;
-}
-
-
-#else
-
-
-MPT_MSVC_WORKAROUND_LNK4221(FileReader)
-
-
-#endif // MPT_ENABLE_TEMPFILE && MPT_OS_WINDOWS
-
-
-OPENMPT_NAMESPACE_END

+ 0 - 1443
libopenmpt.mod/openmpt/common/FileReader.h

@@ -1,1443 +0,0 @@
-/*
- * FileReader.h
- * ------------
- * Purpose: A basic class for transparent reading of memory-based files.
- * Notes  : (currently none)
- * Authors: OpenMPT Devs
- * The OpenMPT source code is released under the BSD license. Read LICENSE for more details.
- */
-
-
-#pragma once
-
-#include "BuildSettings.h"
-
-
-#include "mptStringBuffer.h"
-#include "misc_util.h"
-#include "Endianness.h"
-#include "mptIO.h"
-#include <algorithm>
-#include <limits>
-#include <vector>
-#include <cstring>
-
-#include "FileReaderFwd.h"
-
-
-OPENMPT_NAMESPACE_BEGIN
-
-
-// change to show warnings for functions which trigger pre-caching the whole file for unseekable streams
-//#define FILEREADER_DEPRECATED [[deprecated]]
-#define FILEREADER_DEPRECATED
-
-
-class FileReaderTraitsMemory
-{
-
-public:
-
-	using off_t = FileDataContainerMemory::off_t;
-
-	using data_type = FileDataContainerMemory;
-	using ref_data_type = const FileDataContainerMemory &;
-	using shared_data_type = const FileDataContainerMemory &;
-	using value_data_type = FileDataContainerMemory;
-
-	static shared_data_type get_shared(const data_type & data) { return data; }
-	static ref_data_type get_ref(const data_type & data) { return data; }
-
-	static value_data_type make_data() { return mpt::const_byte_span(); }
-	static value_data_type make_data(mpt::const_byte_span data) { return data; }
-
-	static value_data_type make_chunk(shared_data_type data, off_t position, off_t size)
-	{
-		return mpt::as_span(data.GetRawData() + position, size);
-	}
-
-};
-
-class FileReaderTraitsStdStream
-{
-
-public:
-
-	using off_t = IFileDataContainer::off_t;
-
-	using data_type = std::shared_ptr<const IFileDataContainer>;
-	using ref_data_type = const IFileDataContainer &;
-	using shared_data_type = std::shared_ptr<const IFileDataContainer>;
-	using value_data_type = std::shared_ptr<const IFileDataContainer>;
-
-	static shared_data_type get_shared(const data_type & data) { return data; }
-	static ref_data_type get_ref(const data_type & data) { return *data; }
-
-	static value_data_type make_data() { return std::make_shared<FileDataContainerDummy>(); }
-	static value_data_type make_data(mpt::const_byte_span data) { return std::make_shared<FileDataContainerMemory>(data); }
-
-	static value_data_type make_chunk(shared_data_type data, off_t position, off_t size)
-	{
-		return std::static_pointer_cast<IFileDataContainer>(std::make_shared<FileDataContainerWindow>(data, position, size));
-	}
-
-};
-
-using FileReaderTraitsDefault = FileReaderTraitsStdStream;
-
-namespace mpt
-{
-namespace FileReader
-{
-
-	// Read a "T" object from the stream.
-	// If not enough bytes can be read, false is returned.
-	// If successful, the file cursor is advanced by the size of "T".
-	template <typename T, typename TFileCursor>
-	bool Read(TFileCursor &f, T &target)
-	{
-		mpt::byte_span dst = mpt::as_raw_memory(target);
-		if(dst.size() != f.GetRaw(dst))
-		{
-			return false;
-		}
-		f.Skip(dst.size());
-		return true;
-	}
-
-	// Read some kind of integer in little-endian format.
-	// If successful, the file cursor is advanced by the size of the integer.
-	template <typename T, typename TFileCursor>
-	T ReadIntLE(TFileCursor &f)
-	{
-		static_assert(std::numeric_limits<T>::is_integer == true, "Target type is a not an integer");
-		typename mpt::make_le<T>::type target;
-		if(Read(f, target))
-		{
-			return target;
-		} else
-		{
-			return 0;
-		}
-	}
-
-	// Read some kind of integer in big-endian format.
-	// If successful, the file cursor is advanced by the size of the integer.
-	template <typename T, typename TFileCursor>
-	T ReadIntBE(TFileCursor &f)
-	{
-		static_assert(std::numeric_limits<T>::is_integer == true, "Target type is a not an integer");
-		typename mpt::make_be<T>::type target;
-		if(Read(f, target))
-		{
-			return target;
-		} else
-		{
-			return 0;
-		}
-	}
-
-	// Read a integer in little-endian format which has some of its higher bytes not stored in file.
-	// If successful, the file cursor is advanced by the given size.
-	template <typename T, typename TFileCursor>
-	T ReadTruncatedIntLE(TFileCursor &f, typename TFileCursor::off_t size)
-	{
-		static_assert(std::numeric_limits<T>::is_integer == true, "Target type is a not an integer");
-		MPT_ASSERT(sizeof(T) >= size);
-		if(size == 0)
-		{
-			return 0;
-		}
-		if(!f.CanRead(size))
-		{
-			return 0;
-		}
-		uint8 buf[sizeof(T)];
-		bool negative = false;
-		for(std::size_t i = 0; i < sizeof(T); ++i)
-		{
-			uint8 byte = 0;
-			if(i < size)
-			{
-				Read(f, byte);
-				negative = std::numeric_limits<T>::is_signed && ((byte & 0x80) != 0x00);
-			} else
-			{
-				// sign or zero extend
-				byte = negative ? 0xff : 0x00;
-			}
-			buf[i] = byte;
-		}
-		typename mpt::make_le<T>::type target;
-		std::memcpy(&target, buf, sizeof(T));
-		return target;
-	}
-
-	// Read a supplied-size little endian integer to a fixed size variable.
-	// The data is properly sign-extended when fewer bytes are stored.
-	// If more bytes are stored, higher order bytes are silently ignored.
-	// If successful, the file cursor is advanced by the given size.
-	template <typename T, typename TFileCursor>
-	T ReadSizedIntLE(TFileCursor &f, typename TFileCursor::off_t size)
-	{
-		static_assert(std::numeric_limits<T>::is_integer == true, "Target type is a not an integer");
-		if(size == 0)
-		{
-			return 0;
-		}
-		if(!f.CanRead(size))
-		{
-			return 0;
-		}
-		if(size < sizeof(T))
-		{
-			return ReadTruncatedIntLE<T>(f, size);
-		}
-		T retval = ReadIntLE<T>(f);
-		f.Skip(size - sizeof(T));
-		return retval;
-	}
-
-	// Read unsigned 32-Bit integer in little-endian format.
-	// If successful, the file cursor is advanced by the size of the integer.
-	template <typename TFileCursor>
-	uint32 ReadUint32LE(TFileCursor &f)
-	{
-		return ReadIntLE<uint32>(f);
-	}
-
-	// Read unsigned 32-Bit integer in big-endian format.
-	// If successful, the file cursor is advanced by the size of the integer.
-	template <typename TFileCursor>
-	uint32 ReadUint32BE(TFileCursor &f)
-	{
-		return ReadIntBE<uint32>(f);
-	}
-
-	// Read signed 32-Bit integer in little-endian format.
-	// If successful, the file cursor is advanced by the size of the integer.
-	template <typename TFileCursor>
-	int32 ReadInt32LE(TFileCursor &f)
-	{
-		return ReadIntLE<int32>(f);
-	}
-
-	// Read signed 32-Bit integer in big-endian format.
-	// If successful, the file cursor is advanced by the size of the integer.
-	template <typename TFileCursor>
-	int32 ReadInt32BE(TFileCursor &f)
-	{
-		return ReadIntBE<int32>(f);
-	}
-
-	// Read unsigned 16-Bit integer in little-endian format.
-	// If successful, the file cursor is advanced by the size of the integer.
-	template <typename TFileCursor>
-	uint16 ReadUint16LE(TFileCursor &f)
-	{
-		return ReadIntLE<uint16>(f);
-	}
-
-	// Read unsigned 16-Bit integer in big-endian format.
-	// If successful, the file cursor is advanced by the size of the integer.
-	template <typename TFileCursor>
-	uint16 ReadUint16BE(TFileCursor &f)
-	{
-		return ReadIntBE<uint16>(f);
-	}
-
-	// Read signed 16-Bit integer in little-endian format.
-	// If successful, the file cursor is advanced by the size of the integer.
-	template <typename TFileCursor>
-	int16 ReadInt16LE(TFileCursor &f)
-	{
-		return ReadIntLE<int16>(f);
-	}
-
-	// Read signed 16-Bit integer in big-endian format.
-	// If successful, the file cursor is advanced by the size of the integer.
-	template <typename TFileCursor>
-	int16 ReadInt16BE(TFileCursor &f)
-	{
-		return ReadIntBE<int16>(f);
-	}
-
-	// Read a single 8bit character.
-	// If successful, the file cursor is advanced by the size of the integer.
-	template <typename TFileCursor>
-	char ReadChar(TFileCursor &f)
-	{
-		char target;
-		if(Read(f, target))
-		{
-			return target;
-		} else
-		{
-			return 0;
-		}
-	}
-
-	// Read unsigned 8-Bit integer.
-	// If successful, the file cursor is advanced by the size of the integer.
-	template <typename TFileCursor>
-	uint8 ReadUint8(TFileCursor &f)
-	{
-		uint8 target;
-		if(Read(f, target))
-		{
-			return target;
-		} else
-		{
-			return 0;
-		}
-	}
-
-	// Read signed 8-Bit integer. If successful, the file cursor is advanced by the size of the integer.
-	template <typename TFileCursor>
-	int8 ReadInt8(TFileCursor &f)
-	{
-		int8 target;
-		if(Read(f, target))
-		{
-			return target;
-		} else
-		{
-			return 0;
-		}
-	}
-
-	// Read 32-Bit float in little-endian format.
-	// If successful, the file cursor is advanced by the size of the float.
-	template <typename TFileCursor>
-	float ReadFloatLE(TFileCursor &f)
-	{
-		IEEE754binary32LE target;
-		if(Read(f, target))
-		{
-			return target;
-		} else
-		{
-			return 0.0f;
-		}
-	}
-
-	// Read 32-Bit float in big-endian format.
-	// If successful, the file cursor is advanced by the size of the float.
-	template <typename TFileCursor>
-	float ReadFloatBE(TFileCursor &f)
-	{
-		IEEE754binary32BE target;
-		if(Read(f, target))
-		{
-			return target;
-		} else
-		{
-			return 0.0f;
-		}
-	}
-
-	// Read 64-Bit float in little-endian format.
-	// If successful, the file cursor is advanced by the size of the float.
-	template <typename TFileCursor>
-	double ReadDoubleLE(TFileCursor &f)
-	{
-		IEEE754binary64LE target;
-		if(Read(f, target))
-		{
-			return target;
-		} else
-		{
-			return 0.0;
-		}
-	}
-
-	// Read 64-Bit float in big-endian format.
-	// If successful, the file cursor is advanced by the size of the float.
-	template <typename TFileCursor>
-	double ReadDoubleBE(TFileCursor &f)
-	{
-		IEEE754binary64BE target;
-		if(Read(f, target))
-		{
-			return target;
-		} else
-		{
-			return 0.0;
-		}
-	}
-
-	// Read a struct.
-	// If successful, the file cursor is advanced by the size of the struct. Otherwise, the target is zeroed.
-	template <typename T, typename TFileCursor>
-	bool ReadStruct(TFileCursor &f, T &target)
-	{
-		static_assert(mpt::is_binary_safe<T>::value);
-		if(Read(f, target))
-		{
-			return true;
-		} else
-		{
-			Clear(target);
-			return false;
-		}
-	}
-
-	// Allow to read a struct partially (if there's less memory available than the struct's size, fill it up with zeros).
-	// The file cursor is advanced by "partialSize" bytes.
-	template <typename T, typename TFileCursor>
-	typename TFileCursor::off_t ReadStructPartial(TFileCursor &f, T &target, typename TFileCursor::off_t partialSize = sizeof(T))
-	{
-		static_assert(mpt::is_binary_safe<T>::value);
-		typename TFileCursor::off_t copyBytes = std::min(partialSize, sizeof(T));
-		if(!f.CanRead(copyBytes))
-		{
-			copyBytes = f.BytesLeft();
-		}
-		f.GetRaw(mpt::as_raw_memory(target).data(), copyBytes);
-		std::memset(mpt::as_raw_memory(target).data() + copyBytes, 0, sizeof(target) - copyBytes);
-		f.Skip(partialSize);
-		return copyBytes;
-	}
-
-	// Read a string of length srcSize into fixed-length char array destBuffer using a given read mode.
-	// The file cursor is advanced by "srcSize" bytes.
-	// Returns true if at least one byte could be read or 0 bytes were requested.
-	template<mpt::String::ReadWriteMode mode, size_t destSize, typename TFileCursor>
-	bool ReadString(TFileCursor &f, char (&destBuffer)[destSize], const typename TFileCursor::off_t srcSize)
-	{
-		typename TFileCursor::PinnedRawDataView source = f.ReadPinnedRawDataView(srcSize); // Make sure the string is cached properly.
-		typename TFileCursor::off_t realSrcSize = source.size();	// In case fewer bytes are available
-		mpt::String::WriteAutoBuf(destBuffer) = mpt::String::ReadBuf(mode, mpt::byte_cast<const char*>(source.data()), realSrcSize);
-		return (realSrcSize > 0 || srcSize == 0);
-	}
-
-	// Read a string of length srcSize into a std::string dest using a given read mode.
-	// The file cursor is advanced by "srcSize" bytes.
-	// Returns true if at least one character could be read or 0 characters were requested.
-	template<mpt::String::ReadWriteMode mode, typename TFileCursor>
-	bool ReadString(TFileCursor &f, std::string &dest, const typename TFileCursor::off_t srcSize)
-	{
-		dest.clear();
-		typename TFileCursor::PinnedRawDataView source = f.ReadPinnedRawDataView(srcSize);	// Make sure the string is cached properly.
-		typename TFileCursor::off_t realSrcSize = source.size();	// In case fewer bytes are available
-		dest = mpt::String::ReadBuf(mode, mpt::byte_cast<const char*>(source.data()), realSrcSize);
-		return (realSrcSize > 0 || srcSize == 0);
-	}
-
-	// Read a string of length srcSize into a mpt::charbuf dest using a given read mode.
-	// The file cursor is advanced by "srcSize" bytes.
-	// Returns true if at least one character could be read or 0 characters were requested.
-	template<mpt::String::ReadWriteMode mode, std::size_t len, typename TFileCursor>
-	bool ReadString(TFileCursor &f, mpt::charbuf<len> &dest, const typename TFileCursor::off_t srcSize)
-	{
-		typename TFileCursor::PinnedRawDataView source = f.ReadPinnedRawDataView(srcSize);	// Make sure the string is cached properly.
-		typename TFileCursor::off_t realSrcSize = source.size();	// In case fewer bytes are available
-		dest = mpt::String::ReadBuf(mode, mpt::byte_cast<const char*>(source.data()), realSrcSize);
-		return (realSrcSize > 0 || srcSize == 0);
-	}
-
-	// Read a charset encoded string of length srcSize into a mpt::ustring dest using a given read mode.
-	// The file cursor is advanced by "srcSize" bytes.
-	// Returns true if at least one character could be read or 0 characters were requested.
-	template<mpt::String::ReadWriteMode mode, typename TFileCursor>
-	bool ReadString(TFileCursor &f, mpt::ustring &dest, mpt::Charset charset, const typename TFileCursor::off_t srcSize)
-	{
-		dest.clear();
-		typename TFileCursor::PinnedRawDataView source = f.ReadPinnedRawDataView(srcSize);	// Make sure the string is cached properly.
-		typename TFileCursor::off_t realSrcSize = source.size();	// In case fewer bytes are available
-		dest = mpt::ToUnicode(charset, mpt::String::ReadBuf(mode, mpt::byte_cast<const char*>(source.data()), realSrcSize));
-		return (realSrcSize > 0 || srcSize == 0);
-	}
-
-	// Read a string with a preprended length field of type Tsize (must be a packed<*,*> type) into a std::string dest using a given read mode.
-	// The file cursor is advanced by the string length.
-	// Returns true if the size field could be read and at least one character could be read or 0 characters were requested.
-	template<typename Tsize, mpt::String::ReadWriteMode mode, size_t destSize, typename TFileCursor>
-	bool ReadSizedString(TFileCursor &f, char (&destBuffer)[destSize], const typename TFileCursor::off_t maxLength = std::numeric_limits<typename TFileCursor::off_t>::max())
-	{
-		packed<typename Tsize::base_type, typename Tsize::endian_type> srcSize;	// Enforce usage of a packed type by ensuring that the passed type has the required typedefs
-		if(!Read(f, srcSize))
-			return false;
-		return ReadString<mode>(f, destBuffer, std::min(static_cast<typename TFileCursor::off_t>(srcSize), maxLength));
-	}
-
-	// Read a string with a preprended length field of type Tsize (must be a packed<*,*> type) into a std::string dest using a given read mode.
-	// The file cursor is advanced by the string length.
-	// Returns true if the size field could be read and at least one character could be read or 0 characters were requested.
-	template<typename Tsize, mpt::String::ReadWriteMode mode, typename TFileCursor>
-	bool ReadSizedString(TFileCursor &f, std::string &dest, const typename TFileCursor::off_t maxLength = std::numeric_limits<typename TFileCursor::off_t>::max())
-	{
-		packed<typename Tsize::base_type, typename Tsize::endian_type> srcSize;	// Enforce usage of a packed type by ensuring that the passed type has the required typedefs
-		if(!Read(f, srcSize))
-			return false;
-		return ReadString<mode>(f, dest, std::min(static_cast<typename TFileCursor::off_t>(srcSize), maxLength));
-	}
-
-	// Read a string with a preprended length field of type Tsize (must be a packed<*,*> type) into a mpt::charbuf dest using a given read mode.
-	// The file cursor is advanced by the string length.
-	// Returns true if the size field could be read and at least one character could be read or 0 characters were requested.
-	template<typename Tsize, mpt::String::ReadWriteMode mode, std::size_t len, typename TFileCursor>
-	bool ReadSizedString(TFileCursor &f, mpt::charbuf<len> &dest, const typename TFileCursor::off_t maxLength = std::numeric_limits<typename TFileCursor::off_t>::max())
-	{
-		packed<typename Tsize::base_type, typename Tsize::endian_type> srcSize;	// Enforce usage of a packed type by ensuring that the passed type has the required typedefs
-		if(!Read(f, srcSize))
-			return false;
-		return ReadString<mode>(f, dest, std::min(static_cast<typename TFileCursor::off_t>(srcSize), maxLength));
-	}
-
-	// Read a null-terminated string into a std::string
-	template <typename TFileCursor>
-	bool ReadNullString(TFileCursor &f, std::string &dest, const typename TFileCursor::off_t maxLength = std::numeric_limits<typename TFileCursor::off_t>::max())
-	{
-		dest.clear();
-		if(!f.CanRead(1))
-			return false;
-		try
-		{
-			char buffer[64];
-			typename TFileCursor::off_t avail = 0;
-			while((avail = std::min(f.GetRaw(buffer, std::size(buffer)), maxLength - dest.length())) != 0)
-			{
-				auto end = std::find(buffer, buffer + avail, '\0');
-				dest.insert(dest.end(), buffer, end);
-				f.Skip(end - buffer);
-				if(end < buffer + avail)
-				{
-					// Found null char
-					f.Skip(1);
-					break;
-				}
-			}
-		} MPT_EXCEPTION_CATCH_OUT_OF_MEMORY(e)
-		{
-			MPT_EXCEPTION_DELETE_OUT_OF_MEMORY(e);
-		}
-		return dest.length() != 0;
-	}
-
-	// Read a string up to the next line terminator into a std::string
-	template <typename TFileCursor>
-	bool ReadLine(TFileCursor &f, std::string &dest, const typename TFileCursor::off_t maxLength = std::numeric_limits<typename TFileCursor::off_t>::max())
-	{
-		dest.clear();
-		if(!f.CanRead(1))
-			return false;
-		try
-		{
-			char buffer[64];
-			char c = '\0';
-			typename TFileCursor::off_t avail = 0;
-			while((avail = std::min(f.GetRaw(buffer, std::size(buffer)), maxLength - dest.length())) != 0)
-			{
-				auto end = std::find_if(buffer, buffer + avail, mpt::String::Traits<std::string>::IsLineEnding);
-				dest.insert(dest.end(), buffer, end);
-				f.Skip(end - buffer);
-				if(end < buffer + avail)
-				{
-					// Found line ending
-					f.Skip(1);
-					// Handle CRLF line ending
-					if(*end == '\r')
-					{
-						if(Read(f, c) && c != '\n')
-							f.SkipBack(1);
-					}
-					break;
-				}
-			}
-		} MPT_EXCEPTION_CATCH_OUT_OF_MEMORY(e)
-		{
-			MPT_EXCEPTION_DELETE_OUT_OF_MEMORY(e);
-		}
-		return true;
-	}
-
-	// Read an array of binary-safe T values.
-	// If successful, the file cursor is advanced by the size of the array.
-	// Otherwise, the target is zeroed.
-	template<typename T, std::size_t destSize, typename TFileCursor>
-	bool ReadArray(TFileCursor &f, T (&destArray)[destSize])
-	{
-		static_assert(mpt::is_binary_safe<T>::value);
-		if(f.CanRead(sizeof(destArray)))
-		{
-			for(auto &element : destArray)
-			{
-				Read(f, element);
-			}
-			return true;
-		} else
-		{
-			Clear(destArray);
-			return false;
-		}
-	}
-
-	// Read an array of binary-safe T values.
-	// If successful, the file cursor is advanced by the size of the array.
-	// Otherwise, the target is zeroed.
-	template<typename T, std::size_t destSize, typename TFileCursor>
-	bool ReadArray(TFileCursor &f, std::array<T, destSize> &destArray)
-	{
-		static_assert(mpt::is_binary_safe<T>::value);
-		if(f.CanRead(sizeof(destArray)))
-		{
-			for(auto &element : destArray)
-			{
-				Read(f, element);
-			}
-			return true;
-		} else
-		{
-			destArray.fill(T());
-			return false;
-		}
-	}
-
-	// Read destSize elements of binary-safe type T into a vector.
-	// If successful, the file cursor is advanced by the size of the vector.
-	// Otherwise, the vector is resized to destSize, but possibly existing contents are not cleared.
-	template<typename T, typename TFileCursor>
-	bool ReadVector(TFileCursor &f, std::vector<T> &destVector, size_t destSize)
-	{
-		static_assert(mpt::is_binary_safe<T>::value);
-		destVector.resize(destSize);
-		if(f.CanRead(sizeof(T) * destSize))
-		{
-			for(auto &element : destVector)
-			{
-				Read(f, element);
-			}
-			return true;
-		} else
-		{
-			return false;
-		}
-	}
-
-	template <typename T, std::size_t destSize, typename TFileCursor>
-	std::array<T, destSize> ReadArray(TFileCursor &f)
-	{
-		std::array<T, destSize> destArray;
-		ReadArray(f, destArray);
-		return destArray;
-	}
-
-	// Compare a magic string with the current stream position.
-	// Returns true if they are identical and advances the file cursor by the the length of the "magic" string.
-	// Returns false if the string could not be found. The file cursor is not advanced in this case.
-	template <typename TFileCursor>
-	bool ReadMagic(TFileCursor &f, const char *const magic, typename TFileCursor::off_t magicLength)
-	{
-		std::byte buffer[16] = { std::byte(0) };
-		typename TFileCursor::off_t bytesRead = 0;
-		typename TFileCursor::off_t bytesRemain = magicLength;
-		while(bytesRemain)
-		{
-			typename TFileCursor::off_t numBytes = std::min(static_cast<typename TFileCursor::off_t>(sizeof(buffer)), bytesRemain);
-			if(f.GetRawWithOffset(bytesRead, buffer, numBytes) != numBytes)
-				return false;
-			if(memcmp(buffer, magic + bytesRead, numBytes))
-				return false;
-			bytesRemain -= numBytes;
-			bytesRead += numBytes;
-		}
-		f.Skip(magicLength);
-		return true;
-	}
-	template<size_t N, typename TFileCursor>
-	bool ReadMagic(TFileCursor &f, const char (&magic)[N])
-	{
-		MPT_ASSERT(magic[N - 1] == '\0');
-		for(std::size_t i = 0; i < N - 1; ++i)
-		{
-			MPT_ASSERT(magic[i] != '\0');
-		}
-		return ReadMagic(f, static_cast<const char*>(magic), static_cast<typename TFileCursor::off_t>(N - 1));
-	}
-
-	// Read variable-length unsigned integer (as found in MIDI files).
-	// If successful, the file cursor is advanced by the size of the integer and true is returned.
-	// False is returned if not enough bytes were left to finish reading of the integer or if an overflow happened (source doesn't fit into target integer).
-	// In case of an overflow, the target is also set to the maximum value supported by its data type.
-	template<typename T, typename TFileCursor>
-	bool ReadVarInt(TFileCursor &f, T &target)
-	{
-		static_assert(std::numeric_limits<T>::is_integer == true
-			&& std::numeric_limits<T>::is_signed == false,
-			"Target type is not an unsigned integer");
-
-		if(f.NoBytesLeft())
-		{
-			target = 0;
-			return false;
-		}
-
-		std::byte bytes[16];	// More than enough for any valid VarInt
-		typename TFileCursor::off_t avail = f.GetRaw(bytes, sizeof(bytes));
-		typename TFileCursor::off_t readPos = 1;
-		
-		size_t writtenBits = 0;
-		uint8 b = mpt::byte_cast<uint8>(bytes[0]);
-		target = (b & 0x7F);
-
-		// Count actual bits used in most significant byte (i.e. this one)
-		for(size_t bit = 0; bit < 7; bit++)
-		{
-			if((b & (1u << bit)) != 0)
-			{
-				writtenBits = bit + 1;
-			}
-		}
-
-		while(readPos < avail && (b & 0x80) != 0)
-		{
-			b = mpt::byte_cast<uint8>(bytes[readPos++]);
-			target <<= 7;
-			target |= (b & 0x7F);
-			writtenBits += 7;
-			if(readPos == avail)
-			{
-				f.Skip(readPos);
-				avail = f.GetRaw(bytes, sizeof(bytes));
-				readPos = 0;
-			}
-		}
-		f.Skip(readPos);
-
-		if(writtenBits > sizeof(target) * 8u)
-		{
-			// Overflow
-			target = Util::MaxValueOfType<T>(target);
-			return false;
-		} else if((b & 0x80) != 0)
-		{
-			// Reached EOF
-			return false;
-		}
-		return true;
-	}
-
-} // namespace FileReader
-} // namespace mpt
-
-namespace FR = mpt::FileReader;
-
-namespace detail {
-
-template <typename Ttraits>
-class FileReader
-{
-
-private:
-
-	using traits_type = Ttraits;
-	
-public:
-
-	using off_t = typename traits_type::off_t;
-
-	using data_type        = typename traits_type::data_type;
-	using ref_data_type    = typename traits_type::ref_data_type;
-	using shared_data_type = typename traits_type::shared_data_type;
-	using value_data_type  = typename traits_type::value_data_type;
-
-protected:
-
-	shared_data_type SharedDataContainer() const { return traits_type::get_shared(m_data); }
-	ref_data_type DataContainer() const { return traits_type::get_ref(m_data); }
-
-	static value_data_type DataInitializer() { return traits_type::make_data(); }
-	static value_data_type DataInitializer(mpt::const_byte_span data) { return traits_type::make_data(data); }
-
-	static value_data_type CreateChunkImpl(shared_data_type data, off_t position, off_t size) { return traits_type::make_chunk(data, position, size); }
-
-private:
-
-	data_type m_data;
-
-	off_t streamPos;		// Cursor location in the file
-
-	const mpt::PathString *fileName;  // Filename that corresponds to this FileReader. It is only set if this FileReader represents the whole contents of fileName. May be nullptr. Lifetime is managed outside of FileReader.
-
-public:
-
-	// Initialize invalid file reader object.
-	FileReader() : m_data(DataInitializer()), streamPos(0), fileName(nullptr) { }
-
-	// Initialize file reader object with pointer to data and data length.
-	template <typename Tbyte> FileReader(mpt::span<Tbyte> bytedata, const mpt::PathString *filename = nullptr) : m_data(DataInitializer(mpt::byte_cast<mpt::const_byte_span>(bytedata))), streamPos(0), fileName(filename) { }
-
-	// Initialize file reader object based on an existing file reader object window.
-	explicit FileReader(value_data_type other, const mpt::PathString *filename = nullptr) : m_data(other), streamPos(0), fileName(filename) { }
-
-public:
-
-	mpt::PathString GetFileName() const
-	{
-		if(!fileName)
-		{
-			return mpt::PathString();
-		}
-		return *fileName;
-	}
-
-	// Returns true if the object points to a valid (non-empty) stream.
-	operator bool() const
-	{
-		return IsValid();
-	}
-
-	// Returns true if the object points to a valid (non-empty) stream.
-	bool IsValid() const
-	{
-		return DataContainer().IsValid();
-	}
-
-	// Reset cursor to first byte in file.
-	void Rewind()
-	{
-		streamPos = 0;
-	}
-
-	// Seek to a position in the mapped file.
-	// Returns false if position is invalid.
-	bool Seek(off_t position)
-	{
-		if(position <= streamPos)
-		{
-			streamPos = position;
-			return true;
-		}
-		if(position <= DataContainer().GetLength())
-		{
-			streamPos = position;
-			return true;
-		} else
-		{
-			return false;
-		}
-	}
-
-	// Increases position by skipBytes.
-	// Returns true if skipBytes could be skipped or false if the file end was reached earlier.
-	bool Skip(off_t skipBytes)
-	{
-		if(CanRead(skipBytes))
-		{
-			streamPos += skipBytes;
-			return true;
-		} else
-		{
-			streamPos = DataContainer().GetLength();
-			return false;
-		}
-	}
-
-	// Decreases position by skipBytes.
-	// Returns true if skipBytes could be skipped or false if the file start was reached earlier.
-	bool SkipBack(off_t skipBytes)
-	{
-		if(streamPos >= skipBytes)
-		{
-			streamPos -= skipBytes;
-			return true;
-		} else
-		{
-			streamPos = 0;
-			return false;
-		}
-	}
-
-	// Returns cursor position in the mapped file.
-	off_t GetPosition() const
-	{
-		return streamPos;
-	}
-
-	// Return true IFF seeking and GetLength() is fast.
-	// In particular, it returns false for unseekable stream where GetLength()
-	// requires pre-caching.
-	bool HasFastGetLength() const
-	{
-		return DataContainer().HasFastGetLength();
-	}
-
-	// Returns size of the mapped file in bytes.
-	FILEREADER_DEPRECATED off_t GetLength() const
-	{
-		// deprecated because in case of an unseekable std::istream, this triggers caching of the whole file
-		return DataContainer().GetLength();
-	}
-
-	// Return byte count between cursor position and end of file, i.e. how many bytes can still be read.
-	FILEREADER_DEPRECATED off_t BytesLeft() const
-	{
-		// deprecated because in case of an unseekable std::istream, this triggers caching of the whole file
-		return DataContainer().GetLength() - streamPos;
-	}
-
-	bool EndOfFile() const
-	{
-		return !CanRead(1);
-	}
-
-	bool NoBytesLeft() const
-	{
-		return !CanRead(1);
-	}
-
-	// Check if "amount" bytes can be read from the current position in the stream.
-	bool CanRead(off_t amount) const
-	{
-		return DataContainer().CanRead(streamPos, amount);
-	}
-
-	// Check if file size is at least size, without potentially caching the whole file to query the exact file length.
-	bool LengthIsAtLeast(off_t size) const
-	{
-		return DataContainer().CanRead(0, size);
-	}
-
-	// Check if file size is exactly size, without potentially caching the whole file if it is larger.
-	bool LengthIs(off_t size) const
-	{
-		return DataContainer().CanRead(0, size) && !DataContainer().CanRead(size, 1);
-	}
-
-protected:
-
-	FileReader CreateChunk(off_t position, off_t length) const
-	{
-		off_t readableLength = DataContainer().GetReadableLength(position, length);
-		if(readableLength == 0)
-		{
-			return FileReader();
-		}
-		return FileReader(CreateChunkImpl(SharedDataContainer(), position, std::min(length, DataContainer().GetLength() - position)));
-	}
-
-public:
-
-	// Create a new FileReader object for parsing a sub chunk at a given position with a given length.
-	// The file cursor is not modified.
-	FileReader GetChunkAt(off_t position, off_t length) const
-	{
-		return CreateChunk(position, length);
-	}
-
-	// Create a new FileReader object for parsing a sub chunk at the current position with a given length.
-	// The file cursor is not advanced.
-	FileReader GetChunk(off_t length)
-	{
-		return CreateChunk(streamPos, length);
-	}
-	// Create a new FileReader object for parsing a sub chunk at the current position with a given length.
-	// The file cursor is advanced by "length" bytes.
-	FileReader ReadChunk(off_t length)
-	{
-		off_t position = streamPos;
-		Skip(length);
-		return CreateChunk(position, length);
-	}
-
-	class PinnedRawDataView
-	{
-	private:
-		std::size_t size_;
-		const std::byte *pinnedData;
-		std::vector<std::byte> cache;
-	private:
-		void Init(const FileReader &file, std::size_t size)
-		{
-			size_ = 0;
-			pinnedData = nullptr;
-			if(!file.CanRead(size))
-			{
-				size = file.BytesLeft();
-			}
-			size_ = size;
-			if(file.DataContainer().HasPinnedView())
-			{
-				pinnedData = file.DataContainer().GetRawData() + file.GetPosition();
-			} else
-			{
-				cache.resize(size_);
-				if(!cache.empty())
-				{
-					// cppcheck false-positive
-					// cppcheck-suppress containerOutOfBounds
-					file.GetRaw(&(cache[0]), size);
-				}
-			}
-		}
-	public:
-		PinnedRawDataView()
-			: size_(0)
-			, pinnedData(nullptr)
-		{
-		}
-		PinnedRawDataView(const FileReader &file)
-		{
-			Init(file, file.BytesLeft());
-		}
-		PinnedRawDataView(const FileReader &file, std::size_t size)
-		{
-			Init(file, size);
-		}
-		PinnedRawDataView(FileReader &file, bool advance)
-		{
-			Init(file, file.BytesLeft());
-			if(advance)
-			{
-				file.Skip(size_);
-			}
-		}
-		PinnedRawDataView(FileReader &file, std::size_t size, bool advance)
-		{
-			Init(file, size);
-			if(advance)
-			{
-				file.Skip(size_);
-			}
-		}
-	public:
-		mpt::const_byte_span GetSpan() const
-		{
-			if(pinnedData)
-			{
-				return mpt::as_span(pinnedData, size_);
-			} else if(!cache.empty())
-			{
-				return mpt::as_span(cache);
-			} else
-			{
-				return mpt::const_byte_span();
-			}
-		}
-		mpt::const_byte_span span() const { return GetSpan(); }
-		void invalidate() { size_ = 0; pinnedData = nullptr; cache = std::vector<std::byte>(); }
-		const std::byte *data() const { return span().data(); }
-		std::size_t size() const { return size_; }
-		mpt::const_byte_span::iterator begin() const { return span().begin(); }
-		mpt::const_byte_span::iterator end() const { return span().end(); }
-		mpt::const_byte_span::const_iterator cbegin() const { return span().cbegin(); }
-		mpt::const_byte_span::const_iterator cend() const { return span().cend(); }
-	};
-
-	// Returns a pinned view into the remaining raw data from cursor position.
-	PinnedRawDataView GetPinnedRawDataView() const
-	{
-		return PinnedRawDataView(*this);
-	}
-	// Returns a pinned view into the remeining raw data from cursor position, clamped at size.
-	PinnedRawDataView GetPinnedRawDataView(std::size_t size) const
-	{
-		return PinnedRawDataView(*this, size);
-	}
-
-	// Returns a pinned view into the remeining raw data from cursor position.
-	// File cursor is advaned by the size of the returned pinned view.
-	PinnedRawDataView ReadPinnedRawDataView()
-	{
-		return PinnedRawDataView(*this, true);
-	}
-	// Returns a pinned view into the remeining raw data from cursor position, clamped at size.
-	// File cursor is advaned by the size of the returned pinned view.
-	PinnedRawDataView ReadPinnedRawDataView(std::size_t size)
-	{
-		return PinnedRawDataView(*this, size, true);
-	}
-
-	// Returns raw stream data at cursor position.
-	// Should only be used if absolutely necessary, for example for sample reading, or when used with a small chunk of the file retrieved by ReadChunk().
-	// Use GetPinnedRawDataView(size) whenever possible.
-	FILEREADER_DEPRECATED const std::byte *GetRawData() const
-	{
-		// deprecated because in case of an unseekable std::istream, this triggers caching of the whole file
-		return DataContainer().GetRawData() + streamPos;
-	}
-	template <typename T>
-	FILEREADER_DEPRECATED const T *GetRawData() const
-	{
-		// deprecated because in case of an unseekable std::istream, this triggers caching of the whole file
-		return mpt::byte_cast<const T*>(DataContainer().GetRawData() + streamPos);
-	}
-
-	template <typename T>
-	std::size_t GetRawWithOffset(std::size_t offset, T *dst, std::size_t count) const
-	{
-		return static_cast<std::size_t>(DataContainer().Read(mpt::byte_cast<std::byte*>(dst), streamPos + offset, count));
-	}
-	std::size_t GetRawWithOffset(std::size_t offset, mpt::byte_span dst) const
-	{
-		return static_cast<std::size_t>(DataContainer().Read(streamPos + offset, dst));
-	}
-
-	template <typename T>
-	std::size_t GetRaw(T *dst, std::size_t count) const
-	{
-		return static_cast<std::size_t>(DataContainer().Read(mpt::byte_cast<std::byte*>(dst), streamPos, count));
-	}
-	std::size_t GetRaw(mpt::byte_span dst) const
-	{
-		return static_cast<std::size_t>(DataContainer().Read(streamPos, dst));
-	}
-
-	template <typename T>
-	std::size_t ReadRaw(T *dst, std::size_t count)
-	{
-		std::size_t result = static_cast<std::size_t>(DataContainer().Read(mpt::byte_cast<std::byte*>(dst), streamPos, count));
-		streamPos += result;
-		return result;
-	}
-	std::size_t ReadRaw(mpt::byte_span dst)
-	{
-		std::size_t result = static_cast<std::size_t>(DataContainer().Read(streamPos, dst));
-		streamPos += result;
-		return result;
-	}
-	
-	std::vector<std::byte> GetRawDataAsByteVector() const
-	{
-		PinnedRawDataView view = GetPinnedRawDataView();
-		return std::vector<std::byte>(view.span().begin(), view.span().end());
-	}
-	std::vector<std::byte> ReadRawDataAsByteVector()
-	{
-		PinnedRawDataView view = ReadPinnedRawDataView();
-		return std::vector<std::byte>(view.span().begin(), view.span().end());
-	}
-	std::vector<std::byte> GetRawDataAsByteVector(std::size_t size) const
-	{
-		PinnedRawDataView view = GetPinnedRawDataView(size);
-		return std::vector<std::byte>(view.span().begin(), view.span().end());
-	}
-	std::vector<std::byte> ReadRawDataAsByteVector(std::size_t size)
-	{
-		PinnedRawDataView view = ReadPinnedRawDataView(size);
-		return std::vector<std::byte>(view.span().begin(), view.span().end());
-	}
-
-	std::string GetRawDataAsString() const
-	{
-		PinnedRawDataView view = GetPinnedRawDataView();
-		return std::string(mpt::byte_cast<const char*>(view.span().begin()), mpt::byte_cast<const char*>(view.span().end()));
-	}
-	std::string ReadRawDataAsString()
-	{
-		PinnedRawDataView view = ReadPinnedRawDataView();
-		return std::string(mpt::byte_cast<const char*>(view.span().begin()), mpt::byte_cast<const char*>(view.span().end()));
-	}
-	std::string GetRawDataAsString(std::size_t size) const
-	{
-		PinnedRawDataView view = GetPinnedRawDataView(size);
-		return std::string(mpt::byte_cast<const char*>(view.span().begin()), mpt::byte_cast<const char*>(view.span().end()));
-	}
-	std::string ReadRawDataAsString(std::size_t size)
-	{
-		PinnedRawDataView view = ReadPinnedRawDataView(size);
-		return std::string(mpt::byte_cast<const char*>(view.span().begin()), mpt::byte_cast<const char*>(view.span().end()));
-	}
-
-	template <typename T>
-	bool Read(T &target)
-	{
-		return mpt::FileReader::Read(*this, target);
-	}
-
-	template <typename T>
-	T ReadIntLE()
-	{
-		return mpt::FileReader::ReadIntLE<T>(*this);
-	}
-
-	template <typename T>
-	T ReadIntBE()
-	{
-		return mpt::FileReader::ReadIntLE<T>(*this);
-	}
-
-	template <typename T>
-	T ReadTruncatedIntLE(off_t size)
-	{
-		return mpt::FileReader::ReadTruncatedIntLE<T>(*this, size);
-	}
-
-	template <typename T>
-	T ReadSizedIntLE(off_t size)
-	{
-		return mpt::FileReader::ReadSizedIntLE<T>(*this, size);
-	}
-
-	uint32 ReadUint32LE()
-	{
-		return mpt::FileReader::ReadUint32LE(*this);
-	}
-
-	uint32 ReadUint32BE()
-	{
-		return mpt::FileReader::ReadUint32BE(*this);
-	}
-
-	int32 ReadInt32LE()
-	{
-		return mpt::FileReader::ReadInt32LE(*this);
-	}
-
-	int32 ReadInt32BE()
-	{
-		return mpt::FileReader::ReadInt32BE(*this);
-	}
-
-	uint16 ReadUint16LE()
-	{
-		return mpt::FileReader::ReadUint16LE(*this);
-	}
-
-	uint16 ReadUint16BE()
-	{
-		return mpt::FileReader::ReadUint16BE(*this);
-	}
-
-	int16 ReadInt16LE()
-	{
-		return mpt::FileReader::ReadInt16LE(*this);
-	}
-
-	int16 ReadInt16BE()
-	{
-		return mpt::FileReader::ReadInt16BE(*this);
-	}
-
-	char ReadChar()
-	{
-		return mpt::FileReader::ReadChar(*this);
-	}
-
-	uint8 ReadUint8()
-	{
-		return mpt::FileReader::ReadUint8(*this);
-	}
-
-	int8 ReadInt8()
-	{
-		return mpt::FileReader::ReadInt8(*this);
-	}
-
-	float ReadFloatLE()
-	{
-		return mpt::FileReader::ReadFloatLE(*this);
-	}
-
-	float ReadFloatBE()
-	{
-		return mpt::FileReader::ReadFloatBE(*this);
-	}
-
-	double ReadDoubleLE()
-	{
-		return mpt::FileReader::ReadDoubleLE(*this);
-	}
-
-	double ReadDoubleBE()
-	{
-		return mpt::FileReader::ReadDoubleBE(*this);
-	}
-
-	template <typename T>
-	bool ReadStruct(T &target)
-	{
-		return mpt::FileReader::ReadStruct(*this, target);
-	}
-
-	template <typename T>
-	size_t ReadStructPartial(T &target, size_t partialSize = sizeof(T))
-	{
-		return mpt::FileReader::ReadStructPartial(*this, target, partialSize);
-	}
-
-	template<mpt::String::ReadWriteMode mode, size_t destSize>
-	bool ReadString(char (&destBuffer)[destSize], const off_t srcSize)
-	{
-		return mpt::FileReader::ReadString<mode>(*this, destBuffer, srcSize);
-	}
-
-	template<mpt::String::ReadWriteMode mode>
-	bool ReadString(std::string &dest, const off_t srcSize)
-	{
-		return mpt::FileReader::ReadString<mode>(*this, dest, srcSize);
-	}
-
-	template<mpt::String::ReadWriteMode mode, std::size_t len>
-	bool ReadString(mpt::charbuf<len> &dest, const off_t srcSize)
-	{
-		return mpt::FileReader::ReadString<mode>(*this, dest, srcSize);
-	}
-
-	template<mpt::String::ReadWriteMode mode>
-	bool ReadString(mpt::ustring &dest, mpt::Charset charset, const off_t srcSize)
-	{
-		return mpt::FileReader::ReadString<mode>(*this, dest, charset, srcSize);
-	}
-
-	template<typename Tsize, mpt::String::ReadWriteMode mode, size_t destSize>
-	bool ReadSizedString(char (&destBuffer)[destSize], const off_t maxLength = std::numeric_limits<off_t>::max())
-	{
-		return mpt::FileReader::ReadSizedString<Tsize, mode>(*this, destBuffer, maxLength);
-	}
-
-	template<typename Tsize, mpt::String::ReadWriteMode mode>
-	bool ReadSizedString(std::string &dest, const off_t maxLength = std::numeric_limits<off_t>::max())
-	{
-		return mpt::FileReader::ReadSizedString<Tsize, mode>(*this, dest, maxLength);
-	}
-
-	template<typename Tsize, mpt::String::ReadWriteMode mode, std::size_t len>
-	bool ReadSizedString(mpt::charbuf<len> &dest, const off_t maxLength = std::numeric_limits<off_t>::max())
-	{
-		return mpt::FileReader::ReadSizedString<Tsize, mode, len>(*this, dest, maxLength);
-	}
-
-	bool ReadNullString(std::string &dest, const off_t maxLength = std::numeric_limits<off_t>::max())
-	{
-		return mpt::FileReader::ReadNullString(*this, dest, maxLength);
-	}
-
-	bool ReadLine(std::string &dest, const off_t maxLength = std::numeric_limits<off_t>::max())
-	{
-		return mpt::FileReader::ReadLine(*this, dest, maxLength);
-	}
-
-	template<typename T, std::size_t destSize>
-	bool ReadArray(T (&destArray)[destSize])
-	{
-		return mpt::FileReader::ReadArray(*this, destArray);
-	}
-
-	template<typename T, std::size_t destSize>
-	bool ReadArray(std::array<T, destSize> &destArray)
-	{
-		return mpt::FileReader::ReadArray(*this, destArray);
-	}
-
-	template <typename T, std::size_t destSize>
-	std::array<T, destSize> ReadArray()
-	{
-		return mpt::FileReader::ReadArray<T, destSize>(*this);
-	}
-
-	template<typename T>
-	bool ReadVector(std::vector<T> &destVector, size_t destSize)
-	{
-		return mpt::FileReader::ReadVector(*this, destVector, destSize);
-	}
-
-	template<size_t N>
-	bool ReadMagic(const char (&magic)[N])
-	{
-		return mpt::FileReader::ReadMagic(*this, magic);
-	}
-
-	bool ReadMagic(const char *const magic, off_t magicLength)
-	{
-		return mpt::FileReader::ReadMagic(*this, magic, magicLength);
-	}
-
-	template<typename T>
-	bool ReadVarInt(T &target)
-	{
-		return mpt::FileReader::ReadVarInt(*this, target);
-	}
-
-};
-
-} // namespace detail
-
-using FileReader = detail::FileReader<FileReaderTraitsDefault>;
-
-using MemoryFileReader = detail::FileReader<FileReaderTraitsMemory>;
-
-
-// Initialize file reader object with pointer to data and data length.
-template <typename Tbyte> static inline FileReader make_FileReader(mpt::span<Tbyte> bytedata, const mpt::PathString *filename = nullptr)
-{
-	return FileReader(mpt::byte_cast<mpt::const_byte_span>(bytedata), filename);
-}
-
-#if defined(MPT_FILEREADER_CALLBACK_STREAM)
-
-// Initialize file reader object with a CallbackStream.
-static inline FileReader make_FileReader(CallbackStream s, const mpt::PathString *filename = nullptr)
-{
-	return FileReader(
-				FileDataContainerCallbackStreamSeekable::IsSeekable(s) ?
-					std::static_pointer_cast<IFileDataContainer>(std::make_shared<FileDataContainerCallbackStreamSeekable>(s))
-				:
-					std::static_pointer_cast<IFileDataContainer>(std::make_shared<FileDataContainerCallbackStream>(s))
-			, filename
-		);
-}
-#endif // MPT_FILEREADER_CALLBACK_STREAM
-	
-// Initialize file reader object with a std::istream.
-static inline FileReader make_FileReader(std::istream *s, const mpt::PathString *filename = nullptr)
-{
-	return FileReader(
-				FileDataContainerStdStreamSeekable::IsSeekable(s) ?
-					std::static_pointer_cast<IFileDataContainer>(std::make_shared<FileDataContainerStdStreamSeekable>(s))
-				:
-					std::static_pointer_cast<IFileDataContainer>(std::make_shared<FileDataContainerStdStream>(s))
-			, filename
-		);
-}
-
-
-#if defined(MPT_ENABLE_FILEIO)
-// templated in order to reduce header inter-dependencies
-template <typename TInputFile>
-FileReader GetFileReader(TInputFile &file)
-{
-	if(!file.IsValid())
-	{
-		return FileReader();
-	}
-	if(file.IsCached())
-	{
-		return make_FileReader(file.GetCache(), &file.GetFilenameRef());
-	} else
-	{
-		return make_FileReader(file.GetStream(), &file.GetFilenameRef());
-	}
-}
-#endif // MPT_ENABLE_FILEIO
-
-
-#if defined(MPT_ENABLE_TEMPFILE) && MPT_OS_WINDOWS
-
-class OnDiskFileWrapper
-{
-
-private:
-
-	mpt::PathString m_Filename;
-	bool m_IsTempFile;
-
-public:
-
-	OnDiskFileWrapper(FileReader &file, const mpt::PathString &fileNameExtension = P_("tmp"));
-
-	~OnDiskFileWrapper();
-
-public:
-
-	bool IsValid() const;
-
-	mpt::PathString GetFilename() const;
-
-}; // class OnDiskFileWrapper
-
-#endif // MPT_ENABLE_TEMPFILE && MPT_OS_WINDOWS
-
-
-OPENMPT_NAMESPACE_END

+ 0 - 35
libopenmpt.mod/openmpt/common/FileReaderFwd.h

@@ -1,35 +0,0 @@
-/*
- * FileReaderFwd.h
- * ---------------
- * Purpose: Forward declaration for class FileReader.
- * Notes  : (currently none)
- * Authors: OpenMPT Devs
- * The OpenMPT source code is released under the BSD license. Read LICENSE for more details.
- */
-
-#pragma once
-
-#include "BuildSettings.h"
-
-
-OPENMPT_NAMESPACE_BEGIN
-
-class FileReaderTraitsMemory;
-
-class FileReaderTraitsStdStream;
-
-using FileReaderTraitsDefault = FileReaderTraitsStdStream;
-
-namespace detail {
-
-template <typename Ttraits>
-class FileReader;
-
-} // namespace detail
-
-using FileReader = detail::FileReader<FileReaderTraitsDefault>;
-
-using MemoryFileReader = detail::FileReader<FileReaderTraitsMemory>;
-
-OPENMPT_NAMESPACE_END
-

+ 0 - 415
libopenmpt.mod/openmpt/common/FlagSet.h

@@ -1,415 +0,0 @@
-/*
- * FlagSet.h
- * ---------
- * Purpose: A flexible and typesafe flag set class.
- * Notes  : Originally based on http://stackoverflow.com/questions/4226960/type-safer-bitflags-in-c .
- *          Rewritten to be standard-conforming.
- * Authors: OpenMPT Devs
- * The OpenMPT source code is released under the BSD license. Read LICENSE for more details.
- */
-
-
-#pragma once
-
-#include "BuildSettings.h"
-
-#include <string>
-
-OPENMPT_NAMESPACE_BEGIN
-
-
-// Be aware of the required size when specializing this.
-// We cannot assert the minimum size because some compilers always allocate an 'int',
-// even for enums that would fit in smaller integral types.
-template <typename Tenum>
-struct enum_traits
-{
-	using store_type = typename std::make_unsigned<Tenum>::type;
-};
-
-
-// Type-safe wrapper around an enum, that can represent all enum values and bitwise compositions thereof.
-// Conversions to and from plain integers as well as conversions to the base enum are always explicit.
-template <typename enum_t>
-// cppcheck-suppress copyCtorAndEqOperator
-class enum_value_type
-{
-public:
-	using enum_type = enum_t;
-	using value_type = enum_value_type;
-	using store_type = typename enum_traits<enum_t>::store_type;
-private:
-	store_type bits;
-public:
-	MPT_CONSTEXPR11_FUN enum_value_type() noexcept : bits(0) { }
-	MPT_CONSTEXPR11_FUN enum_value_type(const enum_value_type &x) noexcept : bits(x.bits) { }
-	MPT_CONSTEXPR11_FUN enum_value_type(enum_type x) noexcept : bits(static_cast<store_type>(x)) { }
-private:
-	explicit MPT_CONSTEXPR11_FUN enum_value_type(store_type x) noexcept : bits(x) { } // private in order to prevent accidental conversions. use from_bits.
-	MPT_CONSTEXPR11_FUN operator store_type () const noexcept { return bits; }  // private in order to prevent accidental conversions. use as_bits.
-public:
-	static MPT_CONSTEXPR11_FUN enum_value_type from_bits(store_type bits) noexcept { return value_type(bits); }
-	MPT_CONSTEXPR11_FUN enum_type as_enum() const noexcept { return static_cast<enum_t>(bits); }
-	MPT_CONSTEXPR11_FUN store_type as_bits() const noexcept { return bits; }
-public:
-	MPT_CONSTEXPR11_FUN operator bool () const noexcept { return bits != store_type(); }
-	MPT_CONSTEXPR11_FUN bool operator ! () const noexcept { return bits == store_type(); }
-
-	MPT_CONSTEXPR11_FUN const enum_value_type operator ~ () const noexcept { return enum_value_type(~bits); }
-
-	friend MPT_CONSTEXPR11_FUN bool operator == (enum_value_type a, enum_value_type b) noexcept { return a.bits == b.bits; }
-	friend MPT_CONSTEXPR11_FUN bool operator != (enum_value_type a, enum_value_type b) noexcept { return a.bits != b.bits; }
-	
-	friend MPT_CONSTEXPR11_FUN bool operator == (enum_value_type a, enum_t b) noexcept { return a == enum_value_type(b); }
-	friend MPT_CONSTEXPR11_FUN bool operator != (enum_value_type a, enum_t b) noexcept { return a != enum_value_type(b); }
-	
-	friend MPT_CONSTEXPR11_FUN bool operator == (enum_t a, enum_value_type b) noexcept { return enum_value_type(a) == b; }
-	friend MPT_CONSTEXPR11_FUN bool operator != (enum_t a, enum_value_type b) noexcept { return enum_value_type(a) != b; }
-	
-	friend MPT_CONSTEXPR11_FUN const enum_value_type operator | (enum_value_type a, enum_value_type b) noexcept { return enum_value_type(a.bits | b.bits); }
-	friend MPT_CONSTEXPR11_FUN const enum_value_type operator & (enum_value_type a, enum_value_type b) noexcept { return enum_value_type(a.bits & b.bits); }
-	friend MPT_CONSTEXPR11_FUN const enum_value_type operator ^ (enum_value_type a, enum_value_type b) noexcept { return enum_value_type(a.bits ^ b.bits); }
-	
-	friend MPT_CONSTEXPR11_FUN const enum_value_type operator | (enum_value_type a, enum_t b) noexcept { return a | enum_value_type(b); }
-	friend MPT_CONSTEXPR11_FUN const enum_value_type operator & (enum_value_type a, enum_t b) noexcept { return a & enum_value_type(b); }
-	friend MPT_CONSTEXPR11_FUN const enum_value_type operator ^ (enum_value_type a, enum_t b) noexcept { return a ^ enum_value_type(b); }
-	
-	friend MPT_CONSTEXPR11_FUN const enum_value_type operator | (enum_t a, enum_value_type b) noexcept { return enum_value_type(a) | b; }
-	friend MPT_CONSTEXPR11_FUN const enum_value_type operator & (enum_t a, enum_value_type b) noexcept { return enum_value_type(a) & b; }
-	friend MPT_CONSTEXPR11_FUN const enum_value_type operator ^ (enum_t a, enum_value_type b) noexcept { return enum_value_type(a) ^ b; }
-	
-	MPT_CONSTEXPR14_FUN enum_value_type &operator |= (enum_value_type b) noexcept { *this = *this | b; return *this; }
-	MPT_CONSTEXPR14_FUN enum_value_type &operator &= (enum_value_type b) noexcept { *this = *this & b; return *this; }
-	MPT_CONSTEXPR14_FUN enum_value_type &operator ^= (enum_value_type b) noexcept { *this = *this ^ b; return *this; }
-
-	MPT_CONSTEXPR14_FUN enum_value_type &operator |= (enum_t b) noexcept { *this = *this | b; return *this; }
-	MPT_CONSTEXPR14_FUN enum_value_type &operator &= (enum_t b) noexcept { *this = *this & b; return *this; }
-	MPT_CONSTEXPR14_FUN enum_value_type &operator ^= (enum_t b) noexcept { *this = *this ^ b; return *this; }
-
-};
-
-
-// Type-safe enum wrapper that allows type-safe bitwise testing.
-template <typename enum_t>
-class Enum
-{
-public:
-	using self_type = Enum;
-	using enum_type = enum_t;
-	using value_type = enum_value_type<enum_t>;
-	using store_type = typename value_type::store_type;
-private:
-	enum_type value;
-public:
-	explicit MPT_CONSTEXPR11_FUN Enum(enum_type val) noexcept : value(val) { }
-	MPT_CONSTEXPR11_FUN operator enum_type () const noexcept { return value; }
-	MPT_CONSTEXPR14_FUN Enum &operator = (enum_type val) noexcept { value = val; return *this; }
-public:
-	MPT_CONSTEXPR11_FUN const value_type operator ~ () const { return ~value_type(value); }
-
-	friend MPT_CONSTEXPR11_FUN bool operator == (self_type a, self_type b) noexcept { return value_type(a) == value_type(b); }
-	friend MPT_CONSTEXPR11_FUN bool operator != (self_type a, self_type b) noexcept { return value_type(a) != value_type(b); }
-
-	friend MPT_CONSTEXPR11_FUN bool operator == (self_type a, value_type b) noexcept { return value_type(a) == value_type(b); }
-	friend MPT_CONSTEXPR11_FUN bool operator != (self_type a, value_type b) noexcept { return value_type(a) != value_type(b); }
-
-	friend MPT_CONSTEXPR11_FUN bool operator == (value_type a, self_type b) noexcept { return value_type(a) == value_type(b); }
-	friend MPT_CONSTEXPR11_FUN bool operator != (value_type a, self_type b) noexcept { return value_type(a) != value_type(b); }
-
-	friend MPT_CONSTEXPR11_FUN bool operator == (self_type a, enum_type b) noexcept { return value_type(a) == value_type(b); }
-	friend MPT_CONSTEXPR11_FUN bool operator != (self_type a, enum_type b) noexcept { return value_type(a) != value_type(b); }
-
-	friend MPT_CONSTEXPR11_FUN bool operator == (enum_type a, self_type b) noexcept { return value_type(a) == value_type(b); }
-	friend MPT_CONSTEXPR11_FUN bool operator != (enum_type a, self_type b) noexcept { return value_type(a) != value_type(b); }
-
-	friend MPT_CONSTEXPR11_FUN const value_type operator | (self_type a, self_type b) noexcept { return value_type(a) | value_type(b); }
-	friend MPT_CONSTEXPR11_FUN const value_type operator & (self_type a, self_type b) noexcept { return value_type(a) & value_type(b); }
-	friend MPT_CONSTEXPR11_FUN const value_type operator ^ (self_type a, self_type b) noexcept { return value_type(a) ^ value_type(b); }
-
-	friend MPT_CONSTEXPR11_FUN const value_type operator | (self_type a, value_type b) noexcept { return value_type(a) | value_type(b); }
-	friend MPT_CONSTEXPR11_FUN const value_type operator & (self_type a, value_type b) noexcept { return value_type(a) & value_type(b); }
-	friend MPT_CONSTEXPR11_FUN const value_type operator ^ (self_type a, value_type b) noexcept { return value_type(a) ^ value_type(b); }
-
-	friend MPT_CONSTEXPR11_FUN const value_type operator | (value_type a, self_type b) noexcept { return value_type(a) | value_type(b); }
-	friend MPT_CONSTEXPR11_FUN const value_type operator & (value_type a, self_type b) noexcept { return value_type(a) & value_type(b); }
-	friend MPT_CONSTEXPR11_FUN const value_type operator ^ (value_type a, self_type b) noexcept { return value_type(a) ^ value_type(b); }
-
-	friend MPT_CONSTEXPR11_FUN const value_type operator | (self_type a, enum_type b) noexcept { return value_type(a) | value_type(b); }
-	friend MPT_CONSTEXPR11_FUN const value_type operator & (self_type a, enum_type b) noexcept { return value_type(a) & value_type(b); }
-	friend MPT_CONSTEXPR11_FUN const value_type operator ^ (self_type a, enum_type b) noexcept { return value_type(a) ^ value_type(b); }
-
-	friend MPT_CONSTEXPR11_FUN const value_type operator | (enum_type a, self_type b) noexcept { return value_type(a) | value_type(b); }
-	friend MPT_CONSTEXPR11_FUN const value_type operator & (enum_type a, self_type b) noexcept { return value_type(a) & value_type(b); }
-	friend MPT_CONSTEXPR11_FUN const value_type operator ^ (enum_type a, self_type b) noexcept { return value_type(a) ^ value_type(b); }
-
-};
-
-
-template <typename enum_t, typename store_t = typename enum_value_type<enum_t>::store_type >
-// cppcheck-suppress copyCtorAndEqOperator
-class FlagSet
-{
-public:
-	using self_type = FlagSet;
-	using enum_type = enum_t;
-	using value_type = enum_value_type<enum_t>;
-	using store_type = store_t;
-	
-private:
-
-	// support truncated store_type ... :
-	store_type bits_;
-	static MPT_CONSTEXPR11_FUN store_type store_from_value(value_type bits) noexcept { return static_cast<store_type>(bits.as_bits()); }
-	static MPT_CONSTEXPR11_FUN value_type value_from_store(store_type bits) noexcept { return value_type::from_bits(static_cast<typename value_type::store_type>(bits)); }
-
-	MPT_CONSTEXPR14_FUN FlagSet & store(value_type bits) noexcept { bits_ = store_from_value(bits); return *this; }
-	MPT_CONSTEXPR11_FUN value_type load() const noexcept { return value_from_store(bits_); }
-
-public:
-
-	// Default constructor (no flags set)
-	MPT_CONSTEXPR11_FUN FlagSet() noexcept : bits_(store_from_value(value_type()))
-	{
-	}
-	
-	// Copy constructor
-	MPT_CONSTEXPR11_FUN FlagSet(const FlagSet &flags) noexcept
-		: bits_(flags.bits_)
-	{
-	}
-
-	// Value constructor
-	MPT_CONSTEXPR11_FUN FlagSet(value_type flags) noexcept : bits_(store_from_value(value_type(flags)))
-	{
-	}
-
-	MPT_CONSTEXPR11_FUN FlagSet(enum_type flag) noexcept : bits_(store_from_value(value_type(flag)))
-	{
-	}
-
-	explicit MPT_CONSTEXPR11_FUN FlagSet(store_type flags) noexcept : bits_(store_from_value(value_type::from_bits(flags)))
-	{
-	}
-	
-	MPT_CONSTEXPR11_FUN explicit operator bool () const noexcept
-	{
-		return load();
-	}
-	MPT_CONSTEXPR11_FUN explicit operator store_type () const noexcept
-	{
-		return load().as_bits();
-	}
-	
-	MPT_CONSTEXPR11_FUN value_type value() const noexcept
-	{
-		return load();
-	}
-	
-	MPT_CONSTEXPR11_FUN operator value_type () const noexcept
-	{
-		return load();
-	}
-
-	// Test if one or more flags are set. Returns true if at least one of the given flags is set.
-	MPT_CONSTEXPR11_FUN bool operator[] (value_type flags) const noexcept
-	{
-		return test(flags);
-	}
-
-	// String representation of flag set
-	std::string to_string() const noexcept
-	{
-		std::string str(size_bits(), '0');
-
-		for(size_t x = 0; x < size_bits(); ++x)
-		{
-			str[size_bits() - x - 1] = (load() & (1 << x) ? '1' : '0');
-		}
-
-		return str;
-	}
-	
-	// Set one or more flags.
-	MPT_CONSTEXPR14_FUN FlagSet &set(value_type flags) noexcept
-	{
-		return store(load() | flags);
-	}
-
-	// Set or clear one or more flags.
-	MPT_CONSTEXPR14_FUN FlagSet &set(value_type flags, bool val) noexcept
-	{
-		return store((val ? (load() | flags) : (load() & ~flags)));
-	}
-
-	// Clear or flags.
-	MPT_CONSTEXPR14_FUN FlagSet &reset() noexcept
-	{
-		return store(value_type());
-	}
-
-	// Clear one or more flags.
-	MPT_CONSTEXPR14_FUN FlagSet &reset(value_type flags) noexcept
-	{
-		return store(load() & ~flags);
-	}
-
-	// Toggle all flags.
-	MPT_CONSTEXPR14_FUN FlagSet &flip() noexcept
-	{
-		return store(~load());
-	}
-
-	// Toggle one or more flags.
-	MPT_CONSTEXPR14_FUN FlagSet &flip(value_type flags) noexcept
-	{
-		return store(load() ^ flags);
-	}
-
-	// Returns the size of the flag set in bytes
-	MPT_CONSTEXPR11_FUN std::size_t size() const noexcept
-	{
-		return sizeof(store_type);
-	}
-
-	// Returns the size of the flag set in bits
-	MPT_CONSTEXPR11_FUN std::size_t size_bits() const noexcept
-	{
-		return size() * 8;
-	}
-	
-	// Test if one or more flags are set. Returns true if at least one of the given flags is set.
-	MPT_CONSTEXPR11_FUN bool test(value_type flags) const noexcept
-	{
-		return (load() & flags);
-	}
-
-	// Test if all specified flags are set.
-	MPT_CONSTEXPR11_FUN bool test_all(value_type flags) const noexcept
-	{
-		return (load() & flags) == flags;
-	}
-
-	// Test if any but the specified flags are set.
-	MPT_CONSTEXPR11_FUN bool test_any_except(value_type flags) const noexcept
-	{
-		return (load() & ~flags);
-	}
-
-	// Test if any flag is set.
-	MPT_CONSTEXPR11_FUN bool any() const noexcept
-	{
-		return load();
-	}
-
-	// Test if no flags are set.
-	MPT_CONSTEXPR11_FUN bool none() const noexcept
-	{
-		return !load();
-	}
-	
-	MPT_CONSTEXPR11_FUN store_type GetRaw() const noexcept
-	{
-		return bits_;
-	}
-
-	MPT_CONSTEXPR14_FUN FlagSet & SetRaw(store_type flags) noexcept
-	{
-		bits_ = flags;
-		return *this;
-	}
-
-	MPT_CONSTEXPR14_FUN FlagSet &operator = (value_type flags) noexcept
-	{
-		return store(flags);
-	}
-	
-	MPT_CONSTEXPR14_FUN FlagSet &operator = (enum_type flag) noexcept
-	{
-		return store(flag);
-	}
-
-	MPT_CONSTEXPR14_FUN FlagSet &operator = (FlagSet flags) noexcept
-	{
-		return store(flags.load());
-	}
-
-	MPT_CONSTEXPR14_FUN FlagSet &operator &= (value_type flags) noexcept
-	{
-		return store(load() & flags);
-	}
-
-	MPT_CONSTEXPR14_FUN FlagSet &operator |= (value_type flags) noexcept
-	{
-		return store(load() | flags);
-	}
-
-	MPT_CONSTEXPR14_FUN FlagSet &operator ^= (value_type flags) noexcept
-	{
-		return store(load() ^ flags);
-	}
-	
-	friend MPT_CONSTEXPR11_FUN bool operator == (self_type a, self_type b) noexcept { return a.load() == b.load(); }
-	friend MPT_CONSTEXPR11_FUN bool operator != (self_type a, self_type b) noexcept { return a.load() != b.load(); }
-
-	friend MPT_CONSTEXPR11_FUN bool operator == (self_type a, value_type b) noexcept { return a.load() == value_type(b); }
-	friend MPT_CONSTEXPR11_FUN bool operator != (self_type a, value_type b) noexcept { return a.load() != value_type(b); }
-
-	friend MPT_CONSTEXPR11_FUN bool operator == (value_type a, self_type b) noexcept { return value_type(a) == b.load(); }
-	friend MPT_CONSTEXPR11_FUN bool operator != (value_type a, self_type b) noexcept { return value_type(a) != b.load(); }
-
-	friend MPT_CONSTEXPR11_FUN bool operator == (self_type a, enum_type b) noexcept { return a.load() == value_type(b); }
-	friend MPT_CONSTEXPR11_FUN bool operator != (self_type a, enum_type b) noexcept { return a.load() != value_type(b); }
-
-	friend MPT_CONSTEXPR11_FUN bool operator == (enum_type a, self_type b) noexcept { return value_type(a) == b.load(); }
-	friend MPT_CONSTEXPR11_FUN bool operator != (enum_type a, self_type b) noexcept { return value_type(a) != b.load(); }
-
-	friend MPT_CONSTEXPR11_FUN bool operator == (self_type a, Enum<enum_type> b) noexcept { return a.load() == value_type(b); }
-	friend MPT_CONSTEXPR11_FUN bool operator != (self_type a, Enum<enum_type> b) noexcept { return a.load() != value_type(b); }
-
-	friend MPT_CONSTEXPR11_FUN bool operator == (Enum<enum_type> a, self_type b) noexcept { return value_type(a) == b.load(); }
-	friend MPT_CONSTEXPR11_FUN bool operator != (Enum<enum_type> a, self_type b) noexcept { return value_type(a) != b.load(); }
-
-	friend MPT_CONSTEXPR11_FUN const value_type operator | (self_type a, self_type b) noexcept { return a.load() | b.load(); }
-	friend MPT_CONSTEXPR11_FUN const value_type operator & (self_type a, self_type b) noexcept { return a.load() & b.load(); }
-	friend MPT_CONSTEXPR11_FUN const value_type operator ^ (self_type a, self_type b) noexcept { return a.load() ^ b.load(); }
-
-	friend MPT_CONSTEXPR11_FUN const value_type operator | (self_type a, value_type b) noexcept { return a.load() | value_type(b); }
-	friend MPT_CONSTEXPR11_FUN const value_type operator & (self_type a, value_type b) noexcept { return a.load() & value_type(b); }
-	friend MPT_CONSTEXPR11_FUN const value_type operator ^ (self_type a, value_type b) noexcept { return a.load() ^ value_type(b); }
-
-	friend MPT_CONSTEXPR11_FUN const value_type operator | (value_type a, self_type b) noexcept { return value_type(a) | b.load(); }
-	friend MPT_CONSTEXPR11_FUN const value_type operator & (value_type a, self_type b) noexcept { return value_type(a) & b.load(); }
-	friend MPT_CONSTEXPR11_FUN const value_type operator ^ (value_type a, self_type b) noexcept { return value_type(a) ^ b.load(); }
-
-	friend MPT_CONSTEXPR11_FUN const value_type operator | (self_type a, enum_type b) noexcept { return a.load() | value_type(b); }
-	friend MPT_CONSTEXPR11_FUN const value_type operator & (self_type a, enum_type b) noexcept { return a.load() & value_type(b); }
-	friend MPT_CONSTEXPR11_FUN const value_type operator ^ (self_type a, enum_type b) noexcept { return a.load() ^ value_type(b); }
-
-	friend MPT_CONSTEXPR11_FUN const value_type operator | (enum_type a, self_type b) noexcept { return value_type(a) | b.load(); }
-	friend MPT_CONSTEXPR11_FUN const value_type operator & (enum_type a, self_type b) noexcept { return value_type(a) & b.load(); }
-	friend MPT_CONSTEXPR11_FUN const value_type operator ^ (enum_type a, self_type b) noexcept { return value_type(a) ^ b.load(); }
-
-	friend MPT_CONSTEXPR11_FUN const value_type operator | (self_type a, Enum<enum_type> b) noexcept { return a.load() | value_type(b); }
-	friend MPT_CONSTEXPR11_FUN const value_type operator & (self_type a, Enum<enum_type> b) noexcept { return a.load() & value_type(b); }
-	friend MPT_CONSTEXPR11_FUN const value_type operator ^ (self_type a, Enum<enum_type> b) noexcept { return a.load() ^ value_type(b); }
-
-	friend MPT_CONSTEXPR11_FUN const value_type operator | (Enum<enum_type> a, self_type b) noexcept { return value_type(a) | b.load(); }
-	friend MPT_CONSTEXPR11_FUN const value_type operator & (Enum<enum_type> a, self_type b) noexcept { return value_type(a) & b.load(); }
-	friend MPT_CONSTEXPR11_FUN const value_type operator ^ (Enum<enum_type> a, self_type b) noexcept { return value_type(a) ^ b.load(); }
-
-};
-
-
-// Declare typesafe logical operators for enum_t
-#define MPT_DECLARE_ENUM(enum_t) \
-	MPT_CONSTEXPR11_FUN enum_value_type<enum_t> operator | (enum_t a, enum_t b) noexcept { return enum_value_type<enum_t>(a) | enum_value_type<enum_t>(b); } \
-	MPT_CONSTEXPR11_FUN enum_value_type<enum_t> operator & (enum_t a, enum_t b) noexcept { return enum_value_type<enum_t>(a) & enum_value_type<enum_t>(b); } \
-	MPT_CONSTEXPR11_FUN enum_value_type<enum_t> operator ^ (enum_t a, enum_t b) noexcept { return enum_value_type<enum_t>(a) ^ enum_value_type<enum_t>(b); } \
-	MPT_CONSTEXPR11_FUN enum_value_type<enum_t> operator ~ (enum_t a) noexcept { return ~enum_value_type<enum_t>(a); } \
-/**/
-
-// backwards compatibility
-#define DECLARE_FLAGSET MPT_DECLARE_ENUM
-
-
-OPENMPT_NAMESPACE_END

+ 0 - 433
libopenmpt.mod/openmpt/common/Logging.cpp

@@ -1,433 +0,0 @@
-/*
- * Logging.cpp
- * -----------
- * Purpose: General logging
- * Notes  : (currently none)
- * Authors: OpenMPT Devs
- * The OpenMPT source code is released under the BSD license. Read LICENSE for more details.
- */
-
-
-#include "stdafx.h"
-
-#include "Logging.h"
-#include "mptFileIO.h"
-#if defined(MODPLUG_TRACKER)
-#include <atomic>
-#endif
-#include "version.h"
-
-#include <iostream>
-
-#include <cstdarg>
-#include <cstring>
-
-#include <stdarg.h>
-
-
-OPENMPT_NAMESPACE_BEGIN
-
-
-namespace mpt
-{
-namespace log
-{
-	
-
-#ifndef NO_LOGGING
-
-
-
-#if !defined(MPT_LOG_GLOBAL_LEVEL_STATIC)
-#if defined(MPT_LOG_GLOBAL_LEVEL)
-int GlobalLogLevel = static_cast<int>(MPT_LOG_GLOBAL_LEVEL);
-#else
-int GlobalLogLevel = static_cast<int>(LogDebug);
-#endif
-#endif
-
-
-
-#if defined(MODPLUG_TRACKER) && !defined(MPT_LOG_IS_DISABLED)
-
-bool FileEnabled = false;
-bool DebuggerEnabled = true;
-bool ConsoleEnabled = false;
-
-static char g_FacilitySolo[1024] = {0};
-static char g_FacilityBlocked[1024] = {0};
-
-void SetFacilities(const std::string &solo, const std::string &blocked)
-{
-	std::strcpy(g_FacilitySolo, solo.c_str());
-	std::strcpy(g_FacilityBlocked, blocked.c_str());
-}
-
-bool IsFacilityActive(const char *facility)
-{
-	if(facility)
-	{
-		if(std::strlen(g_FacilitySolo) > 0)
-		{
-			if(std::strcmp(facility, g_FacilitySolo) != 0)
-			{
-				return false;
-			}
-		}
-		if(std::strlen(g_FacilityBlocked) > 0)
-		{
-			if(std::strcmp(facility, g_FacilitySolo) == 0)
-			{
-				return false;
-			}
-		}
-	}
-	return true;
-}
-
-#endif
-
-
-void Logger::SendLogMessage(const mpt::source_location &loc, LogLevel level, const char *facility, const mpt::ustring &text)
-{
-#ifdef MPT_LOG_IS_DISABLED
-	MPT_UNREFERENCED_PARAMETER(loc);
-	MPT_UNREFERENCED_PARAMETER(level);
-	MPT_UNREFERENCED_PARAMETER(facility);
-	MPT_UNREFERENCED_PARAMETER(text);
-#else // !MPT_LOG_IS_DISABLED
-	MPT_MAYBE_CONSTANT_IF(mpt::log::GlobalLogLevel < level)
-	{
-		return;
-	}
-	#if defined(MODPLUG_TRACKER)
-		if(!IsFacilityActive(facility))
-		{
-			return;
-		}
-	#else // !MODPLUG_TRACKER
-		MPT_UNREFERENCED_PARAMETER(facility);
-	#endif // MODPLUG_TRACKER
-	// remove eol if already present and add log level prefix
-	const mpt::ustring message = LogLevelToString(level) + U_(": ") + mpt::String::RTrim(text, U_("\r\n"));
-	const mpt::ustring file = mpt::ToUnicode(mpt::CharsetSource, loc.file_name() ? loc.file_name() : "");
-	const mpt::ustring function = mpt::ToUnicode(mpt::CharsetSource, loc.function_name() ? loc.function_name() : "");
-	const mpt::ustring line = mpt::ufmt::dec(loc.line());
-	#if defined(MODPLUG_TRACKER) && !defined(MPT_BUILD_WINESUPPORT)
-#if MPT_OS_WINDOWS
-		static uint64 s_lastlogtime = 0;
-		uint64 cur = mpt::Date::ANSI::Now();
-		uint64 diff = cur/10000 - s_lastlogtime;
-		s_lastlogtime = cur/10000;
-#else
-		uint64 cur = 0;
-		uint64 diff = 0;
-#endif
-		if(mpt::log::FileEnabled)
-		{
-			static mpt::ofstream s_logfile;
-			if(!s_logfile)
-			{
-				s_logfile.open(P_("mptrack.log"), std::ios::app);
-			}
-			if(s_logfile)
-			{
-				mpt::IO::WriteText(s_logfile, mpt::ToCharset(mpt::CharsetLogfile, mpt::format(U_("%1+%2 %3(%4): %5 [%6]\n"))
-					( mpt::Date::ANSI::ToUString(cur)
-					, mpt::ufmt::right(6, mpt::ufmt::dec(diff))
-					, file
-					, line
-					, message
-					, function
-					)));
-				mpt::IO::Flush(s_logfile);
-			}
-		}
-		if(mpt::log::DebuggerEnabled)
-		{
-			OutputDebugStringW(mpt::ToWide(mpt::format(U_("%1(%2): +%3 %4 [%5]\n"))
-				( file
-				, line
-				, mpt::ufmt::right(6, mpt::ufmt::dec(diff))
-				, message
-				, function
-				)).c_str());
-		}
-		if(mpt::log::ConsoleEnabled)
-		{
-			static bool consoleInited = false;
-			if(!consoleInited)
-			{
-				AllocConsole();
-				consoleInited = true;
-			}
-			std::wstring consoletext = mpt::ToWide(message) + L"\r\n";
-			DWORD dummy = 0;
-			WriteConsoleW(GetStdHandle(STD_OUTPUT_HANDLE), consoletext.c_str(), mpt::saturate_cast<DWORD>(consoletext.length()), &dummy, NULL);
-		}
-	#elif defined(MODPLUG_TRACKER) && defined(MPT_BUILD_WINESUPPORT)
-		std::clog
-			<< "NativeSupport: "
-			<< mpt::ToCharset(mpt::CharsetStdIO, file) << "(" << mpt::ToCharset(mpt::CharsetStdIO, line) << ")" << ": "
-			<< mpt::ToCharset(mpt::CharsetStdIO, message)
-			<< " [" << mpt::ToCharset(mpt::CharsetStdIO, function) << "]"
-			<< std::endl;
-	#else // !MODPLUG_TRACKER
-		std::clog
-			<< "libopenmpt: "
-			<< mpt::ToCharset(mpt::CharsetStdIO, file) << "(" << mpt::ToCharset(mpt::CharsetStdIO, line) << ")" << ": "
-			<< mpt::ToCharset(mpt::CharsetStdIO, message)
-			<< " [" << mpt::ToCharset(mpt::CharsetStdIO, function) << "]"
-			<< std::endl;
-	#endif // MODPLUG_TRACKER
-#endif // MPT_LOG_IS_DISABLED
-}
-
-
-
-
-#endif // !NO_LOGGING
-
-
-
-#if defined(MODPLUG_TRACKER)
-
-namespace Trace {
-
-#if MPT_OS_WINDOWS
-
-// Debugging functionality will use simple globals.
-
-std::atomic<bool> g_Enabled = ATOMIC_VAR_INIT(false);
-
-static bool g_Sealed = false;
-
-struct Entry {
-	uint32       Index;
-	uint32       ThreadId;
-	uint64       Timestamp;
-	const char * Function;
-	const char * File;
-	int          Line;
-	Direction    Direction;
-};
-
-static MPT_FORCEINLINE bool operator < (const Entry &a, const Entry &b) noexcept
-{
-/*
-	return false
-		|| (a.Timestamp < b.Timestamp)
-		|| (a.ThreadID < b.ThreadID)
-		|| (a.File < b.File)
-		|| (a.Line < b.Line)
-		|| (a.Function < b.Function)
-		;
-*/
-	return false
-		|| (a.Index < b.Index)
-		;
-}
-
-static std::vector<mpt::log::Trace::Entry> Entries;
-
-static std::atomic<uint32> NextIndex(0);
-
-static uint32 ThreadIdGUI = 0;
-static uint32 ThreadIdAudio = 0;
-static uint32 ThreadIdNotify = 0;
-static uint32 ThreadIdWatchdir = 0;
-
-void Enable(std::size_t numEntries)
-{
-	if(g_Sealed)
-	{
-		return;
-	}
-	Entries.clear();
-	Entries.resize(numEntries);
-	NextIndex.store(0);
-	g_Enabled = (numEntries > 0);
-}
-
-void Disable()
-{
-	if(g_Sealed)
-	{
-		return;
-	}
-	g_Enabled = false;
-}
-
-MPT_NOINLINE void Trace(const mpt::source_location & loc, Direction direction) noexcept
-{
-	// This will get called in realtime contexts and hot paths.
-	// No blocking allowed here.
-	const uint32 index = NextIndex.fetch_add(1);
-	const std::size_t numEntries = Entries.size();
-#if 1
-	LARGE_INTEGER time;
-	time.QuadPart = 0;
-	QueryPerformanceCounter(&time);
-	const uint64 timestamp = time.QuadPart;
-#else
-	FILETIME time = FILETIME();
-	GetSystemTimeAsFileTime(&time);
-	const uint64 timestamp = (static_cast<uint64>(time.dwHighDateTime) << 32) | (static_cast<uint64>(time.dwLowDateTime) << 0);
-#endif
-	const uint32 threadid = static_cast<uint32>(GetCurrentThreadId());
-	mpt::log::Trace::Entry & entry = Entries[index % numEntries];
-	entry.Index = index;
-	entry.ThreadId = threadid;
-	entry.Timestamp = timestamp;
-	entry.Function = loc.function_name();
-	entry.File = loc.file_name();
-	entry.Line = loc.line();
-	entry.Direction = direction;
-}
-
-void Seal()
-{
-	if(!g_Enabled)
-	{
-		return;
-	}
-	g_Enabled = false;
-	g_Sealed = true;
-	uint32 count = NextIndex.fetch_add(0);
-	if(count < Entries.size())
-	{
-		Entries.resize(count);
-	}
-}
-
-bool Dump(const mpt::PathString &filename)
-{
-	if(!g_Sealed)
-	{
-		return false;
-	}
-
-	LARGE_INTEGER qpcNow;
-	qpcNow.QuadPart = 0;
-	QueryPerformanceCounter(&qpcNow);
-	uint64 ftNow = mpt::Date::ANSI::Now();
-
-	// sort according to index in case of overflows
-	std::stable_sort(Entries.begin(), Entries.end());
-
-	mpt::ofstream f(filename);
-
-	f << "Build: OpenMPT " << mpt::ToCharset(mpt::CharsetLogfile, Build::GetVersionStringExtended()) << std::endl;
-
-	bool qpcValid = false;
-
-	LARGE_INTEGER qpcFreq;
-	qpcFreq.QuadPart = 0;
-	QueryPerformanceFrequency(&qpcFreq);
-	if(qpcFreq.QuadPart > 0)
-	{
-		qpcValid = true;
-	}
-
-	f << "Dump: " << mpt::ToCharset(mpt::CharsetLogfile, mpt::Date::ANSI::ToUString(ftNow)) << std::endl;
-	f << "Captured events: " << Entries.size() << std::endl;
-	if(qpcValid && (Entries.size() > 0))
-	{
-		double period = static_cast<double>(Entries[Entries.size() - 1].Timestamp - Entries[0].Timestamp) / static_cast<double>(qpcFreq.QuadPart);
-		double eventsPerSecond = Entries.size() / period;
-		f << "Period [s]: " << mpt::fmt::fix(period) << std::endl;
-		f << "Events/second: " << mpt::fmt::fix(eventsPerSecond) << std::endl;
-	}
-
-	for(auto &entry : Entries)
-	{
-		if(!entry.Function) entry.Function = "";
-		if(!entry.File) entry.File = "";
-		std::string time;
-		if(qpcValid)
-		{
-			time = mpt::ToCharset(mpt::CharsetLogfile, mpt::Date::ANSI::ToUString( ftNow - static_cast<int64>( static_cast<double>(qpcNow.QuadPart - entry.Timestamp) * (10000000.0 / static_cast<double>(qpcFreq.QuadPart) ) ) ) );
-		} else
-		{
-			time = mpt::format("0x%1")(mpt::fmt::hex0<16>(entry.Timestamp));
-		}
-		f << time;
-		if(entry.ThreadId == ThreadIdGUI)
-		{
-			f << " -----GUI ";
-		} else if(entry.ThreadId == ThreadIdAudio)
-		{
-			f << " ---Audio ";
-		} else if(entry.ThreadId == ThreadIdNotify)
-		{
-			f << " --Notify ";
-		} else if(entry.ThreadId == ThreadIdWatchdir)
-		{
-			f << " WatchDir ";
-		} else
-		{
-			f << " " << mpt::fmt::hex0<8>(entry.ThreadId) << " ";
-		}
-		f << (entry.Direction == mpt::log::Trace::Direction::Enter ? ">" : entry.Direction == mpt::log::Trace::Direction::Leave ? "<" : " ") << " ";
-		f << entry.File << "(" << entry.Line << "): " << entry.Function;
-		f << std::endl;
-	}
-	return true;
-}
-
-void SetThreadId(mpt::log::Trace::ThreadKind kind, uint32 id)
-{
-	if(id == 0)
-	{
-		return;
-	}
-	switch(kind)
-	{
-		case ThreadKindGUI:
-			ThreadIdGUI = id;
-			break;
-		case ThreadKindAudio:
-			ThreadIdAudio = id;
-			break;
-		case ThreadKindNotify:
-			ThreadIdNotify = id;
-			break;
-		case ThreadKindWatchdir:
-			ThreadIdWatchdir = id;
-			break;
-	}
-}
-
-uint32 GetThreadId(mpt::log::Trace::ThreadKind kind)
-{
-	uint32 result = 0;
-	switch(kind)
-	{
-		case ThreadKindGUI:
-			result = ThreadIdGUI;
-			break;
-		case ThreadKindAudio:
-			result = ThreadIdAudio;
-			break;
-		case ThreadKindNotify:
-			result = ThreadIdNotify;
-			break;
-		case ThreadKindWatchdir:
-			result = ThreadIdWatchdir;
-			break;
-	}
-	return result;
-}
-
-#endif // MPT_OS_WINDOWS
-
-} // namespace Trace
-
-#endif // MODPLUG_TRACKER
-
-
-} // namespace log
-} // namespace mpt
-
-
-OPENMPT_NAMESPACE_END

+ 0 - 254
libopenmpt.mod/openmpt/common/Logging.h

@@ -1,254 +0,0 @@
-/*
- * Logging.h
- * ---------
- * Purpose: General logging
- * Notes  : (currently none)
- * Authors: OpenMPT Devs
- * The OpenMPT source code is released under the BSD license. Read LICENSE for more details.
- */
-
-#pragma once
-
-#include "BuildSettings.h"
-
-#if defined(MODPLUG_TRACKER) && MPT_OS_WINDOWS
-#include <atomic>
-#endif
-
-OPENMPT_NAMESPACE_BEGIN
-
-
-/*
-
-
-Build time logging configuration (in BuildSettings.h):
-
- *  #define NO_LOGGING
-    Disables all logging completely.
-    MPT_LOG calls are not even compiled but instead completely removed via the
-    preprocessor.
-
- *  #define MPT_LOG_GLOBAL_LEVEL_STATIC
-    #define MPT_LOG_GLOBAL_LEVEL #
-    Define the former (to anything) and the latter (to one of the log levels
-    below) in order to statically select the verbosity of logging at build time.
-    MPT_LOG calls that exceed the specified logging level will get dead-code
-    eliminated at compile time.
-    This especially means that, when setting MPT_LOG_GLOBAL_LEVEL to 0, no
-    MPT_LOG call (with a constant level parameter) remains in the resulting
-    binary, however, they still do get parsed and properly type checked by the
-    compiler.
-
-
-Logging:
-
-If the context is related to a particular CSoundfile instance, use
-CSoundfile::AddToLog.
-
-Logging a simple message:
-MPT_LOG(LogWarning, "sounddev", "some message");
-MPT_LOG(LogWarning, "sounddev", U_("some message"));
-Facility is some course grained code section identifier (more coarse grained
-than the current file name probably), useful to do some selective logging.
-
-Logging a more complex message:
-MPT_LOG(LogWarning, "sounddev", mpt::format(U_("Some message: foo=%1, bar=0x%2"))(foo, mpt::ufmt::hex0<8>(bar)));
-
-Note that even with full enabled logging and a runtime configurable logging
-level, the runtime overhead of a MPT_LOG(level, facility, text) call is just a
-single conditional in case the verbosity does not require logging the respective
-message. Even the expression "text" is not evaluated.
-
-
-*/
-
-
-enum LogLevel
-{
-	LogDebug        = 5,
-	LogInformation  = 4,
-	LogNotification = 3,
-	LogWarning      = 2,
-	LogError        = 1
-};
-
-
-inline mpt::ustring LogLevelToString(LogLevel level)
-{
-	switch(level)
-	{
-	case LogError:        return U_("error");   break;
-	case LogWarning:      return U_("warning"); break;
-	case LogNotification: return U_("notify");  break;
-	case LogInformation:  return U_("info");    break;
-	case LogDebug:        return U_("debug");   break;
-	}
-	return U_("unknown");
-}
-
-
-class ILog
-{
-protected:
-	virtual ~ILog() { }
-public:
-	virtual	void AddToLog(LogLevel level, const mpt::ustring &text) const = 0;
-};
-
-
-
-namespace mpt
-{
-namespace log
-{
-
-
-
-#ifndef NO_LOGGING
-
-
-#if defined(MPT_LOG_GLOBAL_LEVEL_STATIC)
-#if (MPT_LOG_GLOBAL_LEVEL <= 0)
-// Logging framework is enabled (!NO_LOGGING) but all logging has beeen statically disabled.
-// All logging code gets compiled and immediately dead-code eliminated.
-#define MPT_LOG_IS_DISABLED
-#endif
-static const int GlobalLogLevel = MPT_LOG_GLOBAL_LEVEL ;
-#else
-extern int GlobalLogLevel;
-#endif
-
-
-#if defined(MODPLUG_TRACKER) && !defined(MPT_LOG_IS_DISABLED)
-extern bool FileEnabled;
-extern bool DebuggerEnabled;
-extern bool ConsoleEnabled;
-void SetFacilities(const std::string &solo, const std::string &blocked);
-bool IsFacilityActive(const char *facility);
-#else
-static MPT_FORCEINLINE bool IsFacilityActive(const char * /*facility*/ ) { return true; }
-#endif
-
-
-#endif // !NO_LOGGING
-
-
-
-#ifndef NO_LOGGING
-
-
-class Logger
-{
-public:
-	// facility:ASCII
-	void SendLogMessage(const mpt::source_location &loc, LogLevel level, const char *facility, const mpt::ustring &text);
-};
-
-#define MPT_LOG(level, facility, text) \
-	MPT_DO \
-	{ \
-		MPT_MAYBE_CONSTANT_IF(mpt::log::GlobalLogLevel >= ( level )) \
-		{ \
-			MPT_MAYBE_CONSTANT_IF(mpt::log::IsFacilityActive(( facility ))) \
-			{ \
-				mpt::log::Logger().SendLogMessage( MPT_SOURCE_LOCATION_CURRENT() , ( level ), ( facility ), ( text )); \
-			} \
-		} \
-	} MPT_WHILE_0 \
-/**/
-
-
-#else // !NO_LOGGING
-
-
-#define MPT_LOG(level, facility, text) MPT_DO { } MPT_WHILE_0
-
-
-#endif // NO_LOGGING
-
-
-#if defined(MODPLUG_TRACKER) && MPT_OS_WINDOWS
-
-namespace Trace {
-
-// This is not strictly thread safe in all corner cases because of missing barriers.
-// We do not care in order to not harm the fast path with additional barriers.
-// Enabled tracing incurs a runtime overhead with multiple threads as a global atomic variable
-//  gets modified.
-// This cacheline bouncing does not matter at all
-//  if there are not multiple thread adding trace points at high frequency (way greater than 1000Hz),
-//  which, in OpenMPT, is only ever the case for just a single thread (the audio thread), if at all.
-extern std::atomic<bool> g_Enabled;
-static inline bool IsEnabled() { return g_Enabled; }
-
-enum class Direction : int8
-{
-	Unknown =  0,
-	Enter   =  1,
-	Leave   = -1,
-};
-
-MPT_NOINLINE void Trace(const mpt::source_location & loc, Direction direction = Direction::Unknown) noexcept;
-
-enum ThreadKind {
-	ThreadKindGUI,
-	ThreadKindAudio,
-	ThreadKindNotify,
-	ThreadKindWatchdir,
-};
-
-void Enable(std::size_t numEntries);
-void Disable();
-
-void SetThreadId(mpt::log::Trace::ThreadKind kind, uint32 id);
-uint32 GetThreadId(mpt::log::Trace::ThreadKind kind);
-
-void Seal();
-bool Dump(const mpt::PathString &filename);
-
-class Scope
-{
-private:
-	const mpt::source_location loc;
-public:
-	MPT_FORCEINLINE Scope(mpt::source_location loc) noexcept
-		: loc(loc)
-	{
-		if(mpt::log::Trace::g_Enabled)
-		{
-			mpt::log::Trace::Trace(loc, mpt::log::Trace::Direction::Enter);
-		}
-	}
-	MPT_FORCEINLINE ~Scope() noexcept
-	{
-		if(mpt::log::Trace::g_Enabled)
-		{
-			mpt::log::Trace::Trace(loc, mpt::log::Trace::Direction::Leave);
-		}
-	}
-};
-
-#define MPT_TRACE_CONCAT_HELPER(x, y) x ## y
-#define MPT_TRACE_CONCAT(x, y) MPT_TRACE_CONCAT_HELPER(x, y)
-
-#define MPT_TRACE_SCOPE() mpt::log::Trace::Scope MPT_TRACE_CONCAT(MPT_TRACE_VAR, __LINE__)(MPT_SOURCE_LOCATION_CURRENT())
-
-#define MPT_TRACE() MPT_DO { if(mpt::log::Trace::g_Enabled) { mpt::log::Trace::Trace(MPT_SOURCE_LOCATION_CURRENT()); } } MPT_WHILE_0
-
-} // namespace Trace
-
-#else // !MODPLUG_TRACKER
-
-#define MPT_TRACE_SCOPE() MPT_DO { } MPT_WHILE_0
-
-#define MPT_TRACE() MPT_DO { } MPT_WHILE_0
-
-#endif // MODPLUG_TRACKER
-
-
-
-} // namespace log
-} // namespace mpt
-
-
-OPENMPT_NAMESPACE_END

+ 0 - 221
libopenmpt.mod/openmpt/common/Profiler.cpp

@@ -1,221 +0,0 @@
-/*
- * Profiler.cpp
- * ------------
- * Purpose: Performance measuring
- * Notes  : (currently none)
- * Authors: OpenMPT Devs
- * The OpenMPT source code is released under the BSD license. Read LICENSE for more details.
- */
-
-
-#include "stdafx.h"
-#include "Profiler.h"
-
-
-OPENMPT_NAMESPACE_BEGIN
-
-
-#ifdef USE_PROFILER
-
-
-class Statistics
-{
-public:
-	Profile &profile;
-	Profile::Data data;
-	double usage;
-	Statistics(Profile &p) : profile(p)
-	{
-		usage = 0.0;
-		Update();
-	}
-	void Update()
-	{
-		data = profile.GetAndResetData();
-		uint64 now = profile.GetTime();
-		uint64 timewindow = now - data.Start;
-		if(data.Calls > 0 && timewindow > 0)
-		{
-			usage = (double)data.Sum / (double)timewindow;
-		} else
-		{
-			usage = 0.0;
-		}
-	}
-};
-
-
-struct ProfileBlock
-{
-	class Profile * profile;
-	const char * name;
-	class Statistics * stats;
-};
-
-static const std::size_t MAX_PROFILES = 1024;
-
-static ProfileBlock Profiles[ MAX_PROFILES ];
-
-static std::size_t NextProfile = 0;
-
-
-static void RegisterProfile(Profile *newprofile)
-{
-	if(NextProfile < MAX_PROFILES)
-	{
-		Profiles[NextProfile].profile = newprofile;
-		Profiles[NextProfile].stats = 0;
-		NextProfile++;
-	}
-}
-
-
-static void UnregisterProfile(Profile *oldprofile)
-{
-	for(std::size_t i=0; i<NextProfile; i++) {
-		if(Profiles[i].profile == oldprofile) {
-			Profiles[i].profile = 0;
-			delete Profiles[i].stats;
-			Profiles[i].stats = 0;
-		}
-	}
-}
-
-
-void Profiler::Update()
-{
-	for(std::size_t i=0; i<NextProfile; i++)
-	{
-		if(!Profiles[i].stats)
-		{
-			Profiles[i].stats = new Statistics(*Profiles[i].profile);
-		} else
-		{
-			Profiles[i].stats->Update();
-		}
-	}
-}
-
-
-std::string Profiler::DumpProfiles()
-{
-	std::string ret;
-	for(std::size_t i=0; i<NextProfile; i++)
-	{
-		if(Profiles[i].stats)
-		{
-			Statistics &stats = *Profiles[i].stats;
-			std::string cat;
-			switch(stats.profile.Category)
-			{
-			case Profiler::GUI: cat = "GUI"; break;
-			case Profiler::Audio: cat = "Audio"; break;
-			case Profiler::Notify: cat = "Notify"; break;
-			}
-			ret += cat + " " + std::string(stats.profile.Name) + ": " + mpt::fmt::right(6, mpt::fmt::fix(stats.usage * 100.0, 3)) + "%\r\n";
-		}
-	}
-	ret += "\r\n";
-	return ret;
-}
-
-
-std::vector<double> Profiler::DumpCategories()
-{
-	std::vector<double> ret;
-	ret.resize(Profiler::CategoriesCount);
-	for(std::size_t i=0; i<NextProfile; i++)
-	{
-		if(Profiles[i].stats)
-		{
-			ret[Profiles[i].profile->Category] += Profiles[i].stats->usage;
-		}
-	}
-	return ret;
-}
-
-
-uint64 Profile::GetTime() const
-{
-	LARGE_INTEGER ret;
-	ret.QuadPart = 0;
-	QueryPerformanceCounter(&ret);
-	return ret.QuadPart;
-}
-
-
-uint64 Profile::GetFrequency() const
-{
-	LARGE_INTEGER ret;
-	ret.QuadPart = 0;
-	QueryPerformanceFrequency(&ret);
-	return ret.QuadPart;
-}
-
-
-Profile::Profile(Profiler::Category category, const char *name) : Category(category), Name(name)
-{
-	data.Calls = 0;
-	data.Sum = 0;
-	data.Overhead = 0;
-	data.Start = GetTime();
-	EnterTime = 0;
-	RegisterProfile(this);
-}
-
-
-Profile::~Profile()
-{
-	UnregisterProfile(this);
-}
-
-
-Profile::Data Profile::GetAndResetData()
-{
-	Profile::Data ret;
-	datamutex.lock();
-	ret = data;
-	data.Calls = 0;
-	data.Sum = 0;
-	data.Overhead = 0;
-	data.Start = GetTime();
-	datamutex.unlock();
-	return ret;
-}
-
-
-void Profile::Reset()
-{
-	datamutex.lock();
-	data.Calls = 0;
-	data.Sum = 0;
-	data.Overhead = 0;
-	data.Start = GetTime();
-	datamutex.unlock();
-}
-
-
-void Profile::Enter()
-{
-	EnterTime = GetTime();
-}
-
-
-void Profile::Leave()
-{
-	uint64 LeaveTime = GetTime();
-	datamutex.lock();
-	data.Calls += 1;
-	data.Sum += LeaveTime - EnterTime;
-	datamutex.unlock();
-}
-
-
-#else // !USE_PROFILER
-
-MPT_MSVC_WORKAROUND_LNK4221(Profiler)
-
-#endif // USE_PROFILER
-
-
-OPENMPT_NAMESPACE_END

+ 0 - 127
libopenmpt.mod/openmpt/common/Profiler.h

@@ -1,127 +0,0 @@
-/*
- * Profiler.h
- * ----------
- * Purpose: Performance measuring
- * Notes  : (currently none)
- * Authors: OpenMPT Devs
- * The OpenMPT source code is released under the BSD license. Read LICENSE for more details.
- */
-
-
-#pragma once
-
-#include "BuildSettings.h"
-
-
-#include "../common/mptMutex.h"
-#include <string>
-#include <vector>
-
-
-OPENMPT_NAMESPACE_BEGIN
-
-
-#if defined(MODPLUG_TRACKER)
-
-//#define USE_PROFILER
-
-#endif
-
-#ifdef USE_PROFILER
-
-class Profiler
-{
-public:
-	enum Category
-	{
-		GUI,
-		Audio,
-		Notify,
-		CategoriesCount
-	};
-	static std::vector<std::string> GetCategoryNames()
-	{
-		std::vector<std::string> ret;
-		ret.push_back("GUI");
-		ret.push_back("Audio");
-		ret.push_back("Notify");
-		return ret;
-	}
-public:
-	static void Update();
-	static std::string DumpProfiles();
-	static std::vector<double> DumpCategories();
-};
-
-
-class Profile
-{
-private:
-	mutable mpt::mutex datamutex;
-public:
-	struct Data
-	{
-		uint64 Calls;
-		uint64 Sum;
-		int64  Overhead;
-		uint64 Start;
-	};
-public:
-	Data data;
-	uint64 EnterTime;
-	Profiler::Category Category;
-	const char * const Name;
-	uint64 GetTime() const;
-	uint64 GetFrequency() const;
-public:
-	Profile(Profiler::Category category, const char *name);
-	~Profile();
-	void Reset();
-	void Enter();
-	void Leave();
-	class Scope
-	{
-	private:
-		Profile &profile;
-	public:
-		Scope(Profile &p) : profile(p) { profile.Enter(); }
-		~Scope() { profile.Leave(); }
-	};
-public:
-	Data GetAndResetData();
-};
-
-
-#define OPENMPT_PROFILE_SCOPE(cat, name) \
-	static Profile OPENMPT_PROFILE_VAR(cat, name);\
-	Profile::Scope OPENMPT_PROFILE_SCOPE_VAR(OPENMPT_PROFILE_VAR); \
-/**/
-
-
-#define OPENMPT_PROFILE_FUNCTION(cat) OPENMPT_PROFILE_SCOPE(cat, __func__)
-
-
-#else // !USE_PROFILER
-
-
-class Profiler
-{
-public:
-	enum Category
-	{
-		CategoriesCount
-	};
-	static std::vector<std::string> GetCategoryNames() { return std::vector<std::string>(); } 
-public:
-	static void Update() { }
-	static std::string DumpProfiles() { return std::string(); }
-	static std::vector<double> DumpCategories() { return std::vector<double>(); }
-};
-#define OPENMPT_PROFILE_SCOPE(cat, name) MPT_DO { } MPT_WHILE_0
-#define OPENMPT_PROFILE_FUNCTION(cat) MPT_DO { } MPT_WHILE_0
-
-
-#endif // USE_PROFILER
-
-
-OPENMPT_NAMESPACE_END

+ 0 - 118
libopenmpt.mod/openmpt/common/misc_util.cpp

@@ -1,118 +0,0 @@
-/*
- * misc_util.cpp
- * -------------
- * Purpose: Various useful utility functions.
- * Notes  : (currently none)
- * Authors: OpenMPT Devs
- * The OpenMPT source code is released under the BSD license. Read LICENSE for more details.
- */
-
-
-#include "stdafx.h"
-#include "misc_util.h"
-
-
-OPENMPT_NAMESPACE_BEGIN
-
-
-
-namespace Util
-{
-
-
-static const mpt::uchar EncodeNibble[16] = {
-	UC_('0'), UC_('1'), UC_('2'), UC_('3'),
-	UC_('4'), UC_('5'), UC_('6'), UC_('7'),
-	UC_('8'), UC_('9'), UC_('A'), UC_('B'),
-	UC_('C'), UC_('D'), UC_('E'), UC_('F') };
-
-static inline bool DecodeByte(uint8 &byte, mpt::uchar c1, mpt::uchar c2)
-{
-	byte = 0;
-	if(UC_('0') <= c1 && c1 <= UC_('9'))
-	{
-		byte += static_cast<uint8>((c1 - UC_('0')) << 4);
-	} else if(UC_('A') <= c1 && c1 <= UC_('F'))
-	{
-		byte += static_cast<uint8>((c1 - UC_('A') + 10) << 4);
-	} else if(UC_('a') <= c1 && c1 <= UC_('f'))
-	{
-		byte += static_cast<uint8>((c1 - UC_('a') + 10) << 4);
-	} else
-	{
-		return false;
-	}
-	if(UC_('0') <= c2 && c2 <= UC_('9'))
-	{
-		byte += static_cast<uint8>(c2 - UC_('0'));
-	} else if(UC_('A') <= c2 && c2 <= UC_('F'))
-	{
-		byte += static_cast<uint8>(c2 - UC_('A') + 10);
-	} else if(UC_('a') <= c2 && c2 <= UC_('f'))
-	{
-		byte += static_cast<uint8>(c2 - UC_('a') + 10);
-	} else
-	{
-		return false;
-	}
-	return true;
-}
-
-mpt::ustring BinToHex(mpt::const_byte_span src)
-{
-	mpt::ustring result;
-	result.reserve(src.size() * 2);
-	for(std::byte byte : src)
-	{
-		result.push_back(EncodeNibble[(mpt::byte_cast<uint8>(byte) & 0xf0) >> 4]);
-		result.push_back(EncodeNibble[mpt::byte_cast<uint8>(byte) & 0x0f]);
-	}
-	return result;
-}
-
-std::vector<std::byte> HexToBin(const mpt::ustring &src)
-{
-	std::vector<std::byte> result;
-	result.reserve(src.size() / 2);
-	for(std::size_t i = 0; (i + 1) < src.size(); i += 2)
-	{
-		uint8 byte = 0;
-		if(!DecodeByte(byte, src[i], src[i + 1]))
-		{
-			return result;
-		}
-		result.push_back(mpt::byte_cast<std::byte>(byte));
-	}
-	return result;
-}
-
-
-} // namespace Util
-
-
-#if defined(MODPLUG_TRACKER) || (defined(LIBOPENMPT_BUILD) && defined(LIBOPENMPT_BUILD_TEST))
-
-namespace mpt
-{
-
-std::string getenv(const std::string &env_var, const std::string &def)
-{
-#if MPT_OS_WINDOWS && MPT_OS_WINDOWS_WINRT
-	MPT_UNREFERENCED_PARAMETER(env_var);
-	return def;
-#else
-	const char *val = std::getenv(env_var.c_str());
-	if(!val)
-	{
-		return def;
-	}
-	return val;
-#endif
-}
-
-} // namespace mpt
-
-#endif // MODPLUG_TRACKER || (LIBOPENMPT_BUILD && LIBOPENMPT_BUILD_TEST)
-
-
-OPENMPT_NAMESPACE_END

+ 0 - 233
libopenmpt.mod/openmpt/common/misc_util.h

@@ -1,233 +0,0 @@
-/*
- * misc_util.h
- * -----------
- * Purpose: Various useful utility functions.
- * Notes  : (currently none)
- * Authors: OpenMPT Devs
- * The OpenMPT source code is released under the BSD license. Read LICENSE for more details.
- */
-
-
-#pragma once
-
-#include "BuildSettings.h"
-
-#include "mptAssert.h"
-#include "mptBaseMacros.h"
-#include "mptBaseTypes.h"
-#include "mptBaseUtils.h"
-#include "mptString.h"
-
-// old
-#include "mptBaseUtils.h"
-#include "mptSpan.h"
-#include "mptMemory.h"
-#include "mptExceptionText.h"
-#include "mptStringFormat.h"
-#include "mptStringParse.h"
-#include "mptCPU.h"
-#include "mptOS.h"
-#include "mptTime.h"
-#include "mptLibrary.h"
-
-#include <vector>
-
-#include <cstdlib>
-
-#include <stdlib.h>
-
-
-OPENMPT_NAMESPACE_BEGIN
-
-
-namespace Util
-{
-
-	// Insert a range of items [insStart,  insEnd], and possibly shift item fix to the left.
-	template<typename T>
-	void InsertItem(const T insStart, const T insEnd, T &fix)
-	{
-		MPT_ASSERT(insEnd >= insStart);
-		if(fix >= insStart)
-		{
-			fix += (insEnd - insStart + 1);
-		}
-	}
-
-	// Insert a range of items [insStart,  insEnd], and possibly shift items in range [fixStart, fixEnd] to the right.
-	template<typename T>
-	void InsertRange(const T insStart, const T insEnd, T &fixStart, T &fixEnd)
-	{
-		MPT_ASSERT(insEnd >= insStart);
-		const T insLength = insEnd - insStart + 1;
-		if(fixStart >= insEnd)
-		{
-			fixStart += insLength;
-		}
-		if(fixEnd >= insEnd)
-		{
-			fixEnd += insLength;
-		}
-	}
-
-	// Delete a range of items [delStart,  delEnd], and possibly shift item fix to the left.
-	template<typename T>
-	void DeleteItem(const T delStart, const T delEnd, T &fix)
-	{
-		MPT_ASSERT(delEnd >= delStart);
-		if(fix > delEnd)
-		{
-			fix -= (delEnd - delStart + 1);
-		}
-	}
-
-	// Delete a range of items [delStart,  delEnd], and possibly shift items in range [fixStart, fixEnd] to the left.
-	template<typename T>
-	void DeleteRange(const T delStart, const T delEnd, T &fixStart, T &fixEnd)
-	{
-		MPT_ASSERT(delEnd >= delStart);
-		const T delLength = delEnd - delStart + 1;
-		if(delStart < fixStart  && delEnd < fixStart)
-		{
-			// cut part is before loop start
-			fixStart -= delLength;
-			fixEnd -= delLength;
-		} else if(delStart < fixStart  && delEnd < fixEnd)
-		{
-			// cut part is partly before loop start
-			fixStart = delStart;
-			fixEnd -= delLength;
-		} else if(delStart >= fixStart && delEnd < fixEnd)
-		{
-			// cut part is in the loop
-			fixEnd -= delLength;
-		} else if(delStart >= fixStart && delStart < fixEnd && delEnd > fixEnd)
-		{
-			// cut part is partly before loop end
-			fixEnd = delStart;
-		}
-	}
-
-} // namespace Util
-
-
-
-namespace Util
-{
-
-	template<typename T, std::size_t n>
-	class fixed_size_queue
-	{
-	private:
-		T buffer[n+1];
-		std::size_t read_position;
-		std::size_t write_position;
-	public:
-		fixed_size_queue() : read_position(0), write_position(0)
-		{
-			return;
-		}
-		void clear()
-		{
-			read_position = 0;
-			write_position = 0;
-		}
-		std::size_t read_size() const
-		{
-			if ( write_position > read_position )
-			{
-				return write_position - read_position;
-			} else if ( write_position < read_position )
-			{
-				return write_position - read_position + n + 1;
-			} else
-			{
-				return 0;
-			}
-		}
-		std::size_t write_size() const
-		{
-			if ( write_position > read_position )
-			{
-				return read_position - write_position + n;
-			} else if ( write_position < read_position )
-			{
-				return read_position - write_position - 1;
-			} else
-			{
-				return n;
-			}
-		}
-		bool push( const T & v )
-		{
-			if ( !write_size() )
-			{
-				return false;
-			}
-			buffer[write_position] = v;
-			write_position = ( write_position + 1 ) % ( n + 1 );
-			return true;
-		}
-		bool pop() {
-			if ( !read_size() )
-			{
-				return false;
-			}
-			read_position = ( read_position + 1 ) % ( n + 1 );
-			return true;
-		}
-		T peek() {
-			if ( !read_size() )
-			{
-				return T();
-			}
-			return buffer[read_position];
-		}
-		const T * peek_p()
-		{
-			if ( !read_size() )
-			{
-				return nullptr;
-			}
-			return &(buffer[read_position]);
-		}
-		const T * peek_next_p()
-		{
-			if ( read_size() < 2 )
-			{
-				return nullptr;
-			}
-			return &(buffer[(read_position+1)%(n+1)]);
-		}
-	};
-
-} // namespace Util
-
-
-namespace Util
-{
-
-std::vector<std::byte> HexToBin(const mpt::ustring &src);
-mpt::ustring BinToHex(mpt::const_byte_span src);
-
-template <typename T> inline mpt::ustring BinToHex(mpt::span<T> src) { return Util::BinToHex(mpt::byte_cast<mpt::const_byte_span>(src)); }
-
-} // namespace Util
-
-
-#if defined(MODPLUG_TRACKER) || (defined(LIBOPENMPT_BUILD) && defined(LIBOPENMPT_BUILD_TEST))
-
-namespace mpt
-{
-
-// Wrapper around std::getenv.
-// Instead of returning null pointer if the environment variable is not set,
-// this wrapper returns the provided default value.
-std::string getenv(const std::string &env_var, const std::string &def = std::string());
-
-} // namespace mpt
-
-#endif // MODPLUG_TRACKER || (LIBOPENMPT_BUILD && LIBOPENMPT_BUILD_TEST)
-
-
-OPENMPT_NAMESPACE_END

+ 0 - 36
libopenmpt.mod/openmpt/common/mptAlloc.cpp

@@ -1,36 +0,0 @@
-/*
- * mptAlloc.cpp
- * ------------
- * Purpose: Dynamic memory allocation.
- * Notes  : (currently none)
- * Authors: OpenMPT Devs
- * The OpenMPT source code is released under the BSD license. Read LICENSE for more details.
- */
-
-
-
-#include "stdafx.h"
-#include "mptAlloc.h"
-
-
-
-OPENMPT_NAMESPACE_BEGIN
-
-
-
-#if defined(MPT_ENABLE_ALIGNED_ALLOC)
-
-
-
-namespace mpt
-{
-
-} // namespace mpt
-
-
-
-#endif // MPT_ENABLE_ALIGNED_ALLOC
-
-
-
-OPENMPT_NAMESPACE_END

+ 0 - 125
libopenmpt.mod/openmpt/common/mptAlloc.h

@@ -1,125 +0,0 @@
-/*
- * mptAlloc.h
- * ----------
- * Purpose: Dynamic memory allocation.
- * Notes  : (currently none)
- * Authors: OpenMPT Devs
- * The OpenMPT source code is released under the BSD license. Read LICENSE for more details.
- */
-
-
-#pragma once
-
-#include "BuildSettings.h"
-
-
-
-#include "mptBaseMacros.h"
-#include "mptMemory.h"
-#include "mptSpan.h"
-
-#include <array>
-#include <memory>
-#include <new>
-#include <vector>
-
-
-
-OPENMPT_NAMESPACE_BEGIN
-
-
-
-namespace mpt {
-
-
-
-template <typename T> inline span<T> as_span(std::vector<T> & cont) { return span<T>(cont); }
-
-template <typename T> inline span<const T> as_span(const std::vector<T> & cont) { return span<const T>(cont); }
-
-
-
-template <typename T> inline std::vector<typename std::remove_const<T>::type> make_vector(T * beg, T * end) { return std::vector<typename std::remove_const<T>::type>(beg, end); }
-
-template <typename T> inline std::vector<typename std::remove_const<T>::type> make_vector(T * data, std::size_t size) { return std::vector<typename std::remove_const<T>::type>(data, data + size); }
-
-template <typename T> inline std::vector<typename std::remove_const<T>::type> make_vector(mpt::span<T> data) { return std::vector<typename std::remove_const<T>::type>(data.data(), data.data() + data.size()); }
-
-template <typename T, std::size_t N> inline std::vector<typename std::remove_const<T>::type> make_vector(T (&arr)[N]) { return std::vector<typename std::remove_const<T>::type>(std::begin(arr), std::end(arr)); }
-
-
-
-template <typename T>
-struct GetRawBytesFunctor<std::vector<T>>
-{
-	inline mpt::const_byte_span operator () (const std::vector<T> & v) const
-	{
-		static_assert(mpt::is_binary_safe<typename std::remove_const<T>::type>::value);
-		return mpt::as_span(reinterpret_cast<const std::byte *>(v.data()), v.size() * sizeof(T));
-	}
-	inline mpt::byte_span operator () (std::vector<T> & v) const
-	{
-		static_assert(mpt::is_binary_safe<typename std::remove_const<T>::type>::value);
-		return mpt::as_span(reinterpret_cast<std::byte *>(v.data()), v.size() * sizeof(T));
-	}
-};
-
-template <typename T>
-struct GetRawBytesFunctor<const std::vector<T>>
-{
-	inline mpt::const_byte_span operator () (const std::vector<T> & v) const
-	{
-		static_assert(mpt::is_binary_safe<typename std::remove_const<T>::type>::value);
-		return mpt::as_span(reinterpret_cast<const std::byte *>(v.data()), v.size() * sizeof(T));
-	}
-};
-
-
-
-} // namespace mpt
-
-
-
-#if defined(MPT_ENABLE_ALIGNED_ALLOC)
-
-
-
-namespace mpt
-{
-
-
-
-#if !(MPT_COMPILER_CLANG && defined(__GLIBCXX__)) && !(MPT_COMPILER_CLANG && MPT_OS_MACOSX_OR_IOS)
-using std::launder;
-#else
-template <class T>
-MPT_NOINLINE T* launder(T* p) noexcept
-{
-	return p;
-}
-#endif
-
-
-
-template <typename T, std::size_t count, std::align_val_t alignment>
-struct alignas(static_cast<std::size_t>(alignment)) aligned_array
-	: std::array<T, count>
-{
-	static_assert(static_cast<std::size_t>(alignment) >= alignof(T));
-	static_assert(((count * sizeof(T)) % static_cast<std::size_t>(alignment)) == 0);
-	static_assert(sizeof(std::array<T, count>) == (sizeof(T) * count));
-};
-
-static_assert(sizeof(mpt::aligned_array<float, 4, std::align_val_t{sizeof(float) * 4}>) == sizeof(std::array<float, 4>));
-
-
-
-} // namespace mpt
-
-
-
-#endif // MPT_ENABLE_ALIGNED_ALLOC
-
-
-
-OPENMPT_NAMESPACE_END

+ 0 - 145
libopenmpt.mod/openmpt/common/mptAssert.h

@@ -1,145 +0,0 @@
-/*
- * mptAssert.h
- * -----------
- * Purpose: assert and static_assert
- * Notes  : (currently none)
- * Authors: OpenMPT Devs
- * The OpenMPT source code is released under the BSD license. Read LICENSE for more details.
- */
-
-
-#pragma once
-
-#include "BuildSettings.h"
-
-
-
-#include "mptBaseMacros.h"
-
-
-
-OPENMPT_NAMESPACE_BEGIN
-
-
-
-// Static code checkers might need to get the knowledge of our assertions transferred to them.
-#define MPT_CHECKER_ASSUME_ASSERTIONS 1
-//#define MPT_CHECKER_ASSUME_ASSERTIONS 0
-
-#ifdef MPT_BUILD_ANALYZED
-
-#if MPT_COMPILER_MSVC
-
-#if MPT_CHECKER_ASSUME_ASSERTIONS
-#define MPT_CHECKER_ASSUME(x) __analysis_assume(!!(x))
-#endif
-
-#elif MPT_COMPILER_CLANG
-
-#if MPT_CHECKER_ASSUME_ASSERTIONS
-#ifdef NDEBUG
-#error "Builds for static analyzers depend on assert() being enabled, but the current build has #define NDEBUG. This makes no sense."
-#endif
-OPENMPT_NAMESPACE_END
-#include <cassert>
-OPENMPT_NAMESPACE_BEGIN
-#define MPT_CHECKER_ASSUME(x) assert(!!(x))
-#endif
-
-#endif // MPT_COMPILER
-
-#endif // MPT_BUILD_ANALYZED
-
-#ifndef MPT_CHECKER_ASSUME
-#define MPT_CHECKER_ASSUME(x) MPT_DO { } MPT_WHILE_0
-#endif
-
-
-
-#if defined(_MFC_VER) && !defined(MPT_CPPCHECK_CUSTOM)
-
-#if !defined(ASSERT)
-#error "MFC is expected to #define ASSERT"
-#endif // !defined(ASERRT)
-#define MPT_FRAMEWORK_ASSERT_IS_DEFINED
-
-#if defined(_DEBUG)
- #define MPT_FRAMEWORK_ASSERT_IS_ACTIVE 1
-#else // !_DEBUG
- #define MPT_FRAMEWORK_ASSERT_IS_ACTIVE 0
-#endif // _DEBUG
-
-// let MFC handle our asserts
-#define MPT_ASSERT_USE_FRAMEWORK 1
-
-#else // !_MFC_VER
-
-#if defined(ASSERT)
-#define MPT_FRAMEWORK_ASSERT_IS_DEFINED
-#if defined(_DEBUG)
- #define MPT_FRAMEWORK_ASSERT_IS_ACTIVE 1
-#else // !_DEBUG
- #define MPT_FRAMEWORK_ASSERT_IS_ACTIVE 0
-#endif // _DEBUG
-#endif // !defined(ASERRT)
-
-// handle assert in our own way without relying on some platform-/framework-specific assert implementation
-#define MPT_ASSERT_USE_FRAMEWORK 0
-
-#endif // _MFC_VER
-
-#if defined(MPT_FRAMEWORK_ASSERT_IS_DEFINED) && (MPT_ASSERT_USE_FRAMEWORK == 1)
-
-#define MPT_ASSERT_NOTREACHED()          ASSERT(0)
-#define MPT_ASSERT(expr)                 ASSERT((expr))
-#define MPT_ASSERT_MSG(expr, msg)        ASSERT((expr) && (msg))
-#if (MPT_FRAMEWORK_ASSERT_IS_ACTIVE == 1)
-#define MPT_ASSERT_ALWAYS(expr)          ASSERT((expr))
-#define MPT_ASSERT_ALWAYS_MSG(expr, msg) ASSERT((expr) && (msg))
-#else
-#define MPT_ASSERT_ALWAYS(expr)          MPT_DO { if(!(expr)) { AssertHandler(MPT_SOURCE_LOCATION_CURRENT(), #expr); } MPT_CHECKER_ASSUME(expr); } MPT_WHILE_0
-#define MPT_ASSERT_ALWAYS_MSG(expr, msg) MPT_DO { if(!(expr)) { AssertHandler(MPT_SOURCE_LOCATION_CURRENT(), #expr, msg); } MPT_CHECKER_ASSUME(expr); } MPT_WHILE_0
-#ifndef MPT_ASSERT_HANDLER_NEEDED
-#define MPT_ASSERT_HANDLER_NEEDED
-#endif
-#endif
-
-#elif defined(NO_ASSERTS)
-
-#define MPT_ASSERT_NOTREACHED()          MPT_CHECKER_ASSUME(0)
-#define MPT_ASSERT(expr)                 MPT_CHECKER_ASSUME(expr)
-#define MPT_ASSERT_MSG(expr, msg)        MPT_CHECKER_ASSUME(expr)
-#define MPT_ASSERT_ALWAYS(expr)          MPT_DO { if(!(expr)) { AssertHandler(MPT_SOURCE_LOCATION_CURRENT(), #expr); } MPT_CHECKER_ASSUME(expr); } MPT_WHILE_0
-#define MPT_ASSERT_ALWAYS_MSG(expr, msg) MPT_DO { if(!(expr)) { AssertHandler(MPT_SOURCE_LOCATION_CURRENT(), #expr, msg); } MPT_CHECKER_ASSUME(expr); } MPT_WHILE_0
-#ifndef MPT_ASSERT_HANDLER_NEEDED
-#define MPT_ASSERT_HANDLER_NEEDED
-#endif
-
-#else // !NO_ASSERTS
-
-#define MPT_ASSERT_NOTREACHED()          MPT_DO { if constexpr(!(0)) { AssertHandler(MPT_SOURCE_LOCATION_CURRENT(), "0"); } MPT_CHECKER_ASSUME(0); } MPT_WHILE_0
-#define MPT_ASSERT(expr)                 MPT_DO { if(!(expr)) { AssertHandler(MPT_SOURCE_LOCATION_CURRENT(), #expr); } MPT_CHECKER_ASSUME(expr); } MPT_WHILE_0
-#define MPT_ASSERT_MSG(expr, msg)        MPT_DO { if(!(expr)) { AssertHandler(MPT_SOURCE_LOCATION_CURRENT(), #expr, msg); } MPT_CHECKER_ASSUME(expr); } MPT_WHILE_0
-#define MPT_ASSERT_ALWAYS(expr)          MPT_DO { if(!(expr)) { AssertHandler(MPT_SOURCE_LOCATION_CURRENT(), #expr); } MPT_CHECKER_ASSUME(expr); } MPT_WHILE_0
-#define MPT_ASSERT_ALWAYS_MSG(expr, msg) MPT_DO { if(!(expr)) { AssertHandler(MPT_SOURCE_LOCATION_CURRENT(), #expr, msg); } MPT_CHECKER_ASSUME(expr); } MPT_WHILE_0
-#ifndef MPT_ASSERT_HANDLER_NEEDED
-#define MPT_ASSERT_HANDLER_NEEDED
-#endif
-
-#endif // NO_ASSERTS
-
-
-#if defined(MPT_ASSERT_HANDLER_NEEDED)
-// custom assert handler needed
-MPT_NOINLINE void AssertHandler(const mpt::source_location &loc, const char *expr, const char *msg=nullptr);
-#endif // MPT_ASSERT_HANDLER_NEEDED
-
-
-
-#define MPT_CONSTEXPR11_ASSERT static_assert
-#define MPT_CONSTEXPR14_ASSERT static_assert
-#define MPT_CONSTEXPR17_ASSERT static_assert
-
-
-
-OPENMPT_NAMESPACE_END

+ 0 - 234
libopenmpt.mod/openmpt/common/mptBaseMacros.h

@@ -1,234 +0,0 @@
-/*
- * mptBaseMacros.h
- * ---------------
- * Purpose: Basic assorted compiler-related helpers.
- * Notes  : (currently none)
- * Authors: OpenMPT Devs
- * The OpenMPT source code is released under the BSD license. Read LICENSE for more details.
- */
-
-
-#pragma once
-
-#include "BuildSettings.h"
-
-
-
-#include <array>
-#include <iterator>
-#include <type_traits>
-
-#include <cstddef>
-#include <cstdint>
-
-#include <stddef.h>
-#include <stdint.h>
-
-
-
-OPENMPT_NAMESPACE_BEGIN
-
-
-
-// Advanced inline attributes
-#if MPT_COMPILER_MSVC
-#define MPT_FORCEINLINE __forceinline
-#define MPT_NOINLINE    __declspec(noinline)
-#elif MPT_COMPILER_GCC || MPT_COMPILER_CLANG
-#define MPT_FORCEINLINE __attribute__((always_inline)) inline
-#define MPT_NOINLINE    __attribute__((noinline))
-#else
-#define MPT_FORCEINLINE inline
-#define MPT_NOINLINE
-#endif
-
-
-
-// constexpr
-#define MPT_CONSTEXPR11_FUN constexpr MPT_FORCEINLINE
-#define MPT_CONSTEXPR11_VAR constexpr
-#define MPT_CONSTEXPR14_FUN constexpr MPT_FORCEINLINE
-#define MPT_CONSTEXPR14_VAR constexpr
-#define MPT_CONSTEXPR17_FUN constexpr MPT_FORCEINLINE
-#define MPT_CONSTEXPR17_VAR constexpr
-#if MPT_CXX_AT_LEAST(20)
-#define MPT_CONSTEXPR20_FUN constexpr MPT_FORCEINLINE
-#define MPT_CONSTEXPR20_VAR constexpr
-#else // !C++20
-#define MPT_CONSTEXPR20_FUN MPT_FORCEINLINE
-#define MPT_CONSTEXPR20_VAR const
-#endif // C++20
-
-
-
-namespace mpt
-{
-template <auto V> struct constant_value { static constexpr decltype(V) value() { return V; } };
-#define MPT_FORCE_CONSTEXPR(expr) (mpt::constant_value<( expr )>::value())
-}  // namespace mpt
-
-
-
-#if MPT_CXX_AT_LEAST(20)
-#define MPT_IS_CONSTANT_EVALUATED20() std::is_constant_evaluated()
-#define MPT_IS_CONSTANT_EVALUATED() std::is_constant_evaluated()
-#else // !C++20
-#define MPT_IS_CONSTANT_EVALUATED20() false
-// this pessimizes the case for C++17 by always assuming constexpr context, which implies always running constexpr-friendly code
-#define MPT_IS_CONSTANT_EVALUATED() true
-#endif // C++20
-
-
-
-namespace mpt
-{
-
-template <typename T>
-struct stdarray_extent : std::integral_constant<std::size_t, 0> {};
-
-template <typename T, std::size_t N>
-struct stdarray_extent<std::array<T, N>> : std::integral_constant<std::size_t, N> {};
-
-template <typename T>
-struct is_stdarray : std::false_type {};
-
-template <typename T, std::size_t N>
-struct is_stdarray<std::array<T, N>> : std::true_type {};
-
-// mpt::extent is the same as std::extent,
-// but also works for std::array,
-// and asserts that the given type is actually an array type instead of returning 0.
-// use as:
-// mpt::extent<decltype(expr)>()
-// mpt::extent<decltype(variable)>()
-// mpt::extent<decltype(type)>()
-// mpt::extent<type>()
-template <typename T>
-constexpr std::size_t extent() noexcept
-{
-	using Tarray = typename std::remove_cv<typename std::remove_reference<T>::type>::type;
-	static_assert(std::is_array<Tarray>::value || mpt::is_stdarray<Tarray>::value);
-	if constexpr(mpt::is_stdarray<Tarray>::value)
-	{
-		return mpt::stdarray_extent<Tarray>();
-	} else
-	{
-		return std::extent<Tarray>();
-	}
-}
-
-} // namespace mpt
-
-// legacy
-#if MPT_COMPILER_MSVC
-OPENMPT_NAMESPACE_END
-#include <cstdlib>
-#include <stdlib.h>
-OPENMPT_NAMESPACE_BEGIN
-#define MPT_ARRAY_COUNT(x) _countof(x)
-#else
-#define MPT_ARRAY_COUNT(x) (sizeof((x))/sizeof((x)[0]))
-#endif
-#define CountOf(x) MPT_ARRAY_COUNT(x)
-
-
-
-// Use MPT_RESTRICT to indicate that a pointer is guaranteed to not be aliased.
-#if MPT_COMPILER_MSVC || MPT_COMPILER_GCC || MPT_COMPILER_CLANG
-#define MPT_RESTRICT __restrict
-#else
-#define MPT_RESTRICT
-#endif
-
-
-
-#define MPT_ATTR_NODISCARD [[nodiscard]]
-#define MPT_DISCARD(expr) static_cast<void>(expr)
-
-
-
-#if MPT_COMPILER_MSVC
-#define MPT_MAYBE_CONSTANT_IF(x) \
-  __pragma(warning(push)) \
-  __pragma(warning(disable:4127)) \
-  if(x) \
-  __pragma(warning(pop)) \
-/**/
-#endif
-
-#if MPT_COMPILER_GCC
-#define MPT_MAYBE_CONSTANT_IF(x) \
-  _Pragma("GCC diagnostic push") \
-  _Pragma("GCC diagnostic ignored \"-Wtype-limits\"") \
-  if(x) \
-  _Pragma("GCC diagnostic pop") \
-/**/
-#endif
-
-#if MPT_COMPILER_CLANG
-#define MPT_MAYBE_CONSTANT_IF(x) \
-  _Pragma("clang diagnostic push") \
-  _Pragma("clang diagnostic ignored \"-Wunknown-pragmas\"") \
-  _Pragma("clang diagnostic ignored \"-Wtype-limits\"") \
-  _Pragma("clang diagnostic ignored \"-Wtautological-constant-out-of-range-compare\"") \
-  if(x) \
-  _Pragma("clang diagnostic pop") \
-/**/
-#endif
-
-#if !defined(MPT_MAYBE_CONSTANT_IF)
-// MPT_MAYBE_CONSTANT_IF disables compiler warnings for conditions that may in some case be either always false or always true (this may turn out to be useful in ASSERTions in some cases).
-#define MPT_MAYBE_CONSTANT_IF(x) if(x)
-#endif
-
-
-
-#if MPT_COMPILER_MSVC
-// MSVC warns for the well-known and widespread "do { } while(0)" idiom with warning level 4 ("conditional expression is constant").
-// It does not warn with "while(0,0)". However this again causes warnings with other compilers.
-// Solve it with a macro.
-#define MPT_DO do
-#define MPT_WHILE_0 while(0,0)
-#endif
-
-#ifndef MPT_DO
-#define MPT_DO do
-#endif
-#ifndef MPT_WHILE_0
-#define MPT_WHILE_0 while(0)
-#endif
-
-
-
-#if MPT_COMPILER_MSVC && defined(UNREFERENCED_PARAMETER)
-#define MPT_UNREFERENCED_PARAMETER(x) UNREFERENCED_PARAMETER(x)
-#else
-#define MPT_UNREFERENCED_PARAMETER(x) (void)(x)
-#endif
-
-#define MPT_UNUSED_VARIABLE(x) MPT_UNREFERENCED_PARAMETER(x)
-
-
-
-#if MPT_COMPILER_MSVC
-// warning LNK4221: no public symbols found; archive member will be inaccessible
-// There is no way to selectively disable linker warnings.
-// #pragma warning does not apply and a command line option does not exist.
-// Some options:
-//  1. Macro which generates a variable with a unique name for each file (which means we have to pass the filename to the macro)
-//  2. unnamed namespace containing any symbol (does not work for c++11 compilers because they actually have internal linkage now)
-//  3. An unused trivial inline function.
-// Option 3 does not actually solve the problem though, which leaves us with option 1.
-// In any case, for optimized builds, the linker will just remove the useless symbol.
-#define MPT_MSVC_WORKAROUND_LNK4221_CONCAT_DETAIL(x,y) x##y
-#define MPT_MSVC_WORKAROUND_LNK4221_CONCAT(x,y) MPT_MSVC_WORKAROUND_LNK4221_CONCAT_DETAIL(x,y)
-#define MPT_MSVC_WORKAROUND_LNK4221(x) int MPT_MSVC_WORKAROUND_LNK4221_CONCAT(mpt_msvc_workaround_lnk4221_,x) = 0;
-#endif
-
-#ifndef MPT_MSVC_WORKAROUND_LNK4221
-#define MPT_MSVC_WORKAROUND_LNK4221(x)
-#endif
-
-
-
-OPENMPT_NAMESPACE_END

+ 0 - 290
libopenmpt.mod/openmpt/common/mptBaseTypes.h

@@ -1,290 +0,0 @@
-/*
- * mptBaseTypes.h
- * --------------
- * Purpose: Basic data type definitions.
- * Notes  : (currently none)
- * Authors: OpenMPT Devs
- * The OpenMPT source code is released under the BSD license. Read LICENSE for more details.
- */
-
-
-#pragma once
-
-#include "BuildSettings.h"
-
-
-
-#include "mptBaseMacros.h"
-
-#include <array>
-#include <limits>
-#if MPT_CXX_AT_LEAST(20)
-#include <source_location>
-#endif // C++20
-
-#include <cstddef>
-#include <cstdint>
-
-#include <stdint.h>
-
-
-
-OPENMPT_NAMESPACE_BEGIN
-
-
-
-namespace mpt
-{
-template <bool cond, typename Ta, typename Tb>
-struct select_type
-{
-};
-template <typename Ta, typename Tb>
-struct select_type<true, Ta, Tb>
-{
-	using type = Ta;
-};
-template <typename Ta, typename Tb>
-struct select_type<false, Ta, Tb>
-{
-	using type = Tb;
-};
-} // namespace mpt
-
-
-
-using int8   = std::int8_t;
-using int16  = std::int16_t;
-using int32  = std::int32_t;
-using int64  = std::int64_t;
-using uint8  = std::uint8_t;
-using uint16 = std::uint16_t;
-using uint32 = std::uint32_t;
-using uint64 = std::uint64_t;
-
-constexpr int8 int8_min     = std::numeric_limits<int8>::min();
-constexpr int16 int16_min   = std::numeric_limits<int16>::min();
-constexpr int32 int32_min   = std::numeric_limits<int32>::min();
-constexpr int64 int64_min   = std::numeric_limits<int64>::min();
-
-constexpr int8 int8_max     = std::numeric_limits<int8>::max();
-constexpr int16 int16_max   = std::numeric_limits<int16>::max();
-constexpr int32 int32_max   = std::numeric_limits<int32>::max();
-constexpr int64 int64_max   = std::numeric_limits<int64>::max();
-
-constexpr uint8 uint8_max   = std::numeric_limits<uint8>::max();
-constexpr uint16 uint16_max = std::numeric_limits<uint16>::max();
-constexpr uint32 uint32_max = std::numeric_limits<uint32>::max();
-constexpr uint64 uint64_max = std::numeric_limits<uint64>::max();
-
-
-
-// fp half
-// n/a
-
-// fp single
-using single = float;
-constexpr single operator"" _fs(long double lit)
-{
-	return static_cast<single>(lit);
-}
-
-// fp double
-constexpr double operator"" _fd(long double lit)
-{
-	return static_cast<double>(lit);
-}
-
-// fp extended
-constexpr long double operator"" _fe(long double lit)
-{
-	return static_cast<long double>(lit);
-}
-
-// fp quad
-// n/a
-
-using float32 = mpt::select_type<sizeof(float) == 4,
-		float
-	,
-		mpt::select_type<sizeof(double) == 4,
-			double
-		,
-      mpt::select_type<sizeof(long double) == 4,
-				long double
-			,
-				float
-			>::type
-		>::type
-	>::type;
-constexpr float32 operator"" _f32(long double lit)
-{
-	return static_cast<float32>(lit);
-}
-
-using float64 = mpt::select_type<sizeof(float) == 8,
-		float
-	,
-		mpt::select_type<sizeof(double) == 8,
-			double
-		,
-      mpt::select_type<sizeof(long double) == 8,
-				long double
-			,
-				double
-			>::type
-		>::type
-	>::type;
-constexpr float64 operator"" _f64(long double lit)
-{
-	return static_cast<float64>(lit);
-}
-
-namespace mpt
-{
-template <typename T>
-struct float_traits
-{
-	static constexpr bool is_float = !std::numeric_limits<T>::is_integer;
-	static constexpr bool is_hard = is_float && !MPT_COMPILER_QUIRK_FLOAT_EMULATED;
-	static constexpr bool is_soft = is_float && MPT_COMPILER_QUIRK_FLOAT_EMULATED;
-	static constexpr bool is_float32 = is_float && (sizeof(T) == 4);
-	static constexpr bool is_float64 = is_float && (sizeof(T) == 8);
-	static constexpr bool is_native_endian = is_float && !MPT_COMPILER_QUIRK_FLOAT_NOTNATIVEENDIAN;
-	static constexpr bool is_ieee754_binary = is_float && std::numeric_limits<T>::is_iec559 && !MPT_COMPILER_QUIRK_FLOAT_NOTIEEE754;
-	static constexpr bool is_ieee754_binary32 = is_float && is_ieee754_binary && is_float32;
-	static constexpr bool is_ieee754_binary64 = is_float && is_ieee754_binary && is_float64;
-	static constexpr bool is_ieee754_binary32ne = is_float && is_ieee754_binary && is_float32 && is_native_endian;
-	static constexpr bool is_ieee754_binary64ne = is_float && is_ieee754_binary && is_float64 && is_native_endian;
-};
-}  // namespace mpt
-
-#if MPT_COMPILER_QUIRK_FLOAT_PREFER32
-using nativefloat = float32;
-#elif MPT_COMPILER_QUIRK_FLOAT_PREFER64
-using nativefloat = float64;
-#else
-// prefer smaller floats, but try to use IEEE754 floats
-using nativefloat = mpt::select_type<std::numeric_limits<float>::is_iec559,
-		float
-	,
-		mpt::select_type<std::numeric_limits<double>::is_iec559,
-			double
-		,
-			mpt::select_type<std::numeric_limits<long double>::is_iec559,
-				long double
-			,
-				float
-			>::type
-		>::type
-	>::type;	
-#endif
-constexpr nativefloat operator"" _nf(long double lit)
-{
-	return static_cast<nativefloat>(lit);
-}
-
-
-
-static_assert(sizeof(std::uintptr_t) == sizeof(void*));
-
-
-
-static_assert(std::numeric_limits<unsigned char>::digits == 8);
-
-static_assert(sizeof(char) == 1);
-
-static_assert(sizeof(std::byte) == 1);
-static_assert(alignof(std::byte) == 1);
-
-
-namespace mpt {
-constexpr int arch_bits = sizeof(void*) * 8;
-constexpr std::size_t pointer_size = sizeof(void*);
-} // namespace mpt
-
-static_assert(mpt::arch_bits == static_cast<int>(mpt::pointer_size) * 8);
-
-
-
-namespace mpt {
-
-template <typename T>
-struct limits
-{
-	static constexpr typename std::remove_cv<T>::type min() noexcept { return std::numeric_limits<typename std::remove_cv<T>::type>::min(); }
-	static constexpr typename std::remove_cv<T>::type max() noexcept { return std::numeric_limits<typename std::remove_cv<T>::type>::max(); }
-};
-
-} // namespace mpt
-
-
-
-namespace mpt
-{
-
-#if MPT_CXX_AT_LEAST(20)
-
-using std::source_location;
-
-#define MPT_SOURCE_LOCATION_CURRENT() std::source_location::current()
-
-#else // !C++20
-
-// compatible with std::experimental::source_location from Library Fundamentals TS v2.
-struct source_location
-{
-private:
-	const char* m_file_name;
-	const char* m_function_name;
-	uint32 m_line;
-	uint32 m_column;
-public:
-	constexpr source_location() noexcept
-		: m_file_name("")
-		, m_function_name("")
-		, m_line(0)
-		, m_column(0)
-	{
-	}
-	constexpr source_location(const char* file, const char* function, uint32 line, uint32 column) noexcept
-		: m_file_name(file)
-		, m_function_name(function)
-		, m_line(line)
-		, m_column(column)
-	{
-	}
-	source_location(const source_location&) = default;
-	source_location(source_location&&) = default;
-	//static constexpr current() noexcept;  // use MPT_SOURCE_LOCATION_CURRENT()
-	static constexpr source_location current(const char* file, const char* function, uint32 line, uint32 column) noexcept
-	{
-		return source_location(file, function, line, column);
-	}
-	constexpr uint32 line() const noexcept
-	{
-		return m_line;
-	}
-	constexpr uint32 column() const noexcept
-	{
-		return m_column;
-	}
-	constexpr const char* file_name() const noexcept
-	{
-		return m_file_name;
-	}
-	constexpr const char* function_name() const noexcept
-	{
-		return m_function_name;
-	}
-};
-
-#define MPT_SOURCE_LOCATION_CURRENT() mpt::source_location::current( __FILE__ , __func__ , __LINE__ , 0 )
-
-#endif // C++20
-
-} // namespace mpt
-
-
-
-OPENMPT_NAMESPACE_END

+ 0 - 640
libopenmpt.mod/openmpt/common/mptBaseUtils.h

@@ -1,640 +0,0 @@
-/*
- * mptBaseUtils.h
- * --------------
- * Purpose: Various useful utility functions.
- * Notes  : (currently none)
- * Authors: OpenMPT Devs
- * The OpenMPT source code is released under the BSD license. Read LICENSE for more details.
- */
-
-
-#pragma once
-
-#include "BuildSettings.h"
-
-
-#include "mptBaseMacros.h"
-#include "mptBaseTypes.h"
-
-#include <algorithm>
-#if MPT_CXX_AT_LEAST(20)
-#include <bit>
-#endif
-#include <limits>
-#include <numeric>
-#include <utility>
-
-#include <cmath>
-#include <cstdlib>
-
-#include <math.h>
-#include <stdlib.h>
-
-
-
-OPENMPT_NAMESPACE_BEGIN
-
-
-
-// cmath fixups
-#ifndef M_PI
-#define M_PI       3.14159265358979323846
-#endif
-#ifndef M_PI_2
-#define M_PI_2     1.57079632679489661923
-#endif
-#ifndef M_LN2
-#define M_LN2      0.69314718055994530942
-#endif
-
-
-
-namespace mpt
-{
-template <typename T, std::size_t N, typename Tx>
-MPT_CONSTEXPR14_FUN std::array<T, N> init_array(Tx && x)
-{
-	std::array<T, N> result;
-	for(std::size_t i = 0; i < N; ++i)
-	{
-		result[i] = std::forward<Tx>(x);
-	}
-	return result;
-}
-} // namespace mpt
-
-
-
-namespace mpt
-{
-// Work-around for the requirement of at least 1 non-throwing function argument combination in C++ (17,2a).
-template <typename Exception>
-MPT_CONSTEXPR14_FUN bool constexpr_throw_helper(Exception && e, bool really = true)
-{
-	return !really ? really : throw std::forward<Exception>(e);
-}
-template <typename Exception>
-MPT_CONSTEXPR14_FUN bool constexpr_throw(Exception && e)
-{
-	return mpt::constexpr_throw_helper(std::forward<Exception>(e));
-}
-}  // namespace mpt
-
-
-
-namespace mpt {
-
-// Modulo with more intuitive behaviour for some contexts:
-// Instead of being symmetrical around 0, the pattern for positive numbers is repeated in the negative range.
-// For example, wrapping_modulo(-1, m) == (m - 1).
-// Behaviour is undefined if m<=0.
-template<typename T, typename M>
-MPT_CONSTEXPR11_FUN auto wrapping_modulo(T x, M m) -> decltype(x % m)
-{
-	return (x >= 0) ? (x % m) : (m - 1 - ((-1 - x) % m));
-}
-
-template<typename T, typename D>
-MPT_CONSTEXPR11_FUN auto wrapping_divide(T x, D d) -> decltype(x / d)
-{
-	return (x >= 0) ? (x / d) : (((x + 1) / d) - 1);
-}
-
-} // namespace mpt
-
-
-
-namespace mpt {
-
-
-
-// Saturate the value of src to the domain of Tdst
-template <typename Tdst, typename Tsrc>
-inline Tdst saturate_cast(Tsrc src)
-{
-	// This code tries not only to obviously avoid overflows but also to avoid signed/unsigned comparison warnings and type truncation warnings (which in fact would be safe here) by explicit casting.
-	static_assert(std::numeric_limits<Tdst>::is_integer);
-	static_assert(std::numeric_limits<Tsrc>::is_integer);
-	if constexpr(std::numeric_limits<Tdst>::is_signed && std::numeric_limits<Tsrc>::is_signed)
-	{
-		if constexpr(sizeof(Tdst) >= sizeof(Tsrc))
-		{
-			return static_cast<Tdst>(src);
-		} else
-		{
-			return static_cast<Tdst>(std::max(static_cast<Tsrc>(std::numeric_limits<Tdst>::min()), std::min(src, static_cast<Tsrc>(std::numeric_limits<Tdst>::max()))));
-		}
-	} else if constexpr(!std::numeric_limits<Tdst>::is_signed && !std::numeric_limits<Tsrc>::is_signed)
-	{
-		if constexpr(sizeof(Tdst) >= sizeof(Tsrc))
-		{
-			return static_cast<Tdst>(src);
-		} else
-		{
-			return static_cast<Tdst>(std::min(src, static_cast<Tsrc>(std::numeric_limits<Tdst>::max())));
-		}
-	} else if constexpr(std::numeric_limits<Tdst>::is_signed && !std::numeric_limits<Tsrc>::is_signed)
-	{
-		if constexpr(sizeof(Tdst) > sizeof(Tsrc))
-		{
-			return static_cast<Tdst>(src);
-		} else if constexpr(sizeof(Tdst) == sizeof(Tsrc))
-		{
-			return static_cast<Tdst>(std::min(src, static_cast<Tsrc>(std::numeric_limits<Tdst>::max())));
-		} else
-		{
-			return static_cast<Tdst>(std::min(src, static_cast<Tsrc>(std::numeric_limits<Tdst>::max())));
-		}
-	} else // Tdst unsigned, Tsrc signed
-	{
-		if constexpr(sizeof(Tdst) >= sizeof(Tsrc))
-		{
-			return static_cast<Tdst>(std::max(static_cast<Tsrc>(0), src));
-		} else
-		{
-			return static_cast<Tdst>(std::max(static_cast<Tsrc>(0), std::min(src, static_cast<Tsrc>(std::numeric_limits<Tdst>::max()))));
-		}
-	}
-}
-
-template <typename Tdst>
-inline Tdst saturate_cast(double src)
-{
-	if(src >= std::numeric_limits<Tdst>::max())
-	{
-		return std::numeric_limits<Tdst>::max();
-	}
-	if(src <= std::numeric_limits<Tdst>::min())
-	{
-		return std::numeric_limits<Tdst>::min();
-	}
-	return static_cast<Tdst>(src);
-}
-
-template <typename Tdst>
-inline Tdst saturate_cast(float src)
-{
-	if(src >= std::numeric_limits<Tdst>::max())
-	{
-		return std::numeric_limits<Tdst>::max();
-	}
-	if(src <= std::numeric_limits<Tdst>::min())
-	{
-		return std::numeric_limits<Tdst>::min();
-	}
-	return static_cast<Tdst>(src);
-}
-
-
-template <typename T>
-MPT_CONSTEXPR14_FUN std::size_t weight(T val) noexcept
-{
-	static_assert(std::numeric_limits<T>::is_integer);
-	typedef typename std::make_unsigned<T>::type Tunsigned;
-	Tunsigned uval = static_cast<Tunsigned>(val);
-	std::size_t result = 0;
-	while(uval > 0)
-	{
-		if(uval & 0x1)
-		{
-			result++;
-		}
-		uval >>= 1;
-	}
-	return result;
-}
-
-#if MPT_CXX_AT_LEAST(20)
-
-using std::ispow2;
-using std::ceil2;
-using std::floor2;
-using std::log2p1;
-using std::rotl;
-using std::rotr;
-
-#else
-
-// C++20 <bit> header.
-// Note that we do not use SFINAE here but instead rely on static_assert.
-// Also note that for C++11 compilers, these functions are not constexpr.
-// They could be implemented recursively to make them C++11 constexpr compatible if needed.
-
-template <typename T>
-MPT_CONSTEXPR14_FUN bool ispow2(T x) noexcept
-{
-	static_assert(std::numeric_limits<T>::is_integer);
-	static_assert(std::is_unsigned<T>::value);
-	return mpt::weight(x) == 1;
-}
-
-template <typename T>
-MPT_CONSTEXPR14_FUN T ceil2(T x) noexcept
-{
-	static_assert(std::numeric_limits<T>::is_integer);
-	static_assert(std::is_unsigned<T>::value);
-	T result = 1;
-	while(result < x)
-	{
-		T newresult = result << 1;
-		if(newresult < result)
-		{
-			return 0;
-		}
-		result = newresult;
-	}
-	return result;
-}
-
-template <typename T>
-MPT_CONSTEXPR14_FUN T floor2(T x) noexcept
-{
-	static_assert(std::numeric_limits<T>::is_integer);
-	static_assert(std::is_unsigned<T>::value);
-	if(x == 0)
-	{
-		return 0;
-	}
-	T result = 1;
-	do
-	{
-		T newresult = result << 1;
-		if(newresult < result)
-		{
-			return result;
-		}
-		result = newresult;
-	} while(result <= x);
-	return result >> 1;
-}
- 
-template <typename T>
-MPT_CONSTEXPR14_FUN T log2p1(T x) noexcept
-{
-	static_assert(std::numeric_limits<T>::is_integer);
-	static_assert(std::is_unsigned<T>::value);
-	T result = 0;
-	while(x > 0)
-	{
-		x >>= 1;
-		result += 1;
-	}
-	return result;
-}
-
-namespace detail
-{
-
-template <typename T>
-MPT_CONSTEXPR14_FUN T rotl(T x, int r) noexcept
-{
-	auto N = std::numeric_limits<T>::digits;
-	return (x >> (N - r)) | (x << r);
-}
-
-template <typename T>
-MPT_CONSTEXPR14_FUN T rotr(T x, int r) noexcept
-{
-	auto N = std::numeric_limits<T>::digits;
-	return (x << (N - r)) | (x >> r);
-}
-
-} // namespace detail
-
-template <typename T>
-MPT_CONSTEXPR14_FUN T rotl(T x, int s) noexcept
-{
-	static_assert(std::numeric_limits<T>::is_integer);
-	static_assert(std::is_unsigned<T>::value);
-	auto N = std::numeric_limits<T>::digits;
-	auto r = s % N;
-	return (s < 0) ? detail::rotr(x, -s) : ((x >> (N - r)) | (x << r));
-}
-
-template <typename T>
-MPT_CONSTEXPR14_FUN T rotr(T x, int s) noexcept
-{
-	static_assert(std::numeric_limits<T>::is_integer);
-	static_assert(std::is_unsigned<T>::value);
-	auto N = std::numeric_limits<T>::digits;
-	auto r = s % N;
-	return (s < 0) ? detail::rotl(x, -s) : ((x << (N - r)) | (x >> r));
-}
-
-#endif
-
-} // namespace mpt
-
-
-namespace Util
-{
-
-namespace detail
-{
-template <typename Tmod, Tmod m>
-struct ModIfNotZeroImpl
-{
-	template <typename Tval>
-	inline Tval mod(Tval x)
-	{
-		static_assert(std::numeric_limits<Tmod>::is_integer);
-		static_assert(!std::numeric_limits<Tmod>::is_signed);
-		static_assert(std::numeric_limits<Tval>::is_integer);
-		static_assert(!std::numeric_limits<Tval>::is_signed);
-		return static_cast<Tval>(x % m);
-	}
-};
-template <> struct ModIfNotZeroImpl<uint8 , 0> { template <typename Tval> inline Tval mod(Tval x) { return x; } };
-template <> struct ModIfNotZeroImpl<uint16, 0> { template <typename Tval> inline Tval mod(Tval x) { return x; } };
-template <> struct ModIfNotZeroImpl<uint32, 0> { template <typename Tval> inline Tval mod(Tval x) { return x; } };
-template <> struct ModIfNotZeroImpl<uint64, 0> { template <typename Tval> inline Tval mod(Tval x) { return x; } };
-} // namespace detail
-// Returns x % m if m != 0, x otherwise.
-// i.e. "return (m == 0) ? x : (x % m);", but without causing a warning with stupid older compilers
-template <typename Tmod, Tmod m, typename Tval>
-inline Tval ModIfNotZero(Tval x)
-{
-	return detail::ModIfNotZeroImpl<Tmod, m>().mod(x);
-}
-
-// Returns true iff Tdst can represent the value val.
-// Use as if(Util::TypeCanHoldValue<uint8>(-1)).
-template <typename Tdst, typename Tsrc>
-inline bool TypeCanHoldValue(Tsrc val)
-{
-	return (static_cast<Tsrc>(mpt::saturate_cast<Tdst>(val)) == val);
-}
-
-// Grows x with an exponential factor suitable for increasing buffer sizes.
-// Clamps the result at limit.
-// And avoids integer overflows while doing its business.
-// The growth factor is 1.5, rounding down, execpt for the initial x==1 case.
-template <typename T, typename Tlimit>
-inline T ExponentialGrow(const T &x, const Tlimit &limit)
-{
-	MPT_ASSERT(x > 0);
-	MPT_ASSERT(limit > 0);
-	if(x == 1)
-	{
-		return 2;
-	}
-	T add = std::min(x >> 1, std::numeric_limits<T>::max() - x);
-	return std::min(x + add, mpt::saturate_cast<T>(limit));
-}
-									
-template <typename T>
-inline T ExponentialGrow(const T &x)
-{
-	return Util::ExponentialGrow(x, std::numeric_limits<T>::max());
-}
-
-} //namespace Util
-
-
-// Limits 'val' to given range. If 'val' is less than 'lowerLimit', 'val' is set to value 'lowerLimit'.
-// Similarly if 'val' is greater than 'upperLimit', 'val' is set to value 'upperLimit'.
-// If 'lowerLimit' > 'upperLimit', 'val' won't be modified.
-template<class T, class C>
-inline void Limit(T& val, const C lowerLimit, const C upperLimit)
-{
-	if(lowerLimit > upperLimit) return;
-	if(val < lowerLimit) val = lowerLimit;
-	else if(val > upperLimit) val = upperLimit;
-}
-
-
-// Like Limit, but returns value
-template<class T, class C>
-inline T Clamp(T val, const C lowerLimit, const C upperLimit)
-{
-	if(val < lowerLimit) return lowerLimit;
-	else if(val > upperLimit) return upperLimit;
-	else return val;
-}
-
-// Check if val is in [lo,hi] without causing compiler warnings
-// if theses checks are always true due to the domain of T.
-// GCC does not warn if the type is templated.
-template<typename T, typename C>
-inline bool IsInRange(T val, C lo, C hi)
-{
-	return lo <= val && val <= hi;
-}
-
-// Like Limit, but with upperlimit only.
-template<class T, class C>
-inline void LimitMax(T& val, const C upperLimit)
-{
-	if(val > upperLimit)
-		val = upperLimit;
-}
-
-
-// Returns sign of a number (-1 for negative numbers, 1 for positive numbers, 0 for 0)
-template <class T>
-int sgn(T value)
-{
-	return (value > T(0)) - (value < T(0));
-}
-
-
-
-// mpt::rshift_signed
-// mpt::lshift_signed
-// Shift a signed integer value in a well-defined manner.
-// Does the same thing as MSVC would do. This is verified by the test suite.
-
-namespace mpt
-{
-
-template <typename T>
-MPT_FORCEINLINE auto rshift_signed_standard(T x, int y) -> decltype(x >> y)
-{
-	static_assert(std::numeric_limits<T>::is_integer);
-	static_assert(std::numeric_limits<T>::is_signed);
-	typedef decltype(x >> y) result_type;
-	typedef typename std::make_unsigned<result_type>::type unsigned_result_type;
-	const unsigned_result_type roffset = static_cast<unsigned_result_type>(1) << ((sizeof(result_type) * 8) - 1);
-	result_type rx = x;
-	unsigned_result_type urx = static_cast<unsigned_result_type>(rx);
-	urx += roffset;
-	urx >>= y;
-	urx -= roffset >> y;
-	return static_cast<result_type>(urx);
-}
-
-template <typename T>
-MPT_FORCEINLINE auto lshift_signed_standard(T x, int y) -> decltype(x << y)
-{
-	static_assert(std::numeric_limits<T>::is_integer);
-	static_assert(std::numeric_limits<T>::is_signed);
-	typedef decltype(x << y) result_type;
-	typedef typename std::make_unsigned<result_type>::type unsigned_result_type;
-	const unsigned_result_type roffset = static_cast<unsigned_result_type>(1) << ((sizeof(result_type) * 8) - 1);
-	result_type rx = x;
-	unsigned_result_type urx = static_cast<unsigned_result_type>(rx);
-	urx += roffset;
-	urx <<= y;
-	urx -= roffset << y;
-	return static_cast<result_type>(urx);
-}
-
-#if MPT_COMPILER_SHIFT_SIGNED
-
-template <typename T>
-MPT_FORCEINLINE auto rshift_signed_undefined(T x, int y) -> decltype(x >> y)
-{
-	static_assert(std::numeric_limits<T>::is_integer);
-	static_assert(std::numeric_limits<T>::is_signed);
-	return x >> y;
-}
-
-template <typename T>
-MPT_FORCEINLINE auto lshift_signed_undefined(T x, int y) -> decltype(x << y)
-{
-	static_assert(std::numeric_limits<T>::is_integer);
-	static_assert(std::numeric_limits<T>::is_signed);
-	return x << y;
-}
-
-template <typename T>
-MPT_FORCEINLINE auto rshift_signed(T x, int y) -> decltype(x >> y)
-{
-	return mpt::rshift_signed_undefined(x, y);
-}
-
-template <typename T>
-MPT_FORCEINLINE auto lshift_signed(T x, int y) -> decltype(x << y)
-{
-	return mpt::lshift_signed_undefined(x, y);
-}
-
-#else
-
-template <typename T>
-MPT_FORCEINLINE auto rshift_signed(T x, int y) -> decltype(x >> y)
-{
-	return mpt::rshift_signed_standard(x, y);
-}
-
-template <typename T>
-MPT_FORCEINLINE auto lshift_signed(T x, int y) -> decltype(x << y)
-{
-	return mpt::lshift_signed_standard(x, y);
-}
-
-#endif
-
-} // namespace mpt
-
-
-
-namespace Util
-{
-
-	// Returns maximum value of given integer type.
-	template <class T> constexpr T MaxValueOfType(const T&) {static_assert(std::numeric_limits<T>::is_integer == true, "Only integer types are allowed."); return (std::numeric_limits<T>::max)();}
-
-}
-
-namespace mpt
-{
-
-#if MPT_OS_DJGPP
-
-	inline double round(const double& val) { return ::round(val); }
-	inline float round(const float& val) { return ::roundf(val); }
-
-#else // !MPT_OS_DJGPP
-
-	// C++11 std::round
-	using std::round;
-
-#endif // MPT_OS_DJGPP
-
-
-	// Rounds given double value to nearest integer value of type T.
-	// Out-of-range values are saturated to the specified integer type's limits.
-	template <class T> inline T saturate_round(double val)
-	{
-		static_assert(std::numeric_limits<T>::is_integer == true, "Type is a not an integer");
-		return mpt::saturate_cast<T>(mpt::round(val));
-	}
-
-	template <class T> inline T saturate_round(float val)
-	{
-		static_assert(std::numeric_limits<T>::is_integer == true, "Type is a not an integer");
-		return mpt::saturate_cast<T>(mpt::round(val));
-	}
-
-}
-
-
-namespace Util {
-
-	// Multiply two 32-bit integers, receive 64-bit result.
-	// MSVC generates unnecessarily complicated code for the unoptimized variant using _allmul.
-	MPT_FORCEINLINE int64 mul32to64(int32 a, int32 b)
-	{
-#if MPT_COMPILER_MSVC && (defined(_M_IX86) || defined(_M_X64))
-		return __emul(a, b);
-#else
-		return static_cast<int64>(a) * b;
-#endif
-	}
-
-	MPT_FORCEINLINE uint64 mul32to64_unsigned(uint32 a, uint32 b)
-	{
-#if MPT_COMPILER_MSVC && (defined(_M_IX86) || defined(_M_X64))
-		return __emulu(a, b);
-#else
-		return static_cast<uint64>(a) * b;
-#endif
-	}
-
-	MPT_FORCEINLINE int32 muldiv(int32 a, int32 b, int32 c)
-	{
-		return mpt::saturate_cast<int32>( mul32to64( a, b ) / c );
-	}
-
-	MPT_FORCEINLINE int32 muldivr(int32 a, int32 b, int32 c)
-	{
-		return mpt::saturate_cast<int32>( ( mul32to64( a, b ) + ( c / 2 ) ) / c );
-	}
-
-	// Do not use overloading because catching unsigned version by accident results in slower X86 code.
-	MPT_FORCEINLINE uint32 muldiv_unsigned(uint32 a, uint32 b, uint32 c)
-	{
-		return mpt::saturate_cast<uint32>( mul32to64_unsigned( a, b ) / c );
-	}
-	MPT_FORCEINLINE uint32 muldivr_unsigned(uint32 a, uint32 b, uint32 c)
-	{
-		return mpt::saturate_cast<uint32>( ( mul32to64_unsigned( a, b ) + ( c / 2u ) ) / c );
-	}
-
-	MPT_FORCEINLINE int32 muldivrfloor(int64 a, uint32 b, uint32 c)
-	{
-		a *= b;
-		a += c / 2u;
-		return (a >= 0) ? mpt::saturate_cast<int32>(a / c) : mpt::saturate_cast<int32>((a - (c - 1)) / c);
-	}
-
-	// rounds x up to multiples of target
-	template <typename T>
-	inline T AlignUp(T x, T target)
-	{
-		return ((x + (target - 1)) / target) * target;
-	}
-
-	// rounds x down to multiples of target
-	template <typename T>
-	inline T AlignDown(T x, T target)
-	{
-		return (x / target) * target;
-	}
-
-} // namespace Util
-
-
-
-OPENMPT_NAMESPACE_END

+ 0 - 292
libopenmpt.mod/openmpt/common/mptCPU.cpp

@@ -1,292 +0,0 @@
-/*
- * mptCPU.cpp
- * ----------
- * Purpose: CPU feature detection.
- * Notes  : (currently none)
- * Authors: OpenMPT Devs
- * The OpenMPT source code is released under the BSD license. Read LICENSE for more details.
- */
-
-
-#include "stdafx.h"
-#include "mptCPU.h"
-
-#include "mptStringBuffer.h"
-
-
-OPENMPT_NAMESPACE_BEGIN
-
-
-#if defined(ENABLE_ASM)
-
-
-uint32 RealProcSupport = 0;
-uint32 ProcSupport = 0;
-char ProcVendorID[16+1] = "";
-char ProcBrandID[4*4*3+1] = "";
-uint16 ProcFamily = 0;
-uint8 ProcModel = 0;
-uint8 ProcStepping = 0;
-
-
-#if MPT_COMPILER_MSVC && (defined(ENABLE_X86) || defined(ENABLE_X64)) && defined(ENABLE_CPUID)
-
-
-#include <intrin.h>
-
-
-typedef char cpuid_result_string[12];
-
-
-struct cpuid_result {
-	uint32 a;
-	uint32 b;
-	uint32 c;
-	uint32 d;
-	std::string as_string() const
-	{
-		cpuid_result_string result;
-		result[0+0] = (b >> 0) & 0xff;
-		result[0+1] = (b >> 8) & 0xff;
-		result[0+2] = (b >>16) & 0xff;
-		result[0+3] = (b >>24) & 0xff;
-		result[4+0] = (d >> 0) & 0xff;
-		result[4+1] = (d >> 8) & 0xff;
-		result[4+2] = (d >>16) & 0xff;
-		result[4+3] = (d >>24) & 0xff;
-		result[8+0] = (c >> 0) & 0xff;
-		result[8+1] = (c >> 8) & 0xff;
-		result[8+2] = (c >>16) & 0xff;
-		result[8+3] = (c >>24) & 0xff;
-		return std::string(result, result + 12);
-	}
-	std::string as_string4() const
-	{
-		std::string result;
-		result.push_back(static_cast<uint8>((a >>  0) & 0xff));
-		result.push_back(static_cast<uint8>((a >>  8) & 0xff));
-		result.push_back(static_cast<uint8>((a >> 16) & 0xff));
-		result.push_back(static_cast<uint8>((a >> 24) & 0xff));
-		result.push_back(static_cast<uint8>((b >>  0) & 0xff));
-		result.push_back(static_cast<uint8>((b >>  8) & 0xff));
-		result.push_back(static_cast<uint8>((b >> 16) & 0xff));
-		result.push_back(static_cast<uint8>((b >> 24) & 0xff));
-		result.push_back(static_cast<uint8>((c >>  0) & 0xff));
-		result.push_back(static_cast<uint8>((c >>  8) & 0xff));
-		result.push_back(static_cast<uint8>((c >> 16) & 0xff));
-		result.push_back(static_cast<uint8>((c >> 24) & 0xff));
-		result.push_back(static_cast<uint8>((d >>  0) & 0xff));
-		result.push_back(static_cast<uint8>((d >>  8) & 0xff));
-		result.push_back(static_cast<uint8>((d >> 16) & 0xff));
-		result.push_back(static_cast<uint8>((d >> 24) & 0xff));
-		return result;
-	}
-};
-
-
-static cpuid_result cpuid(uint32 function)
-{
-	cpuid_result result;
-	int CPUInfo[4];
-	__cpuid(CPUInfo, function);
-	result.a = CPUInfo[0];
-	result.b = CPUInfo[1];
-	result.c = CPUInfo[2];
-	result.d = CPUInfo[3];
-	return result;
-}
-
-
-void InitProcSupport()
-{
-
-	RealProcSupport = 0;
-	ProcSupport = 0;
-	mpt::String::WriteAutoBuf(ProcVendorID) = "";
-	mpt::String::WriteAutoBuf(ProcBrandID) = "";
-	ProcFamily = 0;
-	ProcModel = 0;
-	ProcStepping = 0;
-
-	ProcSupport |= PROCSUPPORT_ASM_INTRIN;
-	ProcSupport |= PROCSUPPORT_CPUID;
-
-	{
-
-		cpuid_result VendorString = cpuid(0x00000000u);
-		mpt::String::WriteAutoBuf(ProcVendorID) = VendorString.as_string();
-		if(VendorString.a >= 0x00000001u)
-		{
-			cpuid_result StandardFeatureFlags = cpuid(0x00000001u);
-			uint32 Stepping   = (StandardFeatureFlags.a >>  0) & 0x0f;
-			uint32 BaseModel  = (StandardFeatureFlags.a >>  4) & 0x0f;
-			uint32 BaseFamily = (StandardFeatureFlags.a >>  8) & 0x0f;
-			uint32 ExtModel   = (StandardFeatureFlags.a >> 16) & 0x0f;
-			uint32 ExtFamily  = (StandardFeatureFlags.a >> 20) & 0xff;
-			if(BaseFamily == 0xf)
-			{
-				ProcFamily = static_cast<uint16>(ExtFamily + BaseFamily);
-			} else
-			{
-				ProcFamily = static_cast<uint16>(BaseFamily);
-			}
-			if((BaseFamily == 0x6) || (BaseFamily == 0xf))
-			{
-				ProcModel = static_cast<uint8>((ExtModel << 4) | (BaseModel << 0));
-			} else
-			{
-				ProcModel = static_cast<uint8>(BaseModel);
-			}
-			ProcStepping = static_cast<uint8>(Stepping);
-			if(StandardFeatureFlags.d & (1<<23)) ProcSupport |= PROCSUPPORT_MMX;
-			if(StandardFeatureFlags.d & (1<<25)) ProcSupport |= PROCSUPPORT_SSE;
-			if(StandardFeatureFlags.d & (1<<26)) ProcSupport |= PROCSUPPORT_SSE2;
-			if(StandardFeatureFlags.c & (1<< 0)) ProcSupport |= PROCSUPPORT_SSE3;
-			if(StandardFeatureFlags.c & (1<< 9)) ProcSupport |= PROCSUPPORT_SSSE3;
-			if(StandardFeatureFlags.c & (1<<19)) ProcSupport |= PROCSUPPORT_SSE4_1;
-			if(StandardFeatureFlags.c & (1<<20)) ProcSupport |= PROCSUPPORT_SSE4_2;
-			if(StandardFeatureFlags.c & (1<<28)) ProcSupport |= PROCSUPPORT_AVX;
-		}
-
-		cpuid_result ExtendedVendorString = cpuid(0x80000000u);
-		if(ExtendedVendorString.a >= 0x80000001u)
-		{
-			cpuid_result ExtendedFeatureFlags = cpuid(0x80000001u);
-			if(ExtendedFeatureFlags.d & (1<<29)) ProcSupport |= PROCSUPPORT_LM;
-		}
-		if(ExtendedVendorString.a >= 0x80000004u)
-		{
-			mpt::String::WriteAutoBuf(ProcBrandID) = cpuid(0x80000002u).as_string4() + cpuid(0x80000003u).as_string4() + cpuid(0x80000004u).as_string4();
-			if(ExtendedVendorString.a >= 0x80000007u)
-			{
-				cpuid_result ExtendedFeatures = cpuid(0x80000007u);
-				if(ExtendedFeatures.b & (1<< 5)) ProcSupport |= PROCSUPPORT_AVX2;
-			}
-		}
-
-	}
-
-	RealProcSupport = ProcSupport;
-
-}
-
-
-#elif MPT_COMPILER_MSVC && (defined(ENABLE_X86) || defined(ENABLE_X64))
-
-
-void InitProcSupport()
-{
-
-	RealProcSupport = 0;
-	ProcSupport = 0;
-	mpt::String::WriteAutoBuf(ProcVendorID) = "";
-	mpt::String::WriteAutoBuf(ProcBrandID) = "";
-	ProcFamily = 0;
-	ProcModel = 0;
-	ProcStepping = 0;
-
-	ProcSupport |= PROCSUPPORT_ASM_INTRIN;
-
-	{
-
-		if(IsProcessorFeaturePresent(PF_MMX_INSTRUCTIONS_AVAILABLE) != 0)    ProcSupport |= PROCSUPPORT_MMX;
-		if(IsProcessorFeaturePresent(PF_XMMI_INSTRUCTIONS_AVAILABLE) != 0)   ProcSupport |= PROCSUPPORT_SSE;
-		if(IsProcessorFeaturePresent(PF_XMMI64_INSTRUCTIONS_AVAILABLE) != 0) ProcSupport |= PROCSUPPORT_SSE2;
-		if(IsProcessorFeaturePresent(PF_SSE3_INSTRUCTIONS_AVAILABLE) != 0)   ProcSupport |= PROCSUPPORT_SSE3;
-
-	}
-
-	RealProcSupport = ProcSupport;
-
-}
-
-
-#else // !( MPT_COMPILER_MSVC && ENABLE_X86 )
-
-
-void InitProcSupport()
-{
-	ProcSupport = 0;
-}
-
-
-#endif // MPT_COMPILER_MSVC && ENABLE_X86
-
-#endif // ENABLE_ASM
-
-
-#ifdef MODPLUG_TRACKER
-
-
-uint32 GetMinimumProcSupportFlags()
-{
-	uint32 flags = 0;
-	#ifdef ENABLE_ASM
-		#if MPT_COMPILER_MSVC
-			#if defined(_M_X64)
-				flags |= PROCSUPPORT_AMD64;
-			#elif defined(_M_IX86)
-				#if defined(_M_IX86_FP)
-					#if (_M_IX86_FP >= 2)
-						flags |= PROCSUPPORT_x86_SSE2;
-					#elif (_M_IX86_FP == 1)
-						flags |= PROCSUPPORT_x86_SSE;
-					#endif
-				#else
-					flags |= PROCSUPPORT_i586;
-				#endif
-			#endif
-		#endif	
-	#endif // ENABLE_ASM
-	return flags;
-}
-
-
-
-int GetMinimumSSEVersion()
-{
-	int minimumSSEVersion = 0;
-	#if MPT_COMPILER_MSVC
-		#if defined(_M_X64)
-			minimumSSEVersion = 2;
-		#elif defined(_M_IX86)
-			#if defined(_M_IX86_FP)
-				#if (_M_IX86_FP >= 2)
-					minimumSSEVersion = 2;
-				#elif (_M_IX86_FP == 1)
-					minimumSSEVersion = 1;
-				#endif
-			#endif
-		#endif
-	#endif
-	return minimumSSEVersion;
-}
-
-
-int GetMinimumAVXVersion()
-{
-	int minimumAVXVersion = 0;
-	#if MPT_COMPILER_MSVC
-		#if defined(_M_IX86_FP)
-			#if defined(__AVX2__)
-				minimumAVXVersion = 2;
-			#elif defined(__AVX__)
-				minimumAVXVersion = 1;
-			#endif
-		#endif
-	#endif
-	return minimumAVXVersion;
-}
-
-
-#endif
-
-
-#if !defined(MODPLUG_TRACKER) && !defined(ENABLE_ASM)
-
-MPT_MSVC_WORKAROUND_LNK4221(mptCPU)
-
-#endif
-
-
-OPENMPT_NAMESPACE_END

+ 0 - 76
libopenmpt.mod/openmpt/common/mptCPU.h

@@ -1,76 +0,0 @@
-/*
- * mptCPU.h
- * --------
- * Purpose: CPU feature detection.
- * Notes  : (currently none)
- * Authors: OpenMPT Devs
- * The OpenMPT source code is released under the BSD license. Read LICENSE for more details.
- */
-
-
-#pragma once
-
-#include "BuildSettings.h"
-
-
-OPENMPT_NAMESPACE_BEGIN
-
-
-#ifdef MODPLUG_TRACKER
-
-#define PROCSUPPORT_ASM_INTRIN   0x00001 // assembly and intrinsics are enabled at runtime
-#define PROCSUPPORT_CPUID        0x00002 // Processor supports modern cpuid
-#define PROCSUPPORT_LM           0x00004 // Processor supports long mode (amd64)
-#define PROCSUPPORT_MMX          0x00010 // Processor supports MMX instructions
-#define PROCSUPPORT_SSE          0x00100 // Processor supports SSE instructions
-#define PROCSUPPORT_SSE2         0x00200 // Processor supports SSE2 instructions
-#define PROCSUPPORT_SSE3         0x00400 // Processor supports SSE3 instructions
-#define PROCSUPPORT_SSSE3        0x00800 // Processor supports SSSE3 instructions
-#define PROCSUPPORT_SSE4_1       0x01000 // Processor supports SSE4.1 instructions
-#define PROCSUPPORT_SSE4_2       0x02000 // Processor supports SSE4.2 instructions
-#define PROCSUPPORT_AVX          0x10000 // Processor supports AVX instructions
-#define PROCSUPPORT_AVX2         0x20000 // Processor supports AVX2 instructions
-
-static const uint32 PROCSUPPORT_i586     = 0u                                                      ;
-static const uint32 PROCSUPPORT_x86_SSE  = 0u | PROCSUPPORT_SSE                                    ;
-static const uint32 PROCSUPPORT_x86_SSE2 = 0u | PROCSUPPORT_SSE | PROCSUPPORT_SSE2                 ;
-static const uint32 PROCSUPPORT_AMD64    = 0u | PROCSUPPORT_SSE | PROCSUPPORT_SSE2 | PROCSUPPORT_LM;
-
-#endif
-
-
-#ifdef ENABLE_ASM
-
-extern uint32 RealProcSupport;
-extern uint32 ProcSupport;
-extern char ProcVendorID[16+1];
-extern char ProcBrandID[4*4*3+1];
-extern uint16 ProcFamily;
-extern uint8 ProcModel;
-extern uint8 ProcStepping;
-
-void InitProcSupport();
-
-// enabled processor features for inline asm and intrinsics
-static inline uint32 GetProcSupport()
-{
-	return ProcSupport;
-}
-
-// available processor features
-static inline uint32 GetRealProcSupport()
-{
-	return RealProcSupport;
-}
-
-#endif // ENABLE_ASM
-
-
-#ifdef MODPLUG_TRACKER
-uint32 GetMinimumProcSupportFlags();
-int GetMinimumSSEVersion();
-int GetMinimumAVXVersion();
-#endif
-
-
-OPENMPT_NAMESPACE_END

+ 0 - 259
libopenmpt.mod/openmpt/common/mptCRC.h

@@ -1,259 +0,0 @@
-/*
- * mptCRC.h
- * --------
- * Purpose: generic CRC implementation
- * Notes  : (currently none)
- * Authors: Joern Heusipp
- * The OpenMPT source code is released under the BSD license. Read LICENSE for more details.
- */
-
-#pragma once
-
-#include "BuildSettings.h"
-
-OPENMPT_NAMESPACE_BEGIN
-
-namespace mpt
-{
-
-namespace checksum
-{
-
-template <typename T, T polynomial, T initial, T resultXOR, bool reverseData>
-class crc
-{
-
-public:
-	
-	typedef crc self_type;
-	typedef T value_type;
-	typedef uint8 byte_type;
-
-	enum : std::size_t { size_bytes = sizeof(value_type) };
-	enum : std::size_t { size_bits = sizeof(value_type) * 8 };
-	enum : value_type { top_bit = static_cast<value_type>(1) << ((sizeof(value_type) * 8) - 1) };
-
-private:
-	
-	template <typename Tint>
-	static inline Tint reverse(Tint value)
-	{
-		const std::size_t bits = sizeof(Tint) * 8;
-		Tint result = 0;
-		for(std::size_t i = 0; i < bits; ++i)
-		{
-			result <<= 1;
-			result |= static_cast<Tint>(value & 0x1);
-			value >>= 1;
-		}
-		return result;
-	}
-
-	static inline value_type calculate_table_entry(byte_type pos)
-	{
-		value_type value = 0;
-		value = (static_cast<value_type>(reverseData ? reverse(pos) : pos) << (size_bits - 8));
-		for(std::size_t bit = 0; bit < 8; ++bit)
-		{
-			if(value & top_bit)
-			{
-				value = (value << 1) ^ polynomial;
-			} else
-			{
-				value = (value << 1);
-			}
-		}
-		value = (reverseData ? reverse(value) : value);
-		return value;
-	}
-
-private:
-
-	static value_type table[256];
-	
-	static inline void fill_table()
-	{
-		for(std::size_t i = 0; i < 256; ++i)
-		{
-			table[i] = calculate_table_entry(static_cast<byte_type>(i));
-		}
-	}
-	
-	struct table_filler
-	{
-		inline table_filler()
-		{
-			self_type::fill_table();
-		}
-	};
-
-	static inline void init()
-	{
-		static table_filler table_filler;
-	}
-
-private:
-
-	inline value_type read_table(byte_type pos) const
-	{
-		return table[pos];
-	}
-
-private:
-
-	value_type value;
-
-public:
-
-	crc()
-		: value(initial)
-	{
-		init();
-	}
-
-	inline void processByte(byte_type byte)
-	{
-		if constexpr(reverseData)
-		{
-			value = (value >> 8) ^ read_table(static_cast<byte_type>((value & 0xff) ^ byte));
-		} else
-		{
-			value = (value << 8) ^ read_table(static_cast<byte_type>(((value >> (size_bits - 8)) & 0xff) ^ byte));
-		}
-	}
-
-	inline value_type result() const
-	{
-		return (value ^ resultXOR);
-	}
-
-public:
-
-	inline operator value_type () const
-	{
-		return result();
-	}
-
-	inline crc & process(char c)
-	{
-		processByte(mpt::byte_cast<byte_type>(c));
-		return *this;
-	}
-
-	inline crc & process(signed char c)
-	{
-		processByte(static_cast<byte_type>(c));
-		return *this;
-	}
-
-	inline crc & process(unsigned char c)
-	{
-		processByte(mpt::byte_cast<byte_type>(c));
-		return *this;
-	}
-
-	inline crc & process(std::byte c)
-	{
-		processByte(mpt::byte_cast<byte_type>(c));
-		return *this;
-	}
-
-	template <typename InputIt>
-	crc & process(InputIt beg, InputIt end)
-	{
-		for(InputIt it = beg; it != end; ++it)
-		{
-			static_assert(sizeof(*it) == 1, "1 byte type required");
-			process(*it);
-		}
-		return *this;
-	}
-
-	template <typename Container>
-	inline crc & process(const Container &data)
-	{
-		operator () (data.begin(), data.end());
-		return *this;
-	}
-
-	inline crc & operator () (char c)
-	{
-		processByte(mpt::byte_cast<byte_type>(c));
-		return *this;
-	}
-
-	inline crc & operator () (signed char c)
-	{
-		processByte(static_cast<byte_type>(c));
-		return *this;
-	}
-
-	inline crc & operator () (unsigned char c)
-	{
-		processByte(mpt::byte_cast<byte_type>(c));
-		return *this;
-	}
-
-	inline crc & operator () (std::byte c)
-	{
-		processByte(mpt::byte_cast<byte_type>(c));
-		return *this;
-	}
-
-	template <typename InputIt>
-	crc & operator () (InputIt beg, InputIt end)
-	{
-		for(InputIt it = beg; it != end; ++it)
-		{
-			static_assert(sizeof(*it) == 1, "1 byte type required");
-			operator () (*it);
-		}
-		return *this;
-	}
-
-	template <typename Container>
-	inline crc & operator () (const Container &data)
-	{
-		operator () (data.begin(), data.end());
-		return *this;
-	}
-
-	template <typename InputIt>
-	crc(InputIt beg, InputIt end)
-		: value(initial)
-	{
-		init();
-		for(InputIt it = beg; it != end; ++it)
-		{
-			static_assert(sizeof(*it) == 1, "1 byte type required");
-			process(*it);
-		}
-	}
-
-	template <typename Container>
-	inline crc(const Container &data)
-		: value(initial)
-	{
-		init();
-		process(data.begin(), data.end());
-	}
-
-};
-
-template <typename T, T polynomial, T initial, T resultXOR, bool reverseData>
-typename crc<T, polynomial, initial, resultXOR, reverseData>::value_type crc<T, polynomial, initial, resultXOR, reverseData>::table[256];
-
-typedef crc<uint16, 0x8005, 0, 0, true> crc16;
-typedef crc<uint32, 0x04C11DB7, 0xFFFFFFFF, 0xFFFFFFFF, true> crc32;
-typedef crc<uint32, 0x04C11DB7, 0, 0, false> crc32_ogg;
-typedef crc<uint32, 0x1EDC6F41, 0xFFFFFFFF, 0xFFFFFFFF, true> crc32c;
-typedef crc<uint64, 0xAD93D23594C935A9ull, 0xFFFFFFFFFFFFFFFFull, 0, true> crc64_jones;
-
-} // namespace checksum
-
-using mpt::checksum::crc32;
-using mpt::checksum::crc32_ogg;
-
-} // namespace mpt
-
-OPENMPT_NAMESPACE_END

+ 0 - 56
libopenmpt.mod/openmpt/common/mptException.h

@@ -1,56 +0,0 @@
-/*
- * mptException.h
- * --------------
- * Purpose: Exception abstraction, in particular for bad_alloc.
- * Notes  : (currently none)
- * Authors: OpenMPT Devs
- * The OpenMPT source code is released under the BSD license. Read LICENSE for more details.
- */
-
-
-#pragma once
-
-#include "BuildSettings.h"
-
-
-
-#include "mptBaseMacros.h"
-
-#include <exception>
-#if !defined(_MFC_VER)
-#include <new>
-#endif // !_MFC_VER
-
-#if defined(_MFC_VER)
-// cppcheck-suppress missingInclude
-#include <afx.h>
-#endif // _MFC_VER
-
-
-
-OPENMPT_NAMESPACE_BEGIN
-
-
-
-// Exception handling helpers, because MFC requires explicit deletion of the exception object,
-// Thus, always call exactly one of MPT_EXCEPTION_RETHROW_OUT_OF_MEMORY() or MPT_EXCEPTION_DELETE_OUT_OF_MEMORY(e).
-
-#if defined(_MFC_VER)
-
-#define MPT_EXCEPTION_THROW_OUT_OF_MEMORY()    MPT_DO { AfxThrowMemoryException(); } MPT_WHILE_0
-#define MPT_EXCEPTION_CATCH_OUT_OF_MEMORY(e)   catch ( CMemoryException * e )
-#define MPT_EXCEPTION_RETHROW_OUT_OF_MEMORY(e) MPT_DO { MPT_UNUSED_VARIABLE(e); throw; } MPT_WHILE_0
-#define MPT_EXCEPTION_DELETE_OUT_OF_MEMORY(e)  MPT_DO { if(e) { e->Delete(); e = nullptr; } } MPT_WHILE_0
-
-#else // !_MFC_VER
-
-#define MPT_EXCEPTION_THROW_OUT_OF_MEMORY()    MPT_DO { throw std::bad_alloc(); } MPT_WHILE_0
-#define MPT_EXCEPTION_CATCH_OUT_OF_MEMORY(e)   catch ( const std::bad_alloc & e )
-#define MPT_EXCEPTION_RETHROW_OUT_OF_MEMORY(e) MPT_DO { MPT_UNUSED_VARIABLE(e); throw; } MPT_WHILE_0
-#define MPT_EXCEPTION_DELETE_OUT_OF_MEMORY(e)  MPT_DO { MPT_UNUSED_VARIABLE(e); } MPT_WHILE_0
-
-#endif // _MFC_VER
-
-
-
-OPENMPT_NAMESPACE_END

+ 0 - 76
libopenmpt.mod/openmpt/common/mptExceptionText.h

@@ -1,76 +0,0 @@
-/*
- * mptExceptionText.h
- * ------------------
- * Purpose: Guess encoding of exception string
- * Notes  : (currently none)
- * Authors: OpenMPT Devs
- * The OpenMPT source code is released under the BSD license. Read LICENSE for more details.
- */
-
-
-#pragma once
-
-#include "BuildSettings.h"
-
-
-
-#include "mptException.h"
-#include "mptString.h"
-
-#include <exception>
-
-
-
-OPENMPT_NAMESPACE_BEGIN
-
-
-
-namespace mpt
-{
-
-template <typename T> T get_exception_text_impl(const std::exception & e)
-{
-	if(e.what() && (std::strlen(e.what()) > 0))
-	{
-		return T(e.what());
-	} else if(typeid(e).name() && (std::strlen(typeid(e).name()) > 0))
-	{
-		return T(typeid(e).name());
-	} else
-	{
-		return T("unknown exception");
-	}
-}
-
-template <typename T> inline T get_exception_text(const std::exception & e)
-{
-	return mpt::get_exception_text_impl<T>(e);
-}
-template <> inline std::string get_exception_text<std::string>(const std::exception & e)
-{
-	return mpt::get_exception_text_impl<std::string>(e);
-}
-#if defined(MPT_ENABLE_CHARSET_LOCALE)
-template <> inline mpt::lstring get_exception_text<mpt::lstring>(const std::exception & e)
-{
-	return mpt::ToLocale(mpt::CharsetException, mpt::get_exception_text_impl<std::string>(e));
-}
-#endif
-#if MPT_WSTRING_FORMAT
-template <> inline std::wstring get_exception_text<std::wstring>(const std::exception & e)
-{
-	return mpt::ToWide(mpt::CharsetException, mpt::get_exception_text_impl<std::string>(e));
-}
-#endif
-#if MPT_USTRING_MODE_UTF8
-template <> inline mpt::ustring get_exception_text<mpt::ustring>(const std::exception & e)
-{
-	return mpt::ToUnicode(mpt::CharsetException, mpt::get_exception_text_impl<std::string>(e));
-}
-#endif
-
-} // namespace mpt
-
-
-
-OPENMPT_NAMESPACE_END

+ 0 - 433
libopenmpt.mod/openmpt/common/mptFileIO.cpp

@@ -1,433 +0,0 @@
-/*
- * mptFileIO.cpp
- * -------------
- * Purpose: File I/O wrappers
- * Notes  : (currently none)
- * Authors: OpenMPT Devs
- * The OpenMPT source code is released under the BSD license. Read LICENSE for more details.
- */
-
-
-#include "stdafx.h"
-#include "mptFileIO.h"
-
-#ifdef MODPLUG_TRACKER
-#if MPT_OS_WINDOWS
-#include <WinIoCtl.h>
-#include <io.h>
-#endif // MPT_OS_WINDOWS
-#endif // MODPLUG_TRACKER
-
-#if defined(MPT_ENABLE_FILEIO)
-#if MPT_COMPILER_MSVC
-#include <tchar.h>
-#endif // MPT_COMPILER_MSVC
-#endif // MPT_ENABLE_FILEIO
-
-
-OPENMPT_NAMESPACE_BEGIN
-
-
-#if defined(MPT_ENABLE_FILEIO)
-
-
-
-#ifdef MODPLUG_TRACKER
-#if MPT_OS_WINDOWS
-bool SetFilesystemCompression(HANDLE hFile)
-{
-	if(hFile == INVALID_HANDLE_VALUE)
-	{
-		return false;
-	}
-	USHORT format = COMPRESSION_FORMAT_DEFAULT;
-	DWORD dummy = 0;
-	BOOL result = DeviceIoControl(hFile, FSCTL_SET_COMPRESSION, (LPVOID)&format, sizeof(format), NULL, 0, &dummy /*required*/ , NULL);
-	return result != FALSE;
-}
-bool SetFilesystemCompression(int fd)
-{
-	if(fd < 0)
-	{
-		return false;
-	}
-	uintptr_t fhandle = _get_osfhandle(fd);
-	HANDLE hFile = (HANDLE)fhandle;
-	if(hFile == INVALID_HANDLE_VALUE)
-	{
-		return false;
-	}
-	return SetFilesystemCompression(hFile);
-}
-bool SetFilesystemCompression(const mpt::PathString &filename)
-{
-	DWORD attributes = GetFileAttributes(filename.AsNativePrefixed().c_str());
-	if(attributes == INVALID_FILE_ATTRIBUTES)
-	{
-		return false;
-	}
-	if(attributes & FILE_ATTRIBUTE_COMPRESSED)
-	{
-		return true;
-	}
-	HANDLE hFile = CreateFile(filename.AsNativePrefixed().c_str(), GENERIC_ALL, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL);
-	if(hFile == INVALID_HANDLE_VALUE)
-	{
-		return false;
-	}
-	bool result = SetFilesystemCompression(hFile);
-	CloseHandle(hFile);
-	return result;
-}
-#endif // MPT_OS_WINDOWS
-#endif // MODPLUG_TRACKER
-
-
-
-#ifdef MODPLUG_TRACKER
-
-namespace mpt {
-
-#if MPT_COMPILER_MSVC
-
-mpt::tstring SafeOutputFile::convert_mode(std::ios_base::openmode mode, FlushMode flushMode)
-{
-	mpt::tstring fopen_mode;
-	switch(mode & ~(std::ios_base::ate | std::ios_base::binary))
-	{
-	case std::ios_base::in:
-		fopen_mode = _T("r");
-		break;
-	case std::ios_base::out:
-		[[fallthrough]];
-	case std::ios_base::out | std::ios_base::trunc:
-		fopen_mode = _T("w");
-		break;
-	case std::ios_base::app:
-		[[fallthrough]];
-	case std::ios_base::out | std::ios_base::app:
-		fopen_mode = _T("a");
-		break;
-	case std::ios_base::out | std::ios_base::in:
-		fopen_mode = _T("r+");
-		break;
-	case std::ios_base::out | std::ios_base::in | std::ios_base::trunc:
-		fopen_mode = _T("w+");
-		break;
-	case std::ios_base::out | std::ios_base::in | std::ios_base::app:
-		[[fallthrough]];
-	case std::ios_base::in | std::ios_base::app:
-		fopen_mode = _T("a+");
-		break;
-	}
-	if(fopen_mode.empty())
-	{
-		return fopen_mode;
-	}
-	if(mode & std::ios_base::binary)
-	{
-		fopen_mode += _T("b");
-	}
-	if(flushMode == FlushMode::Full)
-	{
-		fopen_mode += _T("c");  // force commit on fflush (MSVC specific)
-	}
-	return fopen_mode;
-}
-
-FILE * SafeOutputFile::internal_fopen(const mpt::PathString &filename, std::ios_base::openmode mode, FlushMode flushMode)
-{
-	mpt::tstring fopen_mode = convert_mode(mode, flushMode);
-	if(fopen_mode.empty())
-	{
-		return nullptr;
-	}
-	FILE *f =
-#ifdef UNICODE
-		_wfopen(filename.AsNativePrefixed().c_str(), fopen_mode.c_str())
-#else
-		fopen(filename.AsNativePrefixed().c_str(), fopen_mode.c_str())
-#endif
-		;
-	if(!f)
-	{
-		return nullptr;
-	}
-	if(mode & std::ios_base::ate)
-	{
-		if(fseek(f, 0, SEEK_END) != 0)
-		{
-			fclose(f);
-			f = nullptr;
-			return nullptr;
-		}
-	}
-	m_f = f;
-	return f;
-}
-
-#endif // MPT_COMPILER_MSVC
-
-// cppcheck-suppress exceptThrowInDestructor
-SafeOutputFile::~SafeOutputFile() noexcept(false)
-{
-	if(!stream())
-	{
-		return;
-	}
-	if(!stream().rdbuf())
-	{
-		return;
-	}
-#if MPT_COMPILER_MSVC
-	if(!m_f)
-	{
-		return;
-	}
-#endif // MPT_COMPILER_MSVC
-	bool errorOnFlush = false;
-	if(m_FlushMode != FlushMode::None)
-	{
-		try
-		{
-			if(stream().rdbuf()->pubsync() != 0)
-			{
-				errorOnFlush = true;
-			}
-		} catch(const std::exception &)
-		{
-			errorOnFlush = true;
-#if MPT_COMPILER_MSVC
-			if(m_FlushMode != FlushMode::None)
-			{
-				if(fflush(m_f) != 0)
-				{
-					errorOnFlush = true;
-				}
-			}
-			if(fclose(m_f) != 0)
-			{
-				errorOnFlush = true;
-			}
-#endif // MPT_COMPILER_MSVC
-			// ignore errorOnFlush here, and re-throw the earlier exception
-			// cppcheck-suppress exceptThrowInDestructor
-			throw;
-		}
-	}
-#if MPT_COMPILER_MSVC
-	if(m_FlushMode != FlushMode::None)
-	{
-		if(fflush(m_f) != 0)
-		{
-			errorOnFlush = true;
-		}
-	}
-	if(fclose(m_f) != 0)
-	{
-		errorOnFlush = true;
-	}
-#endif // MPT_COMPILER_MSVC
-	if(errorOnFlush && (stream().exceptions() & (std::ios::badbit | std::ios::failbit)))
-	{
-		// cppcheck-suppress exceptThrowInDestructor
-		throw std::ios_base::failure(std::string("Error flushing file buffers."));
-	}
-}
-
-} // namespace mpt
-
-#endif // MODPLUG_TRACKER
-
-
-
-#ifdef MODPLUG_TRACKER
-
-namespace mpt {
-
-LazyFileRef & LazyFileRef::operator = (const std::vector<std::byte> &data)
-{
-	mpt::ofstream file(m_Filename, std::ios::binary);
-	file.exceptions(std::ios_base::failbit | std::ios_base::badbit);
-	mpt::IO::WriteRaw(file, data.data(), data.size());
-	mpt::IO::Flush(file);
-	return *this;
-}
-
-LazyFileRef & LazyFileRef::operator = (const std::vector<char> &data)
-{
-	mpt::ofstream file(m_Filename, std::ios::binary);
-	file.exceptions(std::ios_base::failbit | std::ios_base::badbit);
-	mpt::IO::WriteRaw(file, data.data(), data.size());
-	mpt::IO::Flush(file);
-	return *this;
-}
-
-LazyFileRef & LazyFileRef::operator = (const std::string &data)
-{
-	mpt::ofstream file(m_Filename, std::ios::binary);
-	file.exceptions(std::ios_base::failbit | std::ios_base::badbit);
-	mpt::IO::WriteRaw(file, data.data(), data.size());
-	mpt::IO::Flush(file);
-	return *this;
-}
-
-LazyFileRef::operator std::vector<std::byte> () const
-{
-	mpt::ifstream file(m_Filename, std::ios::binary);
-	if(!mpt::IO::IsValid(file))
-	{
-		return std::vector<std::byte>();
-	}
-	file.exceptions(std::ios_base::failbit | std::ios_base::badbit);
-	mpt::IO::SeekEnd(file);
-	std::vector<std::byte> buf(mpt::saturate_cast<std::size_t>(mpt::IO::TellRead(file)));
-	mpt::IO::SeekBegin(file);
-	mpt::IO::ReadRaw(file, buf.data(), buf.size());
-	return buf;
-}
-
-LazyFileRef::operator std::vector<char> () const
-{
-	mpt::ifstream file(m_Filename, std::ios::binary);
-	if(!mpt::IO::IsValid(file))
-	{
-		return std::vector<char>();
-	}
-	file.exceptions(std::ios_base::failbit | std::ios_base::badbit);
-	mpt::IO::SeekEnd(file);
-	std::vector<char> buf(mpt::saturate_cast<std::size_t>(mpt::IO::TellRead(file)));
-	mpt::IO::SeekBegin(file);
-	mpt::IO::ReadRaw(file, buf.data(), buf.size());
-	return buf;
-}
-
-LazyFileRef::operator std::string () const
-{
-	mpt::ifstream file(m_Filename, std::ios::binary);
-	if(!mpt::IO::IsValid(file))
-	{
-		return std::string();
-	}
-	file.exceptions(std::ios_base::failbit | std::ios_base::badbit);
-	mpt::IO::SeekEnd(file);
-	std::vector<char> buf(mpt::saturate_cast<std::size_t>(mpt::IO::TellRead(file)));
-	mpt::IO::SeekBegin(file);
-	mpt::IO::ReadRaw(file, buf.data(), buf.size());
-	return std::string(buf.begin(), buf.end());
-}
-
-} // namespace mpt
-
-#endif // MODPLUG_TRACKER
-
-
-bool InputFile::DefaultToLargeAddressSpaceUsage()
-{
-	return false;
-}
-
-
-InputFile::InputFile()
-	: m_IsCached(false)
-{
-	return;
-}
-
-InputFile::InputFile(const mpt::PathString &filename, bool allowWholeFileCaching)
-	: m_IsCached(false)
-{
-	Open(filename, allowWholeFileCaching);
-}
-
-InputFile::~InputFile()
-{
-	return;
-}
-
-
-bool InputFile::Open(const mpt::PathString &filename, bool allowWholeFileCaching)
-{
-	m_IsCached = false;
-	m_Cache.resize(0);
-	m_Cache.shrink_to_fit();
-	m_Filename = filename;
-	m_File.open(m_Filename, std::ios::binary | std::ios::in);
-	if(allowWholeFileCaching)
-	{
-		if(mpt::IO::IsReadSeekable(m_File))
-		{
-			if(!mpt::IO::SeekEnd(m_File))
-			{
-				m_File.close();
-				return false;
-			}
-			mpt::IO::Offset filesize = mpt::IO::TellRead(m_File);
-			if(!mpt::IO::SeekBegin(m_File))
-			{
-				m_File.close();
-				return false;
-			}
-			if(Util::TypeCanHoldValue<std::size_t>(filesize))
-			{
-				std::size_t buffersize = mpt::saturate_cast<std::size_t>(filesize);
-				m_Cache.resize(buffersize);
-				if(mpt::IO::ReadRaw(m_File, mpt::as_span(m_Cache)) != filesize)
-				{
-					m_File.close();
-					return false;
-				}
-				if(!mpt::IO::SeekBegin(m_File))
-				{
-					m_File.close();
-					return false;
-				}
-				m_IsCached = true;
-				return true;
-			}
-		}
-	}
-	return m_File.good();
-}
-
-
-bool InputFile::IsValid() const
-{
-	return m_File.good();
-}
-
-
-bool InputFile::IsCached() const
-{
-	return m_IsCached;
-}
-
-
-const mpt::PathString& InputFile::GetFilenameRef() const
-{
-	return m_Filename;
-}
-
-
-std::istream* InputFile::GetStream()
-{
-	MPT_ASSERT(!m_IsCached);
-	return &m_File;
-}
-
-
-mpt::const_byte_span InputFile::GetCache()
-{
-	MPT_ASSERT(m_IsCached);
-	return mpt::as_span(m_Cache);
-}
-
-
-#else // !MPT_ENABLE_FILEIO
-
-MPT_MSVC_WORKAROUND_LNK4221(mptFileIO)
-
-#endif // MPT_ENABLE_FILEIO
-
-
-OPENMPT_NAMESPACE_END

+ 0 - 289
libopenmpt.mod/openmpt/common/mptFileIO.h

@@ -1,289 +0,0 @@
-/*
- * mptFileIO.h
- * -----------
- * Purpose: A wrapper around std::fstream, enforcing usage of mpt::PathString.
- * Notes  : You should only ever use these wrappers instead of plain std::fstream classes.
- * Authors: OpenMPT Devs
- * The OpenMPT source code is released under the BSD license. Read LICENSE for more details.
- */
-
-#pragma once
-
-#include "BuildSettings.h"
-
-#if defined(MPT_ENABLE_FILEIO)
-
-#include "../common/mptString.h"
-#include "../common/mptPathString.h"
-#include "../common/mptIO.h"
-
-#include <fstream>
-#include <ios>
-#include <ostream>
-#include <streambuf>
-#include <utility>
-
-#if MPT_COMPILER_MSVC
-#include <cstdio>
-#endif // !MPT_COMPILER_MSVC
-
-#if MPT_COMPILER_MSVC
-#include <stdio.h>
-#endif // !MPT_COMPILER_MSVC
-
-#endif // MPT_ENABLE_FILEIO
-
-
-OPENMPT_NAMESPACE_BEGIN
-
-
-#if defined(MPT_ENABLE_FILEIO)
-
-
-// Sets the NTFS compression attribute on the file or directory.
-// Requires read and write permissions for already opened files.
-// Returns true if the attribute has been set.
-// In almost all cases, the return value should be ignored because most filesystems other than NTFS do not support compression.
-#ifdef MODPLUG_TRACKER
-#if MPT_OS_WINDOWS
-bool SetFilesystemCompression(HANDLE hFile);
-bool SetFilesystemCompression(int fd);
-bool SetFilesystemCompression(const mpt::PathString &filename);
-#endif // MPT_OS_WINDOWS
-#endif // MODPLUG_TRACKER
-
-
-namespace mpt
-{
-
-#if MPT_COMPILER_GCC && MPT_OS_WINDOWS
-// GCC C++ library has no wchar_t overloads
-#define MPT_FSTREAM_DO_CONVERSIONS_ANSI
-#endif
-
-namespace detail
-{
-
-template<typename Tbase>
-inline void fstream_open(Tbase & base, const mpt::PathString & filename, std::ios_base::openmode mode)
-{
-#if defined(MPT_FSTREAM_DO_CONVERSIONS_ANSI)
-	base.open(mpt::ToCharset(mpt::Charset::Locale, filename.AsNative()).c_str(), mode);
-#else
-	base.open(filename.AsNativePrefixed().c_str(), mode);
-#endif
-}
-
-} // namespace detail
-
-class SafeOutputFile;
-
-class fstream
-	: public std::fstream
-{
-private:
-	typedef std::fstream Tbase;
-public:
-	friend SafeOutputFile;
-public:
-	fstream() {}
-	fstream(const mpt::PathString & filename, std::ios_base::openmode mode = std::ios_base::in | std::ios_base::out)
-	{
-		detail::fstream_open<Tbase>(*this, filename, mode);
-	}
-	void open(const mpt::PathString & filename, std::ios_base::openmode mode = std::ios_base::in | std::ios_base::out)
-	{
-		detail::fstream_open<Tbase>(*this, filename, mode);
-	}
-	void open(const char * filename, std::ios_base::openmode mode = std::ios_base::in | std::ios_base::out) = delete;
-	void open(const std::string & filename, std::ios_base::openmode mode = std::ios_base::in | std::ios_base::out) = delete;
-#if MPT_OS_WINDOWS
-	void open(const wchar_t * filename, std::ios_base::openmode mode = std::ios_base::in | std::ios_base::out) = delete;
-	void open(const std::wstring & filename, std::ios_base::openmode mode = std::ios_base::in | std::ios_base::out) = delete;
-#endif
-};
-
-class ifstream
-	: public std::ifstream
-{
-private:
-	typedef std::ifstream Tbase;
-public:
-	friend SafeOutputFile;
-public:
-	ifstream() {}
-	ifstream(const mpt::PathString & filename, std::ios_base::openmode mode = std::ios_base::in)
-	{
-		detail::fstream_open<Tbase>(*this, filename, mode);
-	}
-	void open(const mpt::PathString & filename, std::ios_base::openmode mode = std::ios_base::in)
-	{
-		detail::fstream_open<Tbase>(*this, filename, mode);
-	}
-	void open(const char * filename, std::ios_base::openmode mode = std::ios_base::in) = delete;
-	void open(const std::string & filename, std::ios_base::openmode mode = std::ios_base::in) = delete;
-#if MPT_OS_WINDOWS
-	void open(const wchar_t * filename, std::ios_base::openmode mode = std::ios_base::in) = delete;
-	void open(const std::wstring & filename, std::ios_base::openmode mode = std::ios_base::in) = delete;
-#endif
-};
-
-class ofstream
-	: public std::ofstream
-{
-private:
-	typedef std::ofstream Tbase;
-public:
-	friend SafeOutputFile;
-public:
-	ofstream() {}
-	ofstream(const mpt::PathString & filename, std::ios_base::openmode mode = std::ios_base::out)
-	{
-		detail::fstream_open<Tbase>(*this, filename, mode);
-	}
-#if MPT_COMPILER_MSVC
-protected:
-	ofstream(FILE * file)
-		: std::ofstream(file)
-	{
-	}
-
-#endif // MPT_COMPILER_MSVC
-public:
-	void open(const mpt::PathString & filename, std::ios_base::openmode mode = std::ios_base::out)
-	{
-		detail::fstream_open<Tbase>(*this, filename, mode);
-	}
-	void open(const char * filename, std::ios_base::openmode mode = std::ios_base::out) = delete;
-	void open(const std::string & filename, std::ios_base::openmode mode = std::ios_base::out) = delete;
-#if MPT_OS_WINDOWS
-	void open(const wchar_t * filename, std::ios_base::openmode mode = std::ios_base::out) = delete;
-	void open(const std::wstring & filename, std::ios_base::openmode mode = std::ios_base::out) = delete;
-#endif
-};
-
-enum class FlushMode
-{
-	None   = 0,  // no explicit flushes at all
-	Single = 1,  // explicitly flush higher-leverl API layers
-	Full   = 2,  // explicitly flush *all* layers, up to and including disk write caches
-};
-
-static inline FlushMode FlushModeFromBool(bool flush)
-{
-	return flush ? FlushMode::Full : FlushMode::None;
-}
-
-#ifdef MODPLUG_TRACKER
-
-class SafeOutputFile
-{
-private:
-	FlushMode m_FlushMode;
-#if MPT_COMPILER_MSVC
-	FILE *m_f;
-#endif // MPT_COMPILER_MSVC
-	mpt::ofstream m_s;
-#if MPT_COMPILER_MSVC
-	static mpt::tstring convert_mode(std::ios_base::openmode mode, FlushMode flushMode);
-	FILE * internal_fopen(const mpt::PathString &filename, std::ios_base::openmode mode, FlushMode flushMode);
-#endif // MPT_COMPILER_MSVC
-public:
-	SafeOutputFile() = delete;
-	explicit SafeOutputFile(const mpt::PathString &filename, std::ios_base::openmode mode = std::ios_base::out, FlushMode flushMode = FlushMode::Full)
-		: m_FlushMode(flushMode)
-#if MPT_COMPILER_MSVC
-		, m_s(internal_fopen(filename, mode | std::ios_base::out, flushMode))
-#else // !MPT_COMPILER_MSVC
-		, m_s(filename, mode)
-#endif // MPT_COMPILER_MSVC
-	{
-	}
-	mpt::ofstream& stream()
-	{
-		return m_s;
-	}
-	operator mpt::ofstream& ()
-	{
-		return stream();
-	}
-	const mpt::ofstream& stream() const
-	{
-		return m_s;
-	}
-	operator const mpt::ofstream& () const
-	{
-		return stream();
-	}
-	operator bool() const
-	{
-		return stream() ? true : false;
-	}
-	bool operator!() const
-	{
-		return stream().operator!();
-	}
-	~SafeOutputFile() noexcept(false);
-};
-
-#endif // MODPLUG_TRACKER
-
-
-
-#ifdef MODPLUG_TRACKER
-
-// LazyFileRef is a simple reference to an on-disk file by the means of a
-// filename which allows easy assignment of the whole file contents to and from
-// byte buffers.
-class LazyFileRef {
-private:
-	const mpt::PathString m_Filename;
-public:
-	LazyFileRef(const mpt::PathString &filename)
-		: m_Filename(filename)
-	{
-		return;
-	}
-public:
-	LazyFileRef & operator = (const std::vector<std::byte> &data);
-	LazyFileRef & operator = (const std::vector<char> &data);
-	LazyFileRef & operator = (const std::string &data);
-	operator std::vector<std::byte> () const;
-	operator std::vector<char> () const;
-	operator std::string () const;
-};
-
-#endif // MODPLUG_TRACKER
-
-
-} // namespace mpt
-
-
-class InputFile
-{
-private:
-	mpt::PathString m_Filename;
-	mpt::ifstream m_File;
-	bool m_IsCached;
-	std::vector<std::byte> m_Cache;
-public:
-	static bool DefaultToLargeAddressSpaceUsage();
-public:
-	InputFile();
-	InputFile(const mpt::PathString &filename, bool allowWholeFileCaching = DefaultToLargeAddressSpaceUsage());
-	~InputFile();
-	bool Open(const mpt::PathString &filename, bool allowWholeFileCaching = DefaultToLargeAddressSpaceUsage());
-	bool IsValid() const;
-	bool IsCached() const;
-	const mpt::PathString& GetFilenameRef() const;
-	std::istream* GetStream();
-	mpt::const_byte_span GetCache();
-};
-
-
-#endif // MPT_ENABLE_FILEIO
-
-
-
-OPENMPT_NAMESPACE_END
-

+ 0 - 671
libopenmpt.mod/openmpt/common/mptIO.cpp

@@ -1,671 +0,0 @@
-/*
- * mptIO.cpp
- * ---------
- * Purpose: Basic functions for reading/writing binary and endian safe data to/from files/streams.
- * Notes  : Some useful functions for reading and writing are still missing.
- * Authors: Joern Heusipp
- *          OpenMPT Devs
- * The OpenMPT source code is released under the BSD license. Read LICENSE for more details.
- */
-
-
-#include "stdafx.h"
-
-#include "mptIO.h"
-
-#include <ios>
-#include <istream>
-#include <ostream>
-#include <sstream>
-
-
-OPENMPT_NAMESPACE_BEGIN
-
-
-namespace mpt {
-
-namespace IO {
-
-
-//static_assert(sizeof(std::streamoff) == 8); // Assert 64bit file support.
-bool IsValid(std::ostream & f) { return !f.fail(); }
-bool IsValid(std::istream & f) { return !f.fail(); }
-bool IsValid(std::iostream & f) { return !f.fail(); }
-bool IsReadSeekable(std::istream & f)
-{
-	f.clear();
-	std::streampos oldpos = f.tellg();
-	if(f.fail() || oldpos == std::streampos(-1))
-	{
-		f.clear();
-		return false;
-	}
-	f.seekg(0, std::ios::beg);
-	if(f.fail())
-	{
-		f.clear();
-		f.seekg(oldpos);
-		f.clear();
-		return false;
-	}
-	f.seekg(0, std::ios::end);
-	if(f.fail())
-	{
-		f.clear();
-		f.seekg(oldpos);
-		f.clear();
-		return false;
-	}
-	std::streampos length = f.tellg();
-	if(f.fail() || length == std::streampos(-1))
-	{
-		f.clear();
-		f.seekg(oldpos);
-		f.clear();
-		return false;
-	}
-	f.seekg(oldpos);
-	f.clear();
-	return true;
-}
-bool IsWriteSeekable(std::ostream & f)
-{
-	f.clear();
-	std::streampos oldpos = f.tellp();
-	if(f.fail() || oldpos == std::streampos(-1))
-	{
-		f.clear();
-		return false;
-	}
-	f.seekp(0, std::ios::beg);
-	if(f.fail())
-	{
-		f.clear();
-		f.seekp(oldpos);
-		f.clear();
-		return false;
-	}
-	f.seekp(0, std::ios::end);
-	if(f.fail())
-	{
-		f.clear();
-		f.seekp(oldpos);
-		f.clear();
-		return false;
-	}
-	std::streampos length = f.tellp();
-	if(f.fail() || length == std::streampos(-1))
-	{
-		f.clear();
-		f.seekp(oldpos);
-		f.clear();
-		return false;
-	}
-	f.seekp(oldpos);
-	f.clear();
-	return true;
-}
-IO::Offset TellRead(std::istream & f)
-{
-	return f.tellg();
-}
-IO::Offset TellWrite(std::ostream & f)
-{
-	return f.tellp();
-}
-bool SeekBegin(std::ostream & f)
-{
-	f.seekp(0); return !f.fail();
-}
-bool SeekBegin(std::istream & f)
-{
-	f.seekg(0); return !f.fail();
-}
-bool SeekBegin(std::iostream & f)
-{
-	f.seekg(0); f.seekp(0); return !f.fail();
-}
-bool SeekEnd(std::ostream & f)
-{
-	f.seekp(0, std::ios::end); return !f.fail();
-}
-bool SeekEnd(std::istream & f)
-{
-	f.seekg(0, std::ios::end); return !f.fail();
-}
-bool SeekEnd(std::iostream & f)
-{
-	f.seekg(0, std::ios::end); f.seekp(0, std::ios::end); return !f.fail();
-}
-bool SeekAbsolute(std::ostream & f, IO::Offset pos)
-{
-	if(!OffsetFits<std::streamoff>(pos)) { return false; }
-	f.seekp(static_cast<std::streamoff>(pos), std::ios::beg); return !f.fail();
-}
-bool SeekAbsolute(std::istream & f, IO::Offset pos)
-{
-	if(!OffsetFits<std::streamoff>(pos)) { return false; }
-	f.seekg(static_cast<std::streamoff>(pos), std::ios::beg); return !f.fail();
-}
-bool SeekAbsolute(std::iostream & f, IO::Offset pos)
-{
-	if(!OffsetFits<std::streamoff>(pos)) { return false; }
-	f.seekg(static_cast<std::streamoff>(pos), std::ios::beg); f.seekp(static_cast<std::streamoff>(pos), std::ios::beg); return !f.fail();
-}
-bool SeekRelative(std::ostream & f, IO::Offset off)
-{
-	if(!OffsetFits<std::streamoff>(off)) { return false; }
-	f.seekp(static_cast<std::streamoff>(off), std::ios::cur); return !f.fail();
-}
-bool SeekRelative(std::istream & f, IO::Offset off)
-{
-	if(!OffsetFits<std::streamoff>(off)) { return false; }
-	f.seekg(static_cast<std::streamoff>(off), std::ios::cur); return !f.fail();
-}
-bool SeekRelative(std::iostream & f, IO::Offset off)
-{
-	if(!OffsetFits<std::streamoff>(off)) { return false; }
-	f.seekg(static_cast<std::streamoff>(off), std::ios::cur); f.seekp(static_cast<std::streamoff>(off), std::ios::cur); return !f.fail();
-}
-IO::Offset ReadRawImpl(std::istream & f, std::byte * data, std::size_t size) { return f.read(mpt::byte_cast<char *>(data), size) ? f.gcount() : std::streamsize(0); }
-bool WriteRawImpl(std::ostream & f, const std::byte * data, std::size_t size) { f.write(mpt::byte_cast<const char *>(data), size); return !f.fail(); }
-bool IsEof(std::istream & f) { return f.eof(); }
-bool Flush(std::ostream & f) { f.flush(); return !f.fail(); }
-
-
-
-} // namespace IO
-
-} // namespace mpt
-
-
-
-FileDataContainerSeekable::FileDataContainerSeekable(off_t streamLength, bool buffered)
-	: streamLength(streamLength)
-	, cached(false)
-	, m_Buffered(buffered)
-	, m_Buffer(m_Buffered ? static_cast<off_t>(BUFFER_SIZE) : 0)
-{
-	if(m_Buffered)
-	{
-		for(std::size_t chunkIndex = 0; chunkIndex < NUM_CHUNKS; ++chunkIndex)
-		{
-			m_ChunkIndexLRU[chunkIndex] = chunkIndex;
-		}
-	}
-}
-
-void FileDataContainerSeekable::CacheStream() const
-{
-	if(cached)
-	{
-		return;
-	}
-	if(m_Buffered)
-	{
-		m_Buffered = false;
-		for (std::size_t chunkIndex = 0; chunkIndex < NUM_CHUNKS; ++chunkIndex)
-		{
-			m_ChunkInfo[chunkIndex].ChunkValid = false;
-		}
-		m_Buffer.resize(0);
-		m_Buffer.shrink_to_fit();
-	}
-	cache.resize(streamLength);
-	InternalRead(cache.data(), 0, streamLength);
-	cached = true;
-}
-
-std::size_t FileDataContainerSeekable::InternalFillPageAndReturnIndex(off_t pos) const
-{
-	pos = Util::AlignDown(pos, static_cast<off_t>(CHUNK_SIZE));
-	for(std::size_t chunkLRUIndex = 0; chunkLRUIndex < NUM_CHUNKS; ++chunkLRUIndex)
-	{
-		std::size_t chunkIndex = m_ChunkIndexLRU[chunkLRUIndex];
-		if(m_ChunkInfo[chunkIndex].ChunkValid && (m_ChunkInfo[chunkIndex].ChunkOffset == pos))
-		{
-			std::size_t chunk = std::move(m_ChunkIndexLRU[chunkLRUIndex]);
-			std::move_backward(m_ChunkIndexLRU.begin(), m_ChunkIndexLRU.begin() + chunkLRUIndex, m_ChunkIndexLRU.begin() + (chunkLRUIndex + 1));
-			m_ChunkIndexLRU[0] = std::move(chunk);
-			return chunkIndex;
-		}
-	}
-	{
-		std::size_t chunk = std::move(m_ChunkIndexLRU[NUM_CHUNKS - 1]);
-		std::move_backward(m_ChunkIndexLRU.begin(), m_ChunkIndexLRU.begin() + (NUM_CHUNKS - 1), m_ChunkIndexLRU.begin() + NUM_CHUNKS);
-		m_ChunkIndexLRU[0] = std::move(chunk);
-	}
-	std::size_t chunkIndex = m_ChunkIndexLRU[0];
-	chunk_info& chunk = m_ChunkInfo[chunkIndex];
-	chunk.ChunkOffset = pos;
-	chunk.ChunkLength = InternalRead(chunk_data(chunkIndex).data(), pos, CHUNK_SIZE);
-	chunk.ChunkValid = true;
-	return chunkIndex;
-}
-
-bool FileDataContainerSeekable::IsValid() const
-{
-	return true;
-}
-
-bool FileDataContainerSeekable::HasFastGetLength() const
-{
-	return true;
-}
-
-bool FileDataContainerSeekable::HasPinnedView() const
-{
-	return cached;
-}
-
-const std::byte *FileDataContainerSeekable::GetRawData() const
-{
-	CacheStream();
-	return cache.data();
-}
-
-IFileDataContainer::off_t FileDataContainerSeekable::GetLength() const
-{
-	return streamLength;
-}
-
-IFileDataContainer::off_t FileDataContainerSeekable::Read(std::byte *dst, IFileDataContainer::off_t pos, IFileDataContainer::off_t count) const
-{
-	if(cached)
-	{
-		IFileDataContainer::off_t cache_avail = std::min(IFileDataContainer::off_t(cache.size()) - pos, count);
-		std::copy(cache.begin() + pos, cache.begin() + pos + cache_avail, dst);
-		return cache_avail;
-	} else
-	{
-		return InternalReadBuffered(dst, pos, count);
-	}
-}
-
-IFileDataContainer::off_t FileDataContainerSeekable::InternalReadBuffered(std::byte* dst, off_t pos, off_t count) const
-{
-	if(!m_Buffered)
-	{
-		return InternalRead(dst, pos, count);
-	}
-	off_t totalRead = 0;
-	while (count > 0)
-	{
-		std::size_t chunkIndex = InternalFillPageAndReturnIndex(pos);
-		off_t pageSkip = pos - m_ChunkInfo[chunkIndex].ChunkOffset;
-		off_t chunkWanted = std::min(static_cast<off_t>(CHUNK_SIZE) - pageSkip, count);
-		off_t chunkGot = (m_ChunkInfo[chunkIndex].ChunkLength > pageSkip) ? (m_ChunkInfo[chunkIndex].ChunkLength - pageSkip) : 0;
-		off_t chunk = std::min(chunkWanted, chunkGot);
-		std::copy(chunk_data(chunkIndex).data() + pageSkip, chunk_data(chunkIndex).data() + pageSkip + chunk, dst);
-		pos += chunk;
-		dst += chunk;
-		totalRead += chunk;
-		count -= chunk;
-		if (chunkWanted > chunk)
-		{
-			return totalRead;
-		}
-	}
-	return totalRead;
-}
-
-
-
-bool FileDataContainerStdStreamSeekable::IsSeekable(std::istream *stream)
-{
-	return mpt::IO::IsReadSeekable(*stream);
-}
-
-IFileDataContainer::off_t FileDataContainerStdStreamSeekable::GetLength(std::istream *stream)
-{
-	stream->clear();
-	std::streampos oldpos = stream->tellg();
-	stream->seekg(0, std::ios::end);
-	std::streampos length = stream->tellg();
-	stream->seekg(oldpos);
-	return mpt::saturate_cast<IFileDataContainer::off_t>(static_cast<int64>(length));
-}
-
-FileDataContainerStdStreamSeekable::FileDataContainerStdStreamSeekable(std::istream *s)
-	: FileDataContainerSeekable(GetLength(s), true)
-	, stream(s)
-{
-	return;
-}
-
-IFileDataContainer::off_t FileDataContainerStdStreamSeekable::InternalRead(std::byte *dst, off_t pos, off_t count) const
-{
-	stream->clear(); // tellg needs eof and fail bits unset
-	std::streampos currentpos = stream->tellg();
-	if(currentpos == std::streampos(-1) || static_cast<int64>(pos) != currentpos)
-	{ // inefficient istream implementations might invalidate their buffer when seeking, even when seeking to the current position
-		stream->seekg(pos);
-	}
-	stream->read(mpt::byte_cast<char*>(dst), count);
-	return static_cast<IFileDataContainer::off_t>(stream->gcount());
-}
-
-
-FileDataContainerUnseekable::FileDataContainerUnseekable()
-	: cachesize(0), streamFullyCached(false)
-{
-	return;
-}
-
-void FileDataContainerUnseekable::EnsureCacheBuffer(std::size_t requiredbuffersize) const
-{
-	if(cache.size() >= cachesize + requiredbuffersize)
-	{
-		return;
-	}
-	if(cache.size() == 0)
-	{
-		cache.resize(Util::AlignUp<std::size_t>(cachesize + requiredbuffersize, BUFFER_SIZE));
-	} else if(Util::ExponentialGrow(cache.size()) < cachesize + requiredbuffersize)
-	{
-		cache.resize(Util::AlignUp<std::size_t>(cachesize + requiredbuffersize, BUFFER_SIZE));
-	} else
-	{
-		cache.resize(Util::ExponentialGrow(cache.size()));
-	}
-}
-
-void FileDataContainerUnseekable::CacheStream() const
-{
-	if(streamFullyCached)
-	{
-		return;
-	}
-	while(!InternalEof())
-	{
-		EnsureCacheBuffer(BUFFER_SIZE);
-		std::size_t readcount = InternalRead(&cache[cachesize], BUFFER_SIZE);
-		cachesize += readcount;
-	}
-	streamFullyCached = true;
-}
-
-void FileDataContainerUnseekable::CacheStreamUpTo(off_t pos, off_t length) const
-{
-	if(streamFullyCached)
-	{
-		return;
-	}
-	if(length > std::numeric_limits<off_t>::max() - pos)
-	{
-		length = std::numeric_limits<off_t>::max() - pos;
-	}
-	std::size_t target = mpt::saturate_cast<std::size_t>(pos + length);
-	if(target <= cachesize)
-	{
-		return;
-	}
-	std::size_t alignedpos = Util::AlignUp<std::size_t>(target, QUANTUM_SIZE);
-	std::size_t needcount = alignedpos - cachesize;
-	EnsureCacheBuffer(needcount);
-	std::size_t readcount = InternalRead(&cache[cachesize], alignedpos - cachesize);
-	cachesize += readcount;
-	if(!InternalEof())
-	{
-		// can read further
-		return;
-	}
-	streamFullyCached = true;
-}
-
-void FileDataContainerUnseekable::ReadCached(std::byte *dst, IFileDataContainer::off_t pos, IFileDataContainer::off_t count) const
-{
-	std::copy(cache.begin() + pos, cache.begin() + pos + count, dst);
-}
-
-bool FileDataContainerUnseekable::IsValid() const
-{
-	return true;
-}
-
-bool FileDataContainerUnseekable::HasFastGetLength() const
-{
-	return false;
-}
-
-bool FileDataContainerUnseekable::HasPinnedView() const
-{
-	return true; // we have the cache which is required for seeking anyway
-}
-
-const std::byte *FileDataContainerUnseekable::GetRawData() const
-{
-	CacheStream();
-	return cache.data();
-}
-
-IFileDataContainer::off_t FileDataContainerUnseekable::GetLength() const
-{
-	CacheStream();
-	return cachesize;
-}
-
-IFileDataContainer::off_t FileDataContainerUnseekable::Read(std::byte *dst, IFileDataContainer::off_t pos, IFileDataContainer::off_t count) const
-{
-	CacheStreamUpTo(pos, count);
-	if(pos >= IFileDataContainer::off_t(cachesize))
-	{
-		return 0;
-	}
-	IFileDataContainer::off_t cache_avail = std::min(IFileDataContainer::off_t(cachesize) - pos, count);
-	ReadCached(dst, pos, cache_avail);
-	return cache_avail;
-}
-
-bool FileDataContainerUnseekable::CanRead(IFileDataContainer::off_t pos, IFileDataContainer::off_t length) const
-{
-	CacheStreamUpTo(pos, length);
-	if((pos == IFileDataContainer::off_t(cachesize)) && (length == 0))
-	{
-		return true;
-	}
-	if(pos >= IFileDataContainer::off_t(cachesize))
-	{
-		return false;
-	}
-	return length <= IFileDataContainer::off_t(cachesize) - pos;
-}
-
-IFileDataContainer::off_t FileDataContainerUnseekable::GetReadableLength(IFileDataContainer::off_t pos, IFileDataContainer::off_t length) const
-{
-	CacheStreamUpTo(pos, length);
-	if(pos >= cachesize)
-	{
-		return 0;
-	}
-	return std::min(static_cast<IFileDataContainer::off_t>(cachesize) - pos, length);
-}
-
-
-
-FileDataContainerStdStream::FileDataContainerStdStream(std::istream *s)
-	: stream(s)
-{
-	return;
-}
-
-bool FileDataContainerStdStream::InternalEof() const
-{
-	if(*stream)
-	{
-		return false;
-	} else
-	{
-		return true;
-	}
-}
-
-IFileDataContainer::off_t FileDataContainerStdStream::InternalRead(std::byte *dst, off_t count) const
-{
-	stream->read(mpt::byte_cast<char*>(dst), count);
-	return static_cast<std::size_t>(stream->gcount());
-}
-
-
-
-#if defined(MPT_FILEREADER_CALLBACK_STREAM)
-
-
-bool FileDataContainerCallbackStreamSeekable::IsSeekable(CallbackStream stream)
-{
-	if(!stream.stream)
-	{
-		return false;
-	}
-	if(!stream.seek)
-	{
-		return false;
-	}
-	if(!stream.tell)
-	{
-		return false;
-	}
-	int64 oldpos = stream.tell(stream.stream);
-	if(oldpos < 0)
-	{
-		return false;
-	}
-	if(stream.seek(stream.stream, 0, CallbackStream::SeekSet) < 0)
-	{
-		stream.seek(stream.stream, oldpos, CallbackStream::SeekSet);
-		return false;
-	}
-	if(stream.seek(stream.stream, 0, CallbackStream::SeekEnd) < 0)
-	{
-		stream.seek(stream.stream, oldpos, CallbackStream::SeekSet);
-		return false;
-	}
-	int64 length = stream.tell(stream.stream);
-	if(length < 0)
-	{
-		stream.seek(stream.stream, oldpos, CallbackStream::SeekSet);
-		return false;
-	}
-	stream.seek(stream.stream, oldpos, CallbackStream::SeekSet);
-	return true;
-}
-
-IFileDataContainer::off_t FileDataContainerCallbackStreamSeekable::GetLength(CallbackStream stream)
-{
-	if(!stream.stream)
-	{
-		return 0;
-	}
-	if(!stream.seek)
-	{
-		return false;
-	}
-	if(!stream.tell)
-	{
-		return false;
-	}
-	int64 oldpos = stream.tell(stream.stream);
-	if(oldpos < 0)
-	{
-		return 0;
-	}
-	if(stream.seek(stream.stream, 0, CallbackStream::SeekSet) < 0)
-	{
-		stream.seek(stream.stream, oldpos, CallbackStream::SeekSet);
-		return 0;
-	}
-	if(stream.seek(stream.stream, 0, CallbackStream::SeekEnd) < 0)
-	{
-		stream.seek(stream.stream, oldpos, CallbackStream::SeekSet);
-		return 0;
-	}
-	int64 length = stream.tell(stream.stream);
-	if(length < 0)
-	{
-		stream.seek(stream.stream, oldpos, CallbackStream::SeekSet);
-		return 0;
-	}
-	stream.seek(stream.stream, oldpos, CallbackStream::SeekSet);
-	return mpt::saturate_cast<IFileDataContainer::off_t>(length);
-}
-
-FileDataContainerCallbackStreamSeekable::FileDataContainerCallbackStreamSeekable(CallbackStream s)
-	: FileDataContainerSeekable(GetLength(s), false)
-	, stream(s)
-{
-	return;
-}
-
-IFileDataContainer::off_t FileDataContainerCallbackStreamSeekable::InternalRead(std::byte *dst, off_t pos, off_t count) const
-{
-	if(!stream.read)
-	{
-		return 0;
-	}
-	if(stream.seek(stream.stream, pos, CallbackStream::SeekSet) < 0)
-	{
-		return 0;
-	}
-	int64 totalread = 0;
-	while(count > 0)
-	{
-		int64 readcount = stream.read(stream.stream, dst, count);
-		if(readcount <= 0)
-		{
-			break;
-		}
-		dst += static_cast<std::size_t>(readcount);
-		count -= static_cast<IFileDataContainer::off_t>(readcount);
-		totalread += readcount;
-	}
-	return static_cast<IFileDataContainer::off_t>(totalread);
-}
-
-
-
-FileDataContainerCallbackStream::FileDataContainerCallbackStream(CallbackStream s)
-	: FileDataContainerUnseekable()
-	, stream(s)
-	, eof_reached(false)
-{
-	return;
-}
-
-bool FileDataContainerCallbackStream::InternalEof() const
-{
-	return eof_reached;
-}
-
-IFileDataContainer::off_t FileDataContainerCallbackStream::InternalRead(std::byte *dst, off_t count) const
-{
-	if(eof_reached)
-	{
-		return 0;
-	}
-	if(!stream.read)
-	{
-		eof_reached = true;
-		return 0;
-	}
-	int64 totalread = 0;
-	while(count > 0)
-	{
-		int64 readcount = stream.read(stream.stream, dst, count);
-		if(readcount <= 0)
-		{
-			eof_reached = true;
-			break;
-		}
-		dst += static_cast<std::size_t>(readcount);
-		count -= static_cast<IFileDataContainer::off_t>(readcount);
-		totalread += readcount;
-	}
-	return static_cast<IFileDataContainer::off_t>(totalread);
-}
-
-
-#endif // MPT_FILEREADER_CALLBACK_STREAM
-
-
-
-OPENMPT_NAMESPACE_END

+ 0 - 1097
libopenmpt.mod/openmpt/common/mptIO.h

@@ -1,1097 +0,0 @@
-/*
- * mptIO.h
- * -------
- * Purpose: Basic functions for reading/writing binary and endian safe data to/from files/streams.
- * Notes  : Some useful functions for reading and writing are still missing.
- * Authors: Joern Heusipp
- *          OpenMPT Devs
- * The OpenMPT source code is released under the BSD license. Read LICENSE for more details.
- */
-
-
-#pragma once
-
-#include "BuildSettings.h"
-
-
-#include "../common/Endianness.h"
-#include <algorithm>
-#include <array>
-#include <iosfwd>
-#include <limits>
-#include <cstring>
-
-
-OPENMPT_NAMESPACE_BEGIN
-
-
-namespace mpt {
-
-namespace IO {
-
-typedef int64 Offset;
-
-static constexpr std::size_t BUFFERSIZE_TINY   =    1 * 1024; // on stack usage
-static constexpr std::size_t BUFFERSIZE_SMALL  =    4 * 1024; // on heap
-static constexpr std::size_t BUFFERSIZE_NORMAL =   64 * 1024; // FILE I/O
-static constexpr std::size_t BUFFERSIZE_LARGE  = 1024 * 1024;
-
-
-
-// Returns true iff 'off' fits into 'Toff'.
-template < typename Toff >
-inline bool OffsetFits(IO::Offset off)
-{
-	return (static_cast<IO::Offset>(mpt::saturate_cast<Toff>(off)) == off);
-}
-
-
-
-bool IsValid(std::ostream & f);
-bool IsValid(std::istream & f);
-bool IsValid(std::iostream & f);
-bool IsReadSeekable(std::istream& f);
-bool IsWriteSeekable(std::ostream& f);
-IO::Offset TellRead(std::istream & f);
-IO::Offset TellWrite(std::ostream & f);
-bool SeekBegin(std::ostream & f);
-bool SeekBegin(std::istream & f);
-bool SeekBegin(std::iostream & f);
-bool SeekEnd(std::ostream & f);
-bool SeekEnd(std::istream & f);
-bool SeekEnd(std::iostream & f);
-bool SeekAbsolute(std::ostream & f, IO::Offset pos);
-bool SeekAbsolute(std::istream & f, IO::Offset pos);
-bool SeekAbsolute(std::iostream & f, IO::Offset pos);
-bool SeekRelative(std::ostream & f, IO::Offset off);
-bool SeekRelative(std::istream & f, IO::Offset off);
-bool SeekRelative(std::iostream & f, IO::Offset off);
-IO::Offset ReadRawImpl(std::istream & f, std::byte * data, std::size_t size);
-bool WriteRawImpl(std::ostream & f, const std::byte * data, std::size_t size);
-bool IsEof(std::istream & f);
-bool Flush(std::ostream & f);
-
-
-
-template <typename Tfile> class WriteBuffer;
-
-template <typename Tfile> bool IsValid(WriteBuffer<Tfile> & f) { return IsValid(f.file()); }
-template <typename Tfile> bool IsReadSeekable(WriteBuffer<Tfile> & f) { return IsReadSeekable(f.file()); }
-template <typename Tfile> bool IsWriteSeekable(WriteBuffer<Tfile> & f) { return IsWriteSeekable(f.file()); }
-template <typename Tfile> IO::Offset TellRead(WriteBuffer<Tfile> & f) { f.FlushLocal(); return TellRead(f.file()); }
-template <typename Tfile> IO::Offset TellWrite(WriteBuffer<Tfile> & f) { return TellWrite(f.file()) + f.GetCurrentSize(); }
-template <typename Tfile> bool SeekBegin(WriteBuffer<Tfile> & f) { f.FlushLocal(); return SeekBegin(f.file()); }
-template <typename Tfile> bool SeekEnd(WriteBuffer<Tfile> & f) { f.FlushLocal(); return SeekEnd(f.file()); }
-template <typename Tfile> bool SeekAbsolute(WriteBuffer<Tfile> & f, IO::Offset pos) { return f.FlushLocal(); SeekAbsolute(f.file(), pos); }
-template <typename Tfile> bool SeekRelative(WriteBuffer<Tfile> & f, IO::Offset off) { return f.FlushLocal(); SeekRelative(f.file(), off); }
-template <typename Tfile> IO::Offset ReadRawImpl(WriteBuffer<Tfile> & f, std::byte * data, std::size_t size) { f.FlushLocal(); return ReadRawImpl(f.file(), data, size); }
-template <typename Tfile> bool WriteRawImpl(WriteBuffer<Tfile> & f, const std::byte * data, std::size_t size) { return f.Write(mpt::as_span(data, size)); }
-template <typename Tfile> bool IsEof(WriteBuffer<Tfile> & f) { f.FlushLocal(); return IsEof(f.file()); }
-template <typename Tfile> bool Flush(WriteBuffer<Tfile> & f) { f.FlushLocal(); return Flush(f.file()); }
-
-
-
-
-
-template <typename Tbyte> bool IsValid(std::pair<mpt::span<Tbyte>, IO::Offset> & f)
-{
-	return (f.second >= 0);
-}
-template <typename Tbyte> IO::Offset TellRead(std::pair<mpt::span<Tbyte>, IO::Offset> & f)
-{
-	return f.second;
-}
-template <typename Tbyte> IO::Offset TellWrite(std::pair<mpt::span<Tbyte>, IO::Offset> & f)
-{
-	return f.second;
-}
-template <typename Tbyte> bool SeekBegin(std::pair<mpt::span<Tbyte>, IO::Offset> & f)
-{
-	f.second = 0;
-	return true;
-}
-template <typename Tbyte> bool SeekEnd(std::pair<mpt::span<Tbyte>, IO::Offset> & f)
-{
-	f.second = f.first.size();
-	return true;
-}
-template <typename Tbyte> bool SeekAbsolute(std::pair<mpt::span<Tbyte>, IO::Offset> & f, IO::Offset pos)
-{
-	f.second = pos;
-	return true;
-}
-template <typename Tbyte> bool SeekRelative(std::pair<mpt::span<Tbyte>, IO::Offset> & f, IO::Offset off)
-{
-	if(f.second < 0)
-	{
-		return false;
-	}
-	f.second += off;
-	return true;
-}
-template <typename Tbyte> IO::Offset ReadRawImpl(std::pair<mpt::span<Tbyte>, IO::Offset> & f, std::byte * data, std::size_t size)
-{
-	if(f.second < 0)
-	{
-		return 0;
-	}
-	if(f.second >= static_cast<IO::Offset>(f.first.size()))
-	{
-		return 0;
-	}
-	std::size_t num = mpt::saturate_cast<std::size_t>(std::min(static_cast<IO::Offset>(f.first.size()) - f.second, static_cast<IO::Offset>(size)));
-	std::copy(mpt::byte_cast<const std::byte*>(f.first.data() + f.second), mpt::byte_cast<const std::byte*>(f.first.data() + f.second + num), data);
-	f.second += num;
-	return num;
-}
-template <typename Tbyte> bool WriteRawImpl(std::pair<mpt::span<Tbyte>, IO::Offset> & f, const std::byte * data, std::size_t size)
-{
-	if(f.second < 0)
-	{
-		return false;
-	}
-	if(f.second >= static_cast<IO::Offset>(f.first.size()))
-	{
-		return false;
-	}
-	std::size_t num = mpt::saturate_cast<std::size_t>(std::min(static_cast<IO::Offset>(f.first.size()) - f.second, static_cast<IO::Offset>(size)));
-	if(num != size)
-	{
-		return false;
-	}
-	std::copy(data, data + num, mpt::byte_cast<std::byte*>(f.first.data() + f.second));
-	f.second += num;
-	return true;
-}
-template <typename Tbyte> bool IsEof(std::pair<mpt::span<Tbyte>, IO::Offset> & f)
-{
-	return (f.second >= static_cast<IO::Offset>(f.first.size()));
-}
-template <typename Tbyte> bool Flush(std::pair<mpt::span<Tbyte>, IO::Offset> & f)
-{
-	MPT_UNREFERENCED_PARAMTER(f);
-	return true;
-}
-
-
-
-template <typename Tbyte, typename Tfile>
-inline IO::Offset ReadRaw(Tfile & f, Tbyte * data, std::size_t size)
-{
-	return IO::ReadRawImpl(f, mpt::byte_cast<std::byte*>(data), size);
-}
-
-template <typename Tbyte, typename Tfile>
-inline IO::Offset ReadRaw(Tfile & f, mpt::span<Tbyte> data)
-{
-	return IO::ReadRawImpl(f, mpt::byte_cast<std::byte*>(data.data()), data.size());
-}
-
-template <typename Tbyte, typename Tfile>
-inline bool WriteRaw(Tfile & f, const Tbyte * data, std::size_t size)
-{
-	return IO::WriteRawImpl(f, mpt::byte_cast<const std::byte*>(data), size);
-}
-
-template <typename Tbyte, typename Tfile>
-inline bool WriteRaw(Tfile & f, mpt::span<Tbyte> data)
-{
-	return IO::WriteRawImpl(f, mpt::byte_cast<const std::byte*>(data.data()), data.size());
-}
-
-template <typename Tbinary, typename Tfile>
-inline bool Read(Tfile & f, Tbinary & v)
-{
-	return IO::ReadRaw(f, mpt::as_raw_memory(v)) == mpt::saturate_cast<mpt::IO::Offset>(mpt::as_raw_memory(v).size());
-}
-
-template <typename Tbinary, typename Tfile>
-inline bool Write(Tfile & f, const Tbinary & v)
-{
-	return IO::WriteRaw(f, mpt::as_raw_memory(v));
-}
-
-template <typename Tbinary, typename Tfile>
-inline bool Write(Tfile & f, const std::vector<Tbinary> & v)
-{
-	static_assert(mpt::is_binary_safe<Tbinary>::value);
-	return IO::WriteRaw(f, mpt::as_raw_memory(v));
-}
-
-template <typename T, typename Tfile>
-inline bool WritePartial(Tfile & f, const T & v, size_t size = sizeof(T))
-{
-	MPT_ASSERT(size <= sizeof(T));
-	return IO::WriteRaw(f, mpt::as_span(mpt::as_raw_memory(v).data(), size));
-}
-
-template <typename Tfile>
-inline bool ReadByte(Tfile & f, std::byte & v)
-{
-	bool result = false;
-	std::byte byte = mpt::as_byte(0);
-	const IO::Offset readResult = IO::ReadRaw(f, &byte, sizeof(std::byte));
-	if(readResult < 0)
-	{
-		result = false;
-	} else
-	{
-		result = (static_cast<uint64>(readResult) == sizeof(std::byte));
-	}
-	v = byte;
-	return result;
-}
-
-template <typename T, typename Tfile>
-inline bool ReadBinaryTruncatedLE(Tfile & f, T & v, std::size_t size)
-{
-	bool result = false;
-	static_assert(std::numeric_limits<T>::is_integer);
-	uint8 bytes[sizeof(T)];
-	std::memset(bytes, 0, sizeof(T));
-	const IO::Offset readResult = IO::ReadRaw(f, bytes, std::min(size, sizeof(T)));
-	if(readResult < 0)
-	{
-		result = false;
-	} else
-	{
-		result = (static_cast<uint64>(readResult) == std::min(size, sizeof(T)));
-	}
-	typename mpt::make_le<T>::type val;
-	std::memcpy(&val, bytes, sizeof(T));
-	v = val;
-	return result;
-}
-
-template <typename T, typename Tfile>
-inline bool ReadIntLE(Tfile & f, T & v)
-{
-	bool result = false;
-	static_assert(std::numeric_limits<T>::is_integer);
-	uint8 bytes[sizeof(T)];
-	std::memset(bytes, 0, sizeof(T));
-	const IO::Offset readResult = IO::ReadRaw(f, bytes, sizeof(T));
-	if(readResult < 0)
-	{
-		result = false;
-	} else
-	{
-		result = (static_cast<uint64>(readResult) == sizeof(T));
-	}
-	typename mpt::make_le<T>::type val;
-	std::memcpy(&val, bytes, sizeof(T));
-	v = val;
-	return result;
-}
-
-template <typename T, typename Tfile>
-inline bool ReadIntBE(Tfile & f, T & v)
-{
-	bool result = false;
-	static_assert(std::numeric_limits<T>::is_integer);
-	uint8 bytes[sizeof(T)];
-	std::memset(bytes, 0, sizeof(T));
-	const IO::Offset readResult = IO::ReadRaw(f, bytes, sizeof(T));
-	if(readResult < 0)
-	{
-		result = false;
-	} else
-	{
-		result = (static_cast<uint64>(readResult) == sizeof(T));
-	}
-	typename mpt::make_be<T>::type val;
-	std::memcpy(&val, bytes, sizeof(T));
-	v = val;
-	return result;
-}
-
-template <typename Tfile>
-inline bool ReadAdaptiveInt16LE(Tfile & f, uint16 & v)
-{
-	bool result = true;
-	uint8 byte = 0;
-	std::size_t additionalBytes = 0;
-	v = 0;
-	byte = 0;
-	if(!IO::ReadIntLE<uint8>(f, byte)) result = false;
-	additionalBytes = (byte & 0x01);
-	v = byte >> 1;
-	for(std::size_t i = 0; i < additionalBytes; ++i)
-	{
-		byte = 0;
-		if(!IO::ReadIntLE<uint8>(f, byte)) result = false;
-		v |= (static_cast<uint16>(byte) << (((i+1)*8) - 1));
-	}
-	return result;
-}
-
-template <typename Tfile>
-inline bool ReadAdaptiveInt32LE(Tfile & f, uint32 & v)
-{
-	bool result = true;
-	uint8 byte = 0;
-	std::size_t additionalBytes = 0;
-	v = 0;
-	byte = 0;
-	if(!IO::ReadIntLE<uint8>(f, byte)) result = false;
-	additionalBytes = (byte & 0x03);
-	v = byte >> 2;
-	for(std::size_t i = 0; i < additionalBytes; ++i)
-	{
-		byte = 0;
-		if(!IO::ReadIntLE<uint8>(f, byte)) result = false;
-		v |= (static_cast<uint32>(byte) << (((i+1)*8) - 2));
-	}
-	return result;
-}
-
-template <typename Tfile>
-inline bool ReadAdaptiveInt64LE(Tfile & f, uint64 & v)
-{
-	bool result = true;
-	uint8 byte = 0;
-	std::size_t additionalBytes = 0;
-	v = 0;
-	byte = 0;
-	if(!IO::ReadIntLE<uint8>(f, byte)) result = false;
-	additionalBytes = (1 << (byte & 0x03)) - 1;
-	v = byte >> 2;
-	for(std::size_t i = 0; i < additionalBytes; ++i)
-	{
-		byte = 0;
-		if(!IO::ReadIntLE<uint8>(f, byte)) result = false;
-		v |= (static_cast<uint64>(byte) << (((i+1)*8) - 2));
-	}
-	return result;
-}
-
-template <typename Tsize, typename Tfile>
-inline bool ReadSizedStringLE(Tfile & f, std::string & str, Tsize maxSize = std::numeric_limits<Tsize>::max())
-{
-	static_assert(std::numeric_limits<Tsize>::is_integer);
-	str.clear();
-	Tsize size = 0;
-	if(!mpt::IO::ReadIntLE(f, size))
-	{
-		return false;
-	}
-	if(size > maxSize)
-	{
-		return false;
-	}
-	for(Tsize i = 0; i != size; ++i)
-	{
-		char c = '\0';
-		if(!mpt::IO::ReadIntLE(f, c))
-		{
-			return false;
-		}
-		str.push_back(c);
-	}
-	return true;
-}
-
-
-template <typename T, typename Tfile>
-inline bool WriteIntLE(Tfile & f, const T v)
-{
-	static_assert(std::numeric_limits<T>::is_integer);
-	return IO::Write(f, mpt::as_le(v));
-}
-
-template <typename T, typename Tfile>
-inline bool WriteIntBE(Tfile & f, const T v)
-{
-	static_assert(std::numeric_limits<T>::is_integer);
-	return IO::Write(f, mpt::as_be(v));
-}
-
-template <typename Tfile>
-inline bool WriteAdaptiveInt16LE(Tfile & f, const uint16 v, std::size_t fixedSize = 0)
-{
-	std::size_t minSize = fixedSize;
-	std::size_t maxSize = fixedSize;
-	MPT_ASSERT(minSize == 0 || minSize == 1 || minSize == 2);
-	MPT_ASSERT(maxSize == 0 || maxSize == 1 || maxSize == 2);
-	MPT_ASSERT(maxSize == 0 || maxSize >= minSize);
-	if(maxSize == 0)
-	{
-		maxSize = 2;
-	}
-	if(v < 0x80 && minSize <= 1 && 1 <= maxSize)
-	{
-		return IO::WriteIntLE<uint8>(f, static_cast<uint8>(v << 1) | 0x00);
-	} else if(v < 0x8000 && minSize <= 2 && 2 <= maxSize)
-	{
-		return IO::WriteIntLE<uint16>(f, static_cast<uint16>(v << 1) | 0x01);
-	} else
-	{
-		MPT_ASSERT_NOTREACHED();
-		return false;
-	}
-}
-
-template <typename Tfile>
-inline bool WriteAdaptiveInt32LE(Tfile & f, const uint32 v, std::size_t fixedSize = 0)
-{
-	std::size_t minSize = fixedSize;
-	std::size_t maxSize = fixedSize;
-	MPT_ASSERT(minSize == 0 || minSize == 1 || minSize == 2 || minSize == 3 || minSize == 4);
-	MPT_ASSERT(maxSize == 0 || maxSize == 1 || maxSize == 2 || maxSize == 3 || maxSize == 4);
-	MPT_ASSERT(maxSize == 0 || maxSize >= minSize);
-	if(maxSize == 0)
-	{
-		maxSize = 4;
-	}
-	if(v < 0x40 && minSize <= 1 && 1 <= maxSize)
-	{
-		return IO::WriteIntLE<uint8>(f, static_cast<uint8>(v << 2) | 0x00);
-	} else if(v < 0x4000 && minSize <= 2 && 2 <= maxSize)
-	{
-		return IO::WriteIntLE<uint16>(f, static_cast<uint16>(v << 2) | 0x01);
-	} else if(v < 0x400000 && minSize <= 3 && 3 <= maxSize)
-	{
-		uint32 value = static_cast<uint32>(v << 2) | 0x02;
-		std::byte bytes[3];
-		bytes[0] = static_cast<std::byte>(value >>  0);
-		bytes[1] = static_cast<std::byte>(value >>  8);
-		bytes[2] = static_cast<std::byte>(value >> 16);
-		return IO::WriteRaw(f, bytes, 3);
-	} else if(v < 0x40000000 && minSize <= 4 && 4 <= maxSize)
-	{
-		return IO::WriteIntLE<uint32>(f, static_cast<uint32>(v << 2) | 0x03);
-	} else
-	{
-		MPT_ASSERT_NOTREACHED();
-		return false;
-	}
-}
-
-template <typename Tfile>
-inline bool WriteAdaptiveInt64LE(Tfile & f, const uint64 v, std::size_t fixedSize = 0)
-{
-	std::size_t minSize = fixedSize;
-	std::size_t maxSize = fixedSize;
-	MPT_ASSERT(minSize == 0 || minSize == 1 || minSize == 2 || minSize == 4 || minSize == 8);
-	MPT_ASSERT(maxSize == 0 || maxSize == 1 || maxSize == 2 || maxSize == 4 || maxSize == 8);
-	MPT_ASSERT(maxSize == 0 || maxSize >= minSize);
-	if(maxSize == 0)
-	{
-		maxSize = 8;
-	}
-	if(v < 0x40 && minSize <= 1 && 1 <= maxSize)
-	{
-		return IO::WriteIntLE<uint8>(f, static_cast<uint8>(v << 2) | 0x00);
-	} else if(v < 0x4000 && minSize <= 2 && 2 <= maxSize)
-	{
-		return IO::WriteIntLE<uint16>(f, static_cast<uint16>(v << 2) | 0x01);
-	} else if(v < 0x40000000 && minSize <= 4 && 4 <= maxSize)
-	{
-		return IO::WriteIntLE<uint32>(f, static_cast<uint32>(v << 2) | 0x02);
-	} else if(v < 0x4000000000000000ull && minSize <= 8 && 8 <= maxSize)
-	{
-		return IO::WriteIntLE<uint64>(f, static_cast<uint64>(v << 2) | 0x03);
-	} else
-	{
-		MPT_ASSERT_NOTREACHED();
-		return false;
-	}
-}
-
-// Write a variable-length integer, as found in MIDI files. The number of written bytes is placed in the bytesWritten parameter.
-template <typename Tfile, typename T>
-bool WriteVarInt(Tfile & f, const T v, size_t *bytesWritten = nullptr)
-{
-	static_assert(std::numeric_limits<T>::is_integer);
-	static_assert(!std::numeric_limits<T>::is_signed);
-	std::byte out[(sizeof(T) * 8 + 6) / 7];
-	size_t numBytes = 0;
-	for(uint32 n = (sizeof(T) * 8) / 7; n > 0; n--)
-	{
-		if(v >= (static_cast<T>(1) << (n * 7u)))
-		{
-			out[numBytes++] = static_cast<std::byte>(((v >> (n * 7u)) & 0x7F) | 0x80);
-		}
-	}
-	out[numBytes++] = static_cast<std::byte>(v & 0x7F);
-	MPT_ASSERT(numBytes <= std::size(out));
-	if(bytesWritten != nullptr) *bytesWritten = numBytes;
-	return mpt::IO::WriteRaw(f, out, numBytes);
-}
-
-template <typename Tsize, typename Tfile>
-inline bool WriteSizedStringLE(Tfile & f, const std::string & str)
-{
-	static_assert(std::numeric_limits<Tsize>::is_integer);
-	if(str.size() > std::numeric_limits<Tsize>::max())
-	{
-		return false;
-	}
-	Tsize size = static_cast<Tsize>(str.size());
-	if(!mpt::IO::WriteIntLE(f, size))
-	{
-		return false;
-	}
-	if(!mpt::IO::WriteRaw(f, str.data(), str.size()))
-	{
-		return false;
-	}
-	return true;
-}
-
-template <typename Tfile>
-inline bool WriteText(Tfile &f, const std::string &s)
-{
-	return mpt::IO::WriteRaw(f, s.data(), s.size());
-}
-
-template <typename Tfile>
-inline bool WriteTextCRLF(Tfile &f)
-{
-	return mpt::IO::WriteText(f, "\r\n");
-}
-
-template <typename Tfile>
-inline bool WriteTextLF(Tfile &f)
-{
-	return mpt::IO::WriteText(f, "\n");
-}
-
-template <typename Tfile>
-inline bool WriteTextCRLF(Tfile &f, const std::string &s)
-{
-	return mpt::IO::WriteText(f, s) && mpt::IO::WriteTextCRLF(f);
-}
-
-template <typename Tfile>
-inline bool WriteTextLF(Tfile &f, const std::string &s)
-{
-	return mpt::IO::WriteText(f, s) && mpt::IO::WriteTextLF(f);
-}
-
-
-
-// WriteBuffer class that avoids calling to the underlying file writing
-// functions for every operation, which would involve rather slow un-inlinable
-// virtual calls in the iostream and FILE* cases. It is the users responabiliy
-// to call HasWriteError() to check for writeback errors at this buffering
-// level.
-
-template <typename Tfile>
-class WriteBuffer
-{
-private:
-	mpt::byte_span buffer;
-	std::size_t size = 0;
-	Tfile & f;
-	bool writeError = false;
-public:
-	WriteBuffer(const WriteBuffer &) = delete;
-	WriteBuffer & operator=(const WriteBuffer &) = delete;
-public:
-	inline WriteBuffer(Tfile & f_, mpt::byte_span buffer_)
-		: buffer(buffer_)
-		, f(f_)
-	{
-	}
-	inline ~WriteBuffer() noexcept(false)
-	{
-		if(!writeError)
-		{
-			FlushLocal();
-		}
-	}
-public:
-	inline Tfile & file() const
-	{
-		if(IsDirty())
-		{
-			FlushLocal();
-		}
-		return f;
-	}
-public:
-	inline bool HasWriteError() const
-	{
-		return writeError;
-	}
-	inline void ClearError()
-	{
-		writeError = false;
-	}
-	inline bool IsDirty() const
-	{
-		return size > 0;
-	}
-	inline bool IsClean() const
-	{
-		return size == 0;
-	}
-	inline bool IsFull() const
-	{
-		return size == buffer.size();
-	}
-	inline std::size_t GetCurrentSize() const
-	{
-		return size;
-	}
-	inline bool Write(mpt::const_byte_span data)
-	{
-		bool result = true;
-		for(std::size_t i = 0; i < data.size(); ++i)
-		{
-			buffer[size] = data[i];
-			size++;
-			if(IsFull())
-			{
-				FlushLocal();
-			}
-		}
-		return result;
-	}
-	inline void FlushLocal()
-	{
-		if(IsClean())
-		{
-			return;
-		}
-		try
-		{
-			if(!mpt::IO::WriteRaw(f, mpt::as_span(buffer.data(), size)))
-			{
-				writeError = true;
-			}
-		} catch (const std::exception &)
-		{
-			writeError = true;
-			throw;
-		}
-		size = 0;
-	}
-};
-
-
-
-} // namespace IO
-
-
-} // namespace mpt
-
-
-
-class IFileDataContainer {
-public:
-	typedef std::size_t off_t;
-protected:
-	IFileDataContainer() = default;
-public:
-	IFileDataContainer(const IFileDataContainer&) = default;
-	IFileDataContainer & operator=(const IFileDataContainer&) = default;
-	virtual ~IFileDataContainer() = default;
-public:
-	virtual bool IsValid() const = 0;
-	virtual bool HasFastGetLength() const = 0;
-	virtual bool HasPinnedView() const = 0;
-	virtual const std::byte *GetRawData() const = 0;
-	virtual off_t GetLength() const = 0;
-	virtual off_t Read(std::byte *dst, off_t pos, off_t count) const = 0;
-
-	virtual off_t Read(off_t pos, mpt::byte_span dst) const
-	{
-		return Read(dst.data(), pos, dst.size());
-	}
-
-	virtual bool CanRead(off_t pos, off_t length) const
-	{
-		off_t dataLength = GetLength();
-		if((pos == dataLength) && (length == 0))
-		{
-			return true;
-		}
-		if(pos >= dataLength)
-		{
-			return false;
-		}
-		return length <= dataLength - pos;
-	}
-
-	virtual off_t GetReadableLength(off_t pos, off_t length) const
-	{
-		off_t dataLength = GetLength();
-		if(pos >= dataLength)
-		{
-			return 0;
-		}
-		return std::min(length, dataLength - pos);
-	}
-};
-
-
-class FileDataContainerDummy : public IFileDataContainer {
-public:
-	FileDataContainerDummy() { }
-public:
-	bool IsValid() const override
-	{
-		return false;
-	}
-
-	bool HasFastGetLength() const override
-	{
-		return true;
-	}
-
-	bool HasPinnedView() const override
-	{
-		return true;
-	}
-
-	const std::byte *GetRawData() const override
-	{
-		return nullptr;
-	}
-
-	off_t GetLength() const override
-	{
-		return 0;
-	}
-	off_t Read(std::byte * /*dst*/, off_t /*pos*/, off_t /*count*/) const override
-	{
-		return 0;
-	}
-};
-
-
-class FileDataContainerWindow : public IFileDataContainer
-{
-private:
-	std::shared_ptr<const IFileDataContainer> data;
-	const off_t dataOffset;
-	const off_t dataLength;
-public:
-	FileDataContainerWindow(std::shared_ptr<const IFileDataContainer> src, off_t off, off_t len) : data(src), dataOffset(off), dataLength(len) { }
-
-	bool IsValid() const override
-	{
-		return data->IsValid();
-	}
-	bool HasFastGetLength() const override
-	{
-		return data->HasFastGetLength();
-	}
-	bool HasPinnedView() const override
-	{
-		return data->HasPinnedView();
-	}
-	const std::byte *GetRawData() const override
-	{
-		return data->GetRawData() + dataOffset;
-	}
-	off_t GetLength() const override
-	{
-		return dataLength;
-	}
-	off_t Read(std::byte *dst, off_t pos, off_t count) const override
-	{
-		if(pos >= dataLength)
-		{
-			return 0;
-		}
-		return data->Read(dst, dataOffset + pos, std::min(count, dataLength - pos));
-	}
-	bool CanRead(off_t pos, off_t length) const override
-	{
-		if((pos == dataLength) && (length == 0))
-		{
-			return true;
-		}
-		if(pos >= dataLength)
-		{
-			return false;
-		}
-		return (length <= dataLength - pos);
-	}
-	off_t GetReadableLength(off_t pos, off_t length) const override
-	{
-		if(pos >= dataLength)
-		{
-			return 0;
-		}
-		return std::min(length, dataLength - pos);
-	}
-};
-
-
-class FileDataContainerSeekable : public IFileDataContainer {
-
-private:
-
-	off_t streamLength;
-
-	mutable bool cached;
-	mutable std::vector<std::byte> cache;
-
-private:
-
-	mutable bool m_Buffered;
-	enum : std::size_t {
-		CHUNK_SIZE = mpt::IO::BUFFERSIZE_SMALL,
-		BUFFER_SIZE = mpt::IO::BUFFERSIZE_NORMAL
-	};
-	enum : std::size_t {
-		NUM_CHUNKS = BUFFER_SIZE / CHUNK_SIZE
-	};
-	struct chunk_info {
-		off_t ChunkOffset = 0;
-		off_t ChunkLength = 0;
-		bool ChunkValid = false;
-	};
-	mutable std::vector<std::byte> m_Buffer;
-	mpt::byte_span chunk_data(std::size_t chunkIndex) const
-	{
-		return mpt::byte_span(m_Buffer.data() + (chunkIndex * CHUNK_SIZE), CHUNK_SIZE);
-	}
-	mutable std::array<chunk_info, NUM_CHUNKS> m_ChunkInfo;
-	mutable std::array<std::size_t, NUM_CHUNKS> m_ChunkIndexLRU;
-
-	std::size_t InternalFillPageAndReturnIndex(off_t pos) const;
-
-protected:
-
-	FileDataContainerSeekable(off_t length, bool buffered);
-
-private:
-	
-	void CacheStream() const;
-
-public:
-
-	bool IsValid() const override;
-	bool HasFastGetLength() const override;
-	bool HasPinnedView() const override;
-	const std::byte *GetRawData() const override;
-	off_t GetLength() const override;
-	off_t Read(std::byte *dst, off_t pos, off_t count) const override;
-
-private:
-
-	off_t InternalReadBuffered(std::byte* dst, off_t pos, off_t count) const;
-
-	virtual off_t InternalRead(std::byte *dst, off_t pos, off_t count) const = 0;
-
-};
-
-
-class FileDataContainerStdStreamSeekable : public FileDataContainerSeekable {
-
-private:
-
-	std::istream *stream;
-
-public:
-
-	FileDataContainerStdStreamSeekable(std::istream *s);
-
-	static bool IsSeekable(std::istream *stream);
-	static off_t GetLength(std::istream *stream);
-
-private:
-
-	off_t InternalRead(std::byte *dst, off_t pos, off_t count) const override;
-
-};
-
-
-class FileDataContainerUnseekable : public IFileDataContainer {
-
-private:
-
-	mutable std::vector<std::byte> cache;
-	mutable std::size_t cachesize;
-	mutable bool streamFullyCached;
-
-protected:
-
-	FileDataContainerUnseekable();
-
-private:
-
-	enum : std::size_t {
-		QUANTUM_SIZE = mpt::IO::BUFFERSIZE_SMALL,
-		BUFFER_SIZE = mpt::IO::BUFFERSIZE_NORMAL
-	};
-
-	void EnsureCacheBuffer(std::size_t requiredbuffersize) const;
-	void CacheStream() const;
-	void CacheStreamUpTo(off_t pos, off_t length) const;
-
-private:
-
-	void ReadCached(std::byte *dst, off_t pos, off_t count) const;
-
-public:
-
-	bool IsValid() const override;
-	bool HasFastGetLength() const override;
-	bool HasPinnedView() const override;
-	const std::byte *GetRawData() const override;
-	off_t GetLength() const override;
-	off_t Read(std::byte *dst, off_t pos, off_t count) const override;
-	bool CanRead(off_t pos, off_t length) const override;
-	off_t GetReadableLength(off_t pos, off_t length) const override;
-
-private:
-
-	virtual bool InternalEof() const = 0;
-	virtual off_t InternalRead(std::byte *dst, off_t count) const = 0;
-
-};
-
-
-class FileDataContainerStdStream : public FileDataContainerUnseekable {
-
-private:
-
-	std::istream *stream;
-
-public:
-
-	FileDataContainerStdStream(std::istream *s);
-
-private:
-
-	bool InternalEof() const override;
-	off_t InternalRead(std::byte *dst, off_t count) const override;
-
-};
-
-
-#if defined(MPT_FILEREADER_CALLBACK_STREAM)
-
-
-struct CallbackStream
-{
-	enum : int {
-		SeekSet = 0,
-		SeekCur = 1,
-		SeekEnd = 2
-	};
-	void *stream;
-	std::size_t (*read)( void * stream, void * dst, std::size_t bytes );
-	int (*seek)( void * stream, int64 offset, int whence );
-	int64 (*tell)( void * stream );
-};
-
-
-class FileDataContainerCallbackStreamSeekable : public FileDataContainerSeekable
-{
-private:
-	CallbackStream stream;
-public:
-	static bool IsSeekable(CallbackStream stream);
-	static off_t GetLength(CallbackStream stream);
-	FileDataContainerCallbackStreamSeekable(CallbackStream s);
-private:
-	off_t InternalRead(std::byte *dst, off_t pos, off_t count) const override;
-};
-
-
-class FileDataContainerCallbackStream : public FileDataContainerUnseekable
-{
-private:
-	CallbackStream stream;
-	mutable bool eof_reached;
-public:
-	FileDataContainerCallbackStream(CallbackStream s);
-private:
-	bool InternalEof() const override;
-	off_t InternalRead(std::byte *dst, off_t count) const override;
-};
-
-
-#endif // MPT_FILEREADER_CALLBACK_STREAM
-
-
-class FileDataContainerMemory
-	: public IFileDataContainer
-{
-
-private:
-
-	const std::byte *streamData;	// Pointer to memory-mapped file
-	off_t streamLength;		// Size of memory-mapped file in bytes
-
-public:
-	FileDataContainerMemory() : streamData(nullptr), streamLength(0) { }
-	FileDataContainerMemory(mpt::const_byte_span data) : streamData(data.data()), streamLength(data.size()) { }
-
-public:
-
-	bool IsValid() const override
-	{
-		return streamData != nullptr;
-	}
-
-	bool HasFastGetLength() const override
-	{
-		return true;
-	}
-
-	bool HasPinnedView() const override
-	{
-		return true;
-	}
-
-	const std::byte *GetRawData() const override
-	{
-		return streamData;
-	}
-
-	off_t GetLength() const override
-	{
-		return streamLength;
-	}
-
-	off_t Read(std::byte *dst, off_t pos, off_t count) const override
-	{
-		if(pos >= streamLength)
-		{
-			return 0;
-		}
-		off_t avail = std::min(streamLength - pos, count);
-		std::copy(streamData + pos, streamData + pos + avail, dst);
-		return avail;
-	}
-
-	off_t Read(off_t pos, mpt::byte_span dst) const override
-	{
-		return Read(dst.data(), pos, dst.size());
-	}
-
-	bool CanRead(off_t pos, off_t length) const override
-	{
-		if((pos == streamLength) && (length == 0))
-		{
-			return true;
-		}
-		if(pos >= streamLength)
-		{
-			return false;
-		}
-		return (length <= streamLength - pos);
-	}
-
-	off_t GetReadableLength(off_t pos, off_t length) const override
-	{
-		if(pos >= streamLength)
-		{
-			return 0;
-		}
-		return std::min(length, streamLength - pos);
-	}
-
-};
-
-
-
-OPENMPT_NAMESPACE_END

+ 0 - 556
libopenmpt.mod/openmpt/common/mptLibrary.cpp

@@ -1,556 +0,0 @@
-/*
- * mptLibrary.cpp
- * --------------
- * Purpose: Shared library handling.
- * Notes  : (currently none)
- * Authors: OpenMPT Devs
- * The OpenMPT source code is released under the BSD license. Read LICENSE for more details.
- */
-
-
-#include "stdafx.h"
-#include "mptLibrary.h"
-
-#if defined(MPT_ENABLE_DYNBIND)
-#if MPT_OS_WINDOWS
-#include <windows.h>
-#elif MPT_OS_ANDROID
-#include <dlfcn.h>
-#elif defined(MPT_WITH_LTDL)
-#include <ltdl.h>
-#elif defined(MPT_WITH_DL)
-#include <dlfcn.h>
-#endif
-#endif
-
-
-OPENMPT_NAMESPACE_BEGIN
-
-
-#if defined(MPT_ENABLE_DYNBIND)
-
-
-namespace mpt
-{
-
-
-#if MPT_OS_WINDOWS
-
-
-// KB2533623 / Win8
-#ifndef LOAD_LIBRARY_SEARCH_DEFAULT_DIRS
-#define LOAD_LIBRARY_SEARCH_DEFAULT_DIRS    0x00001000
-#endif
-#ifndef LOAD_LIBRARY_SEARCH_APPLICATION_DIR
-#define LOAD_LIBRARY_SEARCH_APPLICATION_DIR 0x00000200
-#endif
-#ifndef LOAD_LIBRARY_SEARCH_SYSTEM32
-#define LOAD_LIBRARY_SEARCH_SYSTEM32        0x00000800
-#endif
-#ifndef LOAD_LIBRARY_SEARCH_DLL_LOAD_DIR
-#define LOAD_LIBRARY_SEARCH_DLL_LOAD_DIR    0x00000100
-#endif
-
-
-class LibraryHandle
-{
-
-private:
-
-	HMODULE hModule;
-
-public:
-
-	LibraryHandle(const mpt::LibraryPath &path)
-		: hModule(NULL)
-	{
-
-#if MPT_OS_WINDOWS_WINRT
-
-#if (_WIN32_WINNT < 0x0602)
-		(void)path;
-		hModule = NULL; // unsupported
-#else
-		switch(path.GetSearchPath())
-		{
-			case mpt::LibrarySearchPathDefault:
-				hModule = LoadPackagedLibrary(path.GetFileName().AsNative().c_str(), 0);
-				break;
-			case mpt::LibrarySearchPathApplication:
-				hModule = LoadPackagedLibrary(path.GetFileName().AsNative().c_str(), 0);
-				break;
-			case mpt::LibrarySearchPathSystem:
-				hModule = NULL; // Only application packaged libraries can be loaded dynamically in WinRT
-				break;
-			case mpt::LibrarySearchPathFullPath:
-				hModule = NULL; // Absolute path is not supported in WinRT
-				break;
-			case mpt::LibrarySearchPathInvalid:
-				MPT_ASSERT_NOTREACHED();
-				break;
-		}
-#endif
-
-#else // !MPT_OS_WINDOWS_WINRT
-
-		mpt::Windows::Version WindowsVersion = mpt::Windows::Version::Current();
-
-		// Check for KB2533623:
-		bool hasKB2533623 = false;
-		if(WindowsVersion.IsAtLeast(mpt::Windows::Version::Win8))
-		{
-			hasKB2533623 = true;
-		} else
-		{
-			HMODULE hKernel32DLL = LoadLibraryW(L"kernel32.dll");
-			if(hKernel32DLL)
-			{
-				if(::GetProcAddress(hKernel32DLL, "SetDefaultDllDirectories") != nullptr)
-				{
-					hasKB2533623 = true;
-				}
-				FreeLibrary(hKernel32DLL);
-				hKernel32DLL = NULL;
-			}
-		}
-
-		if(hasKB2533623)
-		{
-			switch(path.GetSearchPath())
-			{
-				case mpt::LibrarySearchPathDefault:
-					hModule = LoadLibraryEx(path.GetFileName().AsNative().c_str(), NULL, LOAD_LIBRARY_SEARCH_DEFAULT_DIRS);
-					break;
-				case mpt::LibrarySearchPathSystem:
-					hModule = LoadLibraryEx(path.GetFileName().AsNative().c_str(), NULL, LOAD_LIBRARY_SEARCH_SYSTEM32);
-					break;
-#if defined(MODPLUG_TRACKER)
-					// Using restricted search paths applies to potential DLL dependencies
-					// recursively.
-					// This fails loading for e.g. Codec or Plugin DLLs in application
-					// directory if they depend on the MSVC C or C++ runtime (which is
-					// located in the system directory).
-					// Just rely on the default search path here.
-				case mpt::LibrarySearchPathApplication:
-					{
-						const mpt::PathString dllPath = mpt::GetExecutablePath();
-						if(!dllPath.empty() && mpt::PathIsAbsolute(dllPath) && dllPath.IsDirectory())
-						{
-							hModule = LoadLibrary((dllPath + path.GetFileName()).AsNative().c_str());
-						}
-					}
-					break;
-				case mpt::LibrarySearchPathFullPath:
-					hModule = LoadLibrary(path.GetFileName().AsNative().c_str());
-					break;
-#else
-					// For libopenmpt, do the safe thing.
-				case mpt::LibrarySearchPathApplication:
-					hModule = LoadLibraryEx(path.GetFileName().AsNative().c_str(), NULL, LOAD_LIBRARY_SEARCH_APPLICATION_DIR);
-					break;
-				case mpt::LibrarySearchPathFullPath:
-					hModule = LoadLibraryEx(path.GetFileName().AsNative().c_str(), NULL, LOAD_LIBRARY_SEARCH_DLL_LOAD_DIR);
-					break;
-#endif
-				case mpt::LibrarySearchPathInvalid:
-					MPT_ASSERT_NOTREACHED();
-					break;
-			}
-		} else
-		{
-			switch(path.GetSearchPath())
-			{
-				case mpt::LibrarySearchPathDefault:
-					hModule = LoadLibrary(path.GetFileName().AsNative().c_str());
-					break;
-				case mpt::LibrarySearchPathApplication:
-					{
-						const mpt::PathString dllPath = mpt::GetExecutablePath();
-						if(!dllPath.empty() && mpt::PathIsAbsolute(dllPath) && dllPath.IsDirectory())
-						{
-							hModule = LoadLibrary((dllPath + path.GetFileName()).AsNative().c_str());
-						}
-					}
-					break;
-				case mpt::LibrarySearchPathSystem:
-					{
-						const mpt::PathString dllPath = mpt::GetSystemPath();
-						if(!dllPath.empty() && mpt::PathIsAbsolute(dllPath) && dllPath.IsDirectory())
-						{
-							hModule = LoadLibrary((dllPath + path.GetFileName()).AsNative().c_str());
-						}
-					}
-					break;
-				case mpt::LibrarySearchPathFullPath:
-					hModule = LoadLibrary(path.GetFileName().AsNative().c_str());
-					break;
-				case mpt::LibrarySearchPathInvalid:
-					MPT_ASSERT_NOTREACHED();
-					break;
-			}
-		}
-
-#endif // MPT_OS_WINDOWS_WINRT
-
-	}
-
-	~LibraryHandle()
-	{
-		if(IsValid())
-		{
-			FreeLibrary(hModule);
-		}
-		hModule = NULL;
-	}
-
-public:
-
-	bool IsValid() const
-	{
-		return (hModule != NULL);
-	}
-
-	FuncPtr GetProcAddress(const std::string &symbol) const
-	{
-		if(!IsValid())
-		{
-			return nullptr;
-		}
-		return reinterpret_cast<FuncPtr>(::GetProcAddress(hModule, symbol.c_str()));
-	}
-
-};
-
-
-#elif MPT_OS_ANDROID
-
-
-// Fake implementation.
-// Load shared objects from the JAVA side of things.
-class LibraryHandle
-{
-
-public:
-
-	LibraryHandle(const mpt::LibraryPath &path)
-	{
-		return;
-	}
-
-	~LibraryHandle()
-	{
-		return;
-	}
-
-public:
-
-	bool IsValid() const
-	{
-		return true;
-	}
-
-	FuncPtr GetProcAddress(const std::string &symbol) const
-	{
-		if(!IsValid())
-		{
-			return nullptr;
-		}
-		return reinterpret_cast<FuncPtr>(dlsym(0, symbol.c_str()));
-	}
-
-};
-
-
-
-#elif defined(MPT_WITH_LTDL)
-
-
-class LibraryHandle
-{
-
-private:
-
-	bool inited;
-	lt_dlhandle handle;
-
-public:
-
-	LibraryHandle(const mpt::LibraryPath &path)
-		: inited(false)
-		, handle(0)
-	{
-		if(lt_dlinit() != 0)
-		{
-			return;
-		}
-		inited = true;
-		handle = lt_dlopenext(path.GetFileName().AsNative().c_str());
-	}
-
-	~LibraryHandle()
-	{
-		if(IsValid())
-		{
-			lt_dlclose(handle);
-		}
-		handle = 0;
-		if(inited)
-		{
-			lt_dlexit();
-			inited = false;
-		}
-	}
-
-public:
-
-	bool IsValid() const
-	{
-		return handle != 0;
-	}
-
-	FuncPtr GetProcAddress(const std::string &symbol) const
-	{
-		if(!IsValid())
-		{
-			return nullptr;
-		}
-		return reinterpret_cast<FuncPtr>(lt_dlsym(handle, symbol.c_str()));
-	}
-
-};
-
-
-#elif defined(MPT_WITH_DL)
-
-
-class LibraryHandle
-{
-
-private:
-
-	void* handle;
-
-public:
-
-	LibraryHandle(const mpt::LibraryPath &path)
-		: handle(NULL)
-	{
-		handle = dlopen(path.GetFileName().AsNative().c_str(), RTLD_NOW);
-	}
-
-	~LibraryHandle()
-	{
-		if(IsValid())
-		{
-			dlclose(handle);
-		}
-		handle = NULL;
-	}
-
-public:
-
-	bool IsValid() const
-	{
-		return handle != NULL;
-	}
-
-	FuncPtr GetProcAddress(const std::string &symbol) const
-	{
-		if(!IsValid())
-		{
-			return NULL;
-		}
-		return reinterpret_cast<FuncPtr>(dlsym(handle, symbol.c_str()));
-	}
-
-};
-
-
-#else // MPT_OS
-
-
-// dummy implementation
-
-class LibraryHandle
-{
-public:
-
-	LibraryHandle(const mpt::LibraryPath &path)
-	{
-		MPT_UNREFERENCED_PARAMETER(path);
-		return;
-	}
-
-	~LibraryHandle()
-	{
-		return;
-	}
-
-public:
-
-	bool IsValid() const
-	{
-		return false;
-	}
-
-	FuncPtr GetProcAddress(const std::string &symbol) const
-	{
-		MPT_UNREFERENCED_PARAMETER(symbol);
-		if(!IsValid())
-		{
-			return nullptr;
-		}
-		return nullptr;
-	}
-
-};
-
-
-#endif // MPT_OS
-
-
-LibraryPath::LibraryPath(mpt::LibrarySearchPath searchPath, class mpt::PathString const &fileName)
-	: searchPath(searchPath)
-	, fileName(fileName)
-{
-	return;
-}
-
-
-mpt::LibrarySearchPath LibraryPath::GetSearchPath() const
-{
-	return searchPath;
-}
-
-
-mpt::PathString LibraryPath::GetFileName() const
-{
-	return fileName;
-}
-
-
-mpt::PathString LibraryPath::GetDefaultPrefix()
-{
-	#if MPT_OS_WINDOWS
-		return P_("");
-	#elif MPT_OS_ANDROID
-		return P_("lib");
-	#elif defined(MPT_WITH_LTDL)
-		return P_("lib");
-	#elif defined(MPT_WITH_DL)
-		return P_("lib");
-	#else
-		return P_("lib");
-	#endif
-}
-
-
-mpt::PathString LibraryPath::GetDefaultSuffix()
-{
-	#if MPT_OS_WINDOWS
-		return P_(".dll");
-	#elif MPT_OS_ANDROID
-		return P_(".so");
-	#elif defined(MPT_WITH_LTDL)
-		return P_("");  // handled by libltdl
-	#elif defined(MPT_WITH_DL)
-		return P_(".so");
-	#else
-		return mpt::PathString();
-	#endif
-}
-
-
-LibraryPath LibraryPath::App(const mpt::PathString &basename)
-{
-	return LibraryPath(mpt::LibrarySearchPathApplication, GetDefaultPrefix() + basename + GetDefaultSuffix());
-}
-
-
-LibraryPath LibraryPath::AppFullName(const mpt::PathString &fullname)
-{
-	return LibraryPath(mpt::LibrarySearchPathApplication, fullname + GetDefaultSuffix());
-}
-
-
-#if defined(MODPLUG_TRACKER) && !defined(MPT_BUILD_WINESUPPORT)
-
-LibraryPath LibraryPath::AppDataFullName(const mpt::PathString &fullname, const mpt::PathString &appdata)
-{
-	if(appdata.empty())
-	{
-		return LibraryPath(mpt::LibrarySearchPathInvalid, P_(""));
-	}
-	return LibraryPath(mpt::LibrarySearchPathFullPath, appdata.WithTrailingSlash() + fullname + GetDefaultSuffix());
-}
-
-#endif // MODPLUG_TRACKER && !MPT_BUILD_WINESUPPORT
-
-
-LibraryPath LibraryPath::System(const mpt::PathString &basename)
-{
-	return LibraryPath(mpt::LibrarySearchPathSystem, GetDefaultPrefix() + basename + GetDefaultSuffix());
-}
-
-
-LibraryPath LibraryPath::FullPath(const mpt::PathString &path)
-{
-	return LibraryPath(mpt::LibrarySearchPathFullPath, path);
-}
-
-
-Library::Library()
-{
-	return;
-}
-
-
-Library::Library(const mpt::LibraryPath &path)
-{
-	if(path.GetSearchPath() == mpt::LibrarySearchPathInvalid)
-	{
-		return;
-	}
-	if(path.GetFileName().empty())
-	{
-		return;
-	}
-	m_Handle = std::make_shared<LibraryHandle>(path);
-}
-
-
-void Library::Unload()
-{
-	*this = mpt::Library();
-}
-
-
-bool Library::IsValid() const
-{
-	return m_Handle && m_Handle->IsValid();
-}
-
-
-FuncPtr Library::GetProcAddress(const std::string &symbol) const
-{
-	if(!IsValid())
-	{
-		return nullptr;
-	}
-	return m_Handle->GetProcAddress(symbol);
-}
-
-
-} // namespace mpt
-
-
-#else // !MPT_ENABLE_DYNBIND
-
-
-MPT_MSVC_WORKAROUND_LNK4221(mptLibrary)
-
-
-#endif // MPT_ENABLE_DYNBIND
-
-
-OPENMPT_NAMESPACE_END

+ 0 - 120
libopenmpt.mod/openmpt/common/mptLibrary.h

@@ -1,120 +0,0 @@
-/*
- * mptLibrary.h
- * ------------
- * Purpose: Shared library handling.
- * Notes  : (currently none)
- * Authors: OpenMPT Devs
- * The OpenMPT source code is released under the BSD license. Read LICENSE for more details.
- */
-
-
-#pragma once
-
-#include "BuildSettings.h"
-
-
-OPENMPT_NAMESPACE_BEGIN
-
-
-#if defined(MPT_ENABLE_DYNBIND)
-
-namespace mpt
-{
-
-
-typedef void* (*FuncPtr)(); // pointer to function returning void*
-
-class LibraryHandle;
-
-enum LibrarySearchPath
-{
-	LibrarySearchPathInvalid,
-	LibrarySearchPathDefault,
-	LibrarySearchPathApplication,
-	LibrarySearchPathSystem,
-	LibrarySearchPathFullPath,
-};
-
-class LibraryPath
-{
-
-private:
-	
-	mpt::LibrarySearchPath searchPath;
-	mpt::PathString fileName;
-
-private:
-
-	LibraryPath(mpt::LibrarySearchPath searchPath, const mpt::PathString &fileName);
-
-public:
-
-	mpt::LibrarySearchPath GetSearchPath() const;
-
-	mpt::PathString GetFileName() const;
-
-public:
-	
-	// "lib" on Unix-like systems, "" on Windows
-	static mpt::PathString GetDefaultPrefix();
-
-	// ".so" or ".dylib" or ".dll"
-	static mpt::PathString GetDefaultSuffix();
-
-	// Returns the library path in the application directory, with os-specific prefix and suffix added to basename.
-	// e.g.: basename = "unmo3" --> "libunmo3.so" / "apppath/unmo3.dll"
-	static LibraryPath App(const mpt::PathString &basename);
-
-	// Returns the library path in the application directory, with os-specific suffix added to fullname.
-	// e.g.: fullname = "libunmo3" --> "libunmo3.so" / "apppath/libunmo3.dll" 
-	static LibraryPath AppFullName(const mpt::PathString &fullname);
-
-#if defined(MODPLUG_TRACKER) && !defined(MPT_BUILD_WINESUPPORT)
-
-	// Returns the library path in the application data directory, with os-specific suffix added to fullname.
-	// e.g.: fullname = "libunmo3" --> "libunmo3.so" / "appdata/libunmo3.dll" (appdata == C:\Users\SOMEUSER\AppData\OpenMPT\Components\)
-	static LibraryPath AppDataFullName(const mpt::PathString &fullname, const mpt::PathString &appdata);
-
-#endif // MODPLUG_TRACKER && !MPT_BUILD_WINESUPPORT
-
-	// Returns a system library name with os-specific prefix and suffix added to basename, but without any full path in order to be searched in the default search path.
-	// e.g.: basename = "unmo3" --> "libunmo3.so" / "unmo3.dll"
-	static LibraryPath System(const mpt::PathString &basename);
-
-	// Returns a system library name with os-specific suffix added to path.
-	// e.g.: path = "somepath/foo" --> "somepath/foo.so" / "somepath/foo.dll"
-	static LibraryPath FullPath(const mpt::PathString &path);
-
-};
-
-class Library
-{
-protected:
-	std::shared_ptr<LibraryHandle> m_Handle;
-public:
-	Library();
-	Library(const mpt::LibraryPath &path);
-public:
-	void Unload();
-	bool IsValid() const;
-	FuncPtr GetProcAddress(const std::string &symbol) const;
-	template <typename Tfunc>
-	bool Bind(Tfunc * & f, const std::string &symbol) const
-	{
-		#if !(MPT_OS_WINDOWS && MPT_COMPILER_GCC)
-			// MinGW64 std::is_function is always false for non __cdecl functions.
-			// See https://connect.microsoft.com/VisualStudio/feedback/details/774720/stl-is-function-bug .
-			static_assert(std::is_function<Tfunc>::value);
-		#endif
-		const FuncPtr addr = GetProcAddress(symbol);
-		f = reinterpret_cast<Tfunc*>(addr);
-		return (addr != nullptr);
-	}
-};
-
-} // namespace mpt
-
-#endif // MPT_ENABLE_DYNBIND
-
-
-OPENMPT_NAMESPACE_END

+ 0 - 334
libopenmpt.mod/openmpt/common/mptMemory.h

@@ -1,334 +0,0 @@
-/*
- * mptMemory.h
- * -----------
- * Purpose: Raw memory manipulation
- * Notes  : (currently none)
- * Authors: OpenMPT Devs
- * The OpenMPT source code is released under the BSD license. Read LICENSE for more details.
- */
-
-
-#pragma once
-
-#include "BuildSettings.h"
-
-
-#include "mptAssert.h"
-#include "mptBaseTypes.h"
-#include "mptSpan.h"
-
-#if MPT_CXX_AT_LEAST(20)
-#include <bit>
-#endif
-#include <utility>
-#include <type_traits>
-
-#include <cstring>
-
-#include <string.h>
-
-
-
-OPENMPT_NAMESPACE_BEGIN
-
-
-
-namespace mpt {
-
-
-
-typedef mpt::span<std::byte> byte_span;
-typedef mpt::span<const std::byte> const_byte_span;
-
-
-
-// Tell which types are safe for mpt::byte_cast.
-// signed char is actually not allowed to alias into an object representation,
-// which means that, if the actual type is not itself signed char but char or
-// unsigned char instead, dereferencing the signed char pointer is undefined
-// behaviour.
-template <typename T> struct is_byte_castable : public std::false_type { };
-template <> struct is_byte_castable<char>                : public std::true_type { };
-template <> struct is_byte_castable<unsigned char>       : public std::true_type { };
-template <> struct is_byte_castable<std::byte>           : public std::true_type { };
-template <> struct is_byte_castable<const char>          : public std::true_type { };
-template <> struct is_byte_castable<const unsigned char> : public std::true_type { };
-template <> struct is_byte_castable<const std::byte>     : public std::true_type { };
-
-
-template <typename T> struct is_byte        : public std::false_type { };
-template <> struct is_byte<std::byte>       : public std::true_type  { };
-template <> struct is_byte<const std::byte> : public std::true_type  { };
-
-
-// Tell which types are safe to binary write into files.
-// By default, no types are safe.
-// When a safe type gets defined,
-// also specialize this template so that IO functions will work.
-template <typename T> struct is_binary_safe : public std::false_type { }; 
-
-// Specialization for byte types.
-template <> struct is_binary_safe<char>      : public std::true_type { };
-template <> struct is_binary_safe<uint8>     : public std::true_type { };
-template <> struct is_binary_safe<int8>      : public std::true_type { };
-template <> struct is_binary_safe<std::byte> : public std::true_type { };
-
-// Generic Specialization for arrays.
-template <typename T, std::size_t N> struct is_binary_safe<T[N]> : public is_binary_safe<T> { };
-template <typename T, std::size_t N> struct is_binary_safe<const T[N]> : public is_binary_safe<T> { };
-template <typename T, std::size_t N> struct is_binary_safe<std::array<T, N>> : public is_binary_safe<T> { };
-template <typename T, std::size_t N> struct is_binary_safe<const std::array<T, N>> : public is_binary_safe<T> { };
-
-
-} // namespace mpt
-
-#define MPT_BINARY_STRUCT(type, size) \
-	static_assert(sizeof( type ) == (size) ); \
-	static_assert(alignof( type ) == 1); \
-	static_assert(std::is_standard_layout< type >::value); \
-	namespace mpt { \
-		template <> struct is_binary_safe< type > : public std::true_type { }; \
-	} \
-/**/
-
-
-
-template <typename T>
-struct value_initializer
-{
-	inline void operator () (T & x)
-	{
-		x = T();
-	}
-};
-
-template <typename T, std::size_t N>
-struct value_initializer<T[N]>
-{
-	inline void operator () (T (& a)[N])
-	{
-		for(auto & e : a)
-		{
-			value_initializer<T>()(e);
-		}
-	}
-};
-
-template <typename T>
-inline void Clear(T & x)
-{
-	static_assert(!std::is_pointer<T>::value);
-	value_initializer<T>()(x);
-}
-
-
-// Memset given object to zero.
-template <class T>
-inline void MemsetZero(T &a)
-{
-	static_assert(std::is_pointer<T>::value == false, "Won't memset pointers.");
-	static_assert(std::is_standard_layout<T>::value);
-	static_assert((std::is_trivially_default_constructible<T>::value && std::is_trivially_copyable<T>::value) || mpt::is_binary_safe<T>::value);
-	std::memset(&a, 0, sizeof(T));
-}
-
-
-
-namespace mpt {
-
-
-
-#if MPT_CXX_AT_LEAST(20)
-using std::bit_cast;
-#else
-// C++2a compatible bit_cast.
-// Not implementing constexpr because this is not easily possible pre C++20.
-template <typename Tdst, typename Tsrc>
-MPT_FORCEINLINE typename std::enable_if<(sizeof(Tdst) == sizeof(Tsrc)) && std::is_trivially_copyable<Tsrc>::value && std::is_trivially_copyable<Tdst>::value, Tdst>::type bit_cast(const Tsrc & src) noexcept
-{
-	Tdst dst{};
-	std::memcpy(&dst, &src, sizeof(Tdst));
-	return dst;
-}
-#endif
-
-
-
-template <typename Tdst, typename Tsrc>
-struct byte_cast_impl
-{
-	inline Tdst operator () (Tsrc src) const
-	{
-		static_assert(sizeof(Tsrc) == sizeof(std::byte));
-		static_assert(sizeof(Tdst) == sizeof(std::byte));
-		// not checking is_byte_castable here because we are actually
-		// doing a static_cast and converting the value
-		static_assert(std::is_integral<Tsrc>::value || mpt::is_byte<Tsrc>::value);
-		static_assert(std::is_integral<Tdst>::value || mpt::is_byte<Tdst>::value);
-		return static_cast<Tdst>(src);
-	}
-};
-template <typename Tdst, typename Tsrc>
-struct byte_cast_impl<mpt::span<Tdst>, mpt::span<Tsrc> >
-{
-	inline mpt::span<Tdst> operator () (mpt::span<Tsrc> src) const
-	{
-		static_assert(sizeof(Tsrc) == sizeof(std::byte));
-		static_assert(sizeof(Tdst) == sizeof(std::byte));
-		static_assert(mpt::is_byte_castable<Tsrc>::value);
-		static_assert(mpt::is_byte_castable<Tdst>::value);
-		static_assert(std::is_integral<Tsrc>::value || mpt::is_byte<Tsrc>::value);
-		static_assert(std::is_integral<Tdst>::value || mpt::is_byte<Tdst>::value);
-		return mpt::as_span(mpt::byte_cast_impl<Tdst*, Tsrc*>()(src.begin()), mpt::byte_cast_impl<Tdst*, Tsrc*>()(src.end()));
-	}
-};
-template <typename Tdst, typename Tsrc>
-struct byte_cast_impl<Tdst*, Tsrc*>
-{
-	inline Tdst* operator () (Tsrc* src) const
-	{
-		static_assert(sizeof(Tsrc) == sizeof(std::byte));
-		static_assert(sizeof(Tdst) == sizeof(std::byte));
-		static_assert(mpt::is_byte_castable<Tsrc>::value);
-		static_assert(mpt::is_byte_castable<Tdst>::value);
-		static_assert(std::is_integral<Tsrc>::value || mpt::is_byte<Tsrc>::value);
-		static_assert(std::is_integral<Tdst>::value || mpt::is_byte<Tdst>::value);
-		return reinterpret_cast<Tdst*>(src);
-	}
-};
-
-template <typename Tdst, typename Tsrc>
-struct void_cast_impl;
-
-template <typename Tdst>
-struct void_cast_impl<Tdst*, void*>
-{
-	inline Tdst* operator () (void* src) const
-	{
-		static_assert(sizeof(Tdst) == sizeof(std::byte));
-		static_assert(mpt::is_byte_castable<Tdst>::value);
-		static_assert(std::is_integral<Tdst>::value || mpt::is_byte<Tdst>::value);
-		return reinterpret_cast<Tdst*>(src);
-	}
-};
-template <typename Tdst>
-struct void_cast_impl<Tdst*, const void*>
-{
-	inline Tdst* operator () (const void* src) const
-	{
-		static_assert(sizeof(Tdst) == sizeof(std::byte));
-		static_assert(mpt::is_byte_castable<Tdst>::value);
-		static_assert(std::is_integral<Tdst>::value || mpt::is_byte<Tdst>::value);
-		return reinterpret_cast<Tdst*>(src);
-	}
-};
-template <typename Tsrc>
-struct void_cast_impl<void*, Tsrc*>
-{
-	inline void* operator () (Tsrc* src) const
-	{
-		static_assert(sizeof(Tsrc) == sizeof(std::byte));
-		static_assert(mpt::is_byte_castable<Tsrc>::value);
-		static_assert(std::is_integral<Tsrc>::value || mpt::is_byte<Tsrc>::value);
-		return reinterpret_cast<void*>(src);
-	}
-};
-template <typename Tsrc>
-struct void_cast_impl<const void*, Tsrc*>
-{
-	inline const void* operator () (Tsrc* src) const
-	{
-		static_assert(sizeof(Tsrc) == sizeof(std::byte));
-		static_assert(mpt::is_byte_castable<Tsrc>::value);
-		static_assert(std::is_integral<Tsrc>::value || mpt::is_byte<Tsrc>::value);
-		return reinterpret_cast<const void*>(src);
-	}
-};
-
-// casts between different byte (char) types or pointers to these types
-template <typename Tdst, typename Tsrc>
-inline Tdst byte_cast(Tsrc src)
-{
-	return byte_cast_impl<Tdst, Tsrc>()(src);
-}
-
-// casts between pointers to void and pointers to byte
-template <typename Tdst, typename Tsrc>
-inline Tdst void_cast(Tsrc src)
-{
-	return void_cast_impl<Tdst, Tsrc>()(src);
-}
-
-
-
-template <typename T>
-MPT_CONSTEXPR14_FUN std::byte as_byte(T src) noexcept
-{
-	static_assert(std::is_integral<T>::value);
-	return static_cast<std::byte>(static_cast<uint8>(src));
-}
-
-
-
-template <typename T>
-struct GetRawBytesFunctor
-{
-	inline mpt::const_byte_span operator () (const T & v) const
-	{
-		static_assert(mpt::is_binary_safe<typename std::remove_const<T>::type>::value);
-		return mpt::as_span(reinterpret_cast<const std::byte *>(&v), sizeof(T));
-	}
-	inline mpt::byte_span operator () (T & v) const
-	{
-		static_assert(mpt::is_binary_safe<typename std::remove_const<T>::type>::value);
-		return mpt::as_span(reinterpret_cast<std::byte *>(&v), sizeof(T));
-	}
-};
-
-template <typename T, std::size_t N>
-struct GetRawBytesFunctor<T[N]>
-{
-	inline mpt::const_byte_span operator () (const T (&v)[N]) const
-	{
-		static_assert(mpt::is_binary_safe<typename std::remove_const<T>::type>::value);
-		return mpt::as_span(reinterpret_cast<const std::byte *>(v), N * sizeof(T));
-	}
-	inline mpt::byte_span operator () (T (&v)[N]) const
-	{
-		static_assert(mpt::is_binary_safe<typename std::remove_const<T>::type>::value);
-		return mpt::as_span(reinterpret_cast<std::byte *>(v), N * sizeof(T));
-	}
-};
-
-template <typename T, std::size_t N>
-struct GetRawBytesFunctor<const T[N]>
-{
-	inline mpt::const_byte_span operator () (const T (&v)[N]) const
-	{
-		static_assert(mpt::is_binary_safe<typename std::remove_const<T>::type>::value);
-		return mpt::as_span(reinterpret_cast<const std::byte *>(v), N * sizeof(T));
-	}
-};
-
-// In order to be able to partially specialize it,
-// as_raw_memory is implemented via a class template.
-// Do not overload or specialize as_raw_memory directly.
-// Using a wrapper (by default just around a cast to const std::byte *),
-// allows for implementing raw memory access
-// via on-demand generating a cached serialized representation.
-template <typename T> inline mpt::const_byte_span as_raw_memory(const T & v)
-{
-	return mpt::GetRawBytesFunctor<T>()(v);
-}
-template <typename T> inline mpt::byte_span as_raw_memory(T & v)
-{
-	return mpt::GetRawBytesFunctor<T>()(v);
-}
-
-
-
-} // namespace mpt
-
-
-
-OPENMPT_NAMESPACE_END

+ 0 - 239
libopenmpt.mod/openmpt/common/mptMutex.h

@@ -1,239 +0,0 @@
-/*
- * mptMutex.h
- * ----------
- * Purpose: Partially implement c++ mutexes as far as openmpt needs them. Can eventually go away when we only support c++11 compilers some time.
- * Notes  : (currently none)
- * Authors: OpenMPT Devs
- * The OpenMPT source code is released under the BSD license. Read LICENSE for more details.
- */
-
-#pragma once
-
-#include "BuildSettings.h"
-
-#include <vector> // some C++ header in order to have the C++ standard library version information available
-
-#if !MPT_PLATFORM_MULTITHREADED
-#define MPT_MUTEX_STD     0
-#define MPT_MUTEX_PTHREAD 0
-#define MPT_MUTEX_WIN32   0
-#elif MPT_OS_EMSCRIPTEN
-#define MPT_MUTEX_STD     0
-#define MPT_MUTEX_PTHREAD 0
-#define MPT_MUTEX_WIN32   0
-#elif MPT_COMPILER_GENERIC
-#define MPT_MUTEX_STD     1
-#define MPT_MUTEX_PTHREAD 0
-#define MPT_MUTEX_WIN32   0
-#elif (defined(__MINGW32__) || defined(__MINGW64__)) && !defined(_GLIBCXX_HAS_GTHREADS) && defined(MPT_WITH_MINGWSTDTHREADS)
-#define MPT_MUTEX_STD     1
-#define MPT_MUTEX_PTHREAD 0
-#define MPT_MUTEX_WIN32   0
-#elif (defined(__MINGW32__) || defined(__MINGW64__)) && !defined(_GLIBCXX_HAS_GTHREADS)
-#define MPT_MUTEX_STD     0
-#define MPT_MUTEX_PTHREAD 0
-#define MPT_MUTEX_WIN32   1
-#elif MPT_COMPILER_MSVC
-#define MPT_MUTEX_STD     1
-#define MPT_MUTEX_PTHREAD 0
-#define MPT_MUTEX_WIN32   0
-#elif MPT_COMPILER_GCC
-#define MPT_MUTEX_STD     1
-#define MPT_MUTEX_PTHREAD 0
-#define MPT_MUTEX_WIN32   0
-#elif MPT_COMPILER_CLANG
-#define MPT_MUTEX_STD     1
-#define MPT_MUTEX_PTHREAD 0
-#define MPT_MUTEX_WIN32   0
-#elif MPT_OS_WINDOWS
-#define MPT_MUTEX_STD     0
-#define MPT_MUTEX_PTHREAD 0
-#define MPT_MUTEX_WIN32   1
-#else
-#define MPT_MUTEX_STD     0
-#define MPT_MUTEX_PTHREAD 1
-#define MPT_MUTEX_WIN32   0
-#endif
-
-#if !MPT_MUTEX_STD && !MPT_MUTEX_PTHREAD && !MPT_MUTEX_WIN32
-#define MPT_MUTEX_NONE 1
-#else
-#define MPT_MUTEX_NONE 0
-#endif
-
-#if defined(MODPLUG_TRACKER) && MPT_MUTEX_NONE
-#error "OpenMPT requires mutexes."
-#endif
-
-#if MPT_MUTEX_STD
-#if (defined(__MINGW32__) || defined(__MINGW64__)) && !defined(_GLIBCXX_HAS_GTHREADS) && defined(MPT_WITH_MINGWSTDTHREADS)
-#include <mingw.mutex.h>
-#else
-#include <mutex>
-#endif
-#elif MPT_MUTEX_WIN32
-#include <windows.h>
-#elif MPT_MUTEX_PTHREAD
-#include <pthread.h>
-#endif // MPT_MUTEX
-
-OPENMPT_NAMESPACE_BEGIN
-
-namespace mpt {
-
-#if MPT_MUTEX_STD
-
-typedef std::mutex mutex;
-typedef std::recursive_mutex recursive_mutex;
-
-#elif MPT_MUTEX_WIN32
-
-// compatible with c++11 std::mutex, can eventually be replaced without touching any usage site
-class mutex {
-private:
-	CRITICAL_SECTION impl;
-public:
-	mutex() { InitializeCriticalSection(&impl); }
-	~mutex() { DeleteCriticalSection(&impl); }
-	void lock() { EnterCriticalSection(&impl); }
-	bool try_lock() { return TryEnterCriticalSection(&impl) ? true : false; }
-	void unlock() { LeaveCriticalSection(&impl); }
-};
-
-// compatible with c++11 std::recursive_mutex, can eventually be replaced without touching any usage site
-class recursive_mutex {
-private:
-	CRITICAL_SECTION impl;
-public:
-	recursive_mutex() { InitializeCriticalSection(&impl); }
-	~recursive_mutex() { DeleteCriticalSection(&impl); }
-	void lock() { EnterCriticalSection(&impl); }
-	bool try_lock() { return TryEnterCriticalSection(&impl) ? true : false; }
-	void unlock() { LeaveCriticalSection(&impl); }
-};
-
-#elif MPT_MUTEX_PTHREAD
-
-class mutex {
-private:
-	pthread_mutex_t hLock;
-public:
-	mutex()
-	{
-		pthread_mutexattr_t attr;
-		pthread_mutexattr_init(&attr);
-		pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_NORMAL);
-		pthread_mutex_init(&hLock, &attr);
-		pthread_mutexattr_destroy(&attr);
-	}
-	~mutex() { pthread_mutex_destroy(&hLock); }
-	void lock() { pthread_mutex_lock(&hLock); }
-	bool try_lock() { return (pthread_mutex_trylock(&hLock) == 0); }
-	void unlock() { pthread_mutex_unlock(&hLock); }
-};
-
-class recursive_mutex {
-private:
-	pthread_mutex_t hLock;
-public:
-	recursive_mutex()
-	{
-		pthread_mutexattr_t attr;
-		pthread_mutexattr_init(&attr);
-		pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE);
-		pthread_mutex_init(&hLock, &attr);
-		pthread_mutexattr_destroy(&attr);
-	}
-	~recursive_mutex() { pthread_mutex_destroy(&hLock); }
-	void lock() { pthread_mutex_lock(&hLock); }
-	bool try_lock() { return (pthread_mutex_trylock(&hLock) == 0); }
-	void unlock() { pthread_mutex_unlock(&hLock); }
-};
-
-#else // MPT_MUTEX_NONE
-
-class mutex {
-public:
-	mutex() { }
-	~mutex() { }
-	void lock() { }
-	bool try_lock() { return true; }
-	void unlock() { }
-};
-
-class recursive_mutex {
-public:
-	recursive_mutex() { }
-	~recursive_mutex() { }
-	void lock() { }
-	bool try_lock() { return true; }
-	void unlock() { }
-};
-
-#endif // MPT_MUTEX
-
-#if MPT_MUTEX_STD
-
-#define MPT_LOCK_GUARD std::lock_guard
-
-#else // !MPT_MUTEX_STD
-
-// compatible with c++11 std::lock_guard, can eventually be replaced without touching any usage site
-template< typename mutex_type >
-class lock_guard {
-private:
-	mutex_type & mutex;
-public:
-	lock_guard( mutex_type & m ) : mutex(m) { mutex.lock(); }
-	~lock_guard() { mutex.unlock(); }
-};
-
-#define MPT_LOCK_GUARD mpt::lock_guard
-
-#endif // MPT_MUTEX_STD
-
-#ifdef MODPLUG_TRACKER
-
-class recursive_mutex_with_lock_count {
-private:
-	mpt::recursive_mutex mutex;
-	long lockCount;
-public:
-	recursive_mutex_with_lock_count()
-		: lockCount(0)
-	{
-		return;
-	}
-	~recursive_mutex_with_lock_count()
-	{
-		return;
-	}
-	void lock()
-	{
-		mutex.lock();
-		lockCount++;
-	}
-	void unlock()
-	{
-		lockCount--;
-		mutex.unlock();
-	}
-public:
-	bool IsLockedByCurrentThread() // DEBUGGING only
-	{
-		bool islocked = false;
-		if(mutex.try_lock())
-		{
-			islocked = (lockCount > 0);
-			mutex.unlock();
-		}
-		return islocked;
-	}
-};
-
-#endif // MODPLUG_TRACKER
-
-} // namespace mpt
-
-OPENMPT_NAMESPACE_END
-

+ 0 - 958
libopenmpt.mod/openmpt/common/mptOS.cpp

@@ -1,958 +0,0 @@
-/*
- * mptOS.cpp
- * ---------
- * Purpose: Operating system version information.
- * Notes  : (currently none)
- * Authors: OpenMPT Devs
- * The OpenMPT source code is released under the BSD license. Read LICENSE for more details.
- */
-
-
-#include "stdafx.h"
-#include "mptOS.h"
-
-#if MPT_OS_WINDOWS
-#include <windows.h>
-#endif
-
-#if defined(MODPLUG_TRACKER)
-#if !MPT_OS_WINDOWS
-#include <sys/utsname.h>
-#endif // !MPT_OS_WINDOWS
-#endif // MODPLUG_TRACKER
-
-
-OPENMPT_NAMESPACE_BEGIN
-
-
-#if defined(MODPLUG_TRACKER)
-
-namespace mpt
-{
-namespace OS
-{
-
-mpt::OS::Class GetClassFromSysname(mpt::ustring sysname)
-{
-	mpt::OS::Class result = mpt::OS::Class::Unknown;
-	if(sysname == U_(""))
-	{
-		result = mpt::OS::Class::Unknown;
-	} else if(sysname == U_("Windows") || sysname == U_("WindowsNT") || sysname == U_("Windows_NT"))
-	{
-		result = mpt::OS::Class::Windows;
-	} else if(sysname == U_("Linux"))
-	{
-		result = mpt::OS::Class::Linux;
-	} else if(sysname == U_("Darwin"))
-	{
-		result = mpt::OS::Class::Darwin;
-	} else if(sysname == U_("FreeBSD") || sysname == U_("DragonFly") || sysname == U_("NetBSD") || sysname == U_("OpenBSD") || sysname == U_("MidnightBSD"))
-	{
-		result = mpt::OS::Class::BSD;
-	} else if(sysname == U_("Haiku"))
-	{
-		result = mpt::OS::Class::Haiku;
-	} else if(sysname == U_("MS-DOS"))
-	{
-		result = mpt::OS::Class::DOS;
-	}
-	return result;
-}
-
-mpt::OS::Class GetClass()
-{
-	#if MPT_OS_WINDOWS
-		return mpt::OS::Class::Windows;
-	#else // !MPT_OS_WINDOWS
-		utsname uname_result;
-		if(uname(&uname_result) != 0)
-		{
-			return mpt::OS::Class::Unknown;
-		}
-		return mpt::OS::GetClassFromSysname(mpt::ToUnicode(mpt::Charset::ASCII, mpt::String::ReadAutoBuf(uname_result.sysname)));
-	#endif // MPT_OS_WINDOWS
-}
-
-}  // namespace OS
-}  // namespace mpt
-
-#endif // MODPLUG_TRACKER
-
-
-namespace mpt
-{
-namespace Windows
-{
-
-
-#if MPT_OS_WINDOWS
-
-
-static mpt::Windows::Version VersionFromNTDDI_VERSION() noexcept
-{
-	// Initialize to used SDK version
-	mpt::Windows::Version::System System =
-		#if NTDDI_VERSION >= 0x0A000000 // NTDDI_WIN10
-			mpt::Windows::Version::Win10
-		#elif NTDDI_VERSION >= 0x06030000 // NTDDI_WINBLUE
-			mpt::Windows::Version::Win81
-		#elif NTDDI_VERSION >= 0x06020000 // NTDDI_WIN8
-			mpt::Windows::Version::Win8
-		#elif NTDDI_VERSION >= 0x06010000 // NTDDI_WIN7
-			mpt::Windows::Version::Win7
-		#elif NTDDI_VERSION >= 0x06000000 // NTDDI_VISTA
-			mpt::Windows::Version::WinVista
-		#elif NTDDI_VERSION >= 0x05020000 // NTDDI_WS03
-			mpt::Windows::Version::WinXP64
-		#elif NTDDI_VERSION >= NTDDI_WINXP
-			mpt::Windows::Version::WinXP
-		#elif NTDDI_VERSION >= NTDDI_WIN2K
-			mpt::Windows::Version::Win2000
-		#else
-			mpt::Windows::Version::WinNT4
-		#endif
-		;
-	return mpt::Windows::Version(System, mpt::Windows::Version::ServicePack(((NTDDI_VERSION & 0xffffu) >> 8) & 0xffu, ((NTDDI_VERSION & 0xffffu) >> 0) & 0xffu), 0, 0);
-}
-
-
-static mpt::Windows::Version::System SystemVersionFrom_WIN32_WINNT() noexcept
-{
-	#if defined(_WIN32_WINNT)
-		return mpt::Windows::Version::System((static_cast<uint64>(_WIN32_WINNT) & 0xff00u) >> 8, (static_cast<uint64>(_WIN32_WINNT) & 0x00ffu) >> 0);
-	#else
-		return mpt::Windows::Version::System();
-	#endif
-}
-
-
-static mpt::Windows::Version GatherWindowsVersion() noexcept
-{
-#if MPT_OS_WINDOWS_WINRT
-	return VersionFromNTDDI_VERSION();
-#else // !MPT_OS_WINDOWS_WINRT
-	OSVERSIONINFOEXW versioninfoex;
-	MemsetZero(versioninfoex);
-	versioninfoex.dwOSVersionInfoSize = sizeof(versioninfoex);
-#if MPT_COMPILER_MSVC
-#pragma warning(push)
-#pragma warning(disable:4996) // 'GetVersionExW': was declared deprecated
-#endif // MPT_COMPILER_MSVC
-#if MPT_COMPILER_CLANG
-#pragma clang diagnostic push
-#pragma clang diagnostic ignored "-Wdeprecated-declarations"
-#endif // MPT_COMPILER_CLANG
-	if(GetVersionExW((LPOSVERSIONINFOW)&versioninfoex) == FALSE)
-	{
-		return VersionFromNTDDI_VERSION();
-	}
-#if MPT_COMPILER_MSVC
-#pragma warning(pop)
-#endif // MPT_COMPILER_MSVC
-#if MPT_COMPILER_CLANG
-#pragma clang diagnostic pop
-#endif // MPT_COMPILER_CLANG
-	if(versioninfoex.dwPlatformId != VER_PLATFORM_WIN32_NT)
-	{
-		return VersionFromNTDDI_VERSION();
-	}
-	DWORD dwProductType = 0;
-	#if (_WIN32_WINNT >= 0x0600) // _WIN32_WINNT_VISTA
-		dwProductType = PRODUCT_UNDEFINED;
-		if(GetProductInfo(versioninfoex.dwMajorVersion, versioninfoex.dwMinorVersion, versioninfoex.wServicePackMajor, versioninfoex.wServicePackMinor, &dwProductType) == FALSE)
-		{
-			dwProductType = PRODUCT_UNDEFINED;
-		}
-	#endif
-	return mpt::Windows::Version(
-		mpt::Windows::Version::System(versioninfoex.dwMajorVersion, versioninfoex.dwMinorVersion),
-		mpt::Windows::Version::ServicePack(versioninfoex.wServicePackMajor, versioninfoex.wServicePackMinor),
-		versioninfoex.dwBuildNumber,
-		dwProductType
-		);
-#endif // MPT_OS_WINDOWS_WINRT
-}
-
-
-#ifdef MODPLUG_TRACKER
-
-namespace {
-struct WindowsVersionCache
-{
-	mpt::Windows::Version version;
-	WindowsVersionCache() noexcept
-		: version(GatherWindowsVersion())
-	{
-	}
-};
-}
-
-static mpt::Windows::Version GatherWindowsVersionFromCache() noexcept
-{
-	static WindowsVersionCache gs_WindowsVersionCache;
-	return gs_WindowsVersionCache.version;
-}
-
-#endif // MODPLUG_TRACKER
-
-
-#endif // MPT_OS_WINDOWS
-
-
-Version::Version() noexcept
-	: m_SystemIsWindows(false)
-	, m_System()
-	, m_ServicePack()
-	, m_Build()
-	, m_Type()
-{
-}
-
-
-Version Version::NoWindows() noexcept
-{
-	return Version();
-}
-
-
-Version::Version(mpt::Windows::Version::System system, mpt::Windows::Version::ServicePack servicePack, mpt::Windows::Version::Build build, mpt::Windows::Version::TypeId type) noexcept
-	: m_SystemIsWindows(true)
-	, m_System(system)
-	, m_ServicePack(servicePack)
-	, m_Build(build)
-	, m_Type(type)
-{
-}
-
-
-mpt::Windows::Version Version::Current() noexcept
-{
-	#if MPT_OS_WINDOWS
-		#ifdef MODPLUG_TRACKER
-			return GatherWindowsVersionFromCache();
-		#else // !MODPLUG_TRACKER
-			return GatherWindowsVersion();
-		#endif // MODPLUG_TRACKER
-	#else // !MPT_OS_WINDOWS
-		return mpt::Windows::Version::NoWindows();
-	#endif // MPT_OS_WINDOWS
-}
-
-
-bool Version::IsWindows() const noexcept
-{
-	return m_SystemIsWindows;
-}
-
-
-bool Version::IsBefore(mpt::Windows::Version::System version) const noexcept
-{
-	if(!m_SystemIsWindows)
-	{
-		return false;
-	}
-	return m_System < version;
-}
-
-
-bool Version::IsBefore(mpt::Windows::Version::System version, mpt::Windows::Version::ServicePack servicePack) const noexcept
-{
-	if(!m_SystemIsWindows)
-	{
-		return false;
-	}
-	if(m_System > version)
-	{
-		return false;
-	}
-	if(m_System < version)
-	{
-		return true;
-	}
-	return m_ServicePack < servicePack;
-}
-
-
-bool Version::IsBefore(mpt::Windows::Version::System version, mpt::Windows::Version::Build build) const noexcept
-{
-	if(!m_SystemIsWindows)
-	{
-		return false;
-	}
-	if(m_System > version)
-	{
-		return false;
-	}
-	if(m_System < version)
-	{
-		return true;
-	}
-	return m_Build < build;
-}
-
-
-bool Version::IsAtLeast(mpt::Windows::Version::System version) const noexcept
-{
-	if(!m_SystemIsWindows)
-	{
-		return false;
-	}
-	return m_System >= version;
-}
-
-
-bool Version::IsAtLeast(mpt::Windows::Version::System version, mpt::Windows::Version::ServicePack servicePack) const noexcept
-{
-	if(!m_SystemIsWindows)
-	{
-		return false;
-	}
-	if(m_System < version)
-	{
-		return false;
-	}
-	if(m_System > version)
-	{
-		return true;
-	}
-	return m_ServicePack >= servicePack;
-}
-
-
-bool Version::IsAtLeast(mpt::Windows::Version::System version, mpt::Windows::Version::Build build) const noexcept
-{
-	if(!m_SystemIsWindows)
-	{
-		return false;
-	}
-	if(m_System < version)
-	{
-		return false;
-	}
-	if(m_System > version)
-	{
-		return true;
-	}
-	return m_Build >= build;
-}
-
-
-mpt::Windows::Version::System Version::GetSystem() const noexcept
-{
-	return m_System;
-}
-
-
-mpt::Windows::Version::ServicePack Version::GetServicePack() const noexcept
-{
-	return m_ServicePack;
-}
-
-
-mpt::Windows::Version::Build Version::GetBuild() const noexcept
-{
-	return m_Build;
-}
-
-
-mpt::Windows::Version::TypeId Version::GetTypeId() const noexcept
-{
-	return m_Type;
-}
-
-
-static MPT_CONSTEXPR11_VAR struct { Version::System version; const mpt::uchar * name; bool showDetails; } versionMap[] =
-{
-	{ mpt::Windows::Version::WinNewer, UL_("Windows 10 (or newer)"), false },
-	{ mpt::Windows::Version::Win10, UL_("Windows 10"), true },
-	{ mpt::Windows::Version::Win81, UL_("Windows 8.1"), true },
-	{ mpt::Windows::Version::Win8, UL_("Windows 8"), true },
-	{ mpt::Windows::Version::Win7, UL_("Windows 7"), true },
-	{ mpt::Windows::Version::WinVista, UL_("Windows Vista"), true },
-	{ mpt::Windows::Version::WinXP64, UL_("Windows XP x64 / Windows Server 2003"), true },
-	{ mpt::Windows::Version::WinXP, UL_("Windows XP"), true },
-	{ mpt::Windows::Version::Win2000, UL_("Windows 2000"), true },
-	{ mpt::Windows::Version::WinNT4, UL_("Windows NT4"), true }
-};
-
-
-mpt::ustring Version::VersionToString(mpt::Windows::Version::System version)
-{
-	mpt::ustring result;
-	for(const auto &v : versionMap)
-	{
-		if(version > v.version)
-		{
-			result = U_("> ") + v.name;
-			break;
-		} else if(version == v.version)
-		{
-			result = v.name;
-			break;
-		}
-	}
-	if(result.empty())
-	{
-		result = mpt::format(U_("0x%1"))(mpt::ufmt::hex0<16>(static_cast<uint64>(version)));
-	}
-	return result;
-}
-
-
-mpt::ustring Version::GetName() const
-{
-	mpt::ustring name = U_("Generic Windows NT");
-	bool showDetails = false;
-	for(const auto &v : versionMap)
-	{
-		if(IsAtLeast(v.version))
-		{
-			name = v.name;
-			showDetails = v.showDetails;
-			break;
-		}
-	}
-	name += U_(" (");
-	name += mpt::format(U_("Version %1.%2"))(m_System.Major, m_System.Minor);
-	if(showDetails)
-	{
-		if(m_ServicePack.HasServicePack())
-		{
-			if(m_ServicePack.Minor)
-			{
-				name += mpt::format(U_(" Service Pack %1.%2"))(m_ServicePack.Major, m_ServicePack.Minor);
-			} else
-			{
-				name += mpt::format(U_(" Service Pack %1"))(m_ServicePack.Major);
-			}
-		}
-		if(m_Build != 0)
-		{
-			name += mpt::format(U_(" (Build %1)"))(m_Build);
-		}
-	}
-	name += U_(")");
-	mpt::ustring result = name;
-	#if defined(MODPLUG_TRACKER) && MPT_OS_WINDOWS
-		if(mpt::Windows::IsWine())
-		{
-			mpt::Wine::VersionContext v;
-			if(v.Version().IsValid())
-			{
-				result = mpt::format(U_("Wine %1 (%2)"))(
-					  v.Version().AsString()
-					, name
-					);
-			} else
-			{
-				result = mpt::format(U_("Wine (unknown version: '%1') (%2)"))(
-					  mpt::ToUnicode(mpt::Charset::UTF8, v.RawVersion())
-					, name
-					);
-			}
-		}
-	#endif // MODPLUG_TRACKER && MPT_OS_WINDOWS
-	return result;
-}
-
-
-#ifdef MODPLUG_TRACKER
-mpt::ustring Version::GetNameShort() const
-{
-	mpt::ustring name;
-	if(mpt::Windows::IsWine())
-	{
-		mpt::Wine::VersionContext v;
-		if(v.Version().IsValid())
-		{
-			name = mpt::format(U_("wine-%1"))(v.Version().AsString());
-		} else if(v.RawVersion().length() > 0)
-		{
-			name = U_("wine-") + Util::BinToHex(mpt::as_span(v.RawVersion()));
-		} else
-		{
-			name = U_("wine-");
-		}
-		name += U_("-") + Util::BinToHex(mpt::as_span(v.RawHostSysName()));
-	} else
-	{
-		name = mpt::format(U_("%1.%2"))(mpt::ufmt::dec(m_System.Major), mpt::ufmt::dec0<2>(m_System.Minor));
-	}
-	return name;
-}
-#endif // MODPLUG_TRACKER
-
-
-mpt::Windows::Version::System Version::GetMinimumKernelLevel() noexcept
-{
-	uint64 minimumKernelVersion = 0;
-	#if MPT_OS_WINDOWS && MPT_COMPILER_MSVC
-		minimumKernelVersion = std::max(minimumKernelVersion, static_cast<uint64>(mpt::Windows::Version::WinVista));
-	#endif
-	return mpt::Windows::Version::System(minimumKernelVersion);
-}
-
-
-mpt::Windows::Version::System Version::GetMinimumAPILevel() noexcept
-{
-	#if MPT_OS_WINDOWS
-		return SystemVersionFrom_WIN32_WINNT();
-	#else // !MPT_OS_WINDOWS
-		return mpt::Windows::Version::System();
-	#endif // MPT_OS_WINDOWS
-}
-
-
-#if defined(MODPLUG_TRACKER) && MPT_OS_WINDOWS
-
-
-#ifndef PROCESSOR_ARCHITECTURE_NEUTRAL
-#define PROCESSOR_ARCHITECTURE_NEUTRAL          11
-#endif
-#ifndef PROCESSOR_ARCHITECTURE_ARM64
-#define PROCESSOR_ARCHITECTURE_ARM64            12
-#endif
-#ifndef PROCESSOR_ARCHITECTURE_ARM32_ON_WIN64
-#define PROCESSOR_ARCHITECTURE_ARM32_ON_WIN64   13
-#endif
-#ifndef PROCESSOR_ARCHITECTURE_IA32_ON_ARM64
-#define PROCESSOR_ARCHITECTURE_IA32_ON_ARM64    14
-#endif
-
-
-struct OSArchitecture
-{
-	uint16 ProcessorArchitectur;
-	Architecture Host;
-	Architecture Process;
-};
-static constexpr OSArchitecture architectures [] = {
-	{ PROCESSOR_ARCHITECTURE_INTEL         , Architecture::x86    , Architecture::x86     },
-	{ PROCESSOR_ARCHITECTURE_AMD64         , Architecture::amd64  , Architecture::amd64   },
-	{ PROCESSOR_ARCHITECTURE_IA32_ON_WIN64 , Architecture::amd64  , Architecture::x86     },
-	{ PROCESSOR_ARCHITECTURE_ARM           , Architecture::arm    , Architecture::arm     },
-	{ PROCESSOR_ARCHITECTURE_ARM64         , Architecture::arm64  , Architecture::arm64   },
-	{ PROCESSOR_ARCHITECTURE_ARM32_ON_WIN64, Architecture::arm64  , Architecture::arm     },
-	{ PROCESSOR_ARCHITECTURE_IA32_ON_ARM64 , Architecture::arm64  , Architecture::x86     },
-	{ PROCESSOR_ARCHITECTURE_MIPS          , Architecture::mips   , Architecture::mips    },
-	{ PROCESSOR_ARCHITECTURE_PPC           , Architecture::ppc    , Architecture::ppc     },
-	{ PROCESSOR_ARCHITECTURE_SHX           , Architecture::shx    , Architecture::shx     },
-	{ PROCESSOR_ARCHITECTURE_ALPHA         , Architecture::alpha  , Architecture::alpha   },
-	{ PROCESSOR_ARCHITECTURE_ALPHA64       , Architecture::alpha64, Architecture::alpha64 },
-	{ PROCESSOR_ARCHITECTURE_IA64          , Architecture::ia64   , Architecture::ia64    },
-	{ PROCESSOR_ARCHITECTURE_MSIL          , Architecture::unknown, Architecture::unknown },
-	{ PROCESSOR_ARCHITECTURE_NEUTRAL       , Architecture::unknown, Architecture::unknown },
-	{ PROCESSOR_ARCHITECTURE_UNKNOWN       , Architecture::unknown, Architecture::unknown }
-};
-
-
-struct HostArchitecture
-{
-	Architecture Host;
-	Architecture Process;
-	EmulationLevel Emulation;
-};
-static constexpr HostArchitecture hostArchitectureCanRun [] = {
-	{ Architecture::x86    , Architecture::x86    , EmulationLevel::Native   },
-	{ Architecture::amd64  , Architecture::amd64  , EmulationLevel::Native   },
-	{ Architecture::amd64  , Architecture::x86    , EmulationLevel::Virtual  },
-	{ Architecture::arm    , Architecture::arm    , EmulationLevel::Native   },
-	{ Architecture::arm64  , Architecture::arm64  , EmulationLevel::Native   },
-	{ Architecture::arm64  , Architecture::arm    , EmulationLevel::Virtual  },
-	{ Architecture::arm64  , Architecture::x86    , EmulationLevel::Software },
-	{ Architecture::mips   , Architecture::mips   , EmulationLevel::Native   },
-	{ Architecture::ppc    , Architecture::ppc    , EmulationLevel::Native   },
-	{ Architecture::shx    , Architecture::shx    , EmulationLevel::Native   },
-	{ Architecture::alpha  , Architecture::alpha  , EmulationLevel::Native   },
-	{ Architecture::alpha64, Architecture::alpha64, EmulationLevel::Native   },
-	{ Architecture::alpha64, Architecture::alpha  , EmulationLevel::Virtual  },
-	{ Architecture::ia64   , Architecture::ia64   , EmulationLevel::Native   },
-	{ Architecture::ia64   , Architecture::x86    , EmulationLevel::Hardware }
-};
-
-
-struct ArchitectureInfo
-{
-	Architecture Arch;
-	int Bitness;
-	const mpt::uchar * Name;
-};
-static constexpr ArchitectureInfo architectureInfo [] = {
-	{ Architecture::x86    , 32, UL_("x86")     },
-	{ Architecture::amd64  , 64, UL_("amd64")   },
-	{ Architecture::arm    , 32, UL_("arm")     },
-	{ Architecture::arm64  , 64, UL_("arm64")   },
-	{ Architecture::mips   , 32, UL_("mips")    },
-	{ Architecture::ppc    , 32, UL_("ppc")     },
-	{ Architecture::shx    , 32, UL_("shx")     },
-	{ Architecture::alpha  , 32, UL_("alpha")   },
-	{ Architecture::alpha64, 64, UL_("alpha64") },
-	{ Architecture::ia64   , 64, UL_("ia64")    }
-};
-
-
-int Bitness(Architecture arch) noexcept
-{
-	for(const auto &info : architectureInfo)
-	{
-		if(arch == info.Arch)
-		{
-			return info.Bitness;
-		}
-	}
-	return 0;
-}
-
-
-mpt::ustring Name(Architecture arch)
-{
-	for(const auto &info : architectureInfo)
-	{
-		if(arch == info.Arch)
-		{
-			return info.Name;
-		}
-	}
-	return mpt::ustring();
-}
-
-
-Architecture GetHostArchitecture() noexcept
-{
-	SYSTEM_INFO systemInfo;
-	MemsetZero(systemInfo);
-	GetNativeSystemInfo(&systemInfo);
-	for(const auto &arch : architectures)
-	{
-		if(systemInfo.wProcessorArchitecture == arch.ProcessorArchitectur)
-		{
-			return arch.Host;
-		}
-	}
-	return Architecture::unknown;
-}
-
-
-Architecture GetProcessArchitecture() noexcept
-{
-	SYSTEM_INFO systemInfo;
-	MemsetZero(systemInfo);
-	GetSystemInfo(&systemInfo);
-	for(const auto &arch : architectures)
-	{
-		if(systemInfo.wProcessorArchitecture == arch.ProcessorArchitectur)
-		{
-			return arch.Process;
-		}
-	}
-	return Architecture::unknown;
-}
-
-
-EmulationLevel HostCanRun(Architecture host, Architecture process) noexcept
-{
-	for(const auto & can : hostArchitectureCanRun)
-	{
-		if(can.Host == host && can.Process == process)
-		{
-			return can.Emulation;
-		}
-	}
-	return EmulationLevel::NA;
-}
-
-
-std::vector<Architecture> GetSupportedProcessArchitectures(Architecture host)
-{
-	std::vector<Architecture> result;
-	for(const auto & entry : hostArchitectureCanRun)
-	{
-		if(entry.Host == host)
-		{
-			result.push_back(entry.Process);
-		}
-	}
-	return result;
-}
-
-
-uint64 GetSystemMemorySize()
-{
-	MEMORYSTATUSEX memoryStatus;
-	MemsetZero(memoryStatus);
-	memoryStatus.dwLength = sizeof(MEMORYSTATUSEX);
-	if(GlobalMemoryStatusEx(&memoryStatus) == 0)
-	{
-		return 0;
-	}
-	return memoryStatus.ullTotalPhys;
-}
-
-
-#endif // MODPLUG_TRACKER && MPT_OS_WINDOWS
-
-
-#if defined(MODPLUG_TRACKER)
-
-
-#if MPT_OS_WINDOWS
-
-static bool GatherSystemIsWine()
-{
-	bool SystemIsWine = false;
-	HMODULE hNTDLL = LoadLibrary(TEXT("ntdll.dll"));
-	if(hNTDLL)
-	{
-		SystemIsWine = (GetProcAddress(hNTDLL, "wine_get_version") != NULL);
-		FreeLibrary(hNTDLL);
-		hNTDLL = NULL;
-	}
-	return SystemIsWine;
-}
-
-namespace {
-struct SystemIsWineCache
-{
-	bool SystemIsWine;
-	SystemIsWineCache()
-		: SystemIsWine(GatherSystemIsWine())
-	{
-		return;
-	}
-	SystemIsWineCache(bool isWine)
-		: SystemIsWine(isWine)
-	{
-		return;
-	}
-};
-}
-
-#endif // MPT_OS_WINDOWS
-
-static bool SystemIsWine(bool allowDetection = true)
-{
-	#if MPT_OS_WINDOWS
-		static SystemIsWineCache gs_SystemIsWineCache = allowDetection ? SystemIsWineCache() : SystemIsWineCache(false);
-		if(!allowDetection)
-		{ // catch too late calls of PreventWineDetection
-			MPT_ASSERT(!gs_SystemIsWineCache.SystemIsWine);
-		}
-		return gs_SystemIsWineCache.SystemIsWine;
-	#else
-		MPT_UNREFERENCED_PARAMETER(allowDetection);
-		return false;
-	#endif
-}
-
-void PreventWineDetection()
-{
-	SystemIsWine(false);
-}
-
-bool IsOriginal()
-{
-	return mpt::Windows::Version::Current().IsWindows() && !SystemIsWine();
-}
-
-bool IsWine()
-{
-	return mpt::Windows::Version::Current().IsWindows() && SystemIsWine();
-}
-
-
-#endif // MODPLUG_TRACKER
-
-
-} // namespace Windows
-} // namespace mpt
-
-
-
-#if defined(MODPLUG_TRACKER)
-
-namespace mpt
-{
-namespace Wine
-{
-
-
-Version::Version()
-	: valid(false)
-	, vmajor(0)
-	, vminor(0)
-	, vupdate(0)
-{
-	return;
-}
-
-
-Version::Version(const mpt::ustring &rawVersion)
-	: valid(false)
-	, vmajor(0)
-	, vminor(0)
-	, vupdate(0)
-{
-	if(rawVersion.empty())
-	{
-		return;
-	}
-	std::vector<uint8> version = mpt::String::Split<uint8>(rawVersion, U_("."));
-	if(version.size() < 2)
-	{
-		return;
-	}
-	mpt::ustring parsedVersion = mpt::String::Combine(version, U_("."));
-	std::size_t len = std::min(parsedVersion.length(), rawVersion.length());
-	if(len == 0)
-	{
-		return;
-	}
-	if(parsedVersion.substr(0, len) != rawVersion.substr(0, len))
-	{
-		return;
-	}
-	valid = true;
-	vmajor = version[0];
-	vminor = version[1];
-	vupdate = (version.size() >= 3) ? version[2] : 0;
-}
-
-
-Version::Version(uint8 vmajor, uint8 vminor, uint8 vupdate)
-	: valid((vmajor > 0) || (vminor > 0) || (vupdate > 0)) 
-	, vmajor(vmajor)
-	, vminor(vminor)
-	, vupdate(vupdate)
-{
-	return;
-}
-
-
-mpt::Wine::Version Version::FromInteger(uint32 version)
-{
-	mpt::Wine::Version result;
-	result.valid = (version <= 0xffffff);
-	result.vmajor = static_cast<uint8>(version >> 16);
-	result.vminor = static_cast<uint8>(version >> 8);
-	result.vupdate = static_cast<uint8>(version >> 0);
-	return result;
-}
-
-
-bool Version::IsValid() const
-{
-	return valid;
-}
-
-
-mpt::ustring Version::AsString() const
-{
-	return mpt::ufmt::dec(vmajor) + U_(".") + mpt::ufmt::dec(vminor) + U_(".") + mpt::ufmt::dec(vupdate);
-}
-
-
-uint32 Version::AsInteger() const
-{
-	uint32 version = 0;
-	version |= static_cast<uint32>(vmajor) << 16;
-	version |= static_cast<uint32>(vminor) << 8;
-	version |= static_cast<uint32>(vupdate) << 0;
-	return version;
-}
-
-
-bool Version::IsBefore(mpt::Wine::Version other) const
-{
-	if(!IsValid())
-	{
-		return false;
-	}
-	return (AsInteger() < other.AsInteger());
-}
-
-
-bool Version::IsAtLeast(mpt::Wine::Version other) const
-{
-	if(!IsValid())
-	{
-		return false;
-	}
-	return (AsInteger() >= other.AsInteger());
-}
-
-
-uint8 Version::GetMajor() const
-{
-	return vmajor;
-}
-
-uint8 Version::GetMinor() const
-{
-	return vminor;
-}
-
-uint8 Version::GetUpdate() const
-{
-	return vupdate;
-}
-
-
-mpt::Wine::Version GetMinimumWineVersion()
-{
-	mpt::Wine::Version minimumWineVersion = mpt::Wine::Version(0,0,0);
-	#if MPT_OS_WINDOWS && MPT_COMPILER_MSVC
-		minimumWineVersion = mpt::Wine::Version(1,8,0);
-	#endif
-	return minimumWineVersion;
-}
-
-
-VersionContext::VersionContext()
-	: m_IsWine(false)
-	, m_HostClass(mpt::OS::Class::Unknown)
-{
-	#if MPT_OS_WINDOWS
-		m_IsWine = mpt::Windows::IsWine();
-		if(!m_IsWine)
-		{
-			return;
-		}
-		m_NTDLL = mpt::Library(mpt::LibraryPath::FullPath(P_("ntdll.dll")));
-		if(m_NTDLL.IsValid())
-		{
-			const char * (__cdecl * wine_get_version)(void) = nullptr;
-			const char * (__cdecl * wine_get_build_id)(void) = nullptr;
-			void (__cdecl * wine_get_host_version)(const char * *, const char * *) = nullptr;
-			m_NTDLL.Bind(wine_get_version, "wine_get_version");
-			m_NTDLL.Bind(wine_get_build_id, "wine_get_build_id");
-			m_NTDLL.Bind(wine_get_host_version, "wine_get_host_version");
-			const char * wine_version = nullptr;
-			const char * wine_build_id = nullptr;
-			const char * wine_host_sysname = nullptr;
-			const char * wine_host_release = nullptr;
-			wine_version = wine_get_version ? wine_get_version() : "";
-			wine_build_id = wine_get_build_id ? wine_get_build_id() : "";
-			if(wine_get_host_version)
-			{
-				wine_get_host_version(&wine_host_sysname, &wine_host_release);
-			}
-			m_RawVersion = wine_version ? wine_version : "";
-			m_RawBuildID = wine_build_id ? wine_build_id : "";
-			m_RawHostSysName = wine_host_sysname ? wine_host_sysname : "";
-			m_RawHostRelease = wine_host_release ? wine_host_release : "";
-		}
-		m_Version = mpt::Wine::Version(mpt::ToUnicode(mpt::Charset::UTF8, m_RawVersion));
-		m_HostClass = mpt::OS::GetClassFromSysname(mpt::ToUnicode(mpt::Charset::UTF8, m_RawHostSysName));
-	#endif // MPT_OS_WINDOWS
-}
-
-
-} // namespace Wine
-} // namespace mpt
-
-#endif // MODPLUG_TRACKER
-
-
-
-OPENMPT_NAMESPACE_END

+ 0 - 304
libopenmpt.mod/openmpt/common/mptOS.h

@@ -1,304 +0,0 @@
-/*
- * mptOS.h
- * -------
- * Purpose: Operating system version information.
- * Notes  : (currently none)
- * Authors: OpenMPT Devs
- * The OpenMPT source code is released under the BSD license. Read LICENSE for more details.
- */
-
-
-#pragma once
-
-#include "BuildSettings.h"
-
-
-#include "mptLibrary.h"
-
-
-OPENMPT_NAMESPACE_BEGIN
-
-
-#if defined(MODPLUG_TRACKER)
-
-namespace mpt
-{
-namespace OS
-{
-
-enum class Class
-{
-	Unknown,
-	Windows,
-	Linux,
-	Darwin,
-	BSD,
-	Haiku,
-	DOS,
-};
-
-mpt::OS::Class GetClassFromSysname(mpt::ustring sysname);
-
-mpt::OS::Class GetClass();
-
-}  // namespace OS
-}  // namespace mpt
-
-#endif // MODPLUG_TRACKER
-
-
-namespace mpt
-{
-namespace Windows
-{
-
-
-class Version
-{
-
-public:
-
-	enum Number : uint64
-	{
-		WinNT4   = 0x0000000400000000ull,
-		Win2000  = 0x0000000500000000ull,
-		WinXP    = 0x0000000500000001ull,
-		WinXP64  = 0x0000000500000002ull,
-		WinVista = 0x0000000600000000ull,
-		Win7     = 0x0000000600000001ull,
-		Win8     = 0x0000000600000002ull,
-		Win81    = 0x0000000600000003ull,
-		Win10    = 0x0000000a00000000ull,
-		WinNewer = Win10 + 1ull
-	};
-
-	struct System
-	{
-		uint32 Major = 0;
-		uint32 Minor = 0;
-		System() = default;
-		constexpr System(Number number) noexcept
-			: Major(static_cast<uint32>((static_cast<uint64>(number) >> 32) & 0xffffffffu))
-			, Minor(static_cast<uint32>((static_cast<uint64>(number) >>  0) & 0xffffffffu))
-		{
-		}
-		explicit constexpr System(uint64 number) noexcept
-			: Major(static_cast<uint32>((number >> 32) & 0xffffffffu))
-			, Minor(static_cast<uint32>((number >>  0) & 0xffffffffu))
-		{
-		}
-		explicit constexpr System(uint32 major, uint32 minor) noexcept
-			: Major(major)
-			, Minor(minor)
-		{
-		}
-		constexpr operator uint64 () const noexcept
-		{
-			return (static_cast<uint64>(Major) << 32) | (static_cast<uint64>(Minor) << 0);
-		}
-	};
-
-	struct ServicePack
-	{
-		uint16 Major = 0;
-		uint16 Minor = 0;
-		ServicePack() = default;
-		explicit constexpr ServicePack(uint16 major, uint16 minor) noexcept
-			: Major(major)
-			, Minor(minor)
-		{
-		}
-		constexpr bool HasServicePack() const noexcept
-		{
-			return Major != 0 || Minor != 0;
-		}
-		constexpr operator uint32 () const noexcept
-		{
-			return (static_cast<uint32>(Major) << 16) | (static_cast<uint32>(Minor) << 0);
-		}
-	};
-
-	typedef uint32 Build;
-
-	typedef uint32 TypeId;
-
-	static mpt::ustring VersionToString(mpt::Windows::Version::System version);
-
-private:
-
-	bool m_SystemIsWindows;
-
-	System m_System;
-	ServicePack m_ServicePack;
-	Build m_Build;
-	TypeId m_Type;
-
-private:
-
-	Version() noexcept;
-
-public:
-
-	static Version NoWindows() noexcept;
-
-	Version(mpt::Windows::Version::System system, mpt::Windows::Version::ServicePack servicePack, mpt::Windows::Version::Build build, mpt::Windows::Version::TypeId type) noexcept;
-
-public:
-
-	static mpt::Windows::Version Current() noexcept;
-
-public:
-
-	bool IsWindows() const noexcept;
-
-	bool IsBefore(mpt::Windows::Version::System version) const noexcept;
-	bool IsBefore(mpt::Windows::Version::System version, mpt::Windows::Version::ServicePack servicePack) const noexcept;
-	bool IsBefore(mpt::Windows::Version::System version, mpt::Windows::Version::Build build) const noexcept;
-
-	bool IsAtLeast(mpt::Windows::Version::System version) const noexcept;
-	bool IsAtLeast(mpt::Windows::Version::System version, mpt::Windows::Version::ServicePack servicePack) const noexcept;
-	bool IsAtLeast(mpt::Windows::Version::System version, mpt::Windows::Version::Build build) const noexcept;
-
-	mpt::Windows::Version::System GetSystem() const noexcept;
-	mpt::Windows::Version::ServicePack GetServicePack() const noexcept;
-	mpt::Windows::Version::Build GetBuild() const noexcept;
-	mpt::Windows::Version::TypeId GetTypeId() const noexcept;
-
-	mpt::ustring GetName() const;
-#ifdef MODPLUG_TRACKER
-	mpt::ustring GetNameShort() const;
-#endif // MODPLUG_TRACKER
-
-public:
-
-	static mpt::Windows::Version::System GetMinimumKernelLevel() noexcept;
-	static mpt::Windows::Version::System GetMinimumAPILevel() noexcept;
-
-}; // class Version
-
-#if defined(MODPLUG_TRACKER) && MPT_OS_WINDOWS
-
-enum class Architecture
-{
-	unknown = -1,
-
-	x86     = 0x0401,
-	amd64   = 0x0801,
-	arm     = 0x0402,
-	arm64   = 0x0802,
-
-	mips    = 0x0403,
-	ppc     = 0x0404,
-	shx     = 0x0405,
-
-	alpha   = 0x0406,
-	alpha64 = 0x0806,
-
-	ia64    = 0x0807,
-};
-
-enum class EmulationLevel
-{
-	Native,
-	Virtual,
-	Hardware,
-	Software,
-	NA,
-};
-
-int Bitness(Architecture arch) noexcept;
-
-mpt::ustring Name(Architecture arch);
-
-Architecture GetHostArchitecture() noexcept;
-Architecture GetProcessArchitecture() noexcept;
-
-EmulationLevel HostCanRun(Architecture host, Architecture process) noexcept;
-
-std::vector<Architecture> GetSupportedProcessArchitectures(Architecture host);
-
-uint64 GetSystemMemorySize();
-
-#endif // MODPLUG_TRACKER && MPT_OS_WINDOWS
-
-
-#if defined(MODPLUG_TRACKER)
-
-void PreventWineDetection();
-
-bool IsOriginal();
-bool IsWine();
-
-#endif // MODPLUG_TRACKER
-
-} // namespace Windows
-} // namespace mpt
-
-
-#if defined(MODPLUG_TRACKER)
-
-namespace mpt
-{
-
-namespace Wine
-{
-
-class Version
-{
-private:
-	bool valid;
-	uint8 vmajor;
-	uint8 vminor;
-	uint8 vupdate;
-public:
-	Version();
-	Version(uint8 vmajor, uint8 vminor, uint8 vupdate);
-	explicit Version(const mpt::ustring &version);
-public:
-	bool IsValid() const;
-	mpt::ustring AsString() const;
-private:
-	static mpt::Wine::Version FromInteger(uint32 version);
-	uint32 AsInteger() const;
-public:
-	bool IsBefore(mpt::Wine::Version other) const;
-	bool IsAtLeast(mpt::Wine::Version other) const;
-	uint8 GetMajor() const;
-	uint8 GetMinor() const;
-	uint8 GetUpdate() const;
-};
-
-mpt::Wine::Version GetMinimumWineVersion();
-
-class VersionContext
-{
-protected:
-	bool m_IsWine;
-	mpt::Library m_NTDLL;
-	std::string m_RawVersion;
-	std::string m_RawBuildID;
-	std::string m_RawHostSysName;
-	std::string m_RawHostRelease;
-	mpt::Wine::Version m_Version;
-	mpt::OS::Class m_HostClass;
-public:
-	VersionContext();
-public:
-	bool IsWine() const { return m_IsWine; }
-	mpt::Library NTDLL() const { return m_NTDLL; }
-	std::string RawVersion() const { return m_RawVersion; }
-	std::string RawBuildID() const { return m_RawBuildID; }
-	std::string RawHostSysName() const { return m_RawHostSysName; }
-	std::string RawHostRelease() const { return m_RawHostRelease; }
-	mpt::Wine::Version Version() const { return m_Version; }
-	mpt::OS::Class HostClass() const { return m_HostClass; }
-};
-
-} // namespace Wine
-
-} // namespace mpt
-
-#endif // MODPLUG_TRACKER
-
-
-OPENMPT_NAMESPACE_END

+ 0 - 80
libopenmpt.mod/openmpt/common/mptOSException.h

@@ -1,80 +0,0 @@
-/*
- * mptOSException.h
- * ----------------
- * Purpose: platform-specific exception/signal handling
- * Notes  : (currently none)
- * Authors: OpenMPT Devs
- * The OpenMPT source code is released under the BSD license. Read LICENSE for more details.
- */
-
-
-#pragma once
-
-#include "BuildSettings.h"
-
-#include "mptBaseMacros.h"
-#include "mptBaseTypes.h"
-
-#if defined(MODPLUG_TRACKER)
-#if MPT_OS_WINDOWS
-#include <windows.h>
-#endif // MPT_OS_WINDOWS
-#endif // MODPLUG_TRACKER
-
-
-OPENMPT_NAMESPACE_BEGIN
-
-
-#if defined(MODPLUG_TRACKER)
-
-
-#if MPT_OS_WINDOWS
-
-
-namespace Windows
-{
-
-
-struct StructuredException
-{
-private:
-	DWORD m_Code;
-public:
-	constexpr StructuredException(DWORD code) noexcept
-		: m_Code(code)
-	{
-		return;
-	}
-public:
-	constexpr DWORD code() const noexcept
-	{
-		return m_Code;
-	}
-};
-
-
-template <typename Tfn>
-auto ThrowOnStructuredException(Tfn fn) -> decltype(fn())
-{
-	DWORD code = 0;
-	__try
-	{
-		return fn();
-	} __except(EXCEPTION_EXECUTE_HANDLER)
-	{
-		code = GetExceptionCode();
-	}
-	throw StructuredException(code);
-}
-
-
-}  // namespace Windows
-
-
-#endif // MPT_OS_WINDOWS
-
-
-#endif // MODPLUG_TRACKER
-
-
-OPENMPT_NAMESPACE_END

+ 0 - 870
libopenmpt.mod/openmpt/common/mptPathString.cpp

@@ -1,870 +0,0 @@
-/*
- * mptPathString.cpp
- * -----------------
- * Purpose: Wrapper class around the platform-native representation of path names. Should be the only type that is used to store path names.
- * Notes  : Currently none.
- * Authors: OpenMPT Devs
- * The OpenMPT source code is released under the BSD license. Read LICENSE for more details.
- */
-
-#include "stdafx.h"
-#include "mptPathString.h"
-
-#include "misc_util.h"
-
-#include "mptUUID.h"
-
-#if MPT_OS_WINDOWS
-#include <windows.h>
-#if defined(MODPLUG_TRACKER)
-#include <shlwapi.h>
-#endif
-#include <tchar.h>
-#endif
-
-#if MPT_OS_WINDOWS && MPT_OS_WINDOWS_WINRT
-#if defined(__MINGW32__) || defined(__MINGW64__)
-// MinGW-w64 headers do not declare this for WinRT, which is wrong.
-extern "C" {
-WINBASEAPI DWORD WINAPI GetFullPathNameW(LPCWSTR lpFileName, DWORD nBufferLength, LPWSTR lpBuffer, LPWSTR *lpFilePart);
-#ifndef GetFullPathName
-#define GetFullPathName GetFullPathNameW
-#endif
-}
-#endif
-#endif
-
-OPENMPT_NAMESPACE_BEGIN
-
-#if MPT_OS_WINDOWS
-
-namespace mpt
-{
-
-
-RawPathString PathString::AsNativePrefixed() const
-{
-	if(path.length() <= MAX_PATH || path.substr(0, 4) == PL_("\\\\?\\"))
-	{
-		// Path is short enough or already in prefixed form
-		return path;
-	}
-	const RawPathString absPath = mpt::GetAbsolutePath(*this).AsNative();
-	if(absPath.substr(0, 2) == PL_("\\\\"))
-	{
-		// Path is a network share: \\server\foo.bar -> \\?\UNC\server\foo.bar
-		return PL_("\\\\?\\UNC") + absPath.substr(1);
-	} else
-	{
-		// Regular file: C:\foo.bar -> \\?\C:\foo.bar
-		return PL_("\\\\?\\") + absPath;
-	}
-}
-
-
-#if !MPT_OS_WINDOWS_WINRT
-
-int PathString::CompareNoCase(const PathString & a, const PathString & b)
-{
-	return lstrcmpi(a.path.c_str(), b.path.c_str());
-}
-
-#endif // !MPT_OS_WINDOWS_WINRT
-
-
-// Convert a path to its simplified form, i.e. remove ".\" and "..\" entries
-// Note: We use our own implementation as PathCanonicalize is limited to MAX_PATH
-// and unlimited versions are only available on Windows 8 and later.
-// Furthermore, we also convert forward-slashes to backslashes and always remove trailing slashes.
-PathString PathString::Simplify() const
-{
-	if(path.empty())
-		return PathString();
-
-	std::vector<RawPathString> components;
-	RawPathString root;
-	RawPathString::size_type startPos = 0;
-	if(path.size() >= 2 && path[1] == PC_(':'))
-	{
-		// Drive letter
-		root = path.substr(0, 2) + PC_('\\');
-		startPos = 2;
-	} else if(path.substr(0, 2) == PL_("\\\\"))
-	{
-		// Network share
-		root = PL_("\\\\");
-		startPos = 2;
-	} else if(path.substr(0, 2) == PL_(".\\") || path.substr(0, 2) == PL_("./"))
-	{
-		// Special case for relative paths
-		root = PL_(".\\");
-		startPos = 2;
-	} else if(path.size() >= 1 && (path[0] == PC_('\\') || path[0] == PC_('/')))
-	{
-		// Special case for relative paths
-		root = PL_("\\");
-		startPos = 1;
-	}
-
-	while(startPos < path.size())
-	{
-		auto pos = path.find_first_of(PL_("\\/"), startPos);
-		if(pos == RawPathString::npos)
-			pos = path.size();
-		mpt::RawPathString dir = path.substr(startPos, pos - startPos);
-		if(dir == PL_(".."))
-		{
-			// Go back one directory
-			if(!components.empty())
-			{
-				components.pop_back();
-			}
-		} else if(dir == PL_("."))
-		{
-			// nop
-		} else if(!dir.empty())
-		{
-			components.push_back(std::move(dir));
-		}
-		startPos = pos + 1;
-	}
-
-	RawPathString result = root;
-	result.reserve(path.size());
-	for(const auto &component : components)
-	{
-		result += component + PL_("\\");
-	}
-	if(!components.empty())
-		result.pop_back();
-	return mpt::PathString(result);
-}
-
-} // namespace mpt
-
-#endif // MPT_OS_WINDOWS
-
-
-namespace mpt
-{
-
-
-#if MPT_OS_WINDOWS && (defined(MPT_ENABLE_DYNBIND) || defined(MPT_ENABLE_TEMPFILE))
-
-void PathString::SplitPath(PathString *drive, PathString *dir, PathString *fname, PathString *ext) const
-{
-	// We cannot use CRT splitpath here, because:
-	//  * limited to _MAX_PATH or similar
-	//  * no support for UNC paths
-	//  * no support for \\?\ prefixed paths
-
-	if(drive) *drive = mpt::PathString();
-	if(dir) *dir = mpt::PathString();
-	if(fname) *fname = mpt::PathString();
-	if(ext) *ext = mpt::PathString();
-
-	mpt::RawPathString p = path;
-
-	// remove \\?\\ prefix
-	if(p.substr(0, 8) == PL_("\\\\?\\UNC\\"))
-	{
-		p = PL_("\\\\") + p.substr(8);
-	} else if(p.substr(0, 4) == PL_("\\\\?\\"))
-	{
-		p = p.substr(4);
-	}
-
-	if (p.length() >= 2 && (
-		p.substr(0, 2) == PL_("\\\\")
-		|| p.substr(0, 2) == PL_("\\/")
-		|| p.substr(0, 2) == PL_("/\\")
-		|| p.substr(0, 2) == PL_("//")
-		))
-	{ // UNC
-		mpt::RawPathString::size_type first_slash = p.substr(2).find_first_of(PL_("\\/"));
-		if(first_slash != mpt::RawPathString::npos)
-		{
-			mpt::RawPathString::size_type second_slash = p.substr(2 + first_slash + 1).find_first_of(PL_("\\/"));
-			if(second_slash != mpt::RawPathString::npos)
-			{
-				if(drive) *drive = mpt::PathString::FromNative(p.substr(0, 2 + first_slash + 1 + second_slash));
-				p = p.substr(2 + first_slash + 1 + second_slash);
-			} else
-			{
-				if(drive) *drive = mpt::PathString::FromNative(p);
-				p = mpt::RawPathString();
-			}
-		} else
-		{
-			if(drive) *drive = mpt::PathString::FromNative(p);
-			p = mpt::RawPathString();
-		}
-	} else
-	{ // local
-		if(p.length() >= 2 && (p[1] == PC_(':')))
-		{
-			if(drive) *drive = mpt::PathString::FromNative(p.substr(0, 2));
-			p = p.substr(2);
-		} else
-		{
-			if(drive) *drive = mpt::PathString();
-		}
-	}
-	mpt::RawPathString::size_type last_slash = p.find_last_of(PL_("\\/"));
-	if(last_slash != mpt::RawPathString::npos)
-	{
-		if(dir) *dir = mpt::PathString::FromNative(p.substr(0, last_slash + 1));
-		p = p.substr(last_slash + 1);
-	} else
-	{
-		if(dir) *dir = mpt::PathString();
-	}
-	mpt::RawPathString::size_type last_dot = p.find_last_of(PL_("."));
-	if(last_dot == mpt::RawPathString::npos)
-	{
-		if(fname) *fname = mpt::PathString::FromNative(p);
-		if(ext) *ext = mpt::PathString();
-	} else if(last_dot == 0)
-	{
-		if(fname) *fname = mpt::PathString::FromNative(p);
-		if(ext) *ext = mpt::PathString();
-	} else if(p == PL_(".") || p == PL_(".."))
-	{
-		if(fname) *fname = mpt::PathString::FromNative(p);
-		if(ext) *ext = mpt::PathString();
-	} else
-	{
-		if(fname) *fname = mpt::PathString::FromNative(p.substr(0, last_dot));
-		if(ext) *ext = mpt::PathString::FromNative(p.substr(last_dot));
-	}
-
-}
-
-PathString PathString::GetDrive() const
-{
-	PathString drive;
-	SplitPath(&drive, nullptr, nullptr, nullptr);
-	return drive;
-}
-PathString PathString::GetDir() const
-{
-	PathString dir;
-	SplitPath(nullptr, &dir, nullptr, nullptr);
-	return dir;
-}
-PathString PathString::GetPath() const
-{
-	PathString drive, dir;
-	SplitPath(&drive, &dir, nullptr, nullptr);
-	return drive + dir;
-}
-PathString PathString::GetFileName() const
-{
-	PathString fname;
-	SplitPath(nullptr, nullptr, &fname, nullptr);
-	return fname;
-}
-PathString PathString::GetFileExt() const
-{
-	PathString ext;
-	SplitPath(nullptr, nullptr, nullptr, &ext);
-	return ext;
-}
-PathString PathString::GetFullFileName() const
-{
-	PathString name, ext;
-	SplitPath(nullptr, nullptr, &name, &ext);
-	return name + ext;
-}
-
-
-bool PathString::IsDirectory() const
-{
-	// Using PathIsDirectoryW here instead would increase libopenmpt dependencies by shlwapi.dll.
-	// GetFileAttributesW also does the job just fine.
-	#if MPT_OS_WINDOWS_WINRT
-		WIN32_FILE_ATTRIBUTE_DATA data;
-		MemsetZero(data);
-		if(::GetFileAttributesExW(path.c_str(), GetFileExInfoStandard, &data) == 0)
-		{
-			return false;
-		}
-		DWORD dwAttrib = data.dwFileAttributes;
-	#else // !MPT_OS_WINDOWS_WINRT
-		DWORD dwAttrib = ::GetFileAttributes(path.c_str());
-	#endif // MPT_OS_WINDOWS_WINRT
-	return ((dwAttrib != INVALID_FILE_ATTRIBUTES) && (dwAttrib & FILE_ATTRIBUTE_DIRECTORY));
-}
-
-bool PathString::IsFile() const
-{
-	#if MPT_OS_WINDOWS_WINRT
-		WIN32_FILE_ATTRIBUTE_DATA data;
-		MemsetZero(data);
-		if (::GetFileAttributesExW(path.c_str(), GetFileExInfoStandard, &data) == 0)
-		{
-			return false;
-		}
-		DWORD dwAttrib = data.dwFileAttributes;
-	#else // !MPT_OS_WINDOWS_WINRT
-		DWORD dwAttrib = ::GetFileAttributes(path.c_str());
-	#endif // MPT_OS_WINDOWS_WINRT
-	return ((dwAttrib != INVALID_FILE_ATTRIBUTES) && !(dwAttrib & FILE_ATTRIBUTE_DIRECTORY));
-}
-
-#endif // MPT_OS_WINDOWS && (MPT_ENABLE_DYNBIND || MPT_ENABLE_TEMPFILE)
-
-
-#if defined(MODPLUG_TRACKER) && MPT_OS_WINDOWS
-
-bool PathString::FileOrDirectoryExists() const
-{
-	return ::PathFileExists(path.c_str()) != FALSE;
-}
-
-#endif // MODPLUG_TRACKER && MPT_OS_WINDOWS
-
-
-#if defined(MODPLUG_TRACKER) && MPT_OS_WINDOWS
-
-PathString PathString::ReplaceExt(const mpt::PathString &newExt) const
-{
-	return GetDrive() + GetDir() + GetFileName() + newExt;
-}
-
-
-PathString PathString::SanitizeComponent() const
-{
-	PathString result = *this;
-	SanitizeFilename(result);
-	return result;
-}
-
-
-// Convert an absolute path to a path that's relative to "&relativeTo".
-PathString PathString::AbsolutePathToRelative(const PathString &relativeTo) const
-{
-	mpt::PathString result = *this;
-	if(path.empty())
-	{
-		return result;
-	}
-	if(!_tcsncicmp(relativeTo.AsNative().c_str(), AsNative().c_str(), relativeTo.AsNative().length()))
-	{
-		// Path is OpenMPT's directory or a sub directory ("C:\OpenMPT\Somepath" => ".\Somepath")
-		result = P_(".\\"); // ".\"
-		result += mpt::PathString::FromNative(AsNative().substr(relativeTo.AsNative().length()));
-	} else if(!_tcsncicmp(relativeTo.AsNative().c_str(), AsNative().c_str(), 2))
-	{
-		// Path is on the same drive as OpenMPT ("C:\Somepath" => "\Somepath")
-		result = mpt::PathString::FromNative(AsNative().substr(2));
-	}
-	return result;
-}
-
-
-// Convert a path that is relative to "&relativeTo" to an absolute path.
-PathString PathString::RelativePathToAbsolute(const PathString &relativeTo) const
-{
-	mpt::PathString result = *this;
-	if(path.empty())
-	{
-		return result;
-	}
-	if(path.length() >= 2 && path.at(0) == PC_('\\') && path.at(1) != PC_('\\'))
-	{
-		// Path is on the same drive as OpenMPT ("\Somepath\" => "C:\Somepath\"), but ignore network paths starting with "\\"
-		result = mpt::PathString::FromNative(relativeTo.AsNative().substr(0, 2));
-		result += mpt::PathString(path);
-	} else if(path.length() >= 2 && path.substr(0, 2) == PL_(".\\"))
-	{
-		// Path is OpenMPT's directory or a sub directory (".\Somepath\" => "C:\OpenMPT\Somepath\")
-		result = relativeTo; // "C:\OpenMPT\"
-		result += mpt::PathString::FromNative(AsNative().substr(2));
-	}
-	return result;
-}
-
-
-#endif // MODPLUG_TRACKER && MPT_OS_WINDOWS
-
-
-bool PathString::IsPathSeparator(RawPathString::value_type c)
-{
-#if MPT_OS_WINDOWS
-	return (c == PC_('\\')) || (c == PC_('/'));
-#else
-	return c == PC_('/');
-#endif
-}
-
-RawPathString::value_type PathString::GetDefaultPathSeparator()
-{
-#if MPT_OS_WINDOWS
-	return PC_('\\');
-#else
-	return PC_('/');
-#endif
-}
-
-
-} // namespace mpt
-
-
-namespace mpt
-{
-
-bool PathIsAbsolute(const mpt::PathString &path) {
-	mpt::RawPathString rawpath = path.AsNative();
-#if MPT_OS_WINDOWS
-	if(rawpath.substr(0, 8) == PL_("\\\\?\\UNC\\"))
-	{
-		return true;
-	}
-	if(rawpath.substr(0, 4) == PL_("\\\\?\\"))
-	{
-		return true;
-	}
-	if(rawpath.substr(0, 2) == PL_("\\\\"))
-	{
-		return true; // UNC
-	}
-	if(rawpath.substr(0, 2) == PL_("//"))
-	{
-		return true; // UNC
-	}
-	return (rawpath.length()) >= 3 && (rawpath[1] == ':') && mpt::PathString::IsPathSeparator(rawpath[2]);
-#else
-	return (rawpath.length() >= 1) && mpt::PathString::IsPathSeparator(rawpath[0]);
-#endif
-}
-
-
-#if MPT_OS_WINDOWS
-
-mpt::PathString GetAbsolutePath(const mpt::PathString &path)
-{
-	DWORD size = GetFullPathName(path.AsNative().c_str(), 0, nullptr, nullptr);
-	if(size == 0)
-	{
-		return path;
-	}
-	std::vector<TCHAR> fullPathName(size, TEXT('\0'));
-	if(GetFullPathName(path.AsNative().c_str(), size, fullPathName.data(), nullptr) == 0)
-	{
-		return path;
-	}
-	return mpt::PathString::FromNative(fullPathName.data());
-}
-
-#ifdef MODPLUG_TRACKER
-
-bool DeleteWholeDirectoryTree(mpt::PathString path)
-{
-	if(path.AsNative().empty())
-	{
-		return false;
-	}
-	if(PathIsRelative(path.AsNative().c_str()) == TRUE)
-	{
-		return false;
-	}
-	if(!path.FileOrDirectoryExists())
-	{
-		return true;
-	}
-	if(!path.IsDirectory())
-	{
-		return false;
-	}
-	path.EnsureTrailingSlash();
-	HANDLE hFind = NULL;
-	WIN32_FIND_DATA wfd;
-	MemsetZero(wfd);
-	hFind = FindFirstFile((path + P_("*.*")).AsNative().c_str(), &wfd);
-	if(hFind != NULL && hFind != INVALID_HANDLE_VALUE)
-	{
-		do
-		{
-			mpt::PathString filename = mpt::PathString::FromNative(wfd.cFileName);
-			if(filename != P_(".") && filename != P_(".."))
-			{
-				filename = path + filename;
-				if(filename.IsDirectory())
-				{
-					if(!DeleteWholeDirectoryTree(filename))
-					{
-						return false;
-					}
-				} else if(filename.IsFile())
-				{
-					if(DeleteFile(filename.AsNative().c_str()) == 0)
-					{
-						return false;
-					}
-				}
-			}
-		} while(FindNextFile(hFind, &wfd));
-		FindClose(hFind);
-	}
-	if(RemoveDirectory(path.AsNative().c_str()) == 0)
-	{
-		return false;
-	}
-	return true;
-}
-
-#endif // MODPLUG_TRACKER
-
-#endif // MPT_OS_WINDOWS
-
-
-
-#if MPT_OS_WINDOWS
-
-#if defined(MPT_ENABLE_DYNBIND) || defined(MPT_ENABLE_TEMPFILE)
-
-mpt::PathString GetExecutablePath()
-{
-	std::vector<TCHAR> exeFileName(MAX_PATH);
-	while(GetModuleFileName(0, exeFileName.data(), mpt::saturate_cast<DWORD>(exeFileName.size())) >= exeFileName.size())
-	{
-		if(GetLastError() != ERROR_INSUFFICIENT_BUFFER)
-		{
-			return mpt::PathString();
-		}
-		exeFileName.resize(exeFileName.size() * 2);
-	}
-	return mpt::GetAbsolutePath(mpt::PathString::FromNative(exeFileName.data()).GetPath());
-}
-
-#endif // MPT_ENABLE_DYNBIND || MPT_ENABLE_TEMPFILE
-
-
-#if defined(MPT_ENABLE_DYNBIND)
-
-#if !MPT_OS_WINDOWS_WINRT
-
-mpt::PathString GetSystemPath()
-{
-	DWORD size = GetSystemDirectory(nullptr, 0);
-	std::vector<TCHAR> path(size + 1);
-	if(!GetSystemDirectory(path.data(), size + 1))
-	{
-		return mpt::PathString();
-	}
-	return mpt::PathString::FromNative(path.data()) + P_("\\");
-}
-
-#endif // !MPT_OS_WINDOWS_WINRT
-
-#endif // MPT_ENABLE_DYNBIND
-
-#endif // MPT_OS_WINDOWS
-
-
-
-#if defined(MPT_ENABLE_TEMPFILE)
-#if MPT_OS_WINDOWS
-
-mpt::PathString GetTempDirectory()
-{
-	DWORD size = GetTempPath(0, nullptr);
-	if(size)
-	{
-		std::vector<TCHAR> tempPath(size + 1);
-		if(GetTempPath(size + 1, tempPath.data()))
-		{
-			return mpt::PathString::FromNative(tempPath.data());
-		}
-	}
-	// use exe directory as fallback
-	return mpt::GetExecutablePath();
-}
-
-mpt::PathString CreateTempFileName(const mpt::PathString &fileNamePrefix, const mpt::PathString &fileNameExtension)
-{
-	mpt::PathString filename = mpt::GetTempDirectory();
-	filename += (!fileNamePrefix.empty() ? fileNamePrefix + P_("_") : mpt::PathString());
-	filename += mpt::PathString::FromUnicode(mpt::UUID::GenerateLocalUseOnly().ToUString());
-	filename += (!fileNameExtension.empty() ? P_(".") + fileNameExtension : mpt::PathString());
-	return filename;
-}
-
-TempFileGuard::TempFileGuard(const mpt::PathString &filename)
-	: filename(filename)
-{
-	return;
-}
-
-mpt::PathString TempFileGuard::GetFilename() const
-{
-	return filename;
-}
-
-TempFileGuard::~TempFileGuard()
-{
-	if(!filename.empty())
-	{
-		DeleteFile(filename.AsNative().c_str());
-	}
-}
-
-#ifdef MODPLUG_TRACKER
-
-TempDirGuard::TempDirGuard(const mpt::PathString &dirname_)
-	: dirname(dirname_.WithTrailingSlash())
-{
-	if(dirname.empty())
-	{
-		return;
-	}
-	if(::CreateDirectory(dirname.AsNative().c_str(), NULL) == 0)
-	{ // fail
-		dirname = mpt::PathString();
-	}
-}
-
-mpt::PathString TempDirGuard::GetDirname() const
-{
-	return dirname;
-}
-
-TempDirGuard::~TempDirGuard()
-{
-	if(!dirname.empty())
-	{
-		DeleteWholeDirectoryTree(dirname);
-	}
-}
-
-#endif // MODPLUG_TRACKER
-
-#endif // MPT_OS_WINDOWS
-#endif // MPT_ENABLE_TEMPFILE
-
-} // namespace mpt
-
-
-
-#if defined(MODPLUG_TRACKER)
-
-static inline char SanitizeFilenameChar(char c)
-{
-	if(	c == '\\' ||
-		c == '\"' ||
-		c == '/'  ||
-		c == ':'  ||
-		c == '?'  ||
-		c == '<'  ||
-		c == '>'  ||
-		c == '|'  ||
-		c == '*')
-	{
-		c = '_';
-	}
-	return c;
-}
-
-static inline wchar_t SanitizeFilenameChar(wchar_t c)
-{
-	if(	c == L'\\' ||
-		c == L'\"' ||
-		c == L'/'  ||
-		c == L':'  ||
-		c == L'?'  ||
-		c == L'<'  ||
-		c == L'>'  ||
-		c == L'|'  ||
-		c == L'*')
-	{
-		c = L'_';
-	}
-	return c;
-}
-
-void SanitizeFilename(mpt::PathString &filename)
-{
-	mpt::RawPathString tmp = filename.AsNative();
-	for(auto &c : tmp)
-	{
-		c = SanitizeFilenameChar(c);
-	}
-	filename = mpt::PathString::FromNative(tmp);
-}
-
-void SanitizeFilename(char *beg, char *end)
-{
-	for(char *it = beg; it != end; ++it)
-	{
-		*it = SanitizeFilenameChar(*it);
-	}
-}
-
-void SanitizeFilename(wchar_t *beg, wchar_t *end)
-{
-	for(wchar_t *it = beg; it != end; ++it)
-	{
-		*it = SanitizeFilenameChar(*it);
-	}
-}
-
-void SanitizeFilename(std::string &str)
-{
-	for(size_t i = 0; i < str.length(); i++)
-	{
-		str[i] = SanitizeFilenameChar(str[i]);
-	}
-}
-
-void SanitizeFilename(std::wstring &str)
-{
-	for(size_t i = 0; i < str.length(); i++)
-	{
-		str[i] = SanitizeFilenameChar(str[i]);
-	}
-}
-
-#if MPT_USTRING_MODE_UTF8
-void SanitizeFilename(mpt::u8string &str)
-{
-	for(size_t i = 0; i < str.length(); i++)
-	{
-		str[i] = SanitizeFilenameChar(str[i]);
-	}
-}
-#endif // MPT_USTRING_MODE_UTF8
-
-#if defined(_MFC_VER)
-void SanitizeFilename(CString &str)
-{
-	for(int i = 0; i < str.GetLength(); i++)
-	{
-		str.SetAt(i, SanitizeFilenameChar(str.GetAt(i)));
-	}
-}
-#endif // MFC
-
-#endif // MODPLUG_TRACKER
-
-
-#if defined(MODPLUG_TRACKER)
-
-
-mpt::PathString FileType::AsFilterString(FlagSet<FileTypeFormat> format) const
-{
-	mpt::PathString filter;
-	if(GetShortName().empty() || GetExtensions().empty())
-	{
-		return filter;
-	}
-	if(!GetDescription().empty())
-	{
-		filter += mpt::PathString::FromUnicode(GetDescription());
-	} else
-	{
-		filter += mpt::PathString::FromUnicode(GetShortName());
-	}
-	const auto extensions = GetExtensions();
-	if(format[FileTypeFormatShowExtensions])
-	{
-		filter += P_(" (");
-		bool first = true;
-		for(const auto &ext : extensions)
-		{
-			if(first)
-			{
-				first = false;
-			} else
-			{
-				filter += P_(",");
-			}
-			filter += P_("*.");
-			filter += ext;
-		}
-		filter += P_(")");
-	}
-	filter += P_("|");
-	{
-		bool first = true;
-		for(const auto &ext : extensions)
-		{
-			if(first)
-			{
-				first = false;
-			} else
-			{
-				filter += P_(";");
-			}
-			filter += P_("*.");
-			filter += ext;
-		}
-	}
-	filter += P_("|");
-	return filter;
-}
-
-
-mpt::PathString FileType::AsFilterOnlyString() const
-{
-	mpt::PathString filter;
-	const auto extensions = GetExtensions();
-	{
-		bool first = true;
-		for(const auto &ext : extensions)
-		{
-			if(first)
-			{
-				first = false;
-			} else
-			{
-				filter += P_(";");
-			}
-			filter += P_("*.");
-			filter += ext;
-		}
-	}
-	return filter;
-}
-
-
-mpt::PathString ToFilterString(const FileType &fileType, FlagSet<FileTypeFormat> format)
-{
-	return fileType.AsFilterString(format);
-}
-
-
-mpt::PathString ToFilterString(const std::vector<FileType> &fileTypes, FlagSet<FileTypeFormat> format)
-{
-	mpt::PathString filter;
-	for(const auto &type : fileTypes)
-	{
-		filter += type.AsFilterString(format);
-	}
-	return filter;
-}
-
-
-mpt::PathString ToFilterOnlyString(const FileType &fileType, bool prependSemicolonWhenNotEmpty)
-{
-	mpt::PathString filter = fileType.AsFilterOnlyString();
-	return filter.empty() ? filter : (prependSemicolonWhenNotEmpty ? P_(";") : P_("")) + filter;
-}
-
-
-mpt::PathString ToFilterOnlyString(const std::vector<FileType> &fileTypes, bool prependSemicolonWhenNotEmpty)
-{
-	mpt::PathString filter;
-	for(const auto &type : fileTypes)
-	{
-		filter += type.AsFilterOnlyString();
-	}
-	return filter.empty() ? filter : (prependSemicolonWhenNotEmpty ? P_(";") : P_("")) + filter;
-}
-
-
-#endif // MODPLUG_TRACKER
-
-
-
-OPENMPT_NAMESPACE_END

+ 0 - 504
libopenmpt.mod/openmpt/common/mptPathString.h

@@ -1,504 +0,0 @@
-/*
- * mptPathString.h
- * ---------------
- * Purpose: Wrapper class around the platform-native representation of path names. Should be the only type that is used to store path names.
- * Notes  : Currently none.
- * Authors: OpenMPT Devs
- * The OpenMPT source code is released under the BSD license. Read LICENSE for more details.
- */
-
-
-#pragma once
-
-#include "BuildSettings.h"
-
-#include <vector>
-
-#include "FlagSet.h"
-
-OPENMPT_NAMESPACE_BEGIN
-
-
-
-#define MPT_DEPRECATED_PATH
-//#define MPT_DEPRECATED_PATH [[deprecated]]
-
-
-
-namespace mpt
-{
-
-#if MPT_OS_WINDOWS
-typedef mpt::winstring RawPathString;
-#else // !MPT_OS_WINDOWS
-typedef std::string RawPathString;
-#endif // if MPT_OS_WINDOWS
-
-
-
-class PathString
-{
-
-private:
-
-	RawPathString path;
-
-private:
-
-	explicit PathString(const RawPathString & path)
-		: path(path)
-	{
-		return;
-	}
-
-public:
-
-	PathString()
-	{
-		return;
-	}
-	PathString(const PathString & other)
-		: path(other.path)
-	{
-		return;
-	}
-	PathString & assign(const PathString & other)
-	{
-		path = other.path;
-		return *this;
-	}
-	PathString & operator = (const PathString & other)
-	{
-		return assign(other);
-	}
-	PathString & append(const PathString & other)
-	{
-		path.append(other.path);
-		return *this;
-	}
-	PathString & operator += (const PathString & other)
-	{
-		return append(other);
-	}
-
-	friend PathString operator + (const PathString & a, const PathString & b)
-	{
-		return PathString(a).append(b);
-	}
-
-	friend bool operator < (const PathString & a, const PathString & b)
-	{
-		return a.AsNative() < b.AsNative();
-	}
-	friend bool operator == (const PathString & a, const PathString & b)
-	{
-		return a.AsNative() == b.AsNative();
-	}
-	friend bool operator != (const PathString & a, const PathString & b)
-	{
-		return a.AsNative() != b.AsNative();
-	}
-
-	bool empty() const { return path.empty(); }
-
-	std::size_t Length() const { return path.size(); }
-
-
-
-public:
-
-#if MPT_OS_WINDOWS
-#if !MPT_OS_WINDOWS_WINRT
-	static int CompareNoCase(const PathString & a, const PathString & b);
-#endif // !MPT_OS_WINDOWS_WINRT
-#endif
-
-#if MPT_OS_WINDOWS && (defined(MPT_ENABLE_DYNBIND) || defined(MPT_ENABLE_TEMPFILE))
-
-	void SplitPath(PathString *drive, PathString *dir, PathString *fname, PathString *ext) const;
-	// \\?\ prefixes will be removed and \\?\\UNC prefixes converted to canonical \\ form.
-	PathString GetDrive() const;		// Drive letter + colon, e.g. "C:" or \\server\\share
-	PathString GetDir() const;			// Directory, e.g. "\OpenMPT\"
-	PathString GetPath() const;			// Drive + Dir, e.g. "C:\OpenMPT\"
-	PathString GetFileName() const;		// File name without extension, e.g. "OpenMPT"
-	PathString GetFileExt() const;		// Extension including dot, e.g. ".exe"
-	PathString GetFullFileName() const;	// File name + extension, e.g. "OpenMPT.exe"
-
-	// Verify if this path represents a valid directory on the file system.
-	bool IsDirectory() const;
-	// Verify if this path exists and is a file on the file system.
-	bool IsFile() const;
-
-#endif // MPT_OS_WINDOWS && (MPT_ENABLE_DYNBIND || MPT_ENABLE_TEMPFILE)
-
-#if defined(MODPLUG_TRACKER) && MPT_OS_WINDOWS
-
-	bool FileOrDirectoryExists() const;
-
-#endif // MODPLUG_TRACKER && MPT_OS_WINDOWS
-
-	static bool IsPathSeparator(RawPathString::value_type c);
-	static RawPathString::value_type GetDefaultPathSeparator();
-
-#if defined(MODPLUG_TRACKER) && MPT_OS_WINDOWS
-
-	// Return the same path string with a different (or appended) extension (including "."), e.g. "foo.bar",".txt" -> "foo.txt" or "C:\OpenMPT\foo",".txt" -> "C:\OpenMPT\foo.txt"
-	PathString ReplaceExt(const mpt::PathString &newExt) const;
-
-	// Removes special characters from a filename component and replaces them with a safe replacement character ("_" on windows).
-	// Returns the result.
-	// Note that this also removes path component separators, so this should only be used on single-component PathString objects.
-	PathString SanitizeComponent() const;
-
-	bool HasTrailingSlash() const
-	{
-		if(path.empty())
-		{
-			return false;
-		}
-		RawPathString::value_type c = path[path.length() - 1];
-		return IsPathSeparator(c);
-	}
-	mpt::PathString &EnsureTrailingSlash()
-	{
-		if(!path.empty() && !HasTrailingSlash())
-		{
-			path += GetDefaultPathSeparator();
-		}
-		return *this;
-	}
-
-	mpt::PathString WithoutTrailingSlash() const
-	{
-		mpt::PathString result = *this;
-		while(result.HasTrailingSlash())
-		{
-			if(result.Length() == 1)
-			{
-				return result;
-			}
-			result = mpt::PathString(result.AsNative().substr(0, result.AsNative().length() - 1));
-		}
-		return result;
-	}
-
-	mpt::PathString WithTrailingSlash() const
-	{
-		mpt::PathString result = *this;
-		result.EnsureTrailingSlash();
-		return result;
-	}
-
-	// Relative / absolute paths conversion
-	mpt::PathString AbsolutePathToRelative(const mpt::PathString &relativeTo) const;
-	mpt::PathString RelativePathToAbsolute(const mpt::PathString &relativeTo) const;
-
-#endif // MODPLUG_TRACKER && MPT_OS_WINDOWS
-
-public:
-
-#if MPT_OS_WINDOWS
-
-#if !(MPT_WSTRING_CONVERT)
-#error "mpt::PathString on Windows depends on MPT_WSTRING_CONVERT)"
-#endif
-	// conversions
-#if defined(MPT_ENABLE_CHARSET_LOCALE)
-	MPT_DEPRECATED_PATH std::string ToLocale() const { return mpt::ToCharset(mpt::Charset::Locale, path); }
-#endif
-	std::string ToUTF8() const { return mpt::ToCharset(mpt::Charset::UTF8, path); }
-	std::wstring ToWide() const { return mpt::ToWide(path); }
-	mpt::ustring ToUnicode() const { return mpt::ToUnicode(path); }
-#if defined(MPT_ENABLE_CHARSET_LOCALE)
-	MPT_DEPRECATED_PATH static PathString FromLocale(const std::string &path) { return PathString(mpt::ToWin(mpt::Charset::Locale, path)); }
-	static PathString FromLocaleSilent(const std::string &path) { return PathString(mpt::ToWin(mpt::Charset::Locale, path)); }
-#endif
-	static PathString FromUTF8(const std::string &path) { return PathString(mpt::ToWin(mpt::Charset::UTF8, path)); }
-	static PathString FromWide(const std::wstring &path) { return PathString(mpt::ToWin(path)); }
-	static PathString FromUnicode(const mpt::ustring &path) { return PathString(mpt::ToWin(path)); }
-	RawPathString AsNative() const { return path; }
-	// Return native string, with possible \\?\ prefix if it exceeds MAX_PATH characters.
-	RawPathString AsNativePrefixed() const;
-	static PathString FromNative(const RawPathString &path) { return PathString(path); }
-#if defined(_MFC_VER)
-	// CString TCHAR, so this is CHAR or WCHAR, depending on UNICODE
-	CString ToCString() const { return mpt::ToCString(path); }
-	static PathString FromCString(const CString &path) { return PathString(mpt::ToWin(path)); }
-#endif
-
-	// Convert a path to its simplified form, i.e. remove ".\" and "..\" entries
-	mpt::PathString Simplify() const;
-
-#else // !MPT_OS_WINDOWS
-
-	// conversions
-#if defined(MPT_ENABLE_CHARSET_LOCALE)
-	std::string ToLocale() const { return path; }
-	std::string ToUTF8() const { return mpt::ToCharset(mpt::Charset::UTF8, mpt::Charset::Locale, path); }
-#if MPT_WSTRING_CONVERT
-	std::wstring ToWide() const { return mpt::ToWide(mpt::Charset::Locale, path); }
-#endif
-	mpt::ustring ToUnicode() const { return mpt::ToUnicode(mpt::Charset::Locale, path); }
-	static PathString FromLocale(const std::string &path) { return PathString(path); }
-	static PathString FromLocaleSilent(const std::string &path) { return PathString(path); }
-	static PathString FromUTF8(const std::string &path) { return PathString(mpt::ToCharset(mpt::Charset::Locale, mpt::Charset::UTF8, path)); }
-#if MPT_WSTRING_CONVERT
-	static PathString FromWide(const std::wstring &path) { return PathString(mpt::ToCharset(mpt::Charset::Locale, path)); }
-#endif
-	static PathString FromUnicode(const mpt::ustring &path) { return PathString(mpt::ToCharset(mpt::Charset::Locale, path)); }
-	RawPathString AsNative() const { return path; }
-	RawPathString AsNativePrefixed() const { return path; }
-	static PathString FromNative(const RawPathString &path) { return PathString(path); }
-#else // !MPT_ENABLE_CHARSET_LOCALE
-	std::string ToUTF8() const { return path; }
-#if MPT_WSTRING_CONVERT
-	std::wstring ToWide() const { return mpt::ToWide(mpt::Charset::UTF8, path); }
-#endif
-	mpt::ustring ToUnicode() const { return mpt::ToUnicode(mpt::Charset::UTF8, path); }
-	static PathString FromUTF8(const std::string &path) { return PathString(path); }
-#if MPT_WSTRING_CONVERT
-	static PathString FromWide(const std::wstring &path) { return PathString(mpt::ToCharset(mpt::Charset::UTF8, path)); }
-#endif
-	static PathString FromUnicode(const mpt::ustring &path) { return PathString(mpt::ToCharset(mpt::Charset::UTF8, path)); }
-	RawPathString AsNative() const { return path; }
-	RawPathString AsNativePrefixed() const { return path; }
-	static PathString FromNative(const RawPathString &path) { return PathString(path); }
-#endif // MPT_ENABLE_CHARSET_LOCALE
-
-	// Convert a path to its simplified form (currently only implemented on Windows)
-	[[deprecated]] mpt::PathString Simplify() const { return PathString(path); }
-
-#endif // MPT_OS_WINDOWS
-
-};
-
-
-
-#if defined(MPT_ENABLE_CHARSET_LOCALE)
-#if MPT_OS_WINDOWS
-#ifdef UNICODE
-[[deprecated]] static inline std::string ToString(const mpt::PathString & x) { return mpt::ToCharset(mpt::Charset::Locale, x.ToUnicode()); }
-#else
-MPT_DEPRECATED_PATH static inline std::string ToString(const mpt::PathString & x) { return mpt::ToCharset(mpt::Charset::Locale, x.AsNative()); }
-#endif
-#else
-MPT_DEPRECATED_PATH static inline std::string ToString(const mpt::PathString & x) { return mpt::ToCharset(mpt::Charset::Locale, x.ToUnicode()); }
-#endif
-#endif
-static inline mpt::ustring ToUString(const mpt::PathString & x) { return x.ToUnicode(); }
-#if MPT_WSTRING_FORMAT
-static inline std::wstring ToWString(const mpt::PathString & x) { return x.ToWide(); }
-#endif
-
-} // namespace mpt
-
-#if MPT_OS_WINDOWS
-
-#ifdef UNICODE
-#define MPT_PATHSTRING_LITERAL(x) ( L ## x )
-#define MPT_PATHSTRING(x) mpt::PathString::FromNative( L ## x )
-#else
-#define MPT_PATHSTRING_LITERAL(x) ( x )
-#define MPT_PATHSTRING(x) mpt::PathString::FromNative( x )
-#endif
-
-#else // !MPT_OS_WINDOWS
-
-#define MPT_PATHSTRING_LITERAL(x) ( x )
-#define MPT_PATHSTRING(x) mpt::PathString::FromNative( x )
-
-#endif // MPT_OS_WINDOWS
-
-#define PC_(x) MPT_PATHSTRING_LITERAL(x)
-#define PL_(x) MPT_PATHSTRING_LITERAL(x)
-#define P_(x) MPT_PATHSTRING(x)
-
-namespace mpt
-{
-
-
-bool PathIsAbsolute(const mpt::PathString &path);
-
-#if MPT_OS_WINDOWS
-
-// Returns the absolute path for a potentially relative path and removes ".." or "." components. (same as GetFullPathNameW)
-mpt::PathString GetAbsolutePath(const mpt::PathString &path);
-
-#ifdef MODPLUG_TRACKER
-
-// Deletes a complete directory tree. Handle with EXTREME care.
-// Returns false if any file could not be removed and aborts as soon as it
-// encounters any error. path must be absolute.
-bool DeleteWholeDirectoryTree(mpt::PathString path);
-
-#endif // MODPLUG_TRACKER
-
-#endif // MPT_OS_WINDOWS
-
-#if MPT_OS_WINDOWS
-
-#if defined(MPT_ENABLE_DYNBIND) || defined(MPT_ENABLE_TEMPFILE)
-
-// Returns the application executable path or an empty string (if unknown), e.g. "C:\mptrack\"
-mpt::PathString GetExecutablePath();
-
-#endif // MPT_ENABLE_DYNBIND || MPT_ENABLE_TEMPFILE
-
-#if defined(MPT_ENABLE_DYNBIND)
-
-#if !MPT_OS_WINDOWS_WINRT
-// Returns the system directory path, e.g. "C:\Windows\System32\"
-mpt::PathString GetSystemPath();
-#endif // !MPT_OS_WINDOWS_WINRT
-
-#endif // MPT_ENABLE_DYNBIND
-
-#endif // MPT_OS_WINDOWS
-
-#if defined(MPT_ENABLE_TEMPFILE)
-#if MPT_OS_WINDOWS
-
-// Returns temporary directory (with trailing backslash added) (e.g. "C:\TEMP\")
-mpt::PathString GetTempDirectory();
-
-// Returns a new unique absolute path.
-mpt::PathString CreateTempFileName(const mpt::PathString &fileNamePrefix = mpt::PathString(), const mpt::PathString &fileNameExtension = P_("tmp"));
-
-
-
-// Scoped temporary file guard. Deletes the file when going out of scope.
-// The file itself is not created automatically.
-class TempFileGuard
-{
-private:
-	const mpt::PathString filename;
-public:
-	TempFileGuard(const mpt::PathString &filename = CreateTempFileName());
-	mpt::PathString GetFilename() const;
-	~TempFileGuard();
-};
-
-#ifdef MODPLUG_TRACKER
-
-// Scoped temporary directory guard. Deletes the directory when going out of scope.
-// The directory itself is created automatically.
-class TempDirGuard
-{
-private:
-	mpt::PathString dirname;
-public:
-	TempDirGuard(const mpt::PathString &dirname_ = CreateTempFileName());
-	mpt::PathString GetDirname() const;
-	~TempDirGuard();
-};
-
-#endif // MODPLUG_TRACKER
-
-#endif // MPT_OS_WINDOWS
-#endif // MPT_ENABLE_TEMPFILE
-
-} // namespace mpt
-
-
-
-#if defined(MODPLUG_TRACKER)
-
-// Sanitize a filename (remove special chars)
-void SanitizeFilename(mpt::PathString &filename);
-
-void SanitizeFilename(char *beg, char *end);
-void SanitizeFilename(wchar_t *beg, wchar_t *end);
-
-void SanitizeFilename(std::string &str);
-void SanitizeFilename(std::wstring &str);
-#if MPT_USTRING_MODE_UTF8
-void SanitizeFilename(mpt::u8string &str);
-#endif // MPT_USTRING_MODE_UTF8
-
-template <std::size_t size>
-void SanitizeFilename(char (&buffer)[size])
-{
-	static_assert(size > 0);
-	SanitizeFilename(buffer, buffer + size);
-}
-
-template <std::size_t size>
-void SanitizeFilename(wchar_t (&buffer)[size])
-{
-	static_assert(size > 0);
-	SanitizeFilename(buffer, buffer + size);
-}
-
-#if defined(_MFC_VER)
-void SanitizeFilename(CString &str);
-#endif
-
-#endif // MODPLUG_TRACKER
-
-
-#if defined(MODPLUG_TRACKER)
-
-enum FileTypeFormat
-{
-	FileTypeFormatNone           = 0   , // do not show extensions after description, i.e. "Foo Files"
-	FileTypeFormatShowExtensions = 1<<0, // show extensions after descripten, i.e. "Foo Files (*.foo,*.bar)"
-};
-MPT_DECLARE_ENUM(FileTypeFormat)
-
-class FileType
-{
-private:
-	mpt::ustring m_ShortName; // "flac", "mod" (lowercase)
-	mpt::ustring m_Description; // "FastTracker 2 Module"
-	std::vector<std::string> m_MimeTypes; // "audio/ogg" (in ASCII)
-	std::vector<mpt::PathString> m_Extensions; // "mod", "xm" (lowercase)
-	std::vector<mpt::PathString> m_Prefixes; // "mod" for "mod.*"
-public:
-	FileType() { }
-	FileType(const std::vector<FileType> &group)
-	{
-		for(const auto &type : group)
-		{
-			m_MimeTypes.insert(m_MimeTypes.end(), type.m_MimeTypes.begin(), type.m_MimeTypes.end());
-			m_Extensions.insert(m_Extensions.end(), type.m_Extensions.begin(), type.m_Extensions.end());
-			m_Prefixes.insert(m_Prefixes.end(), type.m_Prefixes.begin(), type.m_Prefixes.end());
-		}
-	}
-	static FileType Any()
-	{
-		return FileType().ShortName(U_("*")).Description(U_("All Files")).AddExtension(P_("*"));
-	}
-public:
-	FileType& ShortName(const mpt::ustring &shortName) { m_ShortName = shortName; return *this; }
-	FileType& Description(const mpt::ustring &description) { m_Description = description; return *this; }
-	FileType& MimeTypes(const std::vector<std::string> &mimeTypes) { m_MimeTypes = mimeTypes; return *this; }
-	FileType& Extensions(const std::vector<mpt::PathString> &extensions) { m_Extensions = extensions; return *this; }
-	FileType& Prefixes(const std::vector<mpt::PathString> &prefixes) { m_Prefixes = prefixes; return *this; }
-	FileType& AddMimeType(const std::string &mimeType) { m_MimeTypes.push_back(mimeType); return *this; }
-	FileType& AddExtension(const mpt::PathString &extension) { m_Extensions.push_back(extension); return *this; }
-	FileType& AddPrefix(const mpt::PathString &prefix) { m_Prefixes.push_back(prefix); return *this; }
-public:
-	mpt::ustring GetShortName() const { return m_ShortName; }
-	mpt::ustring GetDescription() const { return m_Description; }
-	std::vector<std::string> GetMimeTypes() const { return m_MimeTypes; }
-	std::vector<mpt::PathString> GetExtensions() const { return m_Extensions; }
-	std::vector<mpt::PathString> GetPrefixes() const { return m_Prefixes; }
-public:
-	mpt::PathString AsFilterString(FlagSet<FileTypeFormat> format = FileTypeFormatNone) const;
-	mpt::PathString AsFilterOnlyString() const;
-}; // class FileType
-
-
-// "Ogg Vorbis|*.ogg;*.oga|" // FileTypeFormatNone
-// "Ogg Vorbis (*.ogg,*.oga)|*.ogg;*.oga|" // FileTypeFormatShowExtensions
-mpt::PathString ToFilterString(const FileType &fileType, FlagSet<FileTypeFormat> format = FileTypeFormatNone);
-mpt::PathString ToFilterString(const std::vector<FileType> &fileTypes, FlagSet<FileTypeFormat> format = FileTypeFormatNone);
-
-// "*.ogg;*.oga" / ";*.ogg;*.oga"
-mpt::PathString ToFilterOnlyString(const FileType &fileType, bool prependSemicolonWhenNotEmpty = false);
-mpt::PathString ToFilterOnlyString(const std::vector<FileType> &fileTypes, bool prependSemicolonWhenNotEmpty = false);
-
-#endif // MODPLUG_TRACKER
-
-
-OPENMPT_NAMESPACE_END

+ 0 - 301
libopenmpt.mod/openmpt/common/mptRandom.cpp

@@ -1,301 +0,0 @@
-/*
- * mptRandom.cpp
- * -------------
- * Purpose: PRNG
- * Notes  : (currently none)
- * Authors: OpenMPT Devs
- * The OpenMPT source code is released under the BSD license. Read LICENSE for more details.
- */
-
-#include "stdafx.h"
-
-#include "mptRandom.h"
-
-#include "Endianness.h"
-#include "mptCRC.h"
-
-#include <chrono>
-
-#include <cmath>
-#include <cstdlib>
-
-
-OPENMPT_NAMESPACE_BEGIN
-
-
-namespace mpt
-{
-
-
-template <typename T>
-static T log2(T x)
-{
-	return std::log(x) / std::log(static_cast<T>(2));
-}
-
-
-static MPT_CONSTEXPR11_FUN int lower_bound_entropy_bits(unsigned int x)
-{
-	return detail::lower_bound_entropy_bits(x);
-}
-
-
-template <typename T>
-static MPT_CONSTEXPR14_FUN bool is_mask(T x)
-{
-	static_assert(std::numeric_limits<T>::is_integer);
-	typedef typename std::make_unsigned<T>::type unsigned_T;
-	unsigned_T ux = static_cast<unsigned_T>(x);
-	unsigned_T mask = 0;
-	for(std::size_t bits = 0; bits <= (sizeof(unsigned_T) * 8); ++bits)
-	{
-		mask = (mask << 1) | 1u;
-		if(ux == mask)
-		{
-			return true;
-		}
-	}
-	return false;
-}
-
-
-namespace {
-template <typename T> struct default_hash { };
-template <> struct default_hash<uint8>  { typedef mpt::checksum::crc16 type; };
-template <> struct default_hash<uint16> { typedef mpt::checksum::crc16 type; };
-template <> struct default_hash<uint32> { typedef mpt::checksum::crc32c type; };
-template <> struct default_hash<uint64> { typedef mpt::checksum::crc64_jones type; };
-}
-
-template <typename T>
-static T generate_timeseed()
-{
-	// Note: CRC is actually not that good a choice here, but it is simple and we
-	// already have an implementaion available. Better choices for mixing entropy
-	// would be a hash function with proper avalanche characteristics or a block
-	// or stream cipher with any pre-choosen random key and IV. The only aspect we
-	// really need here is whitening of the bits.
-	typename mpt::default_hash<T>::type hash;
-	
-#ifdef MPT_BUILD_FUZZER
-
-	return static_cast<T>(mpt::FUZZER_RNG_SEED);
-
-#else // !MPT_BUILD_FUZZER
-
-	{
-		uint64be time;
-		time = std::chrono::duration_cast<std::chrono::nanoseconds>(std::chrono::system_clock().now().time_since_epoch()).count();
-		std::byte bytes[sizeof(time)];
-		std::memcpy(bytes, &time, sizeof(time));
-		hash(std::begin(bytes), std::end(bytes));
-	}
-
-	{
-		uint64be time;
-		time = std::chrono::duration_cast<std::chrono::nanoseconds>(std::chrono::high_resolution_clock().now().time_since_epoch()).count();
-		std::byte bytes[sizeof(time)];
-		std::memcpy(bytes, &time, sizeof(time));
-		hash(std::begin(bytes), std::end(bytes));
-	}
-
-	return static_cast<T>(hash.result());
-
-#endif // MPT_BUILD_FUZZER
-
-}
-
-
-#ifdef MODPLUG_TRACKER
-
-namespace rng
-{
-
-void crand::reseed(uint32 seed)
-{
-	std::srand(seed);
-}
-
-crand::result_type crand::operator()()
-{
-	return std::rand();
-}
-
-} // namespace rng
-
-#endif // MODPLUG_TRACKER
-
-sane_random_device::sane_random_device()
-	: rd_reliable(rd.entropy() > 0.0)
-{
-	if(!rd_reliable)
-	{
-		init_fallback();
-	}
-}
-
-sane_random_device::sane_random_device(const std::string & token_)
-	: token(token_)
-	, rd(token)
-	, rd_reliable(rd.entropy() > 0.0)
-{
-	if(!rd_reliable)
-	{
-		init_fallback();
-	}
-}
-
-void sane_random_device::init_fallback()
-{
-	if(!rd_fallback)
-	{
-		if(token.length() > 0)
-		{
-			uint64 seed_val = mpt::generate_timeseed<uint64>();
-			std::vector<unsigned int> seeds;
-			seeds.push_back(static_cast<uint32>(seed_val >> 32));
-			seeds.push_back(static_cast<uint32>(seed_val >>  0));
-			for(std::size_t i = 0; i < token.length(); ++i)
-			{
-				seeds.push_back(static_cast<unsigned int>(static_cast<unsigned char>(token[i])));
-			}
-			std::seed_seq seed(seeds.begin(), seeds.end());
-			rd_fallback = std::make_unique<std::mt19937>(seed);
-		} else
-		{
-			uint64 seed_val = mpt::generate_timeseed<uint64>();
-			unsigned int seeds[2];
-			seeds[0] = static_cast<uint32>(seed_val >> 32);
-			seeds[1] = static_cast<uint32>(seed_val >>  0);
-			std::seed_seq seed(seeds + 0, seeds + 2);
-			rd_fallback = std::make_unique<std::mt19937>(seed);
-		}
-	}
-}
-
-sane_random_device::result_type sane_random_device::operator()()
-{
-	MPT_LOCK_GUARD<mpt::mutex> l(m);
-	result_type result = 0;
-	try
-	{
-		if constexpr(decltype(rd)::min() != 0 || !mpt::is_mask(decltype(rd)::max()))
-		{ // insane std::random_device
-			//  This implementation is not exactly uniformly distributed but good enough
-			// for OpenMPT.
-			double rd_min = static_cast<double>(decltype(rd)::min());
-			double rd_max = static_cast<double>(decltype(rd)::max());
-			double rd_range = rd_max - rd_min;
-			double rd_size = rd_range + 1.0;
-			double rd_entropy = mpt::log2(rd_size);
-			int iterations = static_cast<int>(std::ceil(result_bits() / rd_entropy));
-			double tmp = 0.0;
-			for(int i = 0; i < iterations; ++i)
-			{
-				tmp = (tmp * rd_size) + (static_cast<double>(rd()) - rd_min);
-			}
-			double result_01 = std::floor(tmp / std::pow(rd_size, iterations));
-			result = static_cast<result_type>(std::floor(result_01 * (static_cast<double>(max() - min()) + 1.0))) + min();
-		} else
-		{ // sane std::random_device
-			result = 0;
-			std::size_t rd_bits = mpt::lower_bound_entropy_bits(decltype(rd)::max());
-			for(std::size_t entropy = 0; entropy < (sizeof(result_type) * 8); entropy += rd_bits)
-			{
-				if(rd_bits < (sizeof(result_type) * 8))
-				{
-					result = (result << rd_bits) | static_cast<result_type>(rd());
-				} else
-				{
-					result = result | static_cast<result_type>(rd());
-				}
-			}
-		}
-	} catch(const std::exception &)
-	{
-		rd_reliable = false;
-		init_fallback();
-	}
-	if(!rd_reliable)
-	{ // std::random_device is unreliable
-		//  XOR the generated random number with more entropy from the time-seeded
-		// PRNG.
-		//  Note: This is safe even if the std::random_device itself is implemented
-		// as a std::mt19937 PRNG because we are very likely using a different
-		// seed.
-		result ^= mpt::random<result_type>(*rd_fallback);
-	}
-	return result;
-}
-
-prng_random_device_seeder::prng_random_device_seeder()
-{
-	return;
-}
-
-uint8 prng_random_device_seeder::generate_seed8()
-{
-	return mpt::generate_timeseed<uint8>();
-}
-
-uint16 prng_random_device_seeder::generate_seed16()
-{
-	return mpt::generate_timeseed<uint16>();
-}
-
-uint32 prng_random_device_seeder::generate_seed32()
-{
-	return mpt::generate_timeseed<uint32>();
-}
-
-uint64 prng_random_device_seeder::generate_seed64()
-{
-	return mpt::generate_timeseed<uint64>();
-}
-
-#if defined(MODPLUG_TRACKER) && !defined(MPT_BUILD_WINESUPPORT)
-
-static mpt::random_device *g_rd = nullptr;
-static mpt::thread_safe_prng<mpt::default_prng> *g_global_prng = nullptr;
-
-void set_global_random_device(mpt::random_device *rd)
-{
-	g_rd = rd;
-}
-
-void set_global_prng(mpt::thread_safe_prng<mpt::default_prng> *prng)
-{
-	g_global_prng = prng;
-}
-
-mpt::random_device & global_random_device()
-{
-	return *g_rd;
-}
-
-mpt::thread_safe_prng<mpt::default_prng> & global_prng()
-{
-	return *g_global_prng;
-}
-
-#else
-
-mpt::random_device & global_random_device()
-{
-	static mpt::random_device g_rd;
-	return g_rd;
-}
-
-mpt::thread_safe_prng<mpt::default_prng> & global_prng()
-{
-	static mpt::thread_safe_prng<mpt::default_prng> g_global_prng(mpt::make_prng<mpt::default_prng>(global_random_device()));
-	return g_global_prng;
-}
-
-#endif // MODPLUG_TRACKER && !MPT_BUILD_WINESUPPORT
-
-
-} // namespace mpt
-
-
-OPENMPT_NAMESPACE_END

+ 0 - 668
libopenmpt.mod/openmpt/common/mptRandom.h

@@ -1,668 +0,0 @@
-/*
- * mptRandom.h
- * -----------
- * Purpose: PRNG
- * Notes  : (currently none)
- * Authors: OpenMPT Devs
- * The OpenMPT source code is released under the BSD license. Read LICENSE for more details.
- */
-
-
-#pragma once
-
-#include "BuildSettings.h"
-
-#include "mptMutex.h"
-
-#include <limits>
-#include <random>
-
-#ifdef MODPLUG_TRACKER
-#include <cstdlib>
-#endif // MODPLUG_TRACKER
-
-
-OPENMPT_NAMESPACE_BEGIN
-
-
-// NOTE:
-//  We implement our own PRNG and distribution functions as the implementations
-// of std::uniform_int_distribution is either wrong (not uniform in MSVC2010) or
-// not guaranteed to be livelock-free for bad PRNGs (in GCC, Clang, boost).
-// We resort to a simpler implementation with only power-of-2 result ranges for
-// both the underlying PRNG and our interface function. This saves us from
-// complicated code having to deal with partial bits of entropy.
-//  Our interface still somewhat follows the mindset of C++11 <random> (with the
-// addition of a simple wrapper function mpt::random which saves the caller from
-// instantiating distribution objects for the common uniform distribution case.
-//  We are still using std::random_device for initial seeding when avalable and
-// after working around its set of problems.
-
-
-namespace mpt
-{
-
-
-#ifdef MPT_BUILD_FUZZER
-static const uint32 FUZZER_RNG_SEED = 3141592653u; // pi
-#endif // MPT_BUILD_FUZZER
-
-
-namespace detail
-{
-
-MPT_CONSTEXPR11_FUN int lower_bound_entropy_bits(unsigned int x)
-{
-	// easy to compile-time evaluate even for stupid compilers
-	return
-		x >= 0xffffffffu ? 32 :
-		x >= 0x7fffffffu ? 31 :
-		x >= 0x3fffffffu ? 30 :
-		x >= 0x1fffffffu ? 29 :
-		x >= 0x0fffffffu ? 28 :
-		x >= 0x07ffffffu ? 27 :
-		x >= 0x03ffffffu ? 26 :
-		x >= 0x01ffffffu ? 25 :
-		x >= 0x00ffffffu ? 24 :
-		x >= 0x007fffffu ? 23 :
-		x >= 0x003fffffu ? 22 :
-		x >= 0x001fffffu ? 21 :
-		x >= 0x000fffffu ? 20 :
-		x >= 0x0007ffffu ? 19 :
-		x >= 0x0003ffffu ? 18 :
-		x >= 0x0001ffffu ? 17 :
-		x >= 0x0000ffffu ? 16 :
-		x >= 0x00007fffu ? 15 :
-		x >= 0x00003fffu ? 14 :
-		x >= 0x00001fffu ? 13 :
-		x >= 0x00000fffu ? 12 :
-		x >= 0x000007ffu ? 11 :
-		x >= 0x000003ffu ? 10 :
-		x >= 0x000001ffu ?  9 :
-		x >= 0x000000ffu ?  8 :
-		x >= 0x0000007fu ?  7 :
-		x >= 0x0000003fu ?  6 :
-		x >= 0x0000001fu ?  5 :
-		x >= 0x0000000fu ?  4 :
-		x >= 0x00000007u ?  3 :
-		x >= 0x00000003u ?  2 :
-		x >= 0x00000001u ?  1 :
-		0;
-}
-
-}
-
-
-template <typename Trng> struct engine_traits
-{
-	typedef typename Trng::result_type result_type;
-	static MPT_CONSTEXPR11_FUN int result_bits()
-	{
-		return Trng::result_bits();
-	}
-	template<typename Trd>
-	static inline Trng make(Trd & rd)
-	{
-		return Trng(rd);
-	}
-};
-
-
-template <typename T, typename Trng>
-inline T random(Trng & rng)
-{
-	static_assert(std::numeric_limits<T>::is_integer);
-	typedef typename std::make_unsigned<T>::type unsigned_T;
-	const unsigned int rng_bits = mpt::engine_traits<Trng>::result_bits();
-	unsigned_T result = 0;
-	for(std::size_t entropy = 0; entropy < (sizeof(T) * 8); entropy += rng_bits)
-	{
-		if constexpr(rng_bits < (sizeof(T) * 8))
-		{
-			MPT_CONSTEXPR11_VAR unsigned int shift_bits = rng_bits % (sizeof(T) * 8); // silence utterly stupid MSVC and GCC warnings about shifting by too big amount (in which case this branch is not even taken however)
-			result = (result << shift_bits) ^ static_cast<unsigned_T>(rng());
-		} else
-		{
-			result = static_cast<unsigned_T>(rng());
-		}
-	}
-	return static_cast<T>(result);
-}
-
-template <typename T, std::size_t required_entropy_bits, typename Trng>
-inline T random(Trng & rng)
-{
-	static_assert(std::numeric_limits<T>::is_integer);
-	typedef typename std::make_unsigned<T>::type unsigned_T;
-	const unsigned int rng_bits = mpt::engine_traits<Trng>::result_bits();
-	unsigned_T result = 0;
-	for(std::size_t entropy = 0; entropy < std::min(required_entropy_bits, sizeof(T) * 8); entropy += rng_bits)
-	{
-		if constexpr(rng_bits < (sizeof(T) * 8))
-		{
-			MPT_CONSTEXPR11_VAR unsigned int shift_bits = rng_bits % (sizeof(T) * 8); // silence utterly stupid MSVC and GCC warnings about shifting by too big amount (in which case this branch is not even taken however)
-			result = (result << shift_bits) ^ static_cast<unsigned_T>(rng());
-		} else
-		{
-			result = static_cast<unsigned_T>(rng());
-		}
-	}
-	if constexpr(required_entropy_bits >= (sizeof(T) * 8))
-	{
-		return static_cast<T>(result);
-	} else
-	{
-		return static_cast<T>(result & ((static_cast<unsigned_T>(1) << required_entropy_bits) - static_cast<unsigned_T>(1)));
-	}
-}
-
-template <typename T, typename Trng>
-inline T random(Trng & rng, std::size_t required_entropy_bits)
-{
-	static_assert(std::numeric_limits<T>::is_integer);
-	typedef typename std::make_unsigned<T>::type unsigned_T;
-	const unsigned int rng_bits = mpt::engine_traits<Trng>::result_bits();
-	unsigned_T result = 0;
-	for(std::size_t entropy = 0; entropy < std::min(required_entropy_bits, sizeof(T) * 8); entropy += rng_bits)
-	{
-		if constexpr(rng_bits < (sizeof(T) * 8))
-		{
-			MPT_CONSTEXPR11_VAR unsigned int shift_bits = rng_bits % (sizeof(T) * 8); // silence utterly stupid MSVC and GCC warnings about shifting by too big amount (in which case this branch is not even taken however)
-			result = (result << shift_bits) ^ static_cast<unsigned_T>(rng());
-		} else
-		{
-			result = static_cast<unsigned_T>(rng());
-		}
-	}
-	if(required_entropy_bits >= (sizeof(T) * 8))
-	{
-		return static_cast<T>(result);
-	} else
-	{
-		return static_cast<T>(result & ((static_cast<unsigned_T>(1) << required_entropy_bits) - static_cast<unsigned_T>(1)));
-	}
-}
-
-template <typename T>
-struct uniform_real_distribution
-{
-private:
-	T a;
-	T b;
-public:
-	inline uniform_real_distribution(T a, T b)
-		: a(a)
-		, b(b)
-	{
-		return;
-	}
-	template <typename Trng>
-	inline T operator()(Trng & rng) const
-	{
-		const int mantissa_bits = std::numeric_limits<T>::digits;
-		return ((b - a) * static_cast<T>(mpt::random<uint64, mantissa_bits>(rng)) / static_cast<T>((static_cast<uint64>(1u) << mantissa_bits))) + a;
-	}
-};
-
-
-template <typename T, typename Trng>
-inline T random(Trng & rng, T min, T max)
-{
-	static_assert(!std::numeric_limits<T>::is_integer);
-	typedef mpt::uniform_real_distribution<T> dis_type;
-	dis_type dis(min, max);
-	return static_cast<T>(dis(rng));
-}
-
-
-namespace rng
-{
-
-#if MPT_COMPILER_MSVC
-#pragma warning(push)
-#pragma warning(disable:4724) // potential mod by 0
-#endif // MPT_COMPILER_MSVC
-
-template <typename Tstate, typename Tvalue, Tstate m, Tstate a, Tstate c, Tstate result_mask, int result_shift, int result_bits_>
-class lcg
-{
-public:
-	typedef Tstate state_type;
-	typedef Tvalue result_type;
-private:
-	state_type state;
-public:
-	template <typename Trng>
-	explicit inline lcg(Trng & rd)
-		: state(mpt::random<state_type>(rd))
-	{
-		operator()(); // we return results from the current state and update state after returning. results in better pipelining.
-	}
-	explicit inline lcg(state_type seed)
-		: state(seed)
-	{
-		operator()(); // we return results from the current state and update state after returning. results in better pipelining.
-	}
-public:
-	static MPT_CONSTEXPR11_FUN result_type min()
-	{
-		return static_cast<result_type>(0);
-	}
-	static MPT_CONSTEXPR11_FUN result_type max()
-	{
-		static_assert(((result_mask >> result_shift) << result_shift) == result_mask);
-		return static_cast<result_type>(result_mask >> result_shift);
-	}
-	static MPT_CONSTEXPR11_FUN int result_bits()
-	{
-		static_assert(((static_cast<Tstate>(1) << result_bits_) - 1) == (result_mask >> result_shift));
-		return result_bits_;
-	}
-	inline result_type operator()()
-	{
-		// we return results from the current state and update state after returning. results in better pipelining.
-		state_type s = state;
-		result_type result = static_cast<result_type>((s & result_mask) >> result_shift);
-		s = Util::ModIfNotZero<state_type, m>((a * s) + c);
-		state = s;
-		return result;
-	}
-};
-
-#if MPT_COMPILER_MSVC
-#pragma warning(pop)
-#endif // MPT_COMPILER_MSVC
-
-typedef lcg<uint32, uint16, 0u, 214013u, 2531011u, 0x7fff0000u, 16, 15> lcg_msvc;
-typedef lcg<uint32, uint16, 0x80000000u, 1103515245u, 12345u, 0x7fff0000u, 16, 15> lcg_c99;
-typedef lcg<uint64, uint32, 0ull, 6364136223846793005ull, 1ull, 0xffffffff00000000ull, 32, 32> lcg_musl;
-
-template <typename Tstate, typename Tvalue, Tstate x1, Tstate x2, Tstate x3, Tstate x4, int rol1, int rol2>
-class modplug
-{
-public:
-	typedef Tstate state_type;
-	typedef Tvalue result_type;
-private:
-	state_type state1;
-	state_type state2;
-public:
-	template <typename Trng>
-	explicit inline modplug(Trng &rd)
-		: state1(mpt::random<state_type>(rd))
-	  , state2(mpt::random<state_type>(rd))
-	{
-	}
-	explicit inline modplug(state_type seed1, state_type seed2)
-		: state1(seed1)
-		, state2(seed2)
-	{
-	}
-public:
-	static MPT_CONSTEXPR11_FUN result_type min()
-	{
-		return static_cast<result_type>(0);
-	}
-	static MPT_CONSTEXPR11_FUN result_type max()
-	{
-		return std::numeric_limits<result_type>::max();
-	}
-	static MPT_CONSTEXPR11_FUN int result_bits()
-	{
-		static_assert(std::is_integral<result_type>::value);
-		static_assert(std::is_unsigned<result_type>::value);
-		return std::numeric_limits<result_type>::digits;
-	}
-	inline result_type operator()()
-	{
-		state_type a = state1;
-		state_type b = state2;
-		a = mpt::rotl(a, rol1);
-		a ^= x1;
-		a += x2 + (b * x3);
-		b += mpt::rotl(a, rol2) * x4;
-		state1 = a;
-		state2 = b;
-		result_type result = static_cast<result_type>(b);
-		return result;
-	}
-};
-
-typedef modplug<uint32, uint32, 0x10204080u, 0x78649E7Du, 4, 5, 1, 16> modplug_dither;
-
-} // namespace rng
-
-
-#ifdef MODPLUG_TRACKER
-
-namespace rng
-{
-
-class crand
-{
-public:
-	typedef void state_type;
-	typedef int result_type;
-private:
-	static void reseed(uint32 seed);
-public:
-	template <typename Trd>
-	static void reseed(Trd & rd)
-	{
-		reseed(mpt::random<uint32>(rd));
-	}
-public:
-	crand() { }
-	explicit crand(const std::string &) { }
-public:
-	static MPT_CONSTEXPR11_FUN result_type min()
-	{
-		return 0;
-	}
-	static MPT_CONSTEXPR11_FUN result_type max()
-	{
-		return RAND_MAX;
-	}
-	static MPT_CONSTEXPR11_FUN int result_bits()
-	{
-		return detail::lower_bound_entropy_bits(RAND_MAX);
-	}
-	result_type operator()();
-};
-
-} // namespace rng
-
-#endif // MODPLUG_TRACKER
-
-
-//  C++11 std::random_device may be implemented as a deterministic PRNG.
-//  There is no way to seed this PRNG and it is allowed to be seeded with the
-// same value on each program invocation. This makes std::random_device
-// completely useless even as a non-cryptographic entropy pool.
-//  We fallback to time-seeded std::mt19937 if std::random_device::entropy() is
-// 0 or less.
-class sane_random_device
-{
-private:
-	mpt::mutex m;
-	std::string token;
-	std::random_device rd;
-	bool rd_reliable;
-	std::unique_ptr<std::mt19937> rd_fallback;
-public:
-	typedef unsigned int result_type;
-private:
-	void init_fallback();
-public:
-	sane_random_device();
-	sane_random_device(const std::string & token);
-	static MPT_CONSTEXPR11_FUN result_type min()
-	{
-		return std::numeric_limits<result_type>::min();
-	}
-	static MPT_CONSTEXPR11_FUN result_type max()
-	{
-		return std::numeric_limits<result_type>::max();
-	}
-	static MPT_CONSTEXPR11_FUN int result_bits()
-	{
-		return sizeof(result_type) * 8;
-	}
-	result_type operator()();
-};
-
-
-template <std::size_t N>
-class seed_seq_values
-{
-private:
-	unsigned int seeds[N];
-public:
-	template <typename Trd>
-	explicit seed_seq_values(Trd & rd)
-	{
-		for(std::size_t i = 0; i < N; ++i)
-		{
-			seeds[i] = rd();
-		}
-	}
-	const unsigned int * begin() const
-	{
-		return seeds + 0;
-	}
-	const unsigned int * end() const
-	{
-		return seeds + N;
-	}
-};
-
-
-// C++11 random does not provide any sane way to determine the amount of entropy
-// required to seed a particular engine. VERY STUPID.
-// List the ones we are likely to use.
-
-template <> struct engine_traits<std::mt19937> {
-	enum : std::size_t { seed_bits = sizeof(std::mt19937::result_type) * 8 * std::mt19937::state_size };
-	typedef std::mt19937 rng_type;
-	typedef rng_type::result_type result_type;
-	static MPT_CONSTEXPR11_FUN int result_bits() { return rng_type::word_size; }
-	template<typename Trd> static inline rng_type make(Trd & rd)
-	{
-		std::unique_ptr<mpt::seed_seq_values<seed_bits / sizeof(unsigned int)>> values = std::make_unique<mpt::seed_seq_values<seed_bits / sizeof(unsigned int)>>(rd);
-		std::seed_seq seed(values->begin(), values->end());
-		return rng_type(seed);
-	}
-};
-
-template <> struct engine_traits<std::mt19937_64> {
-	enum : std::size_t { seed_bits = sizeof(std::mt19937_64::result_type) * 8 * std::mt19937_64::state_size };
-	typedef std::mt19937_64 rng_type;
-	typedef rng_type::result_type result_type;
-	static MPT_CONSTEXPR11_FUN int result_bits() { return rng_type::word_size; }
-	template<typename Trd> static inline rng_type make(Trd & rd)
-	{
-		std::unique_ptr<mpt::seed_seq_values<seed_bits / sizeof(unsigned int)>> values = std::make_unique<mpt::seed_seq_values<seed_bits / sizeof(unsigned int)>>(rd);
-		std::seed_seq seed(values->begin(), values->end());
-		return rng_type(seed);
-	}
-};
-
-template <> struct engine_traits<std::ranlux24_base> {
-	enum : std::size_t { seed_bits = std::ranlux24_base::word_size };
-	typedef std::ranlux24_base rng_type;
-	typedef rng_type::result_type result_type;
-	static MPT_CONSTEXPR11_FUN int result_bits() { return rng_type::word_size; }
-	template<typename Trd> static inline rng_type make(Trd & rd)
-	{
-		mpt::seed_seq_values<seed_bits / sizeof(unsigned int)> values(rd);
-		std::seed_seq seed(values.begin(), values.end());
-		return rng_type(seed);
-	}
-};
-
-template <> struct engine_traits<std::ranlux48_base> {
-	enum : std::size_t { seed_bits = std::ranlux48_base::word_size };
-	typedef std::ranlux48_base rng_type;
-	typedef rng_type::result_type result_type;
-	static MPT_CONSTEXPR11_FUN int result_bits() { return rng_type::word_size; }
-	template<typename Trd> static inline rng_type make(Trd & rd)
-	{
-		mpt::seed_seq_values<seed_bits / sizeof(unsigned int)> values(rd);
-		std::seed_seq seed(values.begin(), values.end());
-		return rng_type(seed);
-	}
-};
-
-template <> struct engine_traits<std::ranlux24> {
-	enum : std::size_t { seed_bits = std::ranlux24_base::word_size };
-	typedef std::ranlux24 rng_type;
-	typedef rng_type::result_type result_type;
-	static MPT_CONSTEXPR11_FUN int result_bits() { return std::ranlux24_base::word_size; }
-	template<typename Trd> static inline rng_type make(Trd & rd)
-	{
-		mpt::seed_seq_values<seed_bits / sizeof(unsigned int)> values(rd);
-		std::seed_seq seed(values.begin(), values.end());
-		return rng_type(seed);
-	}
-};
-
-template <> struct engine_traits<std::ranlux48> {
-	enum : std::size_t { seed_bits = std::ranlux48_base::word_size };
-	typedef std::ranlux48 rng_type;
-	typedef rng_type::result_type result_type;
-	static MPT_CONSTEXPR11_FUN int result_bits() { return std::ranlux48_base::word_size; }
-	template<typename Trd> static inline rng_type make(Trd & rd)
-	{
-		mpt::seed_seq_values<seed_bits / sizeof(unsigned int)> values(rd);
-		std::seed_seq seed(values.begin(), values.end());
-		return rng_type(seed);
-	}
-};
-
-
-class prng_random_device_seeder
-{
-private:
-	uint8 generate_seed8();
-	uint16 generate_seed16();
-	uint32 generate_seed32();
-	uint64 generate_seed64();
-protected:
-	template <typename T> inline T generate_seed();
-protected:
-	prng_random_device_seeder();
-};
-
-template <> inline uint8 prng_random_device_seeder::generate_seed() { return generate_seed8(); }
-template <> inline uint16 prng_random_device_seeder::generate_seed() { return generate_seed16(); }
-template <> inline uint32 prng_random_device_seeder::generate_seed() { return generate_seed32(); }
-template <> inline uint64 prng_random_device_seeder::generate_seed() { return generate_seed64(); }
-
-template <typename Trng = mpt::rng::lcg_musl>
-class prng_random_device
-	: public prng_random_device_seeder
-{
-public:
-	typedef unsigned int result_type;
-private:
-	mpt::mutex m;
-	Trng rng;
-public:
-	prng_random_device()
-		: rng(generate_seed<typename Trng::state_type>())
-	{
-		return;
-	}
-	prng_random_device(const std::string &)
-		: rng(generate_seed<typename Trng::state_type>())
-	{
-		return;
-	}
-	static MPT_CONSTEXPR11_FUN result_type min()
-	{
-		return std::numeric_limits<unsigned int>::min();
-	}
-	static MPT_CONSTEXPR11_FUN result_type max()
-	{
-		return std::numeric_limits<unsigned int>::max();
-	}
-	static MPT_CONSTEXPR11_FUN int result_bits()
-	{
-		return sizeof(unsigned int) * 8;
-	}
-	result_type operator()()
-	{
-		MPT_LOCK_GUARD<mpt::mutex> l(m);
-		return mpt::random<unsigned int>(rng);
-	}
-};
-
-
-#ifdef MPT_BUILD_FUZZER
-
-//  1. Use deterministic seeding
-typedef mpt::prng_random_device<mpt::rng::lcg_musl> random_device;
-
-//  2. Use fast PRNGs in order to not waste time fuzzing more complex PRNG
-//     implementations.
-typedef mpt::rng::lcg_msvc fast_prng;
-typedef mpt::rng::lcg_musl good_prng;
-
-#else // !MPT_BUILD_FUZZER
-
-// mpt::random_device always generates 32 bits of entropy
-typedef mpt::sane_random_device random_device;
-
-// We cannot use std::minstd_rand here because it has not a power-of-2 sized
-// output domain which we rely upon.
-typedef mpt::rng::lcg_msvc fast_prng; // about 3 ALU operations, ~32bit of state, suited for inner loops
-typedef std::ranlux48      good_prng;
-
-#endif // MPT_BUILD_FUZZER
-
-
-typedef mpt::good_prng default_prng;
-
-
-template <typename Trng, typename Trd>
-inline Trng make_prng(Trd & rd)
-{
-	return mpt::engine_traits<Trng>::make(rd);
-}
-
-
-template <typename Trng>
-class thread_safe_prng
-	: private Trng
-{
-private:
-	mpt::mutex m;
-public:
-	typedef typename Trng::result_type result_type;
-public:
-	template <typename Trd>
-	explicit thread_safe_prng(Trd & rd)
-		: Trng(mpt::make_prng<Trng>(rd))
-	{
-		return;
-	}
-	thread_safe_prng(Trng rng)
-		: Trng(rng)
-	{
-		return;
-	}
-public:
-	static MPT_CONSTEXPR11_FUN typename engine_traits<Trng>::result_type min()
-	{
-		return Trng::min();
-	}
-	static MPT_CONSTEXPR11_FUN typename engine_traits<Trng>::result_type max()
-	{
-		return Trng::max();
-	}
-	static MPT_CONSTEXPR11_FUN int result_bits()
-	{
-		return engine_traits<Trng>::result_bits();
-	}
-public:
-	typename engine_traits<Trng>::result_type operator()()
-	{
-		MPT_LOCK_GUARD<mpt::mutex> l(m);
-		return Trng::operator()();
-	}
-};
-
-
-mpt::random_device & global_random_device();
-mpt::thread_safe_prng<mpt::default_prng> & global_prng();
-
-#if defined(MODPLUG_TRACKER) && !defined(MPT_BUILD_WINESUPPORT)
-void set_global_random_device(mpt::random_device *rd);
-void set_global_prng(mpt::thread_safe_prng<mpt::default_prng> *rng);
-#endif // MODPLUG_TRACKER && !MPT_BUILD_WINESUPPORT
-
-
-} // namespace mpt
-
-
-OPENMPT_NAMESPACE_END

+ 0 - 139
libopenmpt.mod/openmpt/common/mptSpan.h

@@ -1,139 +0,0 @@
-/*
- * mptSpan.h
- * ---------
- * Purpose: C++20 span.
- * Notes  : (currently none)
- * Authors: OpenMPT Devs
- * The OpenMPT source code is released under the BSD license. Read LICENSE for more details.
- */
-
-
-#pragma once
-
-#include "BuildSettings.h"
-
-
-#include "mptBaseTypes.h"
-
-#if MPT_CXX_AT_LEAST(20)
-#include <array>
-#include <span>
-#else // !C++20
-#include <array>
-#include <iterator>
-#include <type_traits>
-#endif // C++20
-
-
-
-OPENMPT_NAMESPACE_BEGIN
-
-
-
-
-namespace mpt {
-
-
-
-#if MPT_CXX_AT_LEAST(20)
-
-using std::span;
-
-#else // !C++20
-
-//  Simplified version of gsl::span.
-//  Non-owning read-only or read-write view into a contiguous block of T
-// objects, i.e. equivalent to a (beg,end) or (data,size) tuple.
-//  Can eventually be replaced without further modifications with a full C++20
-// std::span.
-template <typename T>
-class span
-{
-
-public:
-
-	using element_type = T;
-	using value_type = typename std::remove_cv<T>::type;
-	using index_type = std::size_t;
-	using pointer = T *;
-	using const_pointer = const T *;
-	using reference = T &;
-	using const_reference = const T &;
-
-	using iterator = pointer;
-	using const_iterator = const_pointer;
-
-	using difference_type = typename std::iterator_traits<iterator>::difference_type;
-
-private:
-
-	T * m_beg;
-	T * m_end;
-
-public:
-
-	span() noexcept : m_beg(nullptr), m_end(nullptr) { }
-
-	span(pointer beg, pointer end) : m_beg(beg), m_end(end) { }
-
-	span(pointer data, index_type size) : m_beg(data), m_end(data + size) { }
-
-	template <std::size_t N> span(element_type (&arr)[N]) : m_beg(arr), m_end(arr + N) { }
-
-	template <std::size_t N> span(std::array<value_type, N> &arr) : m_beg(arr.data()), m_end(arr.data() + arr.size()) { }
-
-	template <std::size_t N> span(const std::array<value_type, N> &arr) : m_beg(arr.data()), m_end(arr.data() + arr.size()) { }
-
-	template <typename Cont> span(Cont &cont) : m_beg(std::data(cont)), m_end(std::data(cont) + std::size(cont)) { }
-
-	span(const span &other) : m_beg(other.begin()), m_end(other.end()) { }
-
-	template <typename U> span(const span<U> &other) : m_beg(other.begin()), m_end(other.end()) { }
-
-	span & operator = (const span & other) noexcept = default;
-	
-	iterator begin() const { return iterator(m_beg); }
-	iterator end() const { return iterator(m_end); }
-
-	const_iterator cbegin() const { return const_iterator(begin()); }
-	const_iterator cend() const { return const_iterator(end()); }
-
-	operator bool () const noexcept { return m_beg != nullptr; }
-
-	reference operator[](index_type index) { return at(index); }
-	const_reference operator[](index_type index) const { return at(index); }
-
-	bool operator==(span const & other) const noexcept { return size() == other.size() && (m_beg == other.m_beg || std::equal(begin(), end(), other.begin())); }
-	bool operator!=(span const & other) const noexcept { return !(*this == other); }
-
-	reference at(index_type index) { return m_beg[index]; }
-	const_reference at(index_type index) const { return m_beg[index]; }
-
-	pointer data() const noexcept { return m_beg; }
-
-	bool empty() const noexcept { return size() == 0; }
-
-	index_type size() const noexcept { return static_cast<index_type>(std::distance(m_beg, m_end)); }
-	index_type length() const noexcept { return size(); }
-
-}; // class span
-
-#endif // C++20
-
-template <typename T> inline span<T> as_span(T * beg, T * end) { return span<T>(beg, end); }
-
-template <typename T> inline span<T> as_span(T * data, std::size_t size) { return span<T>(data, size); }
-
-template <typename T, std::size_t N> inline span<T> as_span(T (&arr)[N]) { return span<T>(std::begin(arr), std::end(arr)); }
-
-template <typename T, std::size_t N> inline span<T> as_span(std::array<T, N> & cont) { return span<T>(cont); }
-
-template <typename T, std::size_t N> inline span<const T> as_span(const std::array<T, N> & cont) { return span<const T>(cont); }
-
-
-
-} // namespace mpt
-
-
-
-OPENMPT_NAMESPACE_END

+ 0 - 1605
libopenmpt.mod/openmpt/common/mptString.cpp

@@ -1,1605 +0,0 @@
-/*
- * mptString.cpp
- * -------------
- * Purpose: Small string-related utilities, number and message formatting.
- * Notes  : Currently none.
- * Authors: OpenMPT Devs
- * The OpenMPT source code is released under the BSD license. Read LICENSE for more details.
- */
-
-#include "stdafx.h"
-#include "mptString.h"
-
-#include "Endianness.h"
-
-#include <locale>
-#include <string>
-#include <stdexcept>
-#include <vector>
-
-#include <cstdlib>
-
-#if defined(MODPLUG_TRACKER)
-#include <cwctype>
-#endif // MODPLUG_TRACKER
-
-#if defined(MODPLUG_TRACKER)
-#include <wctype.h>
-#endif // MODPLUG_TRACKER
-
-#if MPT_OS_WINDOWS
-#include <windows.h>
-#endif
-
-
-OPENMPT_NAMESPACE_BEGIN
-
-
-
-/*
-
-
-
-Quick guide to the OpenMPT string type jungle
-=============================================
-
-
-
-This quick guide is only meant as a hint. There may be valid reasons to not
-honor the recommendations found here. Staying consistent with surrounding and/or
-related code sections may also be important.
-
-
-
-List of string types
---------------------
-
- *  std::string (OpenMPT, libopenmpt)
-    C++ string of unspecifed 8bit encoding. Try to always document the
-    encoding if not clear from context. Do not use unless there is an obvious
-    reason to do so.
-
- *  std::wstring (OpenMPT)
-    UTF16 (on windows) or UTF32 (otherwise). Do not use unless there is an
-    obvious reason to do so.
-
- *  mpt::lstring (OpenMPT)
-    OpenMPT locale string type. The encoding is always CP_ACP. Do not use unless
-    there is an obvious reason to do so.
-
- *  char* (OpenMPT, libopenmpt)
-    C string of unspecified encoding. Use only for static literals or in
-    performance critical inner loops where full control and avoidance of memory
-    allocations is required.
-
- *  wchar_t* (OpenMPT)
-    C wide string. Use only if Unicode is required for static literals or in
-    performance critical inner loops where full control and avoidance of memory
-    allocation is required.
-
- *  mpt::winstring (OpenMPT)
-    OpenMPT type-safe string to interface with native WinAPI, either encoded in
-    locale/CP_ACP (if !UNICODE) or UTF16 (if UNICODE).
-
- *  CString (OpenMPT)
-    MFC string type, either encoded in locale/CP_ACP (if !UNICODE) or UTF16 (if
-    UNICODE). Specify literals with _T(""). Use in MFC GUI code.
-
- *  CStringA (OpenMPT)
-    MFC ANSI string type. The encoding is always CP_ACP. Do not use.
-
- *  CStringW (OpenMPT)
-    MFC Unicode string type. Do not use.
-
- *  mpt::PathString (OpenMPT, libopenmpt)
-    String type representing paths and filenames. Always use for these in order
-    to avoid potentially lossy conversions. Use P_("") macro for
-    literals.
-
- *  mpt::ustring (OpenMPT, libopenmpt)
-    The default unicode string type. Can be encoded in UTF8 or UTF16 or UTF32,
-    depending on MPT_USTRING_MODE_* and sizeof(wchar_t). Literals can written as
-    U_(""). Use as your default string type if no other string type is
-    a measurably better fit.
-
- *  MPT_UTF8 (OpenMPT, libopenmpt)
-    Macro that generates a mpt::ustring from string literals containing
-    non-ascii characters. In order to keep the source code in ascii encoding,
-    always express non-ascii characters using explicit \x23 escaping. Note that
-    depending on the underlying type of mpt::ustring, MPT_UTF8 *requires* a
-    runtime conversion. Only use for string literals containing non-ascii
-    characters (use MPT_USTRING otherwise).
-
- *  MPT_ULITERAL / MPT_UCHAR / mpt::uchar (OpenMPT, libopenmpt)
-    Macros which generate string literals, char literals and the char literal
-    type respectively. These are especially useful in constexpr contexts or
-    global data where MPT_USTRING is either unusable or requires a global
-    contructor to run. Do NOT use as a performance optimization in place of
-    MPT_USTRING however, because MPT_USTRING can be converted to C++11/14 user
-    defined literals eventually, while MPT_ULITERAL cannot because of constexpr
-    requirements.
-
- *  mpt::RawPathString (OpenMPT, libopenmpt)
-    Internal representation of mpt::PathString. Only use for parsing path
-    fragments.
-
- *  mpt::u8string (OpenMPT, libopenmpt)
-    Internal representation of mpt::ustring. Do not use directly. Ever.
-
- *  std::basic_string<char> (OpenMPT)
-    Same as std::string. Do not use std::basic_string in the templated form.
-
- *  std::basic_string<wchar_t> (OpenMPT)
-    Same as std::wstring. Do not use std::basic_string in the templated form.
-
-The following string types are available in order to avoid the need to overload
-functions on a huge variety of string types. Use only ever as function argument
-types.
-Note that the locale charset is not available on all libopenmpt builds (in which
-case the option is ignored or a sensible fallback is used; these types are
-always available).
-All these types publicly inherit from mpt::ustring and do not contain any
-additional state. This means that they work the same way as mpt::ustring does
-and do support type-slicing for both, read and write accesses.
-These types only add conversion constructors for all string types that have a
-defined encoding and for all 8bit string types using the specified encoding
-heuristic.
-
- *  AnyUnicodeString (OpenMPT, libopenmpt)
-    Is constructible from any Unicode string.
-
- *  AnyString (OpenMPT, libopenmpt)
-    Tries to do the smartest auto-magic we can do.
-
- *  AnyStringLocale (OpenMPT, libopenmpt)
-    char-based strings are assumed to be in locale encoding.
-
- *  AnyStringUTF8orLocale (OpenMPT, libopenmpt)
-    char-based strings are tried in UTF8 first, if this fails, locale is used.
-
- *  AnyStringUTF8 (OpenMPT, libopenmpt)
-    char-based strings are assumed to be in UTF8.
-
-
-
-Encoding of 8bit strings
-------------------------
-
-8bit strings have an unspecified encoding. When the string is contained within a
-CSoundFile object, the encoding is most likely CSoundFile::GetCharsetInternal(),
-otherwise, try to gather the most probable encoding from surrounding or related
-code sections.
-
-
-
-Decision tree to help deciding which string type to use
--------------------------------------------------------
-
-if in libopenmpt
- if in libopenmpt c++ interface
-  T = std::string, the encoding is utf8
- elif in libopenmpt c interface
-  T = char*, the encoding is utf8
- elif performance critical inner loop
-  T = char*, document the encoding if not clear from context 
- elif string literal containing non-ascii characters
-  T = MPT_UTF8
- elif path or file
-  if parsing path fragments
-   T = mpt::RawPathString
-       template your function on the concrete underlying string type
-       (std::string and std::wstring) or use preprocessor MPT_OS_WINDOWS
-  else
-   T = mpt::PathString
-  fi
- else
-  T = mpt::ustring
- fi
-else
- if performance critical inner loop
-  if needs unicode support
-   T = mpt::uchar* / MPT_ULITERAL
-  else
-   T = char*, document the encoding if not clear from context 
-  fi
- elif string literal containing non-ascii characters
-  T = MPT_UTF8
- elif path or file
-  if parsing path fragments
-   T = mpt::RawPathString
-       template your function on the concrete underlying string type
-       (std::string and std::wstring) or use preprocessor MPT_OS_WINDOWS
-  else
-   T = mpt::PathString
-  fi
- elif winapi interfacing code
-  T = mpt::winstring
- elif mfc/gui code
-  T = CString
- else
-  if constexpr context or global data
-   T = mpt::uchar* / MPT_ULITERAL
-  else
-   T = mpt::ustring
-  fi
- fi
-fi
-
-This boils down to: Prefer mpt::PathString and mpt::ustring, and only use any
-other string type if there is an obvious reason to do so.
-
-
-
-Character set conversions
--------------------------
-
-Character set conversions in OpenMPT are always fuzzy.
-
-Behaviour in case of an invalid source encoding and behaviour in case of an
-unrepresentable destination encoding can be any of the following:
- *  The character is replaced by some replacement character ('?' or L'\ufffd' in
-    most cases).
- *  The character is replaced by a similar character (either semantically
-    similiar or visually similar).
- *  The character is transcribed with some ASCII text.
- *  The character is discarded.
- *  Conversion stops at this very character.
-
-Additionally. conversion may stop or continue on \0 characters in the middle of
-the string.
-
-Behaviour can vary from one conversion tuple to any other.
-
-If you need to ensure lossless conversion, do a roundtrip conversion and check
-for equality.
-
-
-
-Unicode handling
-----------------
-
-OpenMPT is generally not aware of and does not handle different Unicode
-normalization forms.
-You should be aware of the following possibilities:
- *  Conversion between UTF8, UTF16, UTF32 may or may not change between NFC and
-    NFD.
- *  Conversion from any non-Unicode 8bit encoding can result in both, NFC or NFD
-    forms.
- *  Conversion to any non-Unicode 8bit encoding may or may not involve
-    conversion to NFC, NFD, NFKC or NFKD during the conversion. This in
-    particular means that conversion of decomposed german umlauts to ISO8859-1
-    may fail.
- *  Changing the normalization form of path strings may render the file
-    inaccessible.
-
-Unicode BOM may or may not be preserved and/or discarded during conversion.
-
-Invalid Unicode code points may be treated as invalid or as valid characters
-when converting between different Unicode encodings.
-
-
-
-Interfacing with WinAPI
------------------------
-
-When in MFC code, use CString.
-When in non MFC code, either use std::wstring when directly interfacing with
-APIs only available in WCHAR variants, or use mpt::winstring and
-mpt::WinStringBuf helpers otherwise.
-Specify TCHAR string literals with _T("foo") in mptrack/, and with TEXT("foo")
-in common/ or sounddev/. _T() requires <tchar.h> which is specific to the MSVC
-runtime and not portable across compilers. TEXT() is from <windows.h>. We use
-_T() in mptrack/ only because it is shorter.
-
-
-
-*/
-
-
-
-namespace mpt { namespace String {
-
-
-
-/*
-default 1:1 mapping
-static constexpr char32_t CharsetTableISO8859_1[256] = {
-	0x0000,0x0001,0x0002,0x0003,0x0004,0x0005,0x0006,0x0007,0x0008,0x0009,0x000a,0x000b,0x000c,0x000d,0x000e,0x000f,
-	0x0010,0x0011,0x0012,0x0013,0x0014,0x0015,0x0016,0x0017,0x0018,0x0019,0x001a,0x001b,0x001c,0x001d,0x001e,0x001f,
-	0x0020,0x0021,0x0022,0x0023,0x0024,0x0025,0x0026,0x0027,0x0028,0x0029,0x002a,0x002b,0x002c,0x002d,0x002e,0x002f,
-	0x0030,0x0031,0x0032,0x0033,0x0034,0x0035,0x0036,0x0037,0x0038,0x0039,0x003a,0x003b,0x003c,0x003d,0x003e,0x003f,
-	0x0040,0x0041,0x0042,0x0043,0x0044,0x0045,0x0046,0x0047,0x0048,0x0049,0x004a,0x004b,0x004c,0x004d,0x004e,0x004f,
-	0x0050,0x0051,0x0052,0x0053,0x0054,0x0055,0x0056,0x0057,0x0058,0x0059,0x005a,0x005b,0x005c,0x005d,0x005e,0x005f,
-	0x0060,0x0061,0x0062,0x0063,0x0064,0x0065,0x0066,0x0067,0x0068,0x0069,0x006a,0x006b,0x006c,0x006d,0x006e,0x006f,
-	0x0070,0x0071,0x0072,0x0073,0x0074,0x0075,0x0076,0x0077,0x0078,0x0079,0x007a,0x007b,0x007c,0x007d,0x007e,0x007f,
-	0x0080,0x0081,0x0082,0x0083,0x0084,0x0085,0x0086,0x0087,0x0088,0x0089,0x008a,0x008b,0x008c,0x008d,0x008e,0x008f,
-	0x0090,0x0091,0x0092,0x0093,0x0094,0x0095,0x0096,0x0097,0x0098,0x0099,0x009a,0x009b,0x009c,0x009d,0x009e,0x009f,
-	0x00a0,0x00a1,0x00a2,0x00a3,0x00a4,0x00a5,0x00a6,0x00a7,0x00a8,0x00a9,0x00aa,0x00ab,0x00ac,0x00ad,0x00ae,0x00af,
-	0x00b0,0x00b1,0x00b2,0x00b3,0x00b4,0x00b5,0x00b6,0x00b7,0x00b8,0x00b9,0x00ba,0x00bb,0x00bc,0x00bd,0x00be,0x00bf,
-	0x00c0,0x00c1,0x00c2,0x00c3,0x00c4,0x00c5,0x00c6,0x00c7,0x00c8,0x00c9,0x00ca,0x00cb,0x00cc,0x00cd,0x00ce,0x00cf,
-	0x00d0,0x00d1,0x00d2,0x00d3,0x00d4,0x00d5,0x00d6,0x00d7,0x00d8,0x00d9,0x00da,0x00db,0x00dc,0x00dd,0x00de,0x00df,
-	0x00e0,0x00e1,0x00e2,0x00e3,0x00e4,0x00e5,0x00e6,0x00e7,0x00e8,0x00e9,0x00ea,0x00eb,0x00ec,0x00ed,0x00ee,0x00ef,
-	0x00f0,0x00f1,0x00f2,0x00f3,0x00f4,0x00f5,0x00f6,0x00f7,0x00f8,0x00f9,0x00fa,0x00fb,0x00fc,0x00fd,0x00fe,0x00ff
-};
-*/
-
-static constexpr char32_t CharsetTableISO8859_15[256] = {
-	0x0000,0x0001,0x0002,0x0003,0x0004,0x0005,0x0006,0x0007,0x0008,0x0009,0x000a,0x000b,0x000c,0x000d,0x000e,0x000f,
-	0x0010,0x0011,0x0012,0x0013,0x0014,0x0015,0x0016,0x0017,0x0018,0x0019,0x001a,0x001b,0x001c,0x001d,0x001e,0x001f,
-	0x0020,0x0021,0x0022,0x0023,0x0024,0x0025,0x0026,0x0027,0x0028,0x0029,0x002a,0x002b,0x002c,0x002d,0x002e,0x002f,
-	0x0030,0x0031,0x0032,0x0033,0x0034,0x0035,0x0036,0x0037,0x0038,0x0039,0x003a,0x003b,0x003c,0x003d,0x003e,0x003f,
-	0x0040,0x0041,0x0042,0x0043,0x0044,0x0045,0x0046,0x0047,0x0048,0x0049,0x004a,0x004b,0x004c,0x004d,0x004e,0x004f,
-	0x0050,0x0051,0x0052,0x0053,0x0054,0x0055,0x0056,0x0057,0x0058,0x0059,0x005a,0x005b,0x005c,0x005d,0x005e,0x005f,
-	0x0060,0x0061,0x0062,0x0063,0x0064,0x0065,0x0066,0x0067,0x0068,0x0069,0x006a,0x006b,0x006c,0x006d,0x006e,0x006f,
-	0x0070,0x0071,0x0072,0x0073,0x0074,0x0075,0x0076,0x0077,0x0078,0x0079,0x007a,0x007b,0x007c,0x007d,0x007e,0x007f,
-	0x0080,0x0081,0x0082,0x0083,0x0084,0x0085,0x0086,0x0087,0x0088,0x0089,0x008a,0x008b,0x008c,0x008d,0x008e,0x008f,
-	0x0090,0x0091,0x0092,0x0093,0x0094,0x0095,0x0096,0x0097,0x0098,0x0099,0x009a,0x009b,0x009c,0x009d,0x009e,0x009f,
-	0x00a0,0x00a1,0x00a2,0x00a3,0x20ac,0x00a5,0x0160,0x00a7,0x0161,0x00a9,0x00aa,0x00ab,0x00ac,0x00ad,0x00ae,0x00af,
-	0x00b0,0x00b1,0x00b2,0x00b3,0x017d,0x00b5,0x00b6,0x00b7,0x017e,0x00b9,0x00ba,0x00bb,0x0152,0x0153,0x0178,0x00bf,
-	0x00c0,0x00c1,0x00c2,0x00c3,0x00c4,0x00c5,0x00c6,0x00c7,0x00c8,0x00c9,0x00ca,0x00cb,0x00cc,0x00cd,0x00ce,0x00cf,
-	0x00d0,0x00d1,0x00d2,0x00d3,0x00d4,0x00d5,0x00d6,0x00d7,0x00d8,0x00d9,0x00da,0x00db,0x00dc,0x00dd,0x00de,0x00df,
-	0x00e0,0x00e1,0x00e2,0x00e3,0x00e4,0x00e5,0x00e6,0x00e7,0x00e8,0x00e9,0x00ea,0x00eb,0x00ec,0x00ed,0x00ee,0x00ef,
-	0x00f0,0x00f1,0x00f2,0x00f3,0x00f4,0x00f5,0x00f6,0x00f7,0x00f8,0x00f9,0x00fa,0x00fb,0x00fc,0x00fd,0x00fe,0x00ff
-};
-
-static constexpr char32_t CharsetTableWindows1252[256] = {
-	0x0000,0x0001,0x0002,0x0003,0x0004,0x0005,0x0006,0x0007,0x0008,0x0009,0x000a,0x000b,0x000c,0x000d,0x000e,0x000f,
-	0x0010,0x0011,0x0012,0x0013,0x0014,0x0015,0x0016,0x0017,0x0018,0x0019,0x001a,0x001b,0x001c,0x001d,0x001e,0x001f,
-	0x0020,0x0021,0x0022,0x0023,0x0024,0x0025,0x0026,0x0027,0x0028,0x0029,0x002a,0x002b,0x002c,0x002d,0x002e,0x002f,
-	0x0030,0x0031,0x0032,0x0033,0x0034,0x0035,0x0036,0x0037,0x0038,0x0039,0x003a,0x003b,0x003c,0x003d,0x003e,0x003f,
-	0x0040,0x0041,0x0042,0x0043,0x0044,0x0045,0x0046,0x0047,0x0048,0x0049,0x004a,0x004b,0x004c,0x004d,0x004e,0x004f,
-	0x0050,0x0051,0x0052,0x0053,0x0054,0x0055,0x0056,0x0057,0x0058,0x0059,0x005a,0x005b,0x005c,0x005d,0x005e,0x005f,
-	0x0060,0x0061,0x0062,0x0063,0x0064,0x0065,0x0066,0x0067,0x0068,0x0069,0x006a,0x006b,0x006c,0x006d,0x006e,0x006f,
-	0x0070,0x0071,0x0072,0x0073,0x0074,0x0075,0x0076,0x0077,0x0078,0x0079,0x007a,0x007b,0x007c,0x007d,0x007e,0x007f,
-	0x20ac,0x0081,0x201a,0x0192,0x201e,0x2026,0x2020,0x2021,0x02c6,0x2030,0x0160,0x2039,0x0152,0x008d,0x017d,0x008f,
-	0x0090,0x2018,0x2019,0x201c,0x201d,0x2022,0x2013,0x2014,0x02dc,0x2122,0x0161,0x203a,0x0153,0x009d,0x017e,0x0178,
-	0x00a0,0x00a1,0x00a2,0x00a3,0x00a4,0x00a5,0x00a6,0x00a7,0x00a8,0x00a9,0x00aa,0x00ab,0x00ac,0x00ad,0x00ae,0x00af,
-	0x00b0,0x00b1,0x00b2,0x00b3,0x00b4,0x00b5,0x00b6,0x00b7,0x00b8,0x00b9,0x00ba,0x00bb,0x00bc,0x00bd,0x00be,0x00bf,
-	0x00c0,0x00c1,0x00c2,0x00c3,0x00c4,0x00c5,0x00c6,0x00c7,0x00c8,0x00c9,0x00ca,0x00cb,0x00cc,0x00cd,0x00ce,0x00cf,
-	0x00d0,0x00d1,0x00d2,0x00d3,0x00d4,0x00d5,0x00d6,0x00d7,0x00d8,0x00d9,0x00da,0x00db,0x00dc,0x00dd,0x00de,0x00df,
-	0x00e0,0x00e1,0x00e2,0x00e3,0x00e4,0x00e5,0x00e6,0x00e7,0x00e8,0x00e9,0x00ea,0x00eb,0x00ec,0x00ed,0x00ee,0x00ef,
-	0x00f0,0x00f1,0x00f2,0x00f3,0x00f4,0x00f5,0x00f6,0x00f7,0x00f8,0x00f9,0x00fa,0x00fb,0x00fc,0x00fd,0x00fe,0x00ff
-};
-
-static constexpr char32_t CharsetTableCP437[256] = {
-	0x0000,0x0001,0x0002,0x0003,0x0004,0x0005,0x0006,0x0007,0x0008,0x0009,0x000a,0x000b,0x000c,0x000d,0x000e,0x000f,
-	0x0010,0x0011,0x0012,0x0013,0x0014,0x0015,0x0016,0x0017,0x0018,0x0019,0x001a,0x001b,0x001c,0x001d,0x001e,0x001f,
-	0x0020,0x0021,0x0022,0x0023,0x0024,0x0025,0x0026,0x0027,0x0028,0x0029,0x002a,0x002b,0x002c,0x002d,0x002e,0x002f,
-	0x0030,0x0031,0x0032,0x0033,0x0034,0x0035,0x0036,0x0037,0x0038,0x0039,0x003a,0x003b,0x003c,0x003d,0x003e,0x003f,
-	0x0040,0x0041,0x0042,0x0043,0x0044,0x0045,0x0046,0x0047,0x0048,0x0049,0x004a,0x004b,0x004c,0x004d,0x004e,0x004f,
-	0x0050,0x0051,0x0052,0x0053,0x0054,0x0055,0x0056,0x0057,0x0058,0x0059,0x005a,0x005b,0x005c,0x005d,0x005e,0x005f,
-	0x0060,0x0061,0x0062,0x0063,0x0064,0x0065,0x0066,0x0067,0x0068,0x0069,0x006a,0x006b,0x006c,0x006d,0x006e,0x006f,
-	0x0070,0x0071,0x0072,0x0073,0x0074,0x0075,0x0076,0x0077,0x0078,0x0079,0x007a,0x007b,0x007c,0x007d,0x007e,0x2302,
-	0x00c7,0x00fc,0x00e9,0x00e2,0x00e4,0x00e0,0x00e5,0x00e7,0x00ea,0x00eb,0x00e8,0x00ef,0x00ee,0x00ec,0x00c4,0x00c5,
-	0x00c9,0x00e6,0x00c6,0x00f4,0x00f6,0x00f2,0x00fb,0x00f9,0x00ff,0x00d6,0x00dc,0x00a2,0x00a3,0x00a5,0x20a7,0x0192,
-	0x00e1,0x00ed,0x00f3,0x00fa,0x00f1,0x00d1,0x00aa,0x00ba,0x00bf,0x2310,0x00ac,0x00bd,0x00bc,0x00a1,0x00ab,0x00bb,
-	0x2591,0x2592,0x2593,0x2502,0x2524,0x2561,0x2562,0x2556,0x2555,0x2563,0x2551,0x2557,0x255d,0x255c,0x255b,0x2510,
-	0x2514,0x2534,0x252c,0x251c,0x2500,0x253c,0x255e,0x255f,0x255a,0x2554,0x2569,0x2566,0x2560,0x2550,0x256c,0x2567,
-	0x2568,0x2564,0x2565,0x2559,0x2558,0x2552,0x2553,0x256b,0x256a,0x2518,0x250c,0x2588,0x2584,0x258c,0x2590,0x2580,
-	0x03b1,0x00df,0x0393,0x03c0,0x03a3,0x03c3,0x00b5,0x03c4,0x03a6,0x0398,0x03a9,0x03b4,0x221e,0x03c6,0x03b5,0x2229,
-	0x2261,0x00b1,0x2265,0x2264,0x2320,0x2321,0x00f7,0x2248,0x00b0,0x2219,0x00b7,0x221a,0x207f,0x00b2,0x25a0,0x00a0
-};
-
-
-#define C(x) (static_cast<uint8>((x)))
-
-// AMS1 actually only supports ASCII plus the modified control characters and no high chars at all.
-// Just default to CP437 for those to keep things simple.
-static constexpr char32_t CharsetTableCP437AMS[256] = {
-	C(' '),0x0001,0x0002,0x0003,0x00e4,0x0005,0x00e5,0x0007,0x0008,0x0009,0x000a,0x000b,0x000c,0x000d,0x00c4,0x00c5, // differs from CP437
-	0x0010,0x0011,0x0012,0x0013,0x00f6,0x0015,0x0016,0x0017,0x0018,0x00d6,0x001a,0x001b,0x001c,0x001d,0x001e,0x001f, // differs from CP437
-	0x0020,0x0021,0x0022,0x0023,0x0024,0x0025,0x0026,0x0027,0x0028,0x0029,0x002a,0x002b,0x002c,0x002d,0x002e,0x002f,
-	0x0030,0x0031,0x0032,0x0033,0x0034,0x0035,0x0036,0x0037,0x0038,0x0039,0x003a,0x003b,0x003c,0x003d,0x003e,0x003f,
-	0x0040,0x0041,0x0042,0x0043,0x0044,0x0045,0x0046,0x0047,0x0048,0x0049,0x004a,0x004b,0x004c,0x004d,0x004e,0x004f,
-	0x0050,0x0051,0x0052,0x0053,0x0054,0x0055,0x0056,0x0057,0x0058,0x0059,0x005a,0x005b,0x005c,0x005d,0x005e,0x005f,
-	0x0060,0x0061,0x0062,0x0063,0x0064,0x0065,0x0066,0x0067,0x0068,0x0069,0x006a,0x006b,0x006c,0x006d,0x006e,0x006f,
-	0x0070,0x0071,0x0072,0x0073,0x0074,0x0075,0x0076,0x0077,0x0078,0x0079,0x007a,0x007b,0x007c,0x007d,0x007e,0x2302,
-	0x00c7,0x00fc,0x00e9,0x00e2,0x00e4,0x00e0,0x00e5,0x00e7,0x00ea,0x00eb,0x00e8,0x00ef,0x00ee,0x00ec,0x00c4,0x00c5,
-	0x00c9,0x00e6,0x00c6,0x00f4,0x00f6,0x00f2,0x00fb,0x00f9,0x00ff,0x00d6,0x00dc,0x00a2,0x00a3,0x00a5,0x20a7,0x0192,
-	0x00e1,0x00ed,0x00f3,0x00fa,0x00f1,0x00d1,0x00aa,0x00ba,0x00bf,0x2310,0x00ac,0x00bd,0x00bc,0x00a1,0x00ab,0x00bb,
-	0x2591,0x2592,0x2593,0x2502,0x2524,0x2561,0x2562,0x2556,0x2555,0x2563,0x2551,0x2557,0x255d,0x255c,0x255b,0x2510,
-	0x2514,0x2534,0x252c,0x251c,0x2500,0x253c,0x255e,0x255f,0x255a,0x2554,0x2569,0x2566,0x2560,0x2550,0x256c,0x2567,
-	0x2568,0x2564,0x2565,0x2559,0x2558,0x2552,0x2553,0x256b,0x256a,0x2518,0x250c,0x2588,0x2584,0x258c,0x2590,0x2580,
-	0x03b1,0x00df,0x0393,0x03c0,0x03a3,0x03c3,0x00b5,0x03c4,0x03a6,0x0398,0x03a9,0x03b4,0x221e,0x03c6,0x03b5,0x2229,
-	0x2261,0x00b1,0x2265,0x2264,0x2320,0x2321,0x00f7,0x2248,0x00b0,0x2219,0x00b7,0x221a,0x207f,0x00b2,0x25a0,0x00a0
-};
-
-// AMS2: Looking at Velvet Studio's bitmap font (TPIC32.PCX), these appear to be the only supported non-ASCII chars.
-static constexpr char32_t CharsetTableCP437AMS2[256] = {
-	C(' '),0x00a9,0x221a,0x00b7,C('0'),C('1'),C('2'),C('3'),C('4'),C('5'),C('6'),C('7'),C('8'),C('9'),C('A'),C('B'), // differs from CP437
-	C('C'),C('D'),C('E'),C('F'),C(' '),0x00a7,C(' '),C(' '),C(' '),C(' '),C(' '),C(' '),C(' '),C(' '),C(' '),C(' '), // differs from CP437
-	0x0020,0x0021,0x0022,0x0023,0x0024,0x0025,0x0026,0x0027,0x0028,0x0029,0x002a,0x002b,0x002c,0x002d,0x002e,0x002f,
-	0x0030,0x0031,0x0032,0x0033,0x0034,0x0035,0x0036,0x0037,0x0038,0x0039,0x003a,0x003b,0x003c,0x003d,0x003e,0x003f,
-	0x0040,0x0041,0x0042,0x0043,0x0044,0x0045,0x0046,0x0047,0x0048,0x0049,0x004a,0x004b,0x004c,0x004d,0x004e,0x004f,
-	0x0050,0x0051,0x0052,0x0053,0x0054,0x0055,0x0056,0x0057,0x0058,0x0059,0x005a,0x005b,0x005c,0x005d,0x005e,0x005f,
-	0x0060,0x0061,0x0062,0x0063,0x0064,0x0065,0x0066,0x0067,0x0068,0x0069,0x006a,0x006b,0x006c,0x006d,0x006e,0x006f,
-	0x0070,0x0071,0x0072,0x0073,0x0074,0x0075,0x0076,0x0077,0x0078,0x0079,0x007a,0x007b,0x007c,0x007d,0x007e,0x2302,
-	0x00c7,0x00fc,0x00e9,0x00e2,0x00e4,0x00e0,0x00e5,0x00e7,0x00ea,0x00eb,0x00e8,0x00ef,0x00ee,0x00ec,0x00c4,0x00c5,
-	0x00c9,0x00e6,0x00c6,0x00f4,0x00f6,0x00f2,0x00fb,0x00f9,0x00ff,0x00d6,0x00dc,0x00a2,0x00a3,0x00a5,0x20a7,0x0192,
-	0x00e1,0x00ed,0x00f3,0x00fa,0x00f1,0x00d1,0x00aa,0x00ba,0x00bf,0x2310,0x00ac,0x00bd,0x00bc,0x00a1,0x00ab,0x00bb,
-	0x2591,0x2592,0x2593,0x2502,0x2524,0x2561,0x2562,0x2556,0x2555,0x2563,0x2551,0x2557,0x255d,0x255c,0x255b,0x2510,
-	0x2514,0x2534,0x252c,0x251c,0x2500,0x253c,0x255e,0x255f,0x255a,0x2554,0x2569,0x2566,0x2560,0x2550,0x256c,0x2567,
-	0x2568,0x2564,0x2565,0x2559,0x2558,0x2552,0x2553,0x256b,0x256a,0x2518,0x250c,0x2588,0x2584,0x258c,0x2590,0x2580,
-	0x03b1,0x00df,0x0393,0x03c0,0x03a3,0x03c3,0x00b5,0x03c4,0x03a6,0x0398,0x03a9,0x03b4,0x221e,0x03c6,0x03b5,0x2229,
-	0x2261,0x00b1,0x2265,0x2264,0x2320,0x2321,0x00f7,0x2248,0x00b0,0x2219,0x00b7,0x221a,0x207f,0x00b2,0x25a0,0x00a0
-};
-
-#undef C
-
-
-#if defined(MPT_COMPILER_QUIRK_NO_WCHAR)
-using widechar = char32_t;
-using widestring = std::u32string;
-static constexpr widechar wide_default_replacement = 0xFFFD;
-#else // !MPT_COMPILER_QUIRK_NO_WCHAR
-using widechar = wchar_t;
-using widestring = std::wstring;
-static constexpr widechar wide_default_replacement = L'\uFFFD';
-#endif // !MPT_COMPILER_QUIRK_NO_WCHAR
-
-
-#if MPT_OS_WINDOWS
-
-static bool TestCodePage(UINT cp)
-{
-	return IsValidCodePage(cp) ? true : false;
-}
-
-static bool HasCharset(Charset charset)
-{
-	bool result = false;
-	switch(charset)
-	{
-#if defined(MPT_ENABLE_CHARSET_LOCALE)
-		case Charset::Locale:      result = true; break;
-#endif
-		case Charset::UTF8:        result = TestCodePage(CP_UTF8); break;
-		case Charset::ASCII:       result = TestCodePage(20127);   break;
-		case Charset::ISO8859_1:   result = TestCodePage(28591);   break;
-		case Charset::ISO8859_15:  result = TestCodePage(28605);   break;
-		case Charset::CP437:       result = TestCodePage(437);     break;
-		case Charset::Windows1252: result = TestCodePage(1252);    break;
-		case Charset::CP437AMS:    result = false; break;
-		case Charset::CP437AMS2:   result = false; break;
-	}
-	return result;
-}
-
-static UINT CharsetToCodepage(Charset charset)
-{
-	switch(charset)
-	{
-#if defined(MPT_ENABLE_CHARSET_LOCALE)
-		case Charset::Locale:      return CP_ACP;  break;
-#endif
-		case Charset::UTF8:        return CP_UTF8; break;
-		case Charset::ASCII:       return 20127;   break;
-		case Charset::ISO8859_1:   return 28591;   break;
-		case Charset::ISO8859_15:  return 28605;   break;
-		case Charset::CP437:       return 437;     break;
-		case Charset::CP437AMS:    return 437;     break; // fallback, should not happen
-		case Charset::CP437AMS2:   return 437;     break; // fallback, should not happen
-		case Charset::Windows1252: return 1252;    break;
-	}
-	return 0;
-}
-
-template<typename Tdststring>
-static Tdststring EncodeCodepage(UINT codepage, const widestring &src)
-{
-	static_assert(sizeof(typename Tdststring::value_type) == sizeof(char));
-	static_assert((std::is_same<typename Tdststring::value_type, char>::value));
-	Tdststring encoded_string;
-	int required_size = WideCharToMultiByte(codepage, 0, src.data(), mpt::saturate_cast<int>(src.size()), nullptr, 0, nullptr, nullptr);
-	if(required_size > 0)
-	{
-		encoded_string.resize(required_size);
-		WideCharToMultiByte(codepage, 0, src.data(), mpt::saturate_cast<int>(src.size()), reinterpret_cast<CHAR*>(encoded_string.data()), required_size, nullptr, nullptr);
-	}
-	return encoded_string;
-}
-
-template<typename Tsrcstring>
-static widestring DecodeCodepage(UINT codepage, const Tsrcstring &src)
-{
-	static_assert(sizeof(typename Tsrcstring::value_type) == sizeof(char));
-	static_assert((std::is_same<typename Tsrcstring::value_type, char>::value));
-	widestring decoded_string;
-	int required_size = MultiByteToWideChar(codepage, 0, reinterpret_cast<const CHAR*>(src.data()), mpt::saturate_cast<int>(src.size()), nullptr, 0);
-	if(required_size > 0)
-	{
-		decoded_string.resize(required_size);
-		MultiByteToWideChar(codepage, 0, reinterpret_cast<const CHAR*>(src.data()), mpt::saturate_cast<int>(src.size()), decoded_string.data(), required_size);
-	}
-	return decoded_string;
-}
-
-#endif // MPT_OS_WINDOWS
-
-
-template<typename Tsrcstring>
-static widestring From8bit(const Tsrcstring &str, const char32_t (&table)[256], widechar replacement = wide_default_replacement)
-{
-	widestring res;
-	res.reserve(str.length());
-	for(std::size_t i = 0; i < str.length(); ++i)
-	{
-		std::size_t c = static_cast<std::size_t>(static_cast<uint8>(str[i]));
-		if(c < std::size(table))
-		{
-			res.push_back(static_cast<widechar>(table[c]));
-		} else
-		{
-			res.push_back(replacement);
-		}
-	}
-	return res;
-}
-
-template<typename Tdststring>
-static Tdststring To8bit(const widestring &str, const char32_t (&table)[256], char replacement = '?')
-{
-	Tdststring res;
-	res.reserve(str.length());
-	for(std::size_t i = 0; i < str.length(); ++i)
-	{
-		char32_t c = static_cast<char32_t>(str[i]);
-		bool found = false;
-		// Try non-control characters first.
-		// In cases where there are actual characters mirrored in this range (like in AMS/AMS2 character sets),
-		// characters in the common range are preferred this way.
-		for(std::size_t x = 0x20; x < std::size(table); ++x)
-		{
-			if(c == table[x])
-			{
-				res.push_back(static_cast<typename Tdststring::value_type>(static_cast<uint8>(x)));
-				found = true;
-				break;
-			}
-		}
-		if(!found)
-		{
-			// try control characters
-			for(std::size_t x = 0x00; x < std::size(table) && x < 0x20; ++x)
-			{
-				if(c == table[x])
-				{
-					res.push_back(static_cast<typename Tdststring::value_type>(static_cast<uint8>(x)));
-					found = true;
-					break;
-				}
-			}
-		}
-		if(!found)
-		{
-			res.push_back(replacement);
-		}
-	}
-	return res;
-}
-
-template<typename Tsrcstring>
-static widestring FromAscii(const Tsrcstring &str, widechar replacement = wide_default_replacement)
-{
-	widestring res;
-	res.reserve(str.length());
-	for(std::size_t i = 0; i < str.length(); ++i)
-	{
-		uint8 c = str[i];
-		if(c <= 0x7f)
-		{
-			res.push_back(static_cast<widechar>(static_cast<uint32>(c)));
-		} else
-		{
-			res.push_back(replacement);
-		}
-	}
-	return res;
-}
-
-template<typename Tdststring>
-static Tdststring ToAscii(const widestring &str, char replacement = '?')
-{
-	Tdststring res;
-	res.reserve(str.length());
-	for(std::size_t i = 0; i < str.length(); ++i)
-	{
-		char32_t c = static_cast<char32_t>(str[i]);
-		if(c <= 0x7f)
-		{
-			res.push_back(static_cast<typename Tdststring::value_type>(static_cast<uint8>(c)));
-		} else
-		{
-			res.push_back(replacement);
-		}
-	}
-	return res;
-}
-
-template<typename Tsrcstring>
-static widestring FromISO_8859_1(const Tsrcstring &str, widechar replacement = wide_default_replacement)
-{
-	MPT_UNREFERENCED_PARAMETER(replacement);
-	widestring res;
-	res.reserve(str.length());
-	for(std::size_t i = 0; i < str.length(); ++i)
-	{
-		uint8 c = str[i];
-		res.push_back(static_cast<widechar>(static_cast<uint32>(c)));
-	}
-	return res;
-}
-
-template<typename Tdststring>
-static Tdststring ToISO_8859_1(const widestring &str, char replacement = '?')
-{
-	Tdststring res;
-	res.reserve(str.length());
-	for(std::size_t i = 0; i < str.length(); ++i)
-	{
-		char32_t c = static_cast<char32_t>(str[i]);
-		if(c <= 0xff)
-		{
-			res.push_back(static_cast<typename Tdststring::value_type>(static_cast<uint8>(c)));
-		} else
-		{
-			res.push_back(replacement);
-		}
-	}
-	return res;
-}
-
-
-#if defined(MPT_ENABLE_CHARSET_LOCALE) && !defined(MPT_LOCALE_ASSUME_CHARSET)
-
-// Note:
-//
-//  std::codecvt::out in LLVM libc++ does not advance in and out pointers when
-// running into a non-convertible character. This can happen when no locale is
-// set on FreeBSD or MacOSX. This behaviour violates the C++ standard.
-//
-//  We apply the following (albeit costly, even on other platforms) work-around:
-//  If the conversion errors out and does not advance the pointers at all, we
-// retry the conversion with a space character prepended to the string. If it
-// still does error out, we retry the whole conversion character by character.
-//  This is costly even on other platforms in one single case: The first
-// character is an invalid Unicode code point or otherwise not convertible. Any
-// following non-convertible characters are not a problem.
-
-static std::wstring LocaleDecode(const std::string &str, const std::locale & locale, wchar_t replacement = L'\uFFFD', int retry = 0, bool * progress = nullptr)
-{
-	if(str.empty())
-	{
-		return std::wstring();
-	}
-	std::vector<wchar_t> out;
-	using codecvt_type = std::codecvt<wchar_t, char, std::mbstate_t>;
-	std::mbstate_t state = std::mbstate_t();
-	const codecvt_type & facet = std::use_facet<codecvt_type>(locale);
-	codecvt_type::result result = codecvt_type::partial;
-	const char * in_begin = str.data();
-	const char * in_end = in_begin + str.size();
-	out.resize((in_end - in_begin) * (facet.max_length() + 1));
-	wchar_t * out_begin = &(out[0]);
-	wchar_t * out_end = &(out[0]) + out.size();
-	const char * in_next = nullptr;
-	wchar_t * out_next = nullptr;
-	do
-	{
-		if(retry == 2)
-		{
-			for(;;)
-			{
-				in_next = nullptr;
-				out_next = nullptr;
-				result = facet.in(state, in_begin, in_begin + 1, in_next, out_begin, out_end, out_next);
-				if(result == codecvt_type::partial && in_next == in_begin + 1)
-				{
-					in_begin = in_next;
-					out_begin = out_next;
-					continue;
-				} else
-				{
-					break;
-				}
-			}
-		} else
-		{
-			in_next = nullptr;
-			out_next = nullptr;
-			result = facet.in(state, in_begin, in_end, in_next, out_begin, out_end, out_next);
-		}
-		if(result == codecvt_type::partial || (result == codecvt_type::error && out_next == out_end))
-		{
-			out.resize(out.size() * 2);
-			in_begin = in_next;
-			out_begin = &(out[0]) + (out_next - out_begin);
-			out_end = &(out[0]) + out.size();
-			continue;
-		}
-		if(retry == 0)
-		{
-			if(result == codecvt_type::error && in_next == in_begin && out_next == out_begin)
-			{
-				bool made_progress = true;
-				LocaleDecode(std::string(" ") + str, locale, replacement, 1, &made_progress);
-				if(!made_progress)
-				{
-					return LocaleDecode(str, locale, replacement, 2);
-				}
-			}
-		} else if(retry == 1)
-		{
-			if(result == codecvt_type::error && in_next == in_begin && out_next == out_begin)
-			{
-				*progress = false;
-			} else
-			{
-				*progress = true;
-			}
-			return std::wstring();
-		}
-		if(result == codecvt_type::error)
-		{
-			++in_next;
-			*out_next = replacement;
-			++out_next;
-		}
-		in_begin = in_next;
-		out_begin = out_next;
-	} while((result == codecvt_type::error && in_next < in_end && out_next < out_end) || (retry == 2 && in_next < in_end));
-	return std::wstring(&(out[0]), out_next);
-}
-
-static std::string LocaleEncode(const std::wstring &str, const std::locale & locale, char replacement = '?', int retry = 0, bool * progress = nullptr)
-{
-	if(str.empty())
-	{
-		return std::string();
-	}
-	std::vector<char> out;
-	using codecvt_type = std::codecvt<wchar_t, char, std::mbstate_t>;
-	std::mbstate_t state = std::mbstate_t();
-	const codecvt_type & facet = std::use_facet<codecvt_type>(locale);
-	codecvt_type::result result = codecvt_type::partial;
-	const wchar_t * in_begin = str.data();
-	const wchar_t * in_end = in_begin + str.size();
-	out.resize((in_end - in_begin) * (facet.max_length() + 1));
-	char * out_begin = &(out[0]);
-	char * out_end = &(out[0]) + out.size();
-	const wchar_t * in_next = nullptr;
-	char * out_next = nullptr;
-	do
-	{
-		if(retry == 2)
-		{
-			for(;;)
-			{
-				in_next = nullptr;
-				out_next = nullptr;
-				result = facet.out(state, in_begin, in_begin + 1, in_next, out_begin, out_end, out_next);
-				if(result == codecvt_type::partial && in_next == in_begin + 1)
-				{
-					in_begin = in_next;
-					out_begin = out_next;
-					continue;
-				} else
-				{
-					break;
-				}
-			}
-		} else
-		{
-			in_next = nullptr;
-			out_next = nullptr;
-			result = facet.out(state, in_begin, in_end, in_next, out_begin, out_end, out_next);
-		}
-		if(result == codecvt_type::partial || (result == codecvt_type::error && out_next == out_end))
-		{
-			out.resize(out.size() * 2);
-			in_begin = in_next;
-			out_begin = &(out[0]) + (out_next - out_begin);
-			out_end = &(out[0]) + out.size();
-			continue;
-		}
-		if(retry == 0)
-		{
-			if(result == codecvt_type::error && in_next == in_begin && out_next == out_begin)
-			{
-				bool made_progress = true;
-				LocaleEncode(std::wstring(L" ") + str, locale, replacement, 1, &made_progress);
-				if(!made_progress)
-				{
-					return LocaleEncode(str, locale, replacement, 2);
-				}
-			}
-		} else if(retry == 1)
-		{
-			if(result == codecvt_type::error && in_next == in_begin && out_next == out_begin)
-			{
-				*progress = false;
-			} else
-			{
-				*progress = true;
-			}
-			return std::string();
-		}
-		if(result == codecvt_type::error)
-		{
-			++in_next;
-			*out_next = replacement;
-			++out_next;
-		}
-		in_begin = in_next;
-		out_begin = out_next;
-	} while((result == codecvt_type::error && in_next < in_end && out_next < out_end) || (retry == 2 && in_next < in_end));
-	return std::string(&(out[0]), out_next);
-}
-
-static std::wstring FromLocaleCpp(const std::string &str, wchar_t replacement)
-{
-	try
-	{
-		std::locale locale(""); // user locale
-		return String::LocaleDecode(str, locale, replacement);
-	} MPT_EXCEPTION_CATCH_OUT_OF_MEMORY(e)
-	{
-		MPT_EXCEPTION_RETHROW_OUT_OF_MEMORY(e);
-	} catch(...)
-	{
-		// nothing
-	}
-	try
-	{
-		std::locale locale; // current c++ locale
-		return String::LocaleDecode(str, locale, replacement);
-	} MPT_EXCEPTION_CATCH_OUT_OF_MEMORY(e)
-	{
-		MPT_EXCEPTION_RETHROW_OUT_OF_MEMORY(e);
-	} catch(...)
-	{
-		// nothing
-	}
-	try
-	{
-		std::locale locale = std::locale::classic(); // "C" locale
-		return String::LocaleDecode(str, locale, replacement);
-	} MPT_EXCEPTION_CATCH_OUT_OF_MEMORY(e)
-	{
-		MPT_EXCEPTION_RETHROW_OUT_OF_MEMORY(e);
-	} catch(...)
-	{
-		// nothing
-	}
-	MPT_ASSERT_NOTREACHED();
-	return String::FromAscii<std::string>(str, replacement); // fallback
-}
-
-static std::string ToLocaleCpp(const std::wstring &str, char replacement)
-{
-	try
-	{
-		std::locale locale(""); // user locale
-		return String::LocaleEncode(str, locale, replacement);
-	} MPT_EXCEPTION_CATCH_OUT_OF_MEMORY(e)
-	{
-		MPT_EXCEPTION_RETHROW_OUT_OF_MEMORY(e);
-	} catch(...)
-	{
-		// nothing
-	}
-	try
-	{
-		std::locale locale; // current c++ locale
-		return String::LocaleEncode(str, locale, replacement);
-	} MPT_EXCEPTION_CATCH_OUT_OF_MEMORY(e)
-	{
-		MPT_EXCEPTION_RETHROW_OUT_OF_MEMORY(e);
-	} catch(...)
-	{
-		// nothing
-	}
-	try
-	{
-		std::locale locale = std::locale::classic(); // "C" locale
-		return String::LocaleEncode(str, locale, replacement);
-	} MPT_EXCEPTION_CATCH_OUT_OF_MEMORY(e)
-	{
-		MPT_EXCEPTION_RETHROW_OUT_OF_MEMORY(e);
-	} catch(...)
-	{
-		// nothing
-	}
-	MPT_ASSERT_NOTREACHED();
-	return String::ToAscii<std::string>(str, replacement); // fallback
-}
-
-
-template <typename Tsrcstring>
-static std::wstring FromLocale(const Tsrcstring &str, wchar_t replacement = L'\uFFFD')
-{
-	std::string tmp(str.begin(), str.end());
-	return FromLocaleCpp(tmp, replacement);
-}
-template <>
-std::wstring FromLocale<std::string>(const std::string &str, wchar_t replacement)
-{
-	return FromLocaleCpp(str, replacement);
-}
-
-template <typename Tdststring>
-static Tdststring ToLocale(const std::wstring &str, char replacement = '?')
-{
-	std::string tmp = ToLocaleCpp(str, replacement);
-	return Tdststring(tmp.begin(), tmp.end());
-}
-template <>
-std::string ToLocale(const std::wstring &str, char replacement)
-{
-	return ToLocaleCpp(str, replacement);
-}
-
-
-#endif // MPT_ENABLE_CHARSET_LOCALE && !MPT_LOCALE_ASSUME_CHARSET
-
-template <typename Tsrcstring>
-static widestring FromUTF8(const Tsrcstring &str, widechar replacement = wide_default_replacement)
-{
-	const Tsrcstring &in = str;
-
-	widestring out;
-
-	// state:
-	std::size_t charsleft = 0;
-	char32_t ucs4 = 0;
-
-	for ( uint8 c : in ) {
-
-		if ( charsleft == 0 ) {
-
-			if ( ( c & 0x80 ) == 0x00 ) {
-				out.push_back( (wchar_t)c );
-			} else if ( ( c & 0xE0 ) == 0xC0 ) {
-				ucs4 = c & 0x1F;
-				charsleft = 1;
-			} else if ( ( c & 0xF0 ) == 0xE0 ) {
-				ucs4 = c & 0x0F;
-				charsleft = 2;
-			} else if ( ( c & 0xF8 ) == 0xF0 ) {
-				ucs4 = c & 0x07;
-				charsleft = 3;
-			} else {
-				out.push_back( replacement );
-				ucs4 = 0;
-				charsleft = 0;
-			}
-
-		} else {
-
-			if ( ( c & 0xC0 ) != 0x80 ) {
-				out.push_back( replacement );
-				ucs4 = 0;
-				charsleft = 0;
-			}
-			ucs4 <<= 6;
-			ucs4 |= c & 0x3F;
-			charsleft--;
-
-			if ( charsleft == 0 ) {
-				if constexpr ( sizeof( widechar ) == 2 ) {
-					if ( ucs4 > 0x1fffff ) {
-						out.push_back( replacement );
-						ucs4 = 0;
-						charsleft = 0;
-					}
-					if ( ucs4 <= 0xffff ) {
-						out.push_back( static_cast<widechar>(ucs4) );
-					} else {
-						uint32 surrogate = static_cast<uint32>(ucs4) - 0x10000;
-						uint16 hi_sur = static_cast<uint16>( ( 0x36 << 10 ) | ( (surrogate>>10) & ((1<<10)-1) ) );
-						uint16 lo_sur = static_cast<uint16>( ( 0x37 << 10 ) | ( (surrogate>> 0) & ((1<<10)-1) ) );
-						out.push_back( hi_sur );
-						out.push_back( lo_sur );
-					}
-				} else {
-					out.push_back( static_cast<widechar>( ucs4 ) );
-				}
-				ucs4 = 0;
-			}
-
-		}
-
-	}
-
-	if ( charsleft != 0 ) {
-		out.push_back( replacement );
-		ucs4 = 0;
-		charsleft = 0;
-	}
-
-	return out;
-
-}
-
-template <typename Tdststring>
-static Tdststring ToUTF8(const widestring &str, char replacement = '?')
-{
-	const widestring &in = str;
-
-	Tdststring out;
-
-	for ( std::size_t i=0; i<in.length(); i++ ) {
-
-		wchar_t wc = in[i];
-
-		char32_t ucs4 = 0;
-		if constexpr ( sizeof( widechar ) == 2 ) {
-			uint16 c = static_cast<uint16>( wc );
-			if ( i + 1 < in.length() ) {
-				// check for surrogate pair
-				uint16 hi_sur = in[i+0];
-				uint16 lo_sur = in[i+1];
-				if ( hi_sur >> 10 == 0x36 && lo_sur >> 10 == 0x37 ) {
-					// surrogate pair
-					++i;
-					hi_sur &= (1<<10)-1;
-					lo_sur &= (1<<10)-1;
-					ucs4 = ( static_cast<uint32>(hi_sur) << 10 ) | ( static_cast<uint32>(lo_sur) << 0 );
-				} else {
-					// no surrogate pair
-					ucs4 = static_cast<char32_t>( c );
-				}
-			} else {
-				// no surrogate possible
-				ucs4 = static_cast<char32_t>( c );
-			}
-		} else {
-			ucs4 = static_cast<char32_t>( wc );
-		}
-		
-		if ( ucs4 > 0x1fffff ) {
-			out.push_back( replacement );
-			continue;
-		}
-
-		uint8 utf8[6];
-		std::size_t numchars = 0;
-		for ( numchars = 0; numchars < 6; numchars++ ) {
-			utf8[numchars] = ucs4 & 0x3F;
-			ucs4 >>= 6;
-			if ( ucs4 == 0 ) {
-				break;
-			}
-		}
-		numchars++;
-
-		if ( numchars == 1 ) {
-			out.push_back( utf8[0] );
-			continue;
-		}
-
-		if ( numchars == 2 && utf8[numchars-1] == 0x01 ) {
-			// generate shortest form
-			out.push_back( utf8[0] | 0x40 );
-			continue;
-		}
-
-		std::size_t charsleft = numchars;
-		while ( charsleft > 0 ) {
-			if ( charsleft == numchars ) {
-				out.push_back( utf8[ charsleft - 1 ] | ( ((1<<numchars)-1) << (8-numchars) ) );
-			} else {
-				out.push_back( utf8[ charsleft - 1 ] | 0x80 );
-			}
-			charsleft--;
-		}
-
-	}
-
-	return out;
-
-}
-
-
-// templated on 8bit strings because of type-safe variants
-template<typename Tdststring>
-static Tdststring EncodeImpl(Charset charset, const widestring &src)
-{
-	static_assert(sizeof(typename Tdststring::value_type) == sizeof(char));
-	static_assert((std::is_same<typename Tdststring::value_type, char>::value));
-	#if defined(MPT_ENABLE_CHARSET_LOCALE)
-		#if defined(MPT_LOCALE_ASSUME_CHARSET)
-			if(charset == Charset::Locale)
-			{
-				charset = MPT_LOCALE_ASSUME_CHARSET;
-			}
-		#endif
-	#endif
-	#if MPT_OS_WINDOWS
-		if(HasCharset(charset))
-		{
-			return EncodeCodepage<Tdststring>(CharsetToCodepage(charset), src);
-		}
-	#endif
-	switch(charset)
-	{
-#if defined(MPT_ENABLE_CHARSET_LOCALE)
-	#if defined(MPT_LOCALE_ASSUME_CHARSET)
-		case Charset::Locale:      MPT_ASSERT_NOTREACHED(); break;
-	#else
-		case Charset::Locale:      return String::ToLocale<Tdststring>(src); break;
-	#endif
-#endif
-		case Charset::UTF8:        return String::ToUTF8<Tdststring>(src); break;
-		case Charset::ASCII:       return String::ToAscii<Tdststring>(src); break;
-		case Charset::ISO8859_1:   return String::ToISO_8859_1<Tdststring>(src); break;
-		case Charset::ISO8859_15:  return String::To8bit<Tdststring>(src, CharsetTableISO8859_15); break;
-		case Charset::CP437:       return String::To8bit<Tdststring>(src, CharsetTableCP437); break;
-		case Charset::CP437AMS:    return String::To8bit<Tdststring>(src, CharsetTableCP437AMS); break;
-		case Charset::CP437AMS2:   return String::To8bit<Tdststring>(src, CharsetTableCP437AMS2); break;
-		case Charset::Windows1252: return String::To8bit<Tdststring>(src, CharsetTableWindows1252); break;
-	}
-	return Tdststring();
-}
-
-
-// templated on 8bit strings because of type-safe variants
-template<typename Tsrcstring>
-static widestring DecodeImpl(Charset charset, const Tsrcstring &src)
-{
-	static_assert(sizeof(typename Tsrcstring::value_type) == sizeof(char));
-	static_assert((std::is_same<typename Tsrcstring::value_type, char>::value));
-	#if defined(MPT_ENABLE_CHARSET_LOCALE)
-		#if defined(MPT_LOCALE_ASSUME_CHARSET)
-			if(charset == Charset::Locale)
-			{
-				charset = MPT_LOCALE_ASSUME_CHARSET;
-			}
-		#endif
-	#endif
-	#if MPT_OS_WINDOWS
-		if(HasCharset(charset))
-		{
-			return DecodeCodepage<Tsrcstring>(CharsetToCodepage(charset), src);
-		}
-	#endif
-	switch(charset)
-	{
-#if defined(MPT_ENABLE_CHARSET_LOCALE)
-	#if defined(MPT_LOCALE_ASSUME_CHARSET)
-		case Charset::Locale:      MPT_ASSERT_NOTREACHED(); break;
-	#else
-		case Charset::Locale:      return String::FromLocale<Tsrcstring>(src); break;
-	#endif
-#endif
-		case Charset::UTF8:        return String::FromUTF8<Tsrcstring>(src); break;
-		case Charset::ASCII:       return String::FromAscii<Tsrcstring>(src); break;
-		case Charset::ISO8859_1:   return String::FromISO_8859_1<Tsrcstring>(src); break;
-		case Charset::ISO8859_15:  return String::From8bit<Tsrcstring>(src, CharsetTableISO8859_15); break;
-		case Charset::CP437:       return String::From8bit<Tsrcstring>(src, CharsetTableCP437); break;
-		case Charset::CP437AMS:    return String::From8bit<Tsrcstring>(src, CharsetTableCP437AMS); break;
-		case Charset::CP437AMS2:   return String::From8bit<Tsrcstring>(src, CharsetTableCP437AMS2); break;
-		case Charset::Windows1252: return String::From8bit<Tsrcstring>(src, CharsetTableWindows1252); break;
-	}
-	return widestring();
-}
-
-
-// templated on 8bit strings because of type-safe variants
-template<typename Tdststring, typename Tsrcstring>
-static Tdststring ConvertImpl(Charset to, Charset from, const Tsrcstring &src)
-{
-	static_assert(sizeof(typename Tdststring::value_type) == sizeof(char));
-	static_assert(sizeof(typename Tsrcstring::value_type) == sizeof(char));
-	if(to == from)
-	{
-		const typename Tsrcstring::value_type * src_beg = src.data();
-		const typename Tsrcstring::value_type * src_end = src_beg + src.size();
-		return Tdststring(reinterpret_cast<const typename Tdststring::value_type *>(src_beg), reinterpret_cast<const typename Tdststring::value_type *>(src_end));
-	}
-	return EncodeImpl<Tdststring>(to, DecodeImpl(from, src));
-}
-
-
-
-} // namespace String
-
-
-bool IsUTF8(const std::string &str)
-{
-	return (str == String::EncodeImpl<std::string>(mpt::Charset::UTF8, String::DecodeImpl<std::string>(mpt::Charset::UTF8, str)));
-}
-
-
-#if MPT_WSTRING_CONVERT
-std::wstring ToWide(Charset from, const std::string &str)
-{
-	return String::DecodeImpl(from, str);
-}
-#if defined(MPT_ENABLE_CHARSET_LOCALE)
-std::wstring ToWide(const mpt::lstring &str)
-{
-	return String::DecodeImpl(Charset::Locale, str);
-}
-#endif // MPT_ENABLE_CHARSET_LOCALE
-#endif
-
-#if MPT_WSTRING_CONVERT
-std::string ToCharset(Charset to, const std::wstring &str)
-{
-	return String::EncodeImpl<std::string>(to, str);
-}
-#endif
-std::string ToCharset(Charset to, Charset from, const std::string &str)
-{
-	return String::ConvertImpl<std::string>(to, from, str);
-}
-#if defined(MPT_ENABLE_CHARSET_LOCALE)
-std::string ToCharset(Charset to, const mpt::lstring &str)
-{
-	return String::ConvertImpl<std::string>(to, Charset::Locale, str);
-}
-#endif // MPT_ENABLE_CHARSET_LOCALE
-
-#if defined(MPT_ENABLE_CHARSET_LOCALE)
-#if MPT_WSTRING_CONVERT
-mpt::lstring ToLocale(const std::wstring &str)
-{
-	return String::EncodeImpl<mpt::lstring>(Charset::Locale, str);
-}
-#endif
-mpt::lstring ToLocale(Charset from, const std::string &str)
-{
-	return String::ConvertImpl<mpt::lstring>(Charset::Locale, from, str);
-}
-#endif // MPT_ENABLE_CHARSET_LOCALE
-
-#if MPT_OS_WINDOWS
-#if MPT_WSTRING_CONVERT
-mpt::winstring ToWin(const std::wstring &str)
-{
-	#ifdef UNICODE
-		return str;
-	#else
-		return ToLocale(str);
-	#endif
-}
-#endif
-mpt::winstring ToWin(Charset from, const std::string &str)
-{
-	#ifdef UNICODE
-		return ToWide(from, str);
-	#else
-		return ToLocale(from, str);
-	#endif
-}
-#if defined(MPT_ENABLE_CHARSET_LOCALE)
-mpt::winstring ToWin(const mpt::lstring &str)
-{
-	#ifdef UNICODE
-		return ToWide(str);
-	#else
-		return str;
-	#endif
-}
-#endif // MPT_ENABLE_CHARSET_LOCALE
-#endif // MPT_OS_WINDOWS
-
-
-#if defined(_MFC_VER)
-
-CString ToCString(const std::wstring &str)
-{
-	#ifdef UNICODE
-		return str.c_str();
-	#else
-		return ToCharset(Charset::Locale, str).c_str();
-	#endif
-}
-CString ToCString(Charset from, const std::string &str)
-{
-	#ifdef UNICODE
-		return ToWide(from, str).c_str();
-	#else
-		return ToCharset(Charset::Locale, from, str).c_str();
-	#endif
-}
-std::wstring ToWide(const CString &str)
-{
-	#ifdef UNICODE
-		return str.GetString();
-	#else
-		return ToWide(Charset::Locale, str.GetString());
-	#endif
-}
-std::string ToCharset(Charset to, const CString &str)
-{
-	#ifdef UNICODE
-		return ToCharset(to, str.GetString());
-	#else
-		return ToCharset(to, Charset::Locale, str.GetString());
-	#endif
-}
-#if defined(MPT_ENABLE_CHARSET_LOCALE)
-CString ToCString(const mpt::lstring &str)
-{
-	#ifdef UNICODE
-		return ToWide(str).c_str();
-	#else
-		return str.c_str();
-	#endif
-}
-mpt::lstring ToLocale(const CString &str)
-{
-	#ifdef UNICODE
-		return String::EncodeImpl<mpt::lstring>(Charset::Locale, str.GetString());
-	#else
-		return str.GetString();
-	#endif
-}
-#endif // MPT_ENABLE_CHARSET_LOCALE
-#if MPT_OS_WINDOWS
-mpt::winstring ToWin(const CString &str)
-{
-	return str.GetString();
-}
-#endif // MPT_OS_WINDOWS
-
-#endif // MFC
-
-
-#if MPT_USTRING_MODE_WIDE
-// inline
-#else // !MPT_USTRING_MODE_WIDE
-#if MPT_WSTRING_CONVERT
-mpt::ustring ToUnicode(const std::wstring &str)
-{
-	return String::EncodeImpl<mpt::ustring>(mpt::Charset::UTF8, str);
-}
-#endif
-mpt::ustring ToUnicode(Charset from, const std::string &str)
-{
-	return String::ConvertImpl<mpt::ustring>(mpt::Charset::UTF8, from, str);
-}
-#if defined(MPT_ENABLE_CHARSET_LOCALE)
-mpt::ustring ToUnicode(const mpt::lstring &str)
-{
-	return String::ConvertImpl<mpt::ustring>(mpt::Charset::UTF8, mpt::Charset::Locale, str);
-}
-#endif // MPT_ENABLE_CHARSET_LOCALE
-#if defined(_MFC_VER)
-mpt::ustring ToUnicode(const CString &str)
-{
-	#ifdef UNICODE
-		return String::EncodeImpl<mpt::ustring>(mpt::Charset::UTF8, str.GetString());
-	#else // !UNICODE
-		return String::ConvertImpl<mpt::ustring, std::string>(mpt::Charset::UTF8, mpt::Charset::Locale, str.GetString());
-	#endif // UNICODE
-}
-#endif // MFC
-#endif // MPT_USTRING_MODE_WIDE
-
-#if MPT_USTRING_MODE_WIDE
-// nothing, std::wstring overloads will catch all stuff
-#else // !MPT_USTRING_MODE_WIDE
-#if MPT_WSTRING_CONVERT
-std::wstring ToWide(const mpt::ustring &str)
-{
-	return String::DecodeImpl<mpt::ustring>(mpt::Charset::UTF8, str);
-}
-#endif
-std::string ToCharset(Charset to, const mpt::ustring &str)
-{
-	return String::ConvertImpl<std::string, mpt::ustring>(to, mpt::Charset::UTF8, str);
-}
-#if defined(MPT_ENABLE_CHARSET_LOCALE)
-mpt::lstring ToLocale(const mpt::ustring &str)
-{
-	return String::ConvertImpl<mpt::lstring, mpt::ustring>(mpt::Charset::Locale, mpt::Charset::UTF8, str);
-}
-#endif // MPT_ENABLE_CHARSET_LOCALE
-#if MPT_OS_WINDOWS
-mpt::winstring ToWin(const mpt::ustring &str)
-{
-	#ifdef UNICODE
-		return String::DecodeImpl<mpt::ustring>(mpt::Charset::UTF8, str);
-	#else
-		return String::ConvertImpl<mpt::lstring, mpt::ustring>(mpt::Charset::Locale, mpt::Charset::UTF8, str);
-	#endif
-}
-#endif // MPT_OS_WINDOWS
-#if defined(_MFC_VER)
-CString ToCString(const mpt::ustring &str)
-{
-	#ifdef UNICODE
-		return String::DecodeImpl<mpt::ustring>(mpt::Charset::UTF8, str).c_str();
-	#else // !UNICODE
-		return String::ConvertImpl<std::string, mpt::ustring>(mpt::Charset::Locale, mpt::Charset::UTF8, str).c_str();
-	#endif // UNICODE
-}
-#endif // MFC
-#endif // MPT_USTRING_MODE_WIDE
-
-
-
-
-
-static mpt::Charset CharsetFromCodePage(uint16 codepage, mpt::Charset fallback, bool * isFallback = nullptr)
-{
-	mpt::Charset result = fallback;
-	switch(codepage)
-	{
-	case 65001:
-		result = mpt::Charset::UTF8;
-		if(isFallback) *isFallback = false;
-		break;
-	case 20127:
-		result = mpt::Charset::ASCII;
-		if(isFallback) *isFallback = false;
-		break;
-	case 28591:
-		result = mpt::Charset::ISO8859_1;
-		if(isFallback) *isFallback = false;
-		break;
-	case 28605:
-		result = mpt::Charset::ISO8859_15;
-		if(isFallback) *isFallback = false;
-		break;
-	case 437:
-		result = mpt::Charset::CP437;
-		if(isFallback) *isFallback = false;
-		break;
-	case 1252:
-		result = mpt::Charset::Windows1252;
-		if(isFallback) *isFallback = false;
-		break;
-	default:
-		result = fallback;
-		if(isFallback) *isFallback = true;
-		break;
-	}
-	return result;
-}
-
-mpt::ustring ToUnicode(uint16 codepage, mpt::Charset fallback, const std::string &str)
-{
-	#if MPT_OS_WINDOWS
-		mpt::ustring result;
-		bool noCharsetMatch = true;
-		mpt::Charset charset = mpt::CharsetFromCodePage(codepage, fallback, &noCharsetMatch);
-		if(noCharsetMatch && mpt::String::TestCodePage(codepage))
-		{
-			result = mpt::ToUnicode(mpt::String::DecodeCodepage<std::string>(codepage, str));
-		} else
-		{
-			result = mpt::ToUnicode(charset, str);
-		}
-		return result;
-	#else // !MPT_OS_WINDOWS
-		return mpt::ToUnicode(mpt::CharsetFromCodePage(codepage, fallback), str);
-	#endif // MPT_OS_WINDOWS
-}
-
-
-
-
-
-char ToLowerCaseAscii(char c)
-{
-	if('A' <= c && c <= 'Z')
-	{
-		c += 'a' - 'A';
-	}
-	return c;
-}
-
-char ToUpperCaseAscii(char c)
-{
-	if('a' <= c && c <= 'z')
-	{
-		c -= 'a' - 'A';
-	}
-	return c;
-}
-
-std::string ToLowerCaseAscii(std::string s)
-{
-	std::transform(s.begin(), s.end(), s.begin(), static_cast<char(*)(char)>(&mpt::ToLowerCaseAscii));
-	return s;
-}
-
-std::string ToUpperCaseAscii(std::string s)
-{
-	std::transform(s.begin(), s.end(), s.begin(), static_cast<char(*)(char)>(&mpt::ToUpperCaseAscii));
-	return s;
-}
-
-int CompareNoCaseAscii(const char *a, const char *b, std::size_t n)
-{
-	while(n--)
-	{
-		unsigned char ac = static_cast<unsigned char>(mpt::ToLowerCaseAscii(*a));
-		unsigned char bc = static_cast<unsigned char>(mpt::ToLowerCaseAscii(*b));
-		if(ac != bc)
-		{
-			return ac < bc ? -1 : 1;
-		} else if(!ac && !bc)
-		{
-			return 0;
-		}
-		++a;
-		++b;
-	}
-	return 0;
-}
-
-int CompareNoCaseAscii(const std::string &a, const std::string &b)
-{
-	for(std::size_t i = 0; i < std::min(a.length(), b.length()); ++i)
-	{
-		unsigned char ac = static_cast<unsigned char>(mpt::ToLowerCaseAscii(a[i]));
-		unsigned char bc = static_cast<unsigned char>(mpt::ToLowerCaseAscii(b[i]));
-		if(ac != bc)
-		{
-			return ac < bc ? -1 : 1;
-		} else if(!ac && !bc)
-		{
-			return 0;
-		}
-	}
-	if(a.length() == b.length())
-	{
-		return 0;
-	}
-	return a.length() < b.length() ? -1 : 1;
-}
-
-#if defined(MODPLUG_TRACKER)
-
-mpt::ustring ToLowerCase(const mpt::ustring &s)
-{
-	#if defined(_MFC_VER)
-		#if defined(UNICODE)
-			CString tmp = mpt::ToCString(s);
-			tmp.MakeLower();
-			return mpt::ToUnicode(tmp);
-		#else // !UNICODE
-			CStringW tmp = mpt::ToWide(s).c_str();
-			tmp.MakeLower();
-			return mpt::ToUnicode(tmp.GetString());
-		#endif // UNICODE
-	#else // !_MFC_VER
-		std::wstring ws = mpt::ToWide(s);
-		std::transform(ws.begin(), ws.end(), ws.begin(), &std::towlower);
-		return mpt::ToUnicode(ws);
-	#endif // _MFC_VER
-}
-
-mpt::ustring ToUpperCase(const mpt::ustring &s)
-{
-	#if defined(_MFC_VER)
-		#if defined(UNICODE)
-			CString tmp = mpt::ToCString(s);
-			tmp.MakeUpper();
-			return mpt::ToUnicode(tmp);
-		#else // !UNICODE
-			CStringW tmp = mpt::ToWide(s).c_str();
-			tmp.MakeUpper();
-			return mpt::ToUnicode(tmp.GetString());
-		#endif // UNICODE
-	#else // !_MFC_VER
-		std::wstring ws = mpt::ToWide(s);
-		std::transform(ws.begin(), ws.end(), ws.begin(), &std::towlower);
-		return mpt::ToUnicode(ws);
-	#endif // _MFC_VER
-}
-
-#endif // MODPLUG_TRACKER
-
-
-
-} // namespace mpt
-
-
-
-OPENMPT_NAMESPACE_END

+ 0 - 700
libopenmpt.mod/openmpt/common/mptString.h

@@ -1,700 +0,0 @@
-/*
- * mptString.h
- * ----------
- * Purpose: Small string-related utilities, number and message formatting.
- * Notes  : Currently none.
- * Authors: OpenMPT Devs
- * The OpenMPT source code is released under the BSD license. Read LICENSE for more details.
- */
-
-
-#pragma once
-
-#include "BuildSettings.h"
-
-#include "mptAlloc.h"
-#include "mptBaseTypes.h"
-#include "mptSpan.h"
-
-#include <algorithm>
-#include <limits>
-#include <string>
-
-#include <cstring>
-
-
-OPENMPT_NAMESPACE_BEGIN
-
-
-namespace mpt
-{
-
-
-
-template <typename T> inline span<T> as_span(std::basic_string<T> & str) { return span<T>(&(str[0]), str.length()); }
-
-template <typename T> inline span<const T> as_span(const std::basic_string<T> & str) { return span<const T>(&(str[0]), str.length()); }
-
-
-
-template <typename T> inline std::vector<typename std::remove_const<T>::type> make_vector(const std::basic_string<T> & str) { return std::vector<typename std::remove_const<T>::type>(str.begin(), str.end()); }
-
-
-
-// string_traits abstract the API of underlying string classes, in particular they allow adopting to CString without having to specialize for CString explicitly 
-
-template <typename Tstring>
-struct string_traits
-{
-
-	using string_type = Tstring;
-	using size_type = typename string_type::size_type;
-	using char_type = typename string_type::value_type;
-
-	static inline std::size_t length(const string_type &str) { return str.length(); }
-
-	static inline void reserve(string_type &str, std::size_t size) { str.reserve(size); }
-
-	static inline string_type& append(string_type &str, const string_type &a) { return str.append(a); }
-	static inline string_type& append(string_type &str, string_type &&a) { return str.append(std::move(a)); }
-	static inline string_type& append(string_type &str, std::size_t count, char_type c) { return str.append(count, c); }
-
-	static inline string_type pad(string_type str, std::size_t left, std::size_t right)
-	{
-		str.insert(str.begin(), left, char_type(' '));
-		str.insert(str.end(), right, char_type(' '));
-		return str;
-	}
-
-};
-
-#if defined(_MFC_VER)
-template <>
-struct string_traits<CString>
-{
-
-	using string_type = CString;
-	using size_type = int;
-	using char_type = typename CString::XCHAR;
-
-	static inline size_type length(const string_type &str) { return str.GetLength(); }
-
-	static inline void reserve(string_type &str, size_type size) { str.Preallocate(size); }
-
-	static inline string_type& append(string_type &str, const string_type &a) { str += a; return str; }
-	static inline string_type& append(string_type &str, size_type count, char_type c) { while(count--) str.AppendChar(c); return str; }
-
-	static inline string_type pad(const string_type &str, size_type left, size_type right)
-	{
-		CString tmp;
-		while(left--) tmp.AppendChar(char_type(' '));
-		tmp += str;
-		while(right--) tmp.AppendChar(char_type(' '));
-		return tmp;
-	}
-
-};
-#endif
-
-
-
-namespace String
-{
-
-
-template <typename Tstring> struct Traits {
-	static MPT_FORCEINLINE const char * GetDefaultWhitespace() noexcept { return " \n\r\t"; }
-	static MPT_FORCEINLINE bool IsLineEnding(char c) noexcept { return c == '\r' || c == '\n'; }
-};
-
-template <> struct Traits<std::string> {
-	static MPT_FORCEINLINE const char * GetDefaultWhitespace() noexcept { return " \n\r\t"; }
-	static MPT_FORCEINLINE bool IsLineEnding(char c) noexcept { return c == '\r' || c == '\n'; }
-};
-
-#if !defined(MPT_COMPILER_QUIRK_NO_WCHAR)
-template <> struct Traits<std::wstring> {
-	static MPT_FORCEINLINE const wchar_t * GetDefaultWhitespace() noexcept { return L" \n\r\t"; }
-	static MPT_FORCEINLINE bool IsLineEnding(wchar_t c) noexcept { return c == L'\r' || c == L'\n'; }
-};
-#endif // !MPT_COMPILER_QUIRK_NO_WCHAR
-
-
-// Remove whitespace at start of string
-template <typename Tstring>
-inline Tstring LTrim(Tstring str, const Tstring &whitespace = Tstring(mpt::String::Traits<Tstring>::GetDefaultWhitespace()))
-{
-	typename Tstring::size_type pos = str.find_first_not_of(whitespace);
-	if(pos != Tstring::npos)
-	{
-		str.erase(str.begin(), str.begin() + pos);
-	} else if(pos == Tstring::npos && str.length() > 0 && str.find_last_of(whitespace) == str.length() - 1)
-	{
-		return Tstring();
-	}
-	return str;
-}
-
-
-// Remove whitespace at end of string
-template <typename Tstring>
-inline Tstring RTrim(Tstring str, const Tstring &whitespace = Tstring(mpt::String::Traits<Tstring>::GetDefaultWhitespace()))
-{
-	typename Tstring::size_type pos = str.find_last_not_of(whitespace);
-	if(pos != Tstring::npos)
-	{
-		str.erase(str.begin() + pos + 1, str.end());
-	} else if(pos == Tstring::npos && str.length() > 0 && str.find_first_of(whitespace) == 0)
-	{
-		return Tstring();
-	}
-	return str;
-}
-
-
-// Remove whitespace at start and end of string
-template <typename Tstring>
-inline Tstring Trim(Tstring str, const Tstring &whitespace = Tstring(mpt::String::Traits<Tstring>::GetDefaultWhitespace()))
-{
-	return RTrim(LTrim(str, whitespace), whitespace);
-}
-
-
-template <typename Tstring, typename Tstring2, typename Tstring3>
-inline Tstring Replace(Tstring str, const Tstring2 &oldStr_, const Tstring3 &newStr_)
-{
-	std::size_t pos = 0;
-	const Tstring oldStr = oldStr_;
-	const Tstring newStr = newStr_;
-	while((pos = str.find(oldStr, pos)) != Tstring::npos)
-	{
-		str.replace(pos, oldStr.length(), newStr);
-		pos += newStr.length();
-	}
-	return str;
-}
-
-
-} // namespace String
-
-
-static inline std::string truncate(std::string str, std::size_t maxLen)
-{
-	if(str.length() > maxLen)
-	{
-		str.resize(maxLen);
-	}
-	return str;
-}
-
-
-enum class Charset {
-
-	UTF8,
-
-	ASCII, // strictly 7-bit ASCII
-
-	ISO8859_1,
-	ISO8859_15,
-
-	CP437,
-	CP437AMS,
-	CP437AMS2,
-
-	Windows1252,
-
-#if defined(MPT_ENABLE_CHARSET_LOCALE)
-	Locale, // CP_ACP on windows, current C locale otherwise
-#endif // MPT_ENABLE_CHARSET_LOCALE
-
-};
-
-
-
-// source code / preprocessor (i.e. # token)
-constexpr Charset CharsetSource = Charset::ASCII;
-
-// debug log files
-constexpr Charset CharsetLogfile = Charset::UTF8;
-
-// std::clog / std::cout / std::cerr
-#if defined(MODPLUG_TRACKER) && MPT_OS_WINDOWS && defined(MPT_ENABLE_CHARSET_LOCALE)
-constexpr Charset CharsetStdIO = Charset::Locale;
-#else
-constexpr Charset CharsetStdIO = Charset::UTF8;
-#endif
-
-// std::exception::what()
-#if defined(MPT_ENABLE_CHARSET_LOCALE)
-constexpr Charset CharsetException = Charset::Locale;
-#else
-constexpr Charset CharsetException = Charset::UTF8;
-#endif
-
-// Locale in tracker builds, UTF8 in non-locale-aware libopenmpt builds.
-#if defined(MPT_ENABLE_CHARSET_LOCALE)
-constexpr Charset CharsetLocaleOrUTF8 = Charset::Locale;
-#else
-constexpr Charset CharsetLocaleOrUTF8 = Charset::UTF8;
-#endif
-
-
-
-// Checks if the std::string represents an UTF8 string.
-// This is currently implemented as converting to std::wstring and back assuming UTF8 both ways,
-// and comparing the result to the original string.
-// Caveats:
-//  - can give false negatives because of possible unicode normalization during conversion
-//  - can give false positives if the 8bit encoding contains high-ascii only in valid utf8 groups
-//  - slow because of double conversion
-bool IsUTF8(const std::string &str);
-
-
-#define MPT_CHAR_TYPE    char
-#define MPT_CHAR(x)      x
-#define MPT_LITERAL(x)   x
-#define MPT_STRING(x)    std::string( x )
-
-#if !defined(MPT_COMPILER_QUIRK_NO_WCHAR)
-#define MPT_WCHAR_TYPE   wchar_t
-#define MPT_WCHAR(x)     L ## x
-#define MPT_WLITERAL(x)  L ## x
-#define MPT_WSTRING(x)   std::wstring( L ## x )
-#else // MPT_COMPILER_QUIRK_NO_WCHAR
-#define MPT_WCHAR_TYPE   char32_t
-#define MPT_WCHAR(x)     U ## x
-#define MPT_WLITERAL(x)  U ## x
-#define MPT_WSTRING(x)   std::u32string( U ## x )
-#endif // !MPT_COMPILER_QUIRK_NO_WCHAR
-
-
-template <mpt::Charset charset_tag>
-struct charset_char_traits : std::char_traits<char> {
-	static mpt::Charset charset() { return charset_tag; }
-};
-#define MPT_ENCODED_STRING_TYPE(charset) std::basic_string< char, mpt::charset_char_traits< charset > >
-
-
-#if defined(MPT_ENABLE_CHARSET_LOCALE)
-
-using lstring = MPT_ENCODED_STRING_TYPE(mpt::Charset::Locale);
-
-#endif // MPT_ENABLE_CHARSET_LOCALE
-
-#if MPT_OS_WINDOWS
-
-template <typename Tchar> struct windows_char_traits { };
-template <> struct windows_char_traits<char>  { using string_type = mpt::lstring; };
-template <> struct windows_char_traits<wchar_t> { using string_type = std::wstring; };
-
-#ifdef UNICODE
-using tstring = windows_char_traits<wchar_t>::string_type;
-#else
-using tstring = windows_char_traits<char>::string_type;
-#endif
-
-using winstring = mpt::tstring;
-
-#endif // MPT_OS_WINDOWS
-
-
-#if MPT_ENABLE_U8STRING
-
-#if MPT_CXX_AT_LEAST(20)
-
-using u8string = std::u8string;
-
-#define MPT_U8CHAR_TYPE  char8_t
-#define MPT_U8CHAR(x)    u8 x
-#define MPT_U8LITERAL(x) u8 x
-#define MPT_U8STRING(x)  mpt::u8string( x )
-
-#else // !C++20
-
-using u8string = MPT_ENCODED_STRING_TYPE(mpt::Charset::UTF8);
-
-#define MPT_U8CHAR_TYPE  char
-#define MPT_U8CHAR(x)    x
-#define MPT_U8LITERAL(x) x
-#define MPT_U8STRING(x)  mpt::u8string( x )
-
-// mpt::u8string is a moderately type-safe string that is meant to contain
-// UTF-8 encoded char bytes.
-//
-// mpt::u8string is not implicitely convertible to/from std::string, but
-// it is convertible to/from C strings the same way as std::string is.
-//
-// The implementation of mpt::u8string is a compromise of compatibilty
-// with implementation-defined STL details, efficiency, source code size,
-// executable bloat, type-safety  and simplicity.
-//
-// mpt::u8string is not meant to be used directly though.
-// mpt::u8string is meant as an alternative implementaion to std::wstring
-// for implementing the unicode string type mpt::ustring.
-
-#endif // C++20
-
-#endif // MPT_ENABLE_U8STRING
-
-
-#if MPT_WSTRING_CONVERT
-// Convert to a wide character string.
-// The wide encoding is UTF-16 or UTF-32, based on sizeof(wchar_t).
-// If str does not contain any invalid characters, this conversion is lossless.
-// Invalid source bytes will be replaced by some replacement character or string.
-static inline std::wstring ToWide(const std::wstring &str) { return str; }
-static inline std::wstring ToWide(const wchar_t * str) { return (str ? std::wstring(str) : std::wstring()); }
-std::wstring ToWide(Charset from, const std::string &str);
-static inline std::wstring ToWide(Charset from, const char * str) { return ToWide(from, str ? std::string(str) : std::string()); }
-#if defined(MPT_ENABLE_CHARSET_LOCALE)
-std::wstring ToWide(const mpt::lstring &str);
-#endif // MPT_ENABLE_CHARSET_LOCALE
-#endif
-
-// Convert to a string encoded in the 'to'-specified character set.
-// If str does not contain any invalid characters,
-// this conversion will be lossless iff, and only iff,
-// 'to' is UTF8.
-// Invalid source bytes or characters that are not representable in the
-// destination charset will be replaced by some replacement character or string.
-#if MPT_WSTRING_CONVERT
-std::string ToCharset(Charset to, const std::wstring &str);
-static inline std::string ToCharset(Charset to, const wchar_t * str) { return ToCharset(to, str ? std::wstring(str) : std::wstring()); }
-#endif
-std::string ToCharset(Charset to, Charset from, const std::string &str);
-static inline std::string ToCharset(Charset to, Charset from, const char * str) { return ToCharset(to, from, str ? std::string(str) : std::string()); }
-#if defined(MPT_ENABLE_CHARSET_LOCALE)
-std::string ToCharset(Charset to, const mpt::lstring &str);
-#endif // MPT_ENABLE_CHARSET_LOCALE
-
-#if defined(MPT_ENABLE_CHARSET_LOCALE)
-#if MPT_WSTRING_CONVERT
-mpt::lstring ToLocale(const std::wstring &str);
-static inline mpt::lstring ToLocale(const wchar_t * str) { return ToLocale(str ? std::wstring(str): std::wstring()); }
-#endif
-mpt::lstring ToLocale(Charset from, const std::string &str);
-static inline mpt::lstring ToLocale(Charset from, const char * str) { return ToLocale(from, str ? std::string(str): std::string()); }
-static inline mpt::lstring ToLocale(const mpt::lstring &str) { return str; }
-#endif // MPT_ENABLE_CHARSET_LOCALE
-
-#if MPT_OS_WINDOWS
-#if MPT_WSTRING_CONVERT
-mpt::winstring ToWin(const std::wstring &str);
-static inline mpt::winstring ToWin(const wchar_t * str) { return ToWin(str ? std::wstring(str): std::wstring()); }
-#endif
-mpt::winstring ToWin(Charset from, const std::string &str);
-static inline mpt::winstring ToWin(Charset from, const char * str) { return ToWin(from, str ? std::string(str): std::string()); }
-#if defined(MPT_ENABLE_CHARSET_LOCALE)
-mpt::winstring ToWin(const mpt::lstring &str);
-#endif // MPT_ENABLE_CHARSET_LOCALE
-#endif // MPT_OS_WINDOWS
-
-
-#if defined(_MFC_VER)
-#if !(MPT_WSTRING_CONVERT)
-#error "MFC depends on MPT_WSTRING_CONVERT)"
-#endif
-
-// Convert to a MFC CString. The CString encoding depends on UNICODE.
-// This should also be used when converting to TCHAR strings.
-// If UNICODE is defined, this is a completely lossless operation.
-static inline CString ToCString(const CString &str) { return str; }
-CString ToCString(const std::wstring &str);
-static inline CString ToCString(const wchar_t * str) { return ToCString(str ? std::wstring(str) : std::wstring()); }
-CString ToCString(Charset from, const std::string &str);
-static inline CString ToCString(Charset from, const char * str) { return ToCString(from, str ? std::string(str) : std::string()); }
-#if defined(MPT_ENABLE_CHARSET_LOCALE)
-CString ToCString(const mpt::lstring &str);
-mpt::lstring ToLocale(const CString &str);
-#endif // MPT_ENABLE_CHARSET_LOCALE
-#if MPT_OS_WINDOWS
-mpt::winstring ToWin(const CString &str);
-#endif // MPT_OS_WINDOWS
-
-// Convert from a MFC CString. The CString encoding depends on UNICODE.
-// This should also be used when converting from TCHAR strings.
-// If UNICODE is defined, this is a completely lossless operation.
-std::wstring ToWide(const CString &str);
-std::string ToCharset(Charset to, const CString &str);
-
-#endif // MFC
-
-
-// mpt::ustring
-//
-// mpt::ustring is a string type that can hold unicode strings.
-// It is implemented as a std::basic_string either based on wchar_t (i.e. the
-//  same as std::wstring) or a custom-defined char_traits class that is derived
-//  from std::char_traits<char>.
-// The selection of the underlying implementation is done at compile-time.
-// MPT_UCHAR, MPT_ULITERAL and MPT_USTRING are macros that ease construction
-//  of ustring char literals, ustring char array literals and ustring objects
-//  from ustring char literals that work consistently in both modes.
-//  Note that these are not supported for non-ASCII characters appearing in
-//  the macro argument.
-// Also note that, as both UTF8 and UTF16 (it is less of an issue for UTF32)
-//  are variable-length encodings and mpt::ustring is implemented as a
-//  std::basic_string, all member functions that require individual character
-//  access will not work consistently or even at all in a meaningful way.
-//  This in particular affects operator[], at(), find() and substr().
-//  The code makes no effort in preventing these or generating warnings when
-//  these are used on mpt::ustring objects. However, compiling in the
-//  respectively other mpt::ustring mode will catch most of these anyway.
-
-#if MPT_USTRING_MODE_WIDE
-#if MPT_USTRING_MODE_UTF8
-#error "MPT_USTRING_MODE_WIDE and MPT_USTRING_MODE_UTF8 are mutually exclusive."
-#endif
-
-using ustring = std::wstring;
-using uchar = wchar_t;
-#define MPT_UCHAR(x)     L ## x
-#define MPT_ULITERAL(x)  L ## x
-#define MPT_USTRING(x)   std::wstring( L ## x )
-
-#endif // MPT_USTRING_MODE_WIDE
-
-#if MPT_USTRING_MODE_UTF8
-#if MPT_USTRING_MODE_WIDE
-#error "MPT_USTRING_MODE_WIDE and MPT_USTRING_MODE_UTF8 are mutually exclusive."
-#endif
-
-using ustring = mpt::u8string;
-using uchar = MPT_U8CHAR_TYPE;
-#define MPT_UCHAR(x)     MPT_U8CHAR( x )
-#define MPT_ULITERAL(x)  MPT_U8LITERAL( x )
-#define MPT_USTRING(x)   MPT_U8STRING( x )
-
-#endif // MPT_USTRING_MODE_UTF8
-
-#define UC_(x)           MPT_UCHAR(x)
-#define UL_(x)           MPT_ULITERAL(x)
-#define U_(x)            MPT_USTRING(x)
-
-#if MPT_USTRING_MODE_WIDE
-#if !(MPT_WSTRING_CONVERT)
-#error "MPT_USTRING_MODE_WIDE depends on MPT_WSTRING_CONVERT)"
-#endif
-static inline mpt::ustring ToUnicode(const std::wstring &str) { return str; }
-static inline mpt::ustring ToUnicode(const wchar_t * str) { return (str ? std::wstring(str) : std::wstring()); }
-static inline mpt::ustring ToUnicode(Charset from, const std::string &str) { return ToWide(from, str); }
-static inline mpt::ustring ToUnicode(Charset from, const char * str) { return ToUnicode(from, str ? std::string(str) : std::string()); }
-#if defined(MPT_ENABLE_CHARSET_LOCALE)
-static inline mpt::ustring ToUnicode(const mpt::lstring &str) { return ToWide(str); }
-#endif // MPT_ENABLE_CHARSET_LOCALE
-#if defined(_MFC_VER)
-static inline mpt::ustring ToUnicode(const CString &str) { return ToWide(str); }
-#endif // MFC
-#else // !MPT_USTRING_MODE_WIDE
-static inline mpt::ustring ToUnicode(const mpt::ustring &str) { return str; }
-#if MPT_WSTRING_CONVERT
-mpt::ustring ToUnicode(const std::wstring &str);
-static inline mpt::ustring ToUnicode(const wchar_t * str) { return ToUnicode(str ? std::wstring(str) : std::wstring()); }
-#endif
-mpt::ustring ToUnicode(Charset from, const std::string &str);
-static inline mpt::ustring ToUnicode(Charset from, const char * str) { return ToUnicode(from, str ? std::string(str) : std::string()); }
-#if defined(MPT_ENABLE_CHARSET_LOCALE)
-mpt::ustring ToUnicode(const mpt::lstring &str);
-#endif // MPT_ENABLE_CHARSET_LOCALE
-#if defined(_MFC_VER)
-mpt::ustring ToUnicode(const CString &str);
-#endif // MFC
-#endif // MPT_USTRING_MODE_WIDE
-
-#if MPT_USTRING_MODE_WIDE
-#if !(MPT_WSTRING_CONVERT)
-#error "MPT_USTRING_MODE_WIDE depends on MPT_WSTRING_CONVERT)"
-#endif
-// nothing, std::wstring overloads will catch all stuff
-#else // !MPT_USTRING_MODE_WIDE
-#if MPT_WSTRING_CONVERT
-std::wstring ToWide(const mpt::ustring &str);
-#endif
-std::string ToCharset(Charset to, const mpt::ustring &str);
-#if defined(MPT_ENABLE_CHARSET_LOCALE)
-mpt::lstring ToLocale(const mpt::ustring &str);
-#endif // MPT_ENABLE_CHARSET_LOCALE
-#if MPT_OS_WINDOWS
-mpt::winstring ToWin(const mpt::ustring &str);
-#endif // MPT_OS_WINDOWS
-#if defined(_MFC_VER)
-CString ToCString(const mpt::ustring &str);
-#endif // MFC
-#endif // MPT_USTRING_MODE_WIDE
-
-// The MPT_UTF8 allows specifying UTF8 char arrays.
-// The resulting type is mpt::ustring and the construction might require runtime translation,
-// i.e. it is NOT generally available at compile time.
-// Use explicit UTF8 encoding,
-// i.e. U+00FC (LATIN SMALL LETTER U WITH DIAERESIS) would be written as "\xC3\xBC".
-#define MPT_UTF8(x) mpt::ToUnicode(mpt::Charset::UTF8, x )
-
-
-
-
-
-mpt::ustring ToUnicode(uint16 codepage, mpt::Charset fallback, const std::string &str);
-
-
-
-
-
-char ToLowerCaseAscii(char c);
-char ToUpperCaseAscii(char c);
-std::string ToLowerCaseAscii(std::string s);
-std::string ToUpperCaseAscii(std::string s);
-
-int CompareNoCaseAscii(const char *a, const char *b, std::size_t n);
-int CompareNoCaseAscii(const std::string &a, const std::string &b);
-
-#if defined(MODPLUG_TRACKER)
-
-mpt::ustring ToLowerCase(const mpt::ustring &s);
-mpt::ustring ToUpperCase(const mpt::ustring &s);
-
-#endif // MODPLUG_TRACKER
-
-
-
-
-
-} // namespace mpt
-
-
-
-
-
-// The AnyString types are meant to be used as function argument types only,
-// and only during the transition phase to all-unicode strings in the whole codebase.
-// Using an AnyString type as function argument avoids the need to overload a function for all the
-// different string types that we currently have.
-// Warning: These types will silently do charset conversions. Only use them when this can be tolerated.
-
-// BasicAnyString is convertable to mpt::ustring and constructable from any string at all.
-template <mpt::Charset charset = mpt::Charset::UTF8, bool tryUTF8 = true>
-class BasicAnyString : public mpt::ustring
-{
-
-private:
-	
-	static mpt::ustring From8bit(const std::string &str)
-	{
-		if constexpr(charset == mpt::Charset::UTF8)
-		{
-			return mpt::ToUnicode(mpt::Charset::UTF8, str);
-		} else
-		{
-			// auto utf8 detection
-			if constexpr(tryUTF8)
-			{
-				if(mpt::IsUTF8(str))
-				{
-					return mpt::ToUnicode(mpt::Charset::UTF8, str);
-				} else
-				{
-					return mpt::ToUnicode(charset, str);
-				}
-			} else
-			{
-				return mpt::ToUnicode(charset, str);
-			}
-		}
-	}
-
-public:
-
-	// 8 bit
-	BasicAnyString(const char *str) : mpt::ustring(From8bit(str ? str : std::string())) { }
-	BasicAnyString(const std::string str) : mpt::ustring(From8bit(str)) { }
-
-	// locale
-#if defined(MPT_ENABLE_CHARSET_LOCALE)
-	BasicAnyString(const mpt::lstring str) : mpt::ustring(mpt::ToUnicode(str)) { }
-#endif // MPT_ENABLE_CHARSET_LOCALE
-
-	// unicode
-	BasicAnyString(const mpt::ustring &str) : mpt::ustring(str) { }
-	BasicAnyString(mpt::ustring &&str) : mpt::ustring(std::move(str)) { }
-#if MPT_USTRING_MODE_UTF8 && MPT_WSTRING_CONVERT
-	BasicAnyString(const std::wstring &str) : mpt::ustring(mpt::ToUnicode(str)) { }
-#endif
-#if MPT_WSTRING_CONVERT
-	BasicAnyString(const wchar_t *str) : mpt::ustring(str ? mpt::ToUnicode(str) : mpt::ustring()) { }
-#endif
-
-	// mfc
-#if defined(_MFC_VER)
-	BasicAnyString(const CString &str) : mpt::ustring(mpt::ToUnicode(str)) { }
-#endif
-
-	// fallback for custom string types
-	template <typename Tstring> BasicAnyString(const Tstring &str) : mpt::ustring(mpt::ToUnicode(str)) { }
-	template <typename Tstring> BasicAnyString(Tstring &&str) : mpt::ustring(mpt::ToUnicode(std::forward<Tstring>(str))) { }
-
-};
-
-// AnyUnicodeString is convertable to mpt::ustring and constructable from any unicode string,
-class AnyUnicodeString : public mpt::ustring
-{
-
-public:
-
-	// locale
-#if defined(MPT_ENABLE_CHARSET_LOCALE)
-	AnyUnicodeString(const mpt::lstring &str) : mpt::ustring(mpt::ToUnicode(str)) { }
-#endif // MPT_ENABLE_CHARSET_LOCALE
-
-	// unicode
-	AnyUnicodeString(const mpt::ustring &str) : mpt::ustring(str) { }
-	AnyUnicodeString(mpt::ustring &&str) : mpt::ustring(std::move(str)) { }
-#if MPT_USTRING_MODE_UTF8 && MPT_WSTRING_CONVERT
-	AnyUnicodeString(const std::wstring &str) : mpt::ustring(mpt::ToUnicode(str)) { }
-#endif
-#if MPT_WSTRING_CONVERT
-	AnyUnicodeString(const wchar_t *str) : mpt::ustring(str ? mpt::ToUnicode(str) : mpt::ustring()) { }
-#endif
-
-	// mfc
-#if defined(_MFC_VER)
-	AnyUnicodeString(const CString &str) : mpt::ustring(mpt::ToUnicode(str)) { }
-#endif
-
-	// fallback for custom string types
-	template <typename Tstring> AnyUnicodeString(const Tstring &str) : mpt::ustring(mpt::ToUnicode(str)) { }
-	template <typename Tstring> AnyUnicodeString(Tstring &&str) : mpt::ustring(mpt::ToUnicode(std::forward<Tstring>(str))) { }
-
-};
-
-// AnyString
-// Try to do the smartest auto-magic we can do.
-#if defined(MPT_ENABLE_CHARSET_LOCALE)
-using AnyString = BasicAnyString<mpt::Charset::Locale, true>;
-#elif MPT_OS_WINDOWS
-using AnyString = BasicAnyString<mpt::Charset::Windows1252, true>;
-#else
-using AnyString = BasicAnyString<mpt::Charset::ISO8859_1, true>;
-#endif
-
-// AnyStringLocale
-// char-based strings are assumed to be in locale encoding.
-#if defined(MPT_ENABLE_CHARSET_LOCALE)
-using AnyStringLocale = BasicAnyString<mpt::Charset::Locale, false>;
-#else
-using AnyStringLocale = BasicAnyString<mpt::Charset::UTF8, false>;
-#endif
-
-// AnyStringUTF8orLocale
-// char-based strings are tried in UTF8 first, if this fails, locale is used.
-#if defined(MPT_ENABLE_CHARSET_LOCALE)
-using AnyStringUTF8orLocale = BasicAnyString<mpt::Charset::Locale, true>;
-#else
-using AnyStringUTF8orLocale = BasicAnyString<mpt::Charset::UTF8, false>;
-#endif
-
-// AnyStringUTF8
-// char-based strings are assumed to be in UTF8.
-using AnyStringUTF8 = BasicAnyString<mpt::Charset::UTF8, false>;
-
-
-
-OPENMPT_NAMESPACE_END

+ 0 - 117
libopenmpt.mod/openmpt/common/mptStringBuffer.cpp

@@ -1,117 +0,0 @@
-/*
- * mptStringBuffer.cpp
- * -------------------
- * Purpose: Various functions for "fixing" char array strings for writing to or
- *          reading from module files, or for securing char arrays in general.
- * Notes  : (currently none)
- * Authors: OpenMPT Devs
- * The OpenMPT source code is released under the BSD license. Read LICENSE for more details.
- */
-
-
-#include "stdafx.h"
-
-#include "mptStringBuffer.h"
-
-
-OPENMPT_NAMESPACE_BEGIN
-
-
-
-namespace mpt
-{
-
-namespace String
-{
-
-namespace detail
-{
-
-std::string ReadStringBuffer(String::ReadWriteMode mode, const char *srcBuffer, std::size_t srcSize)
-{
-
-	std::string dest;
-	const char *src = srcBuffer;
-
-	if(mode == nullTerminated || mode == spacePaddedNull)
-	{
-		// We assume that the last character of the source buffer is null.
-		if(srcSize > 0)
-		{
-			srcSize -= 1;
-		}
-	}
-
-	if(mode == nullTerminated || mode == maybeNullTerminated)
-	{
-
-		// Copy null-terminated string, stopping at null.
-		dest.assign(src, std::find(src, src + srcSize, '\0'));
-
-	} else if(mode == spacePadded || mode == spacePaddedNull)
-	{
-
-		// Copy string over.
-		dest.assign(src, src + srcSize);
-
-		// Convert null characters to spaces.
-		std::transform(dest.begin(), dest.end(), dest.begin(), [] (char c) -> char { return (c != '\0') ? c : ' '; });
-
-		// Trim trailing spaces.
-		dest = mpt::String::RTrim(dest, std::string(" "));
-
-	}
-
-	return dest;
-
-}
-
-void WriteStringBuffer(String::ReadWriteMode mode, char *destBuffer, const std::size_t destSize, const char *srcBuffer, const std::size_t srcSize)
-{
-
-	MPT_ASSERT(destSize > 0);
-
-	const size_t maxSize = std::min(destSize, srcSize);
-	char *dst = destBuffer;
-	const char *src = srcBuffer;
-
-	// First, copy over null-terminated string.
-	size_t pos = maxSize;
-	while(pos > 0)
-	{
-		if((*dst = *src) == '\0')
-		{
-			break;
-		}
-		pos--;
-		dst++;
-		src++;
-	}
-
-	if(mode == nullTerminated || mode == maybeNullTerminated)
-	{
-		// Fill rest of string with nulls.
-		std::fill(dst, dst + destSize - maxSize + pos, '\0');
-	} else if(mode == spacePadded || mode == spacePaddedNull)
-	{
-		// Fill the rest of the destination string with spaces.
-		std::fill(dst, dst + destSize - maxSize + pos, ' ');
-	}
-
-	if(mode == nullTerminated || mode == spacePaddedNull)
-	{
-		// Make sure that destination is really null-terminated.
-		SetNullTerminator(destBuffer, destSize);
-	}
-
-}
-
-} // namespace detail
-
-} // namespace String
-
-} // namespace mpt
-
-
-
-OPENMPT_NAMESPACE_END

+ 0 - 565
libopenmpt.mod/openmpt/common/mptStringBuffer.h

@@ -1,565 +0,0 @@
-/*
- * mptStringBuffer.h
- * -----------------
- * Purpose: Various functions for "fixing" char array strings for writing to or
- *          reading from module files, or for securing char arrays in general.
- * Notes  : (currently none)
- * Authors: OpenMPT Devs
- * The OpenMPT source code is released under the BSD license. Read LICENSE for more details.
- */
-
-
-#pragma once
-
-#include "BuildSettings.h"
-
-#include "mptMemory.h"
-#include "mptString.h"
-
-#include <algorithm>
-#include <string>
-#include <vector>
-
-
-
-OPENMPT_NAMESPACE_BEGIN
-
-
-
-namespace mpt
-{
-
-
-namespace String
-{
-
-
-	enum ReadWriteMode : uint8
-	{
-		// Reading / Writing: Standard null-terminated string handling.
-		nullTerminated = 1,
-		// Reading: Source string is not guaranteed to be null-terminated (if it fills the whole char array).
-		// Writing: Destination string is not guaranteed to be null-terminated (if it fills the whole char array).
-		maybeNullTerminated = 2,
-		// Reading: String may contain null characters anywhere. They should be treated as spaces.
-		// Writing: A space-padded string is written.
-		spacePadded = 3,
-		// Reading: String may contain null characters anywhere. The last character is ignored (it is supposed to be 0).
-		// Writing: A space-padded string with a trailing null is written.
-		spacePaddedNull = 4,
-	};
-	
-	namespace detail
-	{
-
-	std::string ReadStringBuffer(String::ReadWriteMode mode, const char *srcBuffer, std::size_t srcSize);
-
-	void WriteStringBuffer(String::ReadWriteMode mode, char *destBuffer, const std::size_t destSize, const char *srcBuffer, const std::size_t srcSize);
-
-	} // namespace detail
-
-
-} // namespace String
-
-
-
-template <typename Tstring, typename Tchar>
-class StringBufRefImpl
-{
-private:
-	Tchar * buf;
-	std::size_t size;
-public:
-	// cppcheck false-positive
-	// cppcheck-suppress uninitMemberVar
-	explicit StringBufRefImpl(Tchar * buf, std::size_t size)
-		: buf(buf)
-		, size(size)
-	{
-		static_assert(sizeof(Tchar) == sizeof(typename Tstring::value_type));
-		MPT_ASSERT(size > 0);
-	}
-	StringBufRefImpl(const StringBufRefImpl &) = delete;
-	StringBufRefImpl(StringBufRefImpl &&) = default;
-	StringBufRefImpl & operator = (const StringBufRefImpl &) = delete;
-	StringBufRefImpl & operator = (StringBufRefImpl &&) = delete;
-	operator Tstring () const
-	{
-		std::size_t len = std::find(buf, buf + size, Tchar('\0')) - buf; // terminate at \0
-		return Tstring(buf, buf + len);
-	}
-	bool empty() const
-	{
-		return buf[0] == Tchar('\0');
-	}
-	StringBufRefImpl & operator = (const Tstring & str)
-	{
-		std::fill(buf, buf + size, Tchar('\0'));
-		std::copy(str.data(), str.data() + std::min(str.length(), size - 1), buf);
-		std::fill(buf + std::min(str.length(), size - 1), buf + size, Tchar('\0'));
-		return *this;
-	}
-};
-
-template <typename Tstring, typename Tchar>
-class StringBufRefImpl<Tstring, const Tchar>
-{
-private:
-	const Tchar * buf;
-	std::size_t size;
-public:
-	// cppcheck false-positive
-	// cppcheck-suppress uninitMemberVar
-	explicit StringBufRefImpl(const Tchar * buf, std::size_t size)
-		: buf(buf)
-		, size(size)
-	{
-		static_assert(sizeof(Tchar) == sizeof(typename Tstring::value_type));
-		MPT_ASSERT(size > 0);
-	}
-	StringBufRefImpl(const StringBufRefImpl &) = delete;
-	StringBufRefImpl(StringBufRefImpl &&) = default;
-	StringBufRefImpl & operator = (const StringBufRefImpl &) = delete;
-	StringBufRefImpl & operator = (StringBufRefImpl &&) = delete;
-	operator Tstring () const
-	{
-		std::size_t len = std::find(buf, buf + size, Tchar('\0')) - buf; // terminate at \0
-		return Tstring(buf, buf + len);
-	}
-	bool empty() const
-	{
-		return buf[0] == Tchar('\0');
-	}
-};
-
-namespace String {
-template <typename Tstring, typename Tchar, std::size_t size>
-inline StringBufRefImpl<Tstring, typename std::add_const<Tchar>::type> ReadTypedBuf(Tchar (&buf)[size])
-{
-	return StringBufRefImpl<Tstring, typename std::add_const<Tchar>::type>(buf, size);
-}
-template <typename Tstring, typename Tchar>
-inline StringBufRefImpl<Tstring, typename std::add_const<Tchar>::type> ReadTypedBuf(Tchar * buf, std::size_t size)
-{
-	return StringBufRefImpl<Tstring, typename std::add_const<Tchar>::type>(buf, size);
-}
-template <typename Tstring, typename Tchar, std::size_t size>
-inline StringBufRefImpl<Tstring, Tchar> WriteTypedBuf(Tchar (&buf)[size])
-{
-	return StringBufRefImpl<Tstring, Tchar>(buf, size);
-}
-template <typename Tstring, typename Tchar>
-inline StringBufRefImpl<Tstring, Tchar> WriteTypedBuf(Tchar * buf, std::size_t size)
-{
-	return StringBufRefImpl<Tstring, Tchar>(buf, size);
-}
-} // namespace String
-
-namespace String {
-template <typename Tchar, std::size_t size>
-inline StringBufRefImpl<typename std::basic_string<typename std::remove_const<Tchar>::type>, typename std::add_const<Tchar>::type> ReadAutoBuf(Tchar (&buf)[size])
-{
-	return StringBufRefImpl<typename std::basic_string<typename std::remove_const<Tchar>::type>, typename std::add_const<Tchar>::type>(buf, size);
-}
-template <typename Tchar>
-inline StringBufRefImpl<typename std::basic_string<typename std::remove_const<Tchar>::type>, typename std::add_const<Tchar>::type> ReadAutoBuf(Tchar * buf, std::size_t size)
-{
-	return StringBufRefImpl<typename std::basic_string<typename std::remove_const<Tchar>::type>, typename std::add_const<Tchar>::type>(buf, size);
-}
-template <typename Tchar, std::size_t size>
-inline StringBufRefImpl<typename std::basic_string<typename std::remove_const<Tchar>::type>, Tchar> WriteAutoBuf(Tchar (&buf)[size])
-{
-	return StringBufRefImpl<typename std::basic_string<typename std::remove_const<Tchar>::type>, Tchar>(buf, size);
-}
-template <typename Tchar>
-inline StringBufRefImpl<typename std::basic_string<typename std::remove_const<Tchar>::type>, Tchar> WriteAutoBuf(Tchar * buf, std::size_t size)
-{
-	return StringBufRefImpl<typename std::basic_string<typename std::remove_const<Tchar>::type>, Tchar>(buf, size);
-}
-} // namespace String
-
-template <std::size_t len, mpt::String::ReadWriteMode mode = static_cast<mpt::String::ReadWriteMode>(0)> struct charbuf;
-
-template <std::size_t len>
-struct charbuf<len, static_cast<mpt::String::ReadWriteMode>(0)>
-{
-public:
-	typedef char Tchar;
-	using char_type = Tchar;
-	using string_type = std::basic_string<Tchar>;
-	constexpr std::size_t static_length() const { return len; }
-public:
-	Tchar buf[len];
-public:
-	charbuf()
-	{
-		Clear(buf);
-	}
-	charbuf(const charbuf &) = default;
-	charbuf(charbuf &&) = default;
-	charbuf & operator = (const charbuf &) = default;
-	charbuf & operator = (charbuf &&) = default;
-	const Tchar & operator[](std::size_t i) const { return buf[i]; }
-	std::string str() const { return static_cast<std::string>(*this); }
-	operator string_type () const
-	{
-		return mpt::String::ReadAutoBuf(buf);
-	}
-	bool empty() const
-	{
-		return mpt::String::ReadAutoBuf(buf).empty();
-	}
-	charbuf & operator = (const string_type & str)
-	{
-		mpt::String::WriteAutoBuf(buf) = str;
-		return *this;
-	}
-public:
-	friend bool operator!=(const std::string & a, const charbuf & b) { return a != b.str(); }
-	friend bool operator!=(const charbuf & a, const std::string & b) { return a.str() != b; }
-	friend bool operator==(const std::string & a, const charbuf & b) { return a == b.str(); }
-	friend bool operator==(const charbuf & a, const std::string & b) { return a.str() == b; }
-};
-
-template <typename Tchar>
-class StringModeBufRefImpl
-{
-private:
-	Tchar * buf;
-	std::size_t size;
-	String::ReadWriteMode mode;
-public:
-	// cppcheck false-positive
-	// cppcheck-suppress uninitMemberVar
-	StringModeBufRefImpl(Tchar * buf, std::size_t size, String::ReadWriteMode mode)
-		: buf(buf)
-		, size(size)
-		, mode(mode)
-	{
-		static_assert(sizeof(Tchar) == 1);
-	}
-	StringModeBufRefImpl(const StringModeBufRefImpl &) = delete;
-	StringModeBufRefImpl(StringModeBufRefImpl &&) = default;
-	StringModeBufRefImpl & operator = (const StringModeBufRefImpl &) = delete;
-	StringModeBufRefImpl & operator = (StringModeBufRefImpl &&) = delete;
-	operator std::string () const
-	{
-		return String::detail::ReadStringBuffer(mode, buf, size);
-	}
-	bool empty() const
-	{
-		return String::detail::ReadStringBuffer(mode, buf, size).empty();
-	}
-	StringModeBufRefImpl & operator = (const std::string & str)
-	{
-		String::detail::WriteStringBuffer(mode, buf, size, str.data(), str.size());
-		return *this;
-	}
-};
-
-template <typename Tchar>
-class StringModeBufRefImpl<const Tchar>
-{
-private:
-	const Tchar * buf;
-	std::size_t size;
-	String::ReadWriteMode mode;
-public:
-	// cppcheck false-positive
-	// cppcheck-suppress uninitMemberVar
-	StringModeBufRefImpl(const Tchar * buf, std::size_t size, String::ReadWriteMode mode)
-		: buf(buf)
-		, size(size)
-		, mode(mode)
-	{
-		static_assert(sizeof(Tchar) == 1);
-	}
-	StringModeBufRefImpl(const StringModeBufRefImpl &) = delete;
-	StringModeBufRefImpl(StringModeBufRefImpl &&) = default;
-	StringModeBufRefImpl & operator = (const StringModeBufRefImpl &) = delete;
-	StringModeBufRefImpl & operator = (StringModeBufRefImpl &&) = delete;
-	operator std::string () const
-	{
-		return String::detail::ReadStringBuffer(mode, buf, size);
-	}
-	bool empty() const
-	{
-		return String::detail::ReadStringBuffer(mode, buf, size).empty();
-	}
-};
-
-namespace String {
-template <typename Tchar, std::size_t size>
-inline StringModeBufRefImpl<typename std::add_const<Tchar>::type> ReadBuf(String::ReadWriteMode mode, Tchar (&buf)[size])
-{
-	return StringModeBufRefImpl<typename std::add_const<Tchar>::type>(buf, size, mode);
-}
-template <typename Tchar>
-inline StringModeBufRefImpl<typename std::add_const<Tchar>::type> ReadBuf(String::ReadWriteMode mode, Tchar * buf, std::size_t size)
-{
-	return StringModeBufRefImpl<typename std::add_const<Tchar>::type>(buf, size, mode);
-}
-template <typename Tchar, std::size_t size>
-inline StringModeBufRefImpl<Tchar> WriteBuf(String::ReadWriteMode mode, Tchar (&buf)[size])
-{
-	return StringModeBufRefImpl<Tchar>(buf, size, mode);
-}
-template <typename Tchar>
-inline StringModeBufRefImpl<Tchar> WriteBuf(String::ReadWriteMode mode, Tchar * buf, std::size_t size)
-{
-	return StringModeBufRefImpl<Tchar>(buf, size, mode);
-}
-} // namespace String
-
-template <std::size_t len, mpt::String::ReadWriteMode mode>
-struct charbuf
-{
-public:
-	typedef char Tchar;
-	using char_type = Tchar;
-	using string_type = std::basic_string<Tchar>;
-public:
-	Tchar buf[len];
-public:
-	charbuf() = default;
-	charbuf(const charbuf &) = default;
-	charbuf(charbuf &&) = default;
-	charbuf & operator = (const charbuf &) = default;
-	charbuf & operator = (charbuf &&) = default;
-	operator string_type () const
-	{
-		return mpt::String::ReadBuf(mode, buf);
-	}
-	bool empty() const
-	{
-		return mpt::String::ReadBuf(mode, buf).empty();
-	}
-	charbuf & operator = (const string_type & str)
-	{
-		mpt::String::WriteBuf(mode, buf) = str;
-		return *this;
-	}
-};
-
-
-// see MPT_BINARY_STRUCT
-template <std::size_t len, mpt::String::ReadWriteMode mode>
-struct is_binary_safe<typename mpt::charbuf<len, mode>> : public std::true_type { };
-template <std::size_t len>
-struct is_binary_safe<typename mpt::charbuf<len, static_cast<mpt::String::ReadWriteMode>(0)>> : public std::false_type { };
-static_assert(sizeof(mpt::charbuf<7>) == 7);
-static_assert(alignof(mpt::charbuf<7>) == 1);
-static_assert(std::is_standard_layout<mpt::charbuf<7>>::value);
-
-
-#ifdef MODPLUG_TRACKER
-
-#if MPT_OS_WINDOWS
-
-namespace String {
-template <typename Tchar, std::size_t size>
-inline StringBufRefImpl<typename mpt::windows_char_traits<typename std::remove_const<Tchar>::type>::string_type, typename std::add_const<Tchar>::type> ReadWinBuf(Tchar (&buf)[size])
-{
-	return StringBufRefImpl<typename mpt::windows_char_traits<typename std::remove_const<Tchar>::type>::string_type, typename std::add_const<Tchar>::type>(buf, size);
-}
-template <typename Tchar>
-inline StringBufRefImpl<typename mpt::windows_char_traits<typename std::remove_const<Tchar>::type>::string_type, typename std::add_const<Tchar>::type> ReadWinBuf(Tchar * buf, std::size_t size)
-{
-	return StringBufRefImpl<typename mpt::windows_char_traits<typename std::remove_const<Tchar>::type>::string_type, typename std::add_const<Tchar>::type>(buf, size);
-}
-template <typename Tchar, std::size_t size>
-inline StringBufRefImpl<typename mpt::windows_char_traits<typename std::remove_const<Tchar>::type>::string_type, Tchar> WriteWinBuf(Tchar (&buf)[size])
-{
-	return StringBufRefImpl<typename mpt::windows_char_traits<typename std::remove_const<Tchar>::type>::string_type, Tchar>(buf, size);
-}
-template <typename Tchar>
-inline StringBufRefImpl<typename mpt::windows_char_traits<typename std::remove_const<Tchar>::type>::string_type, Tchar> WriteWinBuf(Tchar * buf, std::size_t size)
-{
-	return StringBufRefImpl<typename mpt::windows_char_traits<typename std::remove_const<Tchar>::type>::string_type, Tchar>(buf, size);
-}
-} // namespace String
-
-#if defined(_MFC_VER)
-
-template <typename Tchar>
-class CStringBufRefImpl
-{
-private:
-	Tchar * buf;
-	std::size_t size;
-public:
-	// cppcheck false-positive
-	// cppcheck-suppress uninitMemberVar
-	explicit CStringBufRefImpl(Tchar * buf, std::size_t size)
-		: buf(buf)
-		, size(size)
-	{
-		MPT_ASSERT(size > 0);
-	}
-	CStringBufRefImpl(const CStringBufRefImpl &) = delete;
-	CStringBufRefImpl(CStringBufRefImpl &&) = default;
-	CStringBufRefImpl & operator = (const CStringBufRefImpl &) = delete;
-	CStringBufRefImpl & operator = (CStringBufRefImpl &&) = delete;
-	operator CString () const
-	{
-		std::size_t len = std::find(buf, buf + size, Tchar('\0')) - buf; // terminate at \0
-		return CString(buf, mpt::saturate_cast<int>(len));
-	}
-	CStringBufRefImpl & operator = (const CString & str)
-	{
-		std::fill(buf, buf + size, Tchar('\0'));
-		std::copy(str.GetString(), str.GetString() + std::min(static_cast<std::size_t>(str.GetLength()), size - 1), buf);
-		buf[size - 1] = Tchar('\0');
-		return *this;
-	}
-};
-
-template <typename Tchar>
-class CStringBufRefImpl<const Tchar>
-{
-private:
-	const Tchar * buf;
-	std::size_t size;
-public:
-	// cppcheck false-positive
-	// cppcheck-suppress uninitMemberVar
-	explicit CStringBufRefImpl(const Tchar * buf, std::size_t size)
-		: buf(buf)
-		, size(size)
-	{
-		MPT_ASSERT(size > 0);
-	}
-	CStringBufRefImpl(const CStringBufRefImpl &) = delete;
-	CStringBufRefImpl(CStringBufRefImpl &&) = default;
-	CStringBufRefImpl & operator = (const CStringBufRefImpl &) = delete;
-	CStringBufRefImpl & operator = (CStringBufRefImpl &&) = delete;
-	operator CString () const
-	{
-		std::size_t len = std::find(buf, buf + size, Tchar('\0')) - buf; // terminate at \0
-		return CString(buf, mpt::saturate_cast<int>(len));
-	}
-};
-
-namespace String {
-template <typename Tchar, std::size_t size>
-inline CStringBufRefImpl<typename std::add_const<Tchar>::type> ReadCStringBuf(Tchar (&buf)[size])
-{
-	return CStringBufRefImpl<typename std::add_const<Tchar>::type>(buf, size);
-}
-template <typename Tchar>
-inline CStringBufRefImpl<typename std::add_const<Tchar>::type> ReadCStringBuf(Tchar * buf, std::size_t size)
-{
-	return CStringBufRefImpl<typename std::add_const<Tchar>::type>(buf, size);
-}
-template <typename Tchar, std::size_t size>
-inline CStringBufRefImpl<Tchar> WriteCStringBuf(Tchar (&buf)[size])
-{
-	return CStringBufRefImpl<Tchar>(buf, size);
-}
-template <typename Tchar>
-inline CStringBufRefImpl<Tchar> WriteCStringBuf(Tchar * buf, std::size_t size)
-{
-	return CStringBufRefImpl<Tchar>(buf, size);
-}
-} // namespace String
-
-#endif // _MFC_VER
-
-#endif // MPT_OS_WINDOWS
-
-#endif // MODPLUG_TRACKER
-
-
-
-
-
-namespace String
-{
-
-
-#if MPT_COMPILER_MSVC
-#pragma warning(push)
-#pragma warning(disable:4127) // conditional expression is constant
-#endif // MPT_COMPILER_MSVC
-
-
-	// Sets last character to null in given char array.
-	// Size of the array must be known at compile time.
-	template <size_t size>
-	void SetNullTerminator(char (&buffer)[size])
-	{
-		static_assert(size > 0);
-		buffer[size - 1] = 0;
-	}
-
-	inline void SetNullTerminator(char *buffer, size_t size)
-	{
-		MPT_ASSERT(size > 0);
-		buffer[size - 1] = 0;
-	}
-
-#if !defined(MPT_COMPILER_QUIRK_NO_WCHAR)
-
-	template <size_t size>
-	void SetNullTerminator(wchar_t (&buffer)[size])
-	{
-		static_assert(size > 0);
-		buffer[size - 1] = 0;
-	}
-
-	inline void SetNullTerminator(wchar_t *buffer, size_t size)
-	{
-		MPT_ASSERT(size > 0);
-		buffer[size - 1] = 0;
-	}
-
-#endif // !MPT_COMPILER_QUIRK_NO_WCHAR
-
-
-	// Remove any chars after the first null char
-	template <size_t size>
-	void FixNullString(char (&buffer)[size])
-	{
-		static_assert(size > 0);
-		SetNullTerminator(buffer);
-		size_t pos = 0;
-		// Find the first null char.
-		while(pos < size && buffer[pos] != '\0')
-		{
-			pos++;
-		}
-		// Remove everything after the null char.
-		while(pos < size)
-		{
-			buffer[pos++] = '\0';
-		}
-	}
-
-	inline void FixNullString(std::string & str)
-	{
-		for(std::size_t i = 0; i < str.length(); ++i)
-		{
-			if(str[i] == '\0')
-			{
-				// if we copied \0 in the middle of the buffer, terminate std::string here
-				str.resize(i);
-				break;
-			}
-		}
-	}
-
-
-
-#if MPT_COMPILER_MSVC
-#pragma warning(pop)
-#endif // MPT_COMPILER_MSVC
-
-
-} // namespace String
-
-
-} // namespace mpt
-
-
-
-OPENMPT_NAMESPACE_END

+ 0 - 522
libopenmpt.mod/openmpt/common/mptStringFormat.cpp

@@ -1,522 +0,0 @@
-/*
- * mptStringFormat.cpp
- * -------------------
- * Purpose: Convert other types to strings.
- * Notes  : Currently none.
- * Authors: OpenMPT Devs
- * The OpenMPT source code is released under the BSD license. Read LICENSE for more details.
- */
-
-#include "stdafx.h"
-#include "mptStringFormat.h"
-
-#if MPT_COMPILER_MSVC
-#define MPT_FORMAT_CXX17_INT 1
-#else
-#define MPT_FORMAT_CXX17_INT 0
-#endif
-
-#if MPT_FORMAT_CXX17_INT
-#if MPT_MSVC_AT_LEAST(2019,0) && MPT_MSVC_BEFORE(2019,2)
-#if !(defined(UNICODE) || defined(_UNICODE))
-// work-around https://developercommunity.visualstudio.com/content/problem/629849/mfc-headers-conflict-with-c17-charconv-header-in-m.html
-#pragma push_macro("_M2")
-#undef _M2
-#endif
-#endif
-#include <charconv>
-#if MPT_MSVC_AT_LEAST(2019,0) && MPT_MSVC_BEFORE(2019,2)
-#if !(defined(UNICODE) || defined(_UNICODE))
-// work-around https://developercommunity.visualstudio.com/content/problem/629849/mfc-headers-conflict-with-c17-charconv-header-in-m.html
-#pragma pop_macro("_M2")
-#endif
-#endif
-#endif // MPT_FORMAT_CXX17_INT
-#include <iomanip>
-#include <locale>
-#include <sstream>
-#include <string>
-#if MPT_FORMAT_CXX17_INT
-#include <system_error>
-#endif // MPT_FORMAT_CXX17_INT
-
-
-OPENMPT_NAMESPACE_BEGIN
-
-
-
-namespace mpt
-{
-
-
-
-template<typename Tstream, typename T> inline void SaneInsert(Tstream & s, const T & x) { s << x; }
-// do the right thing for signed/unsigned char and bool
-template<typename Tstream> inline void SaneInsert(Tstream & s, const bool & x) { s << static_cast<int>(x); }
-template<typename Tstream> inline void SaneInsert(Tstream & s, const signed char & x) { s << static_cast<signed int>(x); }
-template<typename Tstream> inline void SaneInsert(Tstream & s, const unsigned char & x) { s << static_cast<unsigned int>(x); }
- 
-#if MPT_FORMAT_CXX17_INT
-
-#if MPT_WSTRING_FORMAT
-std::wstring ToWideSimple(const std::string &nstr)
-{
-	std::wstring wstr(nstr.size(), L'\0');
-	for(std::size_t i = 0; i < nstr.size(); ++i)
-	{
-		wstr[i] = static_cast<unsigned char>(nstr[i]);
-	}
-	return wstr;
-}
-#endif // MPT_WSTRING_FORMAT
-
-template<typename T>
-static inline std::string ToChars(const T & x, int base = 10)
-{
-	std::string str(1, '\0');
-	bool done = false;
-	while(!done)
-	{
-		std::to_chars_result result = std::to_chars(str.data(), str.data() + str.size(), x, base);
-		if(result.ec != std::errc{})
-		{
-			str.resize(Util::ExponentialGrow(str.size()), '\0');
-		} else
-		{
-			str.resize(result.ptr - str.data());
-			done = true;
-		}
-	}
-	return str;
-}
-
-template<typename T>
-static inline std::string ToStringHelperInt(const T & x)
-{
-	return ToChars(x);
-}
-
-#if MPT_WSTRING_FORMAT
-template<typename T>
-static inline std::wstring ToWStringHelperInt(const T & x)
-{
-	return ToWideSimple(ToChars(x));
-}
-#endif
-
-#else // !MPT_FORMAT_CXX17_INT
-
-template<typename T>
-static inline std::string ToStringHelperInt(const T & x)
-{
-	std::ostringstream o;
-	o.imbue(std::locale::classic());
-	SaneInsert(o, x);
-	return o.str();
-}
-
-#if MPT_WSTRING_FORMAT
-template<typename T>
-static inline std::wstring ToWStringHelperInt(const T & x)
-{
-	std::wostringstream o;
-	o.imbue(std::locale::classic());
-	SaneInsert(o, x);
-	return o.str();
-}
-#endif
-
-#endif // MPT_FORMAT_CXX17_INT
-
-template<typename T>
-static inline std::string ToStringHelperFloat(const T & x)
-{
-	std::ostringstream o;
-	o.imbue(std::locale::classic());
-	SaneInsert(o, x);
-	return o.str();
-}
-
-#if MPT_WSTRING_FORMAT
-template<typename T>
-static inline std::wstring ToWStringHelperFloat(const T & x)
-{
-	std::wostringstream o;
-	o.imbue(std::locale::classic());
-	SaneInsert(o, x);
-	return o.str();
-}
-#endif
-
-std::string ToString(const bool & x) { return ToStringHelperInt(static_cast<int>(x)); }
-std::string ToString(const signed char & x) { return ToStringHelperInt(x); }
-std::string ToString(const unsigned char & x) { return ToStringHelperInt(x); }
-std::string ToString(const signed short & x) { return ToStringHelperInt(x); }
-std::string ToString(const unsigned short & x) { return ToStringHelperInt(x); }
-std::string ToString(const signed int & x) { return ToStringHelperInt(x); }
-std::string ToString(const unsigned int & x) { return ToStringHelperInt(x); }
-std::string ToString(const signed long & x) { return ToStringHelperInt(x); }
-std::string ToString(const unsigned long & x) { return ToStringHelperInt(x); }
-std::string ToString(const signed long long & x) { return ToStringHelperInt(x); }
-std::string ToString(const unsigned long long & x) { return ToStringHelperInt(x); }
-std::string ToString(const float & x) { return ToStringHelperFloat(x); }
-std::string ToString(const double & x) { return ToStringHelperFloat(x); }
-std::string ToString(const long double & x) { return ToStringHelperFloat(x); }
-
-#if MPT_WSTRING_FORMAT
-#if MPT_USTRING_MODE_UTF8
-mpt::ustring ToUString(const std::wstring & x) { return mpt::ToUnicode(x); }
-#endif
-mpt::ustring ToUString(const wchar_t * const & x) { return mpt::ToUnicode(x); }
-#endif
-#if defined(_MFC_VER)
-mpt::ustring ToUString(const CString & x)  { return mpt::ToUnicode(x); }
-#endif
-#if MPT_USTRING_MODE_WIDE
-mpt::ustring ToUString(const bool & x) { return ToWStringHelperInt(static_cast<int>(x)); }
-mpt::ustring ToUString(const signed char & x) { return ToWStringHelperInt(x); }
-mpt::ustring ToUString(const unsigned char & x) { return ToWStringHelperInt(x); }
-mpt::ustring ToUString(const signed short & x) { return ToWStringHelperInt(x); }
-mpt::ustring ToUString(const unsigned short & x) { return ToWStringHelperInt(x); }
-mpt::ustring ToUString(const signed int & x) { return ToWStringHelperInt(x); }
-mpt::ustring ToUString(const unsigned int & x) { return ToWStringHelperInt(x); }
-mpt::ustring ToUString(const signed long & x) { return ToWStringHelperInt(x); }
-mpt::ustring ToUString(const unsigned long & x) { return ToWStringHelperInt(x); }
-mpt::ustring ToUString(const signed long long & x) { return ToWStringHelperInt(x); }
-mpt::ustring ToUString(const unsigned long long & x) { return ToWStringHelperInt(x); }
-mpt::ustring ToUString(const float & x) { return ToWStringHelperFloat(x); }
-mpt::ustring ToUString(const double & x) { return ToWStringHelperFloat(x); }
-mpt::ustring ToUString(const long double & x) { return ToWStringHelperFloat(x); }
-#endif
-#if MPT_USTRING_MODE_UTF8
-mpt::ustring ToUString(const bool & x) { return mpt::ToUnicode(mpt::Charset::UTF8, ToStringHelperInt(static_cast<int>(x))); }
-mpt::ustring ToUString(const signed char & x) { return mpt::ToUnicode(mpt::Charset::UTF8, ToStringHelperInt(x)); }
-mpt::ustring ToUString(const unsigned char & x) { return mpt::ToUnicode(mpt::Charset::UTF8, ToStringHelperInt(x)); }
-mpt::ustring ToUString(const signed short & x) { return mpt::ToUnicode(mpt::Charset::UTF8, ToStringHelperInt(x)); }
-mpt::ustring ToUString(const unsigned short & x) { return mpt::ToUnicode(mpt::Charset::UTF8, ToStringHelperInt(x)); }
-mpt::ustring ToUString(const signed int & x) { return mpt::ToUnicode(mpt::Charset::UTF8, ToStringHelperInt(x)); }
-mpt::ustring ToUString(const unsigned int & x) { return mpt::ToUnicode(mpt::Charset::UTF8, ToStringHelperInt(x)); }
-mpt::ustring ToUString(const signed long & x) { return mpt::ToUnicode(mpt::Charset::UTF8, ToStringHelperInt(x)); }
-mpt::ustring ToUString(const unsigned long & x) { return mpt::ToUnicode(mpt::Charset::UTF8, ToStringHelperInt(x)); }
-mpt::ustring ToUString(const signed long long & x) { return mpt::ToUnicode(mpt::Charset::UTF8, ToStringHelperInt(x)); }
-mpt::ustring ToUString(const unsigned long long & x) { return mpt::ToUnicode(mpt::Charset::UTF8, ToStringHelperInt(x)); }
-mpt::ustring ToUString(const float & x) { return mpt::ToUnicode(mpt::Charset::UTF8, ToStringHelperFloat(x)); }
-mpt::ustring ToUString(const double & x) { return mpt::ToUnicode(mpt::Charset::UTF8, ToStringHelperFloat(x)); }
-mpt::ustring ToUString(const long double & x) { return mpt::ToUnicode(mpt::Charset::UTF8, ToStringHelperFloat(x)); }
-#endif
-
-#if MPT_WSTRING_FORMAT
-#if MPT_USTRING_MODE_UTF8
-std::wstring ToWString(const mpt::ustring & x) { return mpt::ToWide(x); }
-#endif
-#if defined(_MFC_VER)
-std::wstring ToWString(const CString & x) { return mpt::ToWide(x); }
-#endif
-std::wstring ToWString(const bool & x) { return ToWStringHelperInt(static_cast<int>(x)); }
-std::wstring ToWString(const signed char & x) { return ToWStringHelperInt(x); }
-std::wstring ToWString(const unsigned char & x) { return ToWStringHelperInt(x); }
-std::wstring ToWString(const signed short & x) { return ToWStringHelperInt(x); }
-std::wstring ToWString(const unsigned short & x) { return ToWStringHelperInt(x); }
-std::wstring ToWString(const signed int & x) { return ToWStringHelperInt(x); }
-std::wstring ToWString(const unsigned int & x) { return ToWStringHelperInt(x); }
-std::wstring ToWString(const signed long & x) { return ToWStringHelperInt(x); }
-std::wstring ToWString(const unsigned long & x) { return ToWStringHelperInt(x); }
-std::wstring ToWString(const signed long long & x) { return ToWStringHelperInt(x); }
-std::wstring ToWString(const unsigned long long & x) { return ToWStringHelperInt(x); }
-std::wstring ToWString(const float & x) { return ToWStringHelperFloat(x); }
-std::wstring ToWString(const double & x) { return ToWStringHelperFloat(x); }
-std::wstring ToWString(const long double & x) { return ToWStringHelperFloat(x); }
-#endif
-
-
-template <typename Tchar>
-struct NumPunct : std::numpunct<Tchar>
-{
-private:
-	unsigned int group;
-	char sep;
-public:
-	NumPunct(unsigned int g, char s)
-		: group(g)
-		, sep(s)
-	{}
-	std::string do_grouping() const override
-	{
-		return std::string(1, static_cast<char>(group));
-	}
-	Tchar do_thousands_sep() const override
-	{
-		return static_cast<Tchar>(sep);
-	}
-};
-
-template<typename Tostream, typename T>
-static inline void ApplyFormat(Tostream & o, const FormatSpec & format, const T &)
-{
-	MPT_MAYBE_CONSTANT_IF(!std::numeric_limits<T>::is_integer)
-	{
-		if(format.GetGroup() > 0)
-		{
-			o.imbue(std::locale(o.getloc(), new NumPunct<typename Tostream::char_type>(format.GetGroup(), format.GetGroupSep())));
-		}
-	}
-	FormatFlags f = format.GetFlags();
-	std::size_t width = format.GetWidth();
-	int precision = format.GetPrecision();
-	if(precision != -1 && width != 0 && !(f & fmt_base::NotaFix) && !(f & fmt_base::NotaSci))
-	{
-		// fixup:
-		// precision behaves differently from .#
-		// avoid default format when precision and width are set
-		f &= ~fmt_base::NotaNrm;
-		f |= fmt_base::NotaFix;
-	}
-	if(f & fmt_base::BaseDec) { o << std::dec; }
-	else if(f & fmt_base::BaseHex) { o << std::hex; }
-	if(f & fmt_base::NotaNrm ) { /*nothing*/ }
-	else if(f & fmt_base::NotaFix ) { o << std::setiosflags(std::ios::fixed); }
-	else if(f & fmt_base::NotaSci ) { o << std::setiosflags(std::ios::scientific); }
-	if(f & fmt_base::CaseLow) { o << std::nouppercase; }
-	else if(f & fmt_base::CaseUpp) { o << std::uppercase; }
-	MPT_MAYBE_CONSTANT_IF(!std::numeric_limits<T>::is_integer)
-	{
-		if(f & fmt_base::FillOff) { /* nothing */ }
-		else if(f & fmt_base::FillNul) { o << std::setw(width) << std::setfill(typename Tostream::char_type('0')); }
-	}
-	if(precision != -1) { o << std::setprecision(precision); }
-}
-
-template<typename Tstring>
-static inline Tstring PostProcessCase(Tstring str, const FormatSpec & format)
-{
-	FormatFlags f = format.GetFlags();
-	if(f & fmt_base::CaseUpp)
-	{
-		for(auto & c : str)
-		{
-			if('a' <= c && c <= 'z')
-			{
-				c -= 'a' - 'A';
-			}
-		}
-	}
-	return str;
-}
-
-template<typename Tstring>
-static inline Tstring PostProcessDigits(Tstring str, const FormatSpec & format)
-{
-	FormatFlags f = format.GetFlags();
-	std::size_t width = format.GetWidth();
-	if(f & fmt_base::FillNul)
-	{
-		auto pos = str.begin();
-		if(str.length() > 0)
-		{
-			if(str[0] == typename Tstring::value_type('+'))
-			{
-				pos++;
-				width++;
-			} else if(str[0] == typename Tstring::value_type('-'))
-			{
-				pos++;
-				width++;
-			}
-		}
-		if(str.length() < width)
-		{
-			str.insert(pos, width - str.length(), '0');
-		}
-	}
-	return str;
-}
-
-template<typename Tstring>
-static inline Tstring PostProcessGroup(Tstring str, const FormatSpec & format)
-{
-	if(format.GetGroup() > 0)
-	{
-		const unsigned int groupSize = format.GetGroup();
-		const char groupSep = format.GetGroupSep();
-		std::size_t len = str.length();
-		for(std::size_t n = 0; n < len; ++n)
-		{
-			if(n > 0 && (n % groupSize) == 0)
-			{
-				if(!(n == (len - 1) && (str[0] == typename Tstring::value_type('+') || str[0] == typename Tstring::value_type('-'))))
-				{
-					str.insert(str.begin() + (len - n), 1, groupSep);
-				}
-			}
-		}
-	}
-	return str;
-}
-
-#if MPT_FORMAT_CXX17_INT
-
-template<typename T>
-static inline std::string FormatValHelperInt(const T & x, const FormatSpec & f)
-{
-	int base = 10;
-	if(f.GetFlags() & fmt_base::BaseDec) { base = 10; }
-	if(f.GetFlags() & fmt_base::BaseHex) { base = 16; }
-	return PostProcessGroup(PostProcessDigits(PostProcessCase(ToChars(x, base), f), f), f);
-}
-
-#if MPT_WSTRING_FORMAT
-template<typename T>
-static inline std::wstring FormatValWHelperInt(const T & x, const FormatSpec & f)
-{
-	int base = 10;
-	if(f.GetFlags() & fmt_base::BaseDec) { base = 10; }
-	if(f.GetFlags() & fmt_base::BaseHex) { base = 16; }
-	return ToWideSimple(PostProcessGroup(PostProcessDigits(PostProcessCase(ToChars(x, base), f), f), f));
-}
-#endif
-
-#else // !MPT_FORMAT_CXX17_INT
-
-template<typename T>
-static inline std::string FormatValHelperInt(const T & x, const FormatSpec & f)
-{
-	MPT_MAYBE_CONSTANT_IF((f.GetFlags() & fmt_base::BaseHex) && std::is_signed<T>::value)
-	{
-		if(x == std::numeric_limits<T>::min())
-		{
-			return std::string(1, '-') + FormatValHelperInt(static_cast<typename std::make_unsigned<T>::type>(x), f);
-		} else MPT_MAYBE_CONSTANT_IF(x < 0)
-		{
-			return std::string(1, '-') + FormatValHelperInt(static_cast<typename std::make_unsigned<T>::type>(0-x), f);
-		} else
-		{
-			return FormatValHelperInt(static_cast<typename std::make_unsigned<T>::type>(x), f);
-		}
-	}
-	std::ostringstream o;
-	o.imbue(std::locale::classic());
-	ApplyFormat(o, f, x);
-	SaneInsert(o, x);
-	return PostProcessGroup(PostProcessDigits(o.str(), f), f);
-}
-
-#if MPT_WSTRING_FORMAT
-template<typename T>
-static inline std::wstring FormatValWHelperInt(const T & x, const FormatSpec & f)
-{
-	MPT_MAYBE_CONSTANT_IF((f.GetFlags() & fmt_base::BaseHex) && std::is_signed<T>::value)
-	{
-		if(x == std::numeric_limits<T>::min())
-		{
-			return std::wstring(1, L'-') + FormatValWHelperInt(static_cast<typename std::make_unsigned<T>::type>(x), f);
-		} else MPT_MAYBE_CONSTANT_IF(x < 0)
-		{
-			return std::wstring(1, L'-') + FormatValWHelperInt(static_cast<typename std::make_unsigned<T>::type>(0-x), f);
-		} else
-		{
-			return FormatValWHelperInt(static_cast<typename std::make_unsigned<T>::type>(x), f);
-		}
-	}
-	std::wostringstream o;
-	o.imbue(std::locale::classic());
-	ApplyFormat(o, f, x);
-	SaneInsert(o, x);
-	return PostProcessGroup(PostProcessDigits(o.str(), f), f);
-}
-#endif
-
-#endif // MPT_FORMAT_CXX17_INT
-
-template<typename T>
-static inline std::string FormatValHelperFloat(const T & x, const FormatSpec & f)
-{
-	std::ostringstream o;
-	o.imbue(std::locale::classic());
-	ApplyFormat(o, f, x);
-	SaneInsert(o, x);
-	return o.str();
-}
-
-#if MPT_WSTRING_FORMAT
-template<typename T>
-static inline std::wstring FormatValWHelperFloat(const T & x, const FormatSpec & f)
-{
-	std::wostringstream o;
-	o.imbue(std::locale::classic());
-	ApplyFormat(o, f, x);
-	SaneInsert(o, x);
-	return o.str();
-}
-#endif
-
-
-std::string FormatVal(const bool & x, const FormatSpec & f) { return FormatValHelperInt(static_cast<int>(x), f); }
-std::string FormatVal(const signed char & x, const FormatSpec & f) { return FormatValHelperInt(x, f); }
-std::string FormatVal(const unsigned char & x, const FormatSpec & f) { return FormatValHelperInt(x, f); }
-std::string FormatVal(const signed short & x, const FormatSpec & f) { return FormatValHelperInt(x, f); }
-std::string FormatVal(const unsigned short & x, const FormatSpec & f) { return FormatValHelperInt(x, f); }
-std::string FormatVal(const signed int & x, const FormatSpec & f) { return FormatValHelperInt(x, f); }
-std::string FormatVal(const unsigned int & x, const FormatSpec & f) { return FormatValHelperInt(x, f); }
-std::string FormatVal(const signed long & x, const FormatSpec & f) { return FormatValHelperInt(x, f); }
-std::string FormatVal(const unsigned long & x, const FormatSpec & f) { return FormatValHelperInt(x, f); }
-std::string FormatVal(const signed long long & x, const FormatSpec & f) { return FormatValHelperInt(x, f); }
-std::string FormatVal(const unsigned long long & x, const FormatSpec & f) { return FormatValHelperInt(x, f); }
-std::string FormatVal(const float & x, const FormatSpec & f) { return FormatValHelperFloat(x, f); }
-std::string FormatVal(const double & x, const FormatSpec & f) { return FormatValHelperFloat(x, f); }
-std::string FormatVal(const long double & x, const FormatSpec & f) { return FormatValHelperFloat(x, f); }
-
-#if MPT_USTRING_MODE_WIDE
-mpt::ustring FormatValU(const bool & x, const FormatSpec & f) { return FormatValWHelperInt(static_cast<int>(x), f); }
-mpt::ustring FormatValU(const signed char & x, const FormatSpec & f) { return FormatValWHelperInt(x, f); }
-mpt::ustring FormatValU(const unsigned char & x, const FormatSpec & f) { return FormatValWHelperInt(x, f); }
-mpt::ustring FormatValU(const signed short & x, const FormatSpec & f) { return FormatValWHelperInt(x, f); }
-mpt::ustring FormatValU(const unsigned short & x, const FormatSpec & f) { return FormatValWHelperInt(x, f); }
-mpt::ustring FormatValU(const signed int & x, const FormatSpec & f) { return FormatValWHelperInt(x, f); }
-mpt::ustring FormatValU(const unsigned int & x, const FormatSpec & f) { return FormatValWHelperInt(x, f); }
-mpt::ustring FormatValU(const signed long & x, const FormatSpec & f) { return FormatValWHelperInt(x, f); }
-mpt::ustring FormatValU(const unsigned long & x, const FormatSpec & f) { return FormatValWHelperInt(x, f); }
-mpt::ustring FormatValU(const signed long long & x, const FormatSpec & f) { return FormatValWHelperInt(x, f); }
-mpt::ustring FormatValU(const unsigned long long & x, const FormatSpec & f) { return FormatValWHelperInt(x, f); }
-mpt::ustring FormatValU(const float & x, const FormatSpec & f) { return FormatValWHelperFloat(x, f); }
-mpt::ustring FormatValU(const double & x, const FormatSpec & f) { return FormatValWHelperFloat(x, f); }
-mpt::ustring FormatValU(const long double & x, const FormatSpec & f) { return FormatValWHelperFloat(x, f); }
-#endif
-#if MPT_USTRING_MODE_UTF8
-mpt::ustring FormatValU(const bool & x, const FormatSpec & f) { return mpt::ToUnicode(mpt::Charset::UTF8, FormatValHelperInt(static_cast<int>(x), f)); }
-mpt::ustring FormatValU(const signed char & x, const FormatSpec & f) { return mpt::ToUnicode(mpt::Charset::UTF8, FormatValHelperInt(x, f)); }
-mpt::ustring FormatValU(const unsigned char & x, const FormatSpec & f) { return mpt::ToUnicode(mpt::Charset::UTF8, FormatValHelperInt(x, f)); }
-mpt::ustring FormatValU(const signed short & x, const FormatSpec & f) { return mpt::ToUnicode(mpt::Charset::UTF8, FormatValHelperInt(x, f)); }
-mpt::ustring FormatValU(const unsigned short & x, const FormatSpec & f) { return mpt::ToUnicode(mpt::Charset::UTF8, FormatValHelperInt(x, f)); }
-mpt::ustring FormatValU(const signed int & x, const FormatSpec & f) { return mpt::ToUnicode(mpt::Charset::UTF8, FormatValHelperInt(x, f)); }
-mpt::ustring FormatValU(const unsigned int & x, const FormatSpec & f) { return mpt::ToUnicode(mpt::Charset::UTF8, FormatValHelperInt(x, f)); }
-mpt::ustring FormatValU(const signed long & x, const FormatSpec & f) { return mpt::ToUnicode(mpt::Charset::UTF8, FormatValHelperInt(x, f)); }
-mpt::ustring FormatValU(const unsigned long & x, const FormatSpec & f) { return mpt::ToUnicode(mpt::Charset::UTF8, FormatValHelperInt(x, f)); }
-mpt::ustring FormatValU(const signed long long & x, const FormatSpec & f) { return mpt::ToUnicode(mpt::Charset::UTF8, FormatValHelperInt(x, f)); }
-mpt::ustring FormatValU(const unsigned long long & x, const FormatSpec & f) { return mpt::ToUnicode(mpt::Charset::UTF8, FormatValHelperInt(x, f)); }
-mpt::ustring FormatValU(const float & x, const FormatSpec & f) { return mpt::ToUnicode(mpt::Charset::UTF8, FormatValHelperFloat(x, f)); }
-mpt::ustring FormatValU(const double & x, const FormatSpec & f) { return mpt::ToUnicode(mpt::Charset::UTF8, FormatValHelperFloat(x, f)); }
-mpt::ustring FormatValU(const long double & x, const FormatSpec & f) { return mpt::ToUnicode(mpt::Charset::UTF8, FormatValHelperFloat(x, f)); }
-#endif
-
-#if MPT_WSTRING_FORMAT
-std::wstring FormatValW(const bool & x, const FormatSpec & f) { return FormatValWHelperInt(static_cast<int>(x), f); }
-std::wstring FormatValW(const signed char & x, const FormatSpec & f) { return FormatValWHelperInt(x, f); }
-std::wstring FormatValW(const unsigned char & x, const FormatSpec & f) { return FormatValWHelperInt(x, f); }
-std::wstring FormatValW(const signed short & x, const FormatSpec & f) { return FormatValWHelperInt(x, f); }
-std::wstring FormatValW(const unsigned short & x, const FormatSpec & f) { return FormatValWHelperInt(x, f); }
-std::wstring FormatValW(const signed int & x, const FormatSpec & f) { return FormatValWHelperInt(x, f); }
-std::wstring FormatValW(const unsigned int & x, const FormatSpec & f) { return FormatValWHelperInt(x, f); }
-std::wstring FormatValW(const signed long & x, const FormatSpec & f) { return FormatValWHelperInt(x, f); }
-std::wstring FormatValW(const unsigned long & x, const FormatSpec & f) { return FormatValWHelperInt(x, f); }
-std::wstring FormatValW(const signed long long & x, const FormatSpec & f) { return FormatValWHelperInt(x, f); }
-std::wstring FormatValW(const unsigned long long & x, const FormatSpec & f) { return FormatValWHelperInt(x, f); }
-std::wstring FormatValW(const float & x, const FormatSpec & f) { return FormatValWHelperFloat(x, f); }
-std::wstring FormatValW(const double & x, const FormatSpec & f) { return FormatValWHelperFloat(x, f); }
-std::wstring FormatValW(const long double & x, const FormatSpec & f) { return FormatValWHelperFloat(x, f); }
-#endif
-
-
-} // namespace mpt
-
-
-OPENMPT_NAMESPACE_END

+ 0 - 737
libopenmpt.mod/openmpt/common/mptStringFormat.h

@@ -1,737 +0,0 @@
-/*
- * mptStringFormat.h
- * -----------------
- * Purpose: Convert other types to strings.
- * Notes  : Currently none.
- * Authors: OpenMPT Devs
- * The OpenMPT source code is released under the BSD license. Read LICENSE for more details.
- */
-
-
-#pragma once
-
-#include "BuildSettings.h"
-
-
-#include "mptString.h"
-
-
-OPENMPT_NAMESPACE_BEGIN
-
-
-
-// The following section demands a rationale.
-//  1. mpt::fmt::val(), mpt::wfmt::val() and mpt::ufmt::val() mimic the semantics of c++11 std::to_string() and std::to_wstring().
-//     There is an important difference though. The c++11 versions are specified in terms of sprintf formatting which in turn
-//     depends on the current C locale. This renders these functions unusable in a library context because the current
-//     C locale is set by the library-using application and could be anything. There is no way a library can get reliable semantics
-//     out of these functions. It is thus better to just avoid them.
-//     ToString() and ToWString() are based on iostream internally, but the the locale of the stream is forced to std::locale::classic(),
-//     which results in "C" ASCII locale behavior.
-//  2. The full suite of printf-like or iostream like number formatting is generally not required. Instead, a sane subset functionality
-//     is provided here.
-//     For convenience, mpt::fmt::f(const char *, float) allows formatting a single floating point value with a
-//     standard printf-like format string. This itself relies on iostream with classic() locale internally and is thus current locale
-//     agnostic.
-//     When formatting integers, it is recommended to use mpt::fmt::dec or mpt::fmt::hex. Appending a template argument '<n>' sets the width,
-//     the same way as '%nd' would do. Appending a '0' to the function name causes zero-filling as print-like '%0nd' would do. Spelling 'HEX'
-//     in upper-case generates upper-case hex digits. If these are not known at compile-time, a more verbose FormatVal(int, format) can be
-//     used.
-//  3. mpt::format(format)(...) provides simplified and type-safe message and localization string formatting.
-//     The only specifier allowed is '%' followed by a single digit n. It references to n-th parameter after the format string (1-based).
-//     This mimics the behaviour of QString::arg() in QT4/5 or MFC AfxFormatString2(). C printf-like functions offer similar functionality
-//     with a '%n$TYPE' syntax. In .NET, the syntax is '{n}'. This is useful to support localization strings that can change the parameter
-//     ordering.
-//  4. Every function is available for std::string, std::wstring and mpt::ustring. std::string makes no assumption about the encoding, which
-//     basically means, it should work for any 7-bit or 8-bit encoding, including for example ASCII, UTF8 or the current locale encoding.
-//     std::string         std::wstring          mpt::ustring                    mpt::tsrtring                        CString
-//     mpt::fmt            mpt::wfmt             mpt::ufmt                       mpt::tfmt                            mpt::cfmt
-//     mpt::format("%1")   mpt::wformat(L"%1")   mpt::uformat(MPT_ULITERAL(%1)   mpt::tformat(_T("%1"))               mpt::cformat(_T("%1"))
-//     mpt::format("%1")   mpt::format(L"%1")    mpt::format(MPT_USTRING(%1))    mpt::format(mpt::tstring(_T("%1"))   mpt::format(CString(_T("%1"))
-//  5. All functionality here delegates real work outside of the header file so that <sstream> and <locale> do not need to be included when
-//     using this functionality.
-//     Advantages:
-//      - Avoids binary code bloat when too much of iostream operator << gets inlined at every usage site.
-//      - Faster compile times because <sstream> and <locale> (2 very complex headers) are not included everywhere.
-//     Disadvantages:
-//      - Slightly more c++ code is required for delegating work.
-//      - As the header does not use iostreams, custom types need to overload mpt::UString instead of iostream operator << to allow for custom type
-//        formatting.
-//      - std::string, std::wstring and mpt::ustring are returned from somewhat deep cascades of helper functions. Where possible, code is
-//        written in such a way that return-value-optimization (RVO) or named-return-value-optimization (NRVO) should be able to eliminate
-//        almost all these copies. This should not be a problem for any decent modern compiler (and even less so for a c++11 compiler where
-//        move-semantics will kick in if RVO/NRVO fails).
-
-namespace mpt
-{
-
-// ToUString() converts various built-in types to a well-defined, locale-independent string representation.
-// This is also used as a type-tunnel pattern for mpt::format.
-// Custom types that need to be converted to strings are encouraged to overload ToUString().
-
-// fallback to member function ToUString()
-#if MPT_USTRING_MODE_UTF8
-template <typename T> auto ToString(const T & x) -> decltype(mpt::ToCharset(mpt::Charset::UTF8, x.ToUString())) { return mpt::ToCharset(mpt::Charset::UTF8, x.ToUString()); }
-#else
-template <typename T> auto ToString(const T & x) -> decltype(mpt::ToCharset(mpt::CharsetUnknownInternal, x.ToUString())) { return mpt::ToCharset(mpt::CharsetUnknownInternal, x.ToUString()); }
-#endif
-
-static inline std::string ToString(const std::string & x) { return x; }
-static inline std::string ToString(const char * const & x) { return x; }
-std::string ToString(const char &x) = delete; // deprecated to catch potential API mis-use, use std::string(1, x) instead
-#if MPT_WSTRING_FORMAT
-std::string ToString(const std::wstring & x) = delete; // Unknown encoding.
-std::string ToString(const wchar_t * const & x) = delete; // Unknown encoding.
-std::string ToString(const wchar_t &x ) = delete; // deprecated to catch potential API mis-use, use std::wstring(1, x) instead
-#endif
-#if MPT_USTRING_MODE_UTF8
-std::string ToString(const mpt::ustring & x) = delete; // Unknown encoding.
-#endif
-#if defined(_MFC_VER)
-std::string ToString(const CString & x) = delete; // unknown encoding
-#endif
-std::string ToString(const bool & x);
-std::string ToString(const signed char & x);
-std::string ToString(const unsigned char & x);
-std::string ToString(const signed short & x);
-std::string ToString(const unsigned short & x);
-std::string ToString(const signed int & x);
-std::string ToString(const unsigned int & x);
-std::string ToString(const signed long & x);
-std::string ToString(const unsigned long & x);
-std::string ToString(const signed long long & x);
-std::string ToString(const unsigned long long & x);
-std::string ToString(const float & x);
-std::string ToString(const double & x);
-std::string ToString(const long double & x);
-
-// fallback to member function ToUString()
-template <typename T> auto ToUString(const T & x) -> decltype(x.ToUString()) { return x.ToUString(); }
-
-static inline mpt::ustring ToUString(const mpt::ustring & x) { return x; }
-mpt::ustring ToUString(const std::string & x) = delete; // Unknown encoding.
-mpt::ustring ToUString(const char * const & x) = delete; // Unknown encoding. Note that this also applies to TCHAR in !UNICODE builds as the type is indistinguishable from char. Wrap with CString or FromTcharStr in this case.
-mpt::ustring ToUString(const char & x) = delete; // deprecated to catch potential API mis-use, use std::string(1, x) instead
-#if MPT_WSTRING_FORMAT
-#if MPT_USTRING_MODE_UTF8
-mpt::ustring ToUString(const std::wstring & x);
-#endif
-mpt::ustring ToUString(const wchar_t * const & x);
-mpt::ustring ToUString(const wchar_t & x) = delete; // deprecated to catch potential API mis-use, use std::wstring(1, x) instead
-#endif
-#if defined(_MFC_VER)
-mpt::ustring ToUString(const CString & x);
-#endif
-mpt::ustring ToUString(const bool & x);
-mpt::ustring ToUString(const signed char & x);
-mpt::ustring ToUString(const unsigned char & x);
-mpt::ustring ToUString(const signed short & x);
-mpt::ustring ToUString(const unsigned short & x);
-mpt::ustring ToUString(const signed int & x);
-mpt::ustring ToUString(const unsigned int & x);
-mpt::ustring ToUString(const signed long & x);
-mpt::ustring ToUString(const unsigned long & x);
-mpt::ustring ToUString(const signed long long & x);
-mpt::ustring ToUString(const unsigned long long & x);
-mpt::ustring ToUString(const float & x);
-mpt::ustring ToUString(const double & x);
-mpt::ustring ToUString(const long double & x);
-
-#if MPT_WSTRING_FORMAT
-std::wstring ToWString(const std::string & x) = delete; // Unknown encoding.
-std::wstring ToWString(const char * const & x) = delete; // Unknown encoding. Note that this also applies to TCHAR in !UNICODE builds as the type is indistinguishable from char. Wrap with CString or FromTcharStr in this case.
-std::wstring ToWString(const char & x) = delete; // deprecated to catch potential API mis-use, use std::string(1, x) instead
-static inline std::wstring ToWString(const std::wstring & x) { return x; }
-static inline std::wstring ToWString(const wchar_t * const & x) { return x; }
-std::wstring ToWString(const wchar_t & x) = delete; // deprecated to catch potential API mis-use, use std::wstring(1, x) instead
-#if MPT_USTRING_MODE_UTF8
-std::wstring ToWString(const mpt::ustring & x);
-#endif
-#if defined(_MFC_VER)
-std::wstring ToWString(const CString & x);
-#endif
-std::wstring ToWString(const bool & x);
-std::wstring ToWString(const signed char & x);
-std::wstring ToWString(const unsigned char & x);
-std::wstring ToWString(const signed short & x);
-std::wstring ToWString(const unsigned short & x);
-std::wstring ToWString(const signed int & x);
-std::wstring ToWString(const unsigned int & x);
-std::wstring ToWString(const signed long & x);
-std::wstring ToWString(const unsigned long & x);
-std::wstring ToWString(const signed long long & x);
-std::wstring ToWString(const unsigned long long & x);
-std::wstring ToWString(const float & x);
-std::wstring ToWString(const double & x);
-std::wstring ToWString(const long double & x);
-// fallback to member function ToUString()
-template <typename T> auto ToWString(const T & x) -> decltype(mpt::ToWide(x.ToUString())) { return mpt::ToWide(x.ToUString()); }
-#endif
-
-#if defined(MPT_ENABLE_CHARSET_LOCALE)
-template <typename T> struct ToLocaleHelper { mpt::lstring operator () (const T & v) { return mpt::ToLocale(ToUString(v)); } };
-template <> struct ToLocaleHelper<mpt::lstring> { mpt::lstring operator () (const mpt::lstring & v) { return v; } };
-#endif // MPT_ENABLE_CHARSET_LOCALE
-
-#if defined(_MFC_VER)
-template <typename T> struct ToCStringHelper { CString operator () (const T & v) { return mpt::ToCString(ToUString(v)); } };
-template <> struct ToCStringHelper<CString> { CString operator () (const CString & v) { return v; } };
-#endif
-
-template <typename Tstring> struct ToStringTFunctor {};
-template <> struct ToStringTFunctor<std::string> { template <typename T> inline std::string operator() (const T & x) { return ToString(x); } };
-template <> struct ToStringTFunctor<mpt::ustring> { template <typename T> inline mpt::ustring operator() (const T & x) { return ToUString(x); } };
-#if MPT_WSTRING_FORMAT && MPT_USTRING_MODE_UTF8
-template <> struct ToStringTFunctor<std::wstring> { template <typename T> inline std::wstring operator() (const T & x) { return ToWString(x); } };
-#endif
-#if defined(MPT_ENABLE_CHARSET_LOCALE)
-template <> struct ToStringTFunctor<mpt::lstring> { template <typename T> inline mpt::lstring operator() (const T & x) { return mpt::ToLocaleHelper<T>()(x); } };
-#endif // MPT_ENABLE_CHARSET_LOCALE
-#if defined(_MFC_VER)
-template <> struct ToStringTFunctor<CString> { template <typename T> inline CString operator() (const T & x) { return mpt::ToCStringHelper<T>()(x); } };
-#endif
-
-template<typename Tstring, typename T> inline Tstring ToStringT(const T & x) { return ToStringTFunctor<Tstring>()(x); }
-
-
-
-struct fmt_base
-{
-
-enum FormatFlagsEnum
-{
-	BaseDec = 0x0001, // base 10 (integers only)
-	BaseHex = 0x0002, // base 16 (integers only)
-	CaseLow = 0x0010, // lower case hex digits
-	CaseUpp = 0x0020, // upper case hex digits
-	FillOff = 0x0100, // do not fill up width
-	FillNul = 0x0400, // fill up width with zeros
-	NotaNrm = 0x1000, // float: normal/default notation
-	NotaFix = 0x2000, // float: fixed point notation
-	NotaSci = 0x4000, // float: scientific notation
-};
-
-}; // struct fmt_base
-
-typedef unsigned int FormatFlags;
-
-static_assert(sizeof(FormatFlags) >= sizeof(fmt_base::FormatFlagsEnum));
-
-class FormatSpec;
-
-std::string FormatVal(const char & x, const FormatSpec & f) = delete; // deprecated to catch potential API mis-use, use std::string(1, x) instead
-#if !defined(MPT_COMPILER_QUIRK_NO_WCHAR)
-std::string FormatVal(const wchar_t & x, const FormatSpec & f) = delete; // deprecated to catch potential API mis-use, use std::wstring(1, x) instead
-#endif // !MPT_COMPILER_QUIRK_NO_WCHAR
-std::string FormatVal(const bool & x, const FormatSpec & f);
-std::string FormatVal(const signed char & x, const FormatSpec & f);
-std::string FormatVal(const unsigned char & x, const FormatSpec & f);
-std::string FormatVal(const signed short & x, const FormatSpec & f);
-std::string FormatVal(const unsigned short & x, const FormatSpec & f);
-std::string FormatVal(const signed int & x, const FormatSpec & f);
-std::string FormatVal(const unsigned int & x, const FormatSpec & f);
-std::string FormatVal(const signed long & x, const FormatSpec & f);
-std::string FormatVal(const unsigned long & x, const FormatSpec & f);
-std::string FormatVal(const signed long long & x, const FormatSpec & f);
-std::string FormatVal(const unsigned long long & x, const FormatSpec & f);
-std::string FormatVal(const float & x, const FormatSpec & f);
-std::string FormatVal(const double & x, const FormatSpec & f);
-std::string FormatVal(const long double & x, const FormatSpec & f);
-
-mpt::ustring FormatValU(const char & x, const FormatSpec & f) = delete; // deprecated to catch potential API mis-use, use std::string(1, x) instead
-#if !defined(MPT_COMPILER_QUIRK_NO_WCHAR)
-mpt::ustring FormatValU(const wchar_t & x, const FormatSpec & f) = delete; // deprecated to catch potential API mis-use, use std::wstring(1, x) instead
-#endif // !MPT_COMPILER_QUIRK_NO_WCHAR
-mpt::ustring FormatValU(const bool & x, const FormatSpec & f);
-mpt::ustring FormatValU(const signed char & x, const FormatSpec & f);
-mpt::ustring FormatValU(const unsigned char & x, const FormatSpec & f);
-mpt::ustring FormatValU(const signed short & x, const FormatSpec & f);
-mpt::ustring FormatValU(const unsigned short & x, const FormatSpec & f);
-mpt::ustring FormatValU(const signed int & x, const FormatSpec & f);
-mpt::ustring FormatValU(const unsigned int & x, const FormatSpec & f);
-mpt::ustring FormatValU(const signed long & x, const FormatSpec & f);
-mpt::ustring FormatValU(const unsigned long & x, const FormatSpec & f);
-mpt::ustring FormatValU(const signed long long & x, const FormatSpec & f);
-mpt::ustring FormatValU(const unsigned long long & x, const FormatSpec & f);
-mpt::ustring FormatValU(const float & x, const FormatSpec & f);
-mpt::ustring FormatValU(const double & x, const FormatSpec & f);
-mpt::ustring FormatValU(const long double & x, const FormatSpec & f);
-
-#if MPT_WSTRING_FORMAT
-std::wstring FormatValW(const char & x, const FormatSpec & f) = delete; // deprecated to catch potential API mis-use, use std::string(1, x) instead
-#if !defined(MPT_COMPILER_QUIRK_NO_WCHAR)
-std::wstring FormatValW(const wchar_t & x, const FormatSpec & f) = delete; // deprecated to catch potential API mis-use, use std::wstring(1, x) instead
-#endif // !MPT_COMPILER_QUIRK_NO_WCHAR
-std::wstring FormatValW(const bool & x, const FormatSpec & f);
-std::wstring FormatValW(const signed char & x, const FormatSpec & f);
-std::wstring FormatValW(const unsigned char & x, const FormatSpec & f);
-std::wstring FormatValW(const signed short & x, const FormatSpec & f);
-std::wstring FormatValW(const unsigned short & x, const FormatSpec & f);
-std::wstring FormatValW(const signed int & x, const FormatSpec & f);
-std::wstring FormatValW(const unsigned int & x, const FormatSpec & f);
-std::wstring FormatValW(const signed long & x, const FormatSpec & f);
-std::wstring FormatValW(const unsigned long & x, const FormatSpec & f);
-std::wstring FormatValW(const signed long long & x, const FormatSpec & f);
-std::wstring FormatValW(const unsigned long long & x, const FormatSpec & f);
-std::wstring FormatValW(const float & x, const FormatSpec & f);
-std::wstring FormatValW(const double & x, const FormatSpec & f);
-std::wstring FormatValW(const long double & x, const FormatSpec & f);
-#endif
-
-template <typename Tstring> struct FormatValTFunctor {};
-template <> struct FormatValTFunctor<std::string> { template <typename T> inline std::string operator() (const T & x, const FormatSpec & f) { return FormatVal(x, f); } };
-template <> struct FormatValTFunctor<mpt::ustring> { template <typename T> inline mpt::ustring operator() (const T & x, const FormatSpec & f) { return FormatValU(x, f); } };
-#if MPT_USTRING_MODE_UTF8 && MPT_WSTRING_FORMAT
-template <> struct FormatValTFunctor<std::wstring> { template <typename T> inline std::wstring operator() (const T & x, const FormatSpec & f) { return FormatValW(x, f); } };
-#endif
-#if defined(MPT_ENABLE_CHARSET_LOCALE)
-template <> struct FormatValTFunctor<mpt::lstring> { template <typename T> inline mpt::lstring operator() (const T & x, const FormatSpec & f) { return mpt::ToLocale(mpt::Charset::Locale, FormatVal(x, f)); } };
-#endif // MPT_ENABLE_CHARSET_LOCALE
-#if defined(_MFC_VER)
-#ifdef UNICODE
-template <> struct FormatValTFunctor<CString> { template <typename T> inline CString operator() (const T & x, const FormatSpec & f) { return mpt::ToCString(FormatValW(x, f)); } };
-#else
-template <> struct FormatValTFunctor<CString> { template <typename T> inline CString operator() (const T & x, const FormatSpec & f) { return mpt::ToCString(mpt::Charset::Locale, FormatVal(x, f)); } };
-#endif
-#endif
-
-
-class FormatSpec
-{
-private:
-	FormatFlags flags;
-	std::size_t width;
-	int precision;
-	unsigned int group;
-	char group_sep;
-public:
-	MPT_CONSTEXPR11_FUN FormatSpec() noexcept : flags(0), width(0), precision(-1), group(0), group_sep(',') {}
-	MPT_CONSTEXPR11_FUN FormatFlags GetFlags() const noexcept { return flags; }
-	MPT_CONSTEXPR11_FUN std::size_t GetWidth() const noexcept { return width; }
-	MPT_CONSTEXPR11_FUN int GetPrecision() const noexcept { return precision; }
-	MPT_CONSTEXPR11_FUN unsigned int GetGroup() const noexcept { return group; }
-	MPT_CONSTEXPR11_FUN char GetGroupSep() const noexcept { return group_sep; }
-	MPT_CONSTEXPR14_FUN FormatSpec & SetFlags(FormatFlags f) noexcept { flags = f; return *this; }
-	MPT_CONSTEXPR14_FUN FormatSpec & SetWidth(std::size_t w) noexcept { width = w; return *this; }
-	MPT_CONSTEXPR14_FUN FormatSpec & SetPrecision(int p) noexcept { precision = p; return *this; }
-	MPT_CONSTEXPR14_FUN FormatSpec & SetGroup(unsigned int g) noexcept { group = g; return *this; }
-	MPT_CONSTEXPR14_FUN FormatSpec & SetGroupSep(char s) noexcept { group_sep = s; return *this; }
-public:
-	MPT_CONSTEXPR14_FUN FormatSpec & BaseDec() noexcept { flags &= ~(fmt_base::BaseDec|fmt_base::BaseHex); flags |= fmt_base::BaseDec; return *this; }
-	MPT_CONSTEXPR14_FUN FormatSpec & BaseHex() noexcept { flags &= ~(fmt_base::BaseDec|fmt_base::BaseHex); flags |= fmt_base::BaseHex; return *this; }
-	MPT_CONSTEXPR14_FUN FormatSpec & CaseLow() noexcept { flags &= ~(fmt_base::CaseLow|fmt_base::CaseUpp); flags |= fmt_base::CaseLow; return *this; }
-	MPT_CONSTEXPR14_FUN FormatSpec & CaseUpp() noexcept { flags &= ~(fmt_base::CaseLow|fmt_base::CaseUpp); flags |= fmt_base::CaseUpp; return *this; }
-	MPT_CONSTEXPR14_FUN FormatSpec & FillOff() noexcept { flags &= ~(fmt_base::FillOff|fmt_base::FillNul); flags |= fmt_base::FillOff; return *this; }
-	MPT_CONSTEXPR14_FUN FormatSpec & FillNul() noexcept { flags &= ~(fmt_base::FillOff|fmt_base::FillNul); flags |= fmt_base::FillNul; return *this; }
-	MPT_CONSTEXPR14_FUN FormatSpec & NotaNrm() noexcept { flags &= ~(fmt_base::NotaNrm|fmt_base::NotaFix|fmt_base::NotaSci); flags |= fmt_base::NotaNrm; return *this; }
-	MPT_CONSTEXPR14_FUN FormatSpec & NotaFix() noexcept { flags &= ~(fmt_base::NotaNrm|fmt_base::NotaFix|fmt_base::NotaSci); flags |= fmt_base::NotaFix; return *this; }
-	MPT_CONSTEXPR14_FUN FormatSpec & NotaSci() noexcept { flags &= ~(fmt_base::NotaNrm|fmt_base::NotaFix|fmt_base::NotaSci); flags |= fmt_base::NotaSci; return *this; }
-	MPT_CONSTEXPR14_FUN FormatSpec & Width(std::size_t w) noexcept { width = w; return *this; }
-	MPT_CONSTEXPR14_FUN FormatSpec & Prec(int p) noexcept { precision = p; return *this; }
-	MPT_CONSTEXPR14_FUN FormatSpec & Group(unsigned int g) noexcept { group = g; return *this; }
-	MPT_CONSTEXPR14_FUN FormatSpec & GroupSep(char s) noexcept { group_sep = s; return *this; }
-public:
-	MPT_CONSTEXPR14_FUN FormatSpec & Dec() noexcept { return BaseDec(); }
-	MPT_CONSTEXPR14_FUN FormatSpec & Hex() noexcept { return BaseHex(); }
-	MPT_CONSTEXPR14_FUN FormatSpec & Low() noexcept { return CaseLow(); }
-	MPT_CONSTEXPR14_FUN FormatSpec & Upp() noexcept { return CaseUpp(); }
-	MPT_CONSTEXPR14_FUN FormatSpec & Off() noexcept { return FillOff(); }
-	MPT_CONSTEXPR14_FUN FormatSpec & Nul() noexcept { return FillNul(); }
-	MPT_CONSTEXPR14_FUN FormatSpec & Nrm() noexcept { return NotaNrm(); }
-	MPT_CONSTEXPR14_FUN FormatSpec & Fix() noexcept { return NotaFix(); }
-	MPT_CONSTEXPR14_FUN FormatSpec & Sci() noexcept { return NotaSci(); }
-public:
-	MPT_CONSTEXPR14_FUN FormatSpec & Decimal() noexcept { return BaseDec(); }
-	MPT_CONSTEXPR14_FUN FormatSpec & Hexadecimal() noexcept { return BaseHex(); }
-	MPT_CONSTEXPR14_FUN FormatSpec & Lower() noexcept { return CaseLow(); }
-	MPT_CONSTEXPR14_FUN FormatSpec & Upper() noexcept { return CaseUpp(); }
-	MPT_CONSTEXPR14_FUN FormatSpec & FillNone() noexcept { return FillOff(); }
-	MPT_CONSTEXPR14_FUN FormatSpec & FillZero() noexcept { return FillNul(); }
-	MPT_CONSTEXPR14_FUN FormatSpec & FloatNormal() noexcept { return NotaNrm(); }
-	MPT_CONSTEXPR14_FUN FormatSpec & FloatFixed() noexcept { return NotaFix(); }
-	MPT_CONSTEXPR14_FUN FormatSpec & FloatScientific() noexcept { return NotaSci(); }
-	MPT_CONSTEXPR14_FUN FormatSpec & Precision(int p) noexcept { return Prec(p); }
-};
-
-template <typename Tdst, typename Tsrc>
-struct pointer_cast_helper
-{
-	Tdst operator()(const Tsrc & src) const { return src; }
-};
-template <typename Tdst, typename Tptr>
-struct pointer_cast_helper<Tdst, const Tptr*>
-{
-	Tdst operator()(const Tptr * const & src) const { return reinterpret_cast<const Tdst>(src); }
-};
-template <typename Tdst, typename Tptr>
-struct pointer_cast_helper<Tdst, Tptr*>
-{
-	Tdst operator()(const Tptr * const & src) const { return reinterpret_cast<const Tdst>(src); }
-};
-
-
-template <typename Tdst, typename Tsrc>
-Tdst pointer_cast(const Tsrc & src)
-{
-	return pointer_cast_helper<Tdst, Tsrc>()(src);
-}
-
-template <typename Tstring>
-struct fmtT : fmt_base
-{
-
-template<typename T>
-static inline Tstring val(const T& x)
-{
-	return ToStringTFunctor<Tstring>()(x);
-}
-
-template<typename T>
-static inline Tstring fmt(const T& x, const FormatSpec& f)
-{
-	return FormatValTFunctor<Tstring>()(x, f);
-}
-
-template<typename T>
-static inline Tstring dec(const T& x)
-{
-	static_assert(std::numeric_limits<T>::is_integer);
-	return FormatValTFunctor<Tstring>()(x, FormatSpec().BaseDec().FillOff());
-}
-template<int width, typename T>
-static inline Tstring dec0(const T& x)
-{
-	static_assert(std::numeric_limits<T>::is_integer);
-	return FormatValTFunctor<Tstring>()(x, FormatSpec().BaseDec().FillNul().Width(width));
-}
-
-template<typename T>
-static inline Tstring dec(unsigned int g, char s, const T& x)
-{
-	static_assert(std::numeric_limits<T>::is_integer);
-	return FormatValTFunctor<Tstring>()(x, FormatSpec().BaseDec().FillOff().Group(g).GroupSep(s));
-}
-template<int width, typename T>
-static inline Tstring dec0(unsigned int g, char s, const T& x)
-{
-	static_assert(std::numeric_limits<T>::is_integer);
-	return FormatValTFunctor<Tstring>()(x, FormatSpec().BaseDec().FillNul().Width(width).Group(g).GroupSep(s));
-}
-
-template<typename T>
-static inline Tstring hex(const T& x)
-{
-	static_assert(std::numeric_limits<T>::is_integer);
-	return FormatValTFunctor<Tstring>()(x, FormatSpec().BaseHex().CaseLow().FillOff());
-}
-template<typename T>
-static inline Tstring HEX(const T& x)
-{
-	static_assert(std::numeric_limits<T>::is_integer);
-	return FormatValTFunctor<Tstring>()(x, FormatSpec().BaseHex().CaseUpp().FillOff());
-}
-template<int width, typename T>
-static inline Tstring hex0(const T& x)
-{
-	static_assert(std::numeric_limits<T>::is_integer);
-	return FormatValTFunctor<Tstring>()(x, FormatSpec().BaseHex().CaseLow().FillNul().Width(width));
-}
-template<int width, typename T>
-static inline Tstring HEX0(const T& x)
-{
-	static_assert(std::numeric_limits<T>::is_integer);
-	return FormatValTFunctor<Tstring>()(x, FormatSpec().BaseHex().CaseUpp().FillNul().Width(width));
-}
-
-template<typename T>
-static inline Tstring hex(unsigned int g, char s, const T& x)
-{
-	static_assert(std::numeric_limits<T>::is_integer);
-	return FormatValTFunctor<Tstring>()(x, FormatSpec().BaseHex().CaseLow().FillOff().Group(g).GroupSep(s));
-}
-template<typename T>
-static inline Tstring HEX(unsigned int g, char s, const T& x)
-{
-	static_assert(std::numeric_limits<T>::is_integer);
-	return FormatValTFunctor<Tstring>()(x, FormatSpec().BaseHex().CaseUpp().FillOff().Group(g).GroupSep(s));
-}
-template<int width, typename T>
-static inline Tstring hex0(unsigned int g, char s, const T& x)
-{
-	static_assert(std::numeric_limits<T>::is_integer);
-	return FormatValTFunctor<Tstring>()(x, FormatSpec().BaseHex().CaseLow().FillNul().Width(width).Group(g).GroupSep(s));
-}
-template<int width, typename T>
-static inline Tstring HEX0(unsigned int g, char s, const T& x)
-{
-	static_assert(std::numeric_limits<T>::is_integer);
-	return FormatValTFunctor<Tstring>()(x, FormatSpec().BaseHex().CaseUpp().FillNul().Width(width).Group(g).GroupSep(s));
-}
-
-template<typename T>
-static inline Tstring flt(const T& x, int precision = -1)
-{
-	static_assert(std::is_floating_point<T>::value);
-	return FormatValTFunctor<Tstring>()(x, FormatSpec().NotaNrm().FillOff().Precision(precision));
-}
-template<typename T>
-static inline Tstring fix(const T& x, int precision = -1)
-{
-	static_assert(std::is_floating_point<T>::value);
-	return FormatValTFunctor<Tstring>()(x, FormatSpec().NotaFix().FillOff().Precision(precision));
-}
-template<typename T>
-static inline Tstring sci(const T& x, int precision = -1)
-{
-	static_assert(std::is_floating_point<T>::value);
-	return FormatValTFunctor<Tstring>()(x, FormatSpec().NotaSci().FillOff().Precision(precision));
-}
-
-template<typename T>
-static inline Tstring ptr(const T& x)
-{
-	static_assert(std::is_pointer<T>::value || std::is_same<T, std::uintptr_t>::value || std::is_same<T, std::intptr_t>::value, "");
-	return hex0<mpt::pointer_size * 2>(pointer_cast<const std::uintptr_t>(x));
-}
-template<typename T>
-static inline Tstring PTR(const T& x)
-{
-	static_assert(std::is_pointer<T>::value || std::is_same<T, std::uintptr_t>::value || std::is_same<T, std::intptr_t>::value, "");
-	return HEX0<mpt::pointer_size * 2>(pointer_cast<const std::uintptr_t>(x));
-}
-
-static inline Tstring pad_left(std::size_t width_, const Tstring &str)
-{
-	typedef mpt::string_traits<Tstring> traits;
-	typename traits::size_type width = static_cast<typename traits::size_type>(width_);
-	return traits::pad(str, width, 0);
-}
-static inline Tstring pad_right(std::size_t width_, const Tstring &str)
-{
-	typedef mpt::string_traits<Tstring> traits;
-	typename traits::size_type width = static_cast<typename traits::size_type>(width_);
-	return traits::pad(str, 0, width);
-}
-static inline Tstring left(std::size_t width_, const Tstring &str)
-{
-	typedef mpt::string_traits<Tstring> traits;
-	typename traits::size_type width = static_cast<typename traits::size_type>(width_);
-	return (traits::length(str) < width) ? traits::pad(str, 0, width - traits::length(str)) : str;
-}
-static inline Tstring right(std::size_t width_, const Tstring &str)
-{
-	typedef mpt::string_traits<Tstring> traits;
-	typename traits::size_type width = static_cast<typename traits::size_type>(width_);
-	return (traits::length(str) < width) ? traits::pad(str, width - traits::length(str), 0) : str;
-}
-static inline Tstring center(std::size_t width_, const Tstring &str)
-{
-	typedef mpt::string_traits<Tstring> traits;
-	typename traits::size_type width = static_cast<typename traits::size_type>(width_);
-	return (traits::length(str) < width) ? traits::pad(str, (width - traits::length(str)) / 2, (width - traits::length(str) + 1) / 2) : str;
-}
-
-}; // struct fmtT
-
-
-typedef fmtT<std::string> fmt;
-#if MPT_WSTRING_FORMAT
-typedef fmtT<std::wstring> wfmt;
-#endif
-#if MPT_USTRING_MODE_WIDE
-typedef fmtT<std::wstring> ufmt;
-#else
-typedef fmtT<mpt::ustring> ufmt;
-#endif
-#if defined(MPT_ENABLE_CHARSET_LOCALE)
-typedef fmtT<mpt::lstring> lfmt;
-#endif // MPT_ENABLE_CHARSET_LOCALE
-#if MPT_OS_WINDOWS
-typedef fmtT<mpt::tstring> tfmt;
-#endif
-#if defined(_MFC_VER)
-typedef fmtT<CString> cfmt;
-#endif
-
-} // namespace mpt
-
-namespace mpt {
-
-namespace String {
-
-namespace detail
-{
-
-template <typename T> struct to_string_type { };
-template <> struct to_string_type<std::string    > { typedef std::string  type; };
-template <> struct to_string_type<char           > { typedef std::string  type; };
-template <> struct to_string_type<char *         > { typedef std::string  type; };
-template <> struct to_string_type<const char     > { typedef std::string  type; };
-template <> struct to_string_type<const char *   > { typedef std::string  type; };
-#if !defined(MPT_COMPILER_QUIRK_NO_WCHAR)
-template <> struct to_string_type<std::wstring   > { typedef std::wstring type; };
-template <> struct to_string_type<wchar_t        > { typedef std::wstring type; };
-template <> struct to_string_type<wchar_t *      > { typedef std::wstring type; };
-template <> struct to_string_type<const wchar_t  > { typedef std::wstring type; };
-template <> struct to_string_type<const wchar_t *> { typedef std::wstring type; };
-#endif // !MPT_COMPILER_QUIRK_NO_WCHAR
-#if MPT_USTRING_MODE_UTF8
-template <> struct to_string_type<mpt::ustring   > { typedef mpt::ustring type; };
-#endif
-#if defined(MPT_ENABLE_CHARSET_LOCALE)
-template <> struct to_string_type<mpt::lstring   > { typedef mpt::lstring type; };
-#endif // MPT_ENABLE_CHARSET_LOCALE
-#if defined(_MFC_VER)
-template <> struct to_string_type<CString        > { typedef CString      type; };
-#endif
-template <typename T, std::size_t N> struct to_string_type<T [N]> { typedef typename to_string_type<T>::type type; };
-
-} // namespace detail
-
-} // namespace String
-
-template<typename Tformat>
-class message_formatter
-{
-
-public:
-
-	typedef typename mpt::String::detail::to_string_type<Tformat>::type Tstring;
-
-private:
-
-	Tstring format;
-
-private:
-
-	MPT_NOINLINE Tstring do_format(mpt::span<const Tstring> vals) const
-	{
-		typedef typename mpt::string_traits<Tstring> traits;
-		Tstring result;
-		const typename traits::size_type len = traits::length(format);
-		traits::reserve(result, len);
-		for(typename traits::size_type pos = 0; pos != len; ++pos)
-		{
-			typename traits::char_type c = format[pos];
-			if(pos + 1 != len && c == typename traits::char_type('%'))
-			{
-				pos++;
-				c = format[pos];
-				if(typename traits::char_type('1') <= c && c <= typename traits::char_type('9'))
-				{
-					const std::size_t n = c - typename traits::char_type('0') - 1;
-					if(n < std::size(vals))
-					{
-						traits::append(result, vals[n]);
-					}
-					continue;
-				} else if(c != typename traits::char_type('%'))
-				{
-					traits::append(result, 1, typename traits::char_type('%'));
-				}
-			}
-			traits::append(result, 1, c);
-		}
-		return result;
-	}
-
-public:
-
-	message_formatter(Tstring format_)
-		: format(std::move(format_))
-	{
-	}
-
-public:
-
-	template<typename ...Ts>
-	Tstring operator() (const Ts&... xs) const
-	{
-		const std::array<Tstring, sizeof...(xs)> vals{{ToStringTFunctor<Tstring>()(xs)...}};
-		return do_format(mpt::as_span(vals));
-	}
-
-}; // struct message_formatter<Tformat>
-
-template<typename Tformat>
-message_formatter<typename mpt::String::detail::to_string_type<Tformat>::type> format(Tformat format)
-{
-	typedef typename mpt::String::detail::to_string_type<Tformat>::type Tstring;
-	return message_formatter<Tstring>(Tstring(std::move(format)));
-}
-
-#if MPT_WSTRING_FORMAT
-static inline message_formatter<std::wstring> wformat(std::wstring format)
-{
-	return message_formatter<std::wstring>(std::move(format));
-}
-#endif
-
-static inline message_formatter<mpt::ustring> uformat(mpt::ustring format)
-{
-	return message_formatter<mpt::ustring>(std::move(format));
-}
-
-#if defined(MPT_ENABLE_CHARSET_LOCALE)
-static inline message_formatter<mpt::lstring> lformat(mpt::lstring format)
-{
-	return message_formatter<mpt::lstring>(std::move(format));
-}
-#endif // MPT_ENABLE_CHARSET_LOCALE
-
-#if MPT_OS_WINDOWS
-static inline message_formatter<mpt::tstring> tformat(mpt::tstring format)
-{
-	return message_formatter<mpt::tstring>(std::move(format));
-}
-#endif
-
-#if defined(_MFC_VER)
-static inline message_formatter<CString> cformat(CString format)
-{
-	return message_formatter<CString>(std::move(format));
-}
-#endif
-
-} // namespace mpt
-
-
-
-namespace mpt { namespace String {
-
-// Combine a vector of values into a string, separated with the given separator.
-// No escaping is performed.
-template<typename T>
-mpt::ustring Combine(const std::vector<T> &vals, const mpt::ustring &sep=U_(","))
-{
-	mpt::ustring str;
-	for(std::size_t i = 0; i < vals.size(); ++i)
-	{
-		if(i > 0)
-		{
-			str += sep;
-		}
-		str += mpt::ufmt::val(vals[i]);
-	}
-	return str;
-}
-template<typename T>
-std::string Combine(const std::vector<T> &vals, const std::string &sep=std::string(","))
-{
-	std::string str;
-	for(std::size_t i = 0; i < vals.size(); ++i)
-	{
-		if(i > 0)
-		{
-			str += sep;
-		}
-		str += mpt::fmt::val(vals[i]);
-	}
-	return str;
-}
-
-} } // namespace mpt::String
-
-
-
-OPENMPT_NAMESPACE_END

+ 0 - 120
libopenmpt.mod/openmpt/common/mptStringParse.cpp

@@ -1,120 +0,0 @@
-/*
- * mptStringParse.cpp
- * ------------------
- * Purpose: Convert strings to other types.
- * Notes  : (currently none)
- * Authors: OpenMPT Devs
- * The OpenMPT source code is released under the BSD license. Read LICENSE for more details.
- */
-
-
-#include "stdafx.h"
-#include "mptStringParse.h"
-
-#include <locale>
-#include <sstream>
-
-
-OPENMPT_NAMESPACE_BEGIN
-
-
-template<typename T>
-inline T ConvertStrToHelper(const std::string &str)
-{
-	std::istringstream i(str);
-	i.imbue(std::locale::classic());
-	T x;
-	if(!(i >> x))
-	{
-		return T();
-	}
-	return x;
-}
-template<> inline bool ConvertStrToHelper(const std::string &str) { return ConvertStrToHelper<int>(str)?true:false; }
-template<> inline signed char ConvertStrToHelper(const std::string &str) { return static_cast<signed char>(ConvertStrToHelper<signed int>(str)); }
-template<> inline unsigned char ConvertStrToHelper(const std::string &str) { return static_cast<unsigned char>(ConvertStrToHelper<unsigned int>(str)); }
-
-#if MPT_WSTRING_FORMAT
-template<typename T>
-inline T ConvertStrToHelper(const std::wstring &str)
-{
-	std::wistringstream i(str);
-	i.imbue(std::locale::classic());
-	T x;
-	if(!(i >> x))
-	{
-		return T();
-	}
-	return x;
-}
-template<> inline bool ConvertStrToHelper(const std::wstring &str) { return ConvertStrToHelper<int>(str)?true:false; }
-template<> inline signed char ConvertStrToHelper(const std::wstring &str) { return static_cast<signed char>(ConvertStrToHelper<signed int>(str)); }
-template<> inline unsigned char ConvertStrToHelper(const std::wstring &str) { return static_cast<unsigned char>(ConvertStrToHelper<unsigned int>(str)); }
-#endif
-
-bool ConvertStrToBool(const std::string &str) { return ConvertStrToHelper<bool>(str); }
-signed char ConvertStrToSignedChar(const std::string &str) { return ConvertStrToHelper<signed char>(str); }
-unsigned char ConvertStrToUnsignedChar(const std::string &str) { return ConvertStrToHelper<unsigned char>(str); }
-signed short ConvertStrToSignedShort(const std::string &str) { return ConvertStrToHelper<signed short>(str); }
-unsigned short ConvertStrToUnsignedShort(const std::string &str) { return ConvertStrToHelper<unsigned short>(str); }
-signed int ConvertStrToSignedInt(const std::string &str) { return ConvertStrToHelper<signed int>(str); }
-unsigned int ConvertStrToUnsignedInt(const std::string &str) { return ConvertStrToHelper<unsigned int>(str); }
-signed long ConvertStrToSignedLong(const std::string &str) { return ConvertStrToHelper<signed long>(str); }
-unsigned long ConvertStrToUnsignedLong(const std::string &str) { return ConvertStrToHelper<unsigned long>(str); }
-signed long long ConvertStrToSignedLongLong(const std::string &str) { return ConvertStrToHelper<signed long long>(str); }
-unsigned long long ConvertStrToUnsignedLongLong(const std::string &str) { return ConvertStrToHelper<unsigned long long>(str); }
-float ConvertStrToFloat(const std::string &str) { return ConvertStrToHelper<float>(str); }
-double ConvertStrToDouble(const std::string &str) { return ConvertStrToHelper<double>(str); }
-long double ConvertStrToLongDouble(const std::string &str) { return ConvertStrToHelper<long double>(str); }
-
-#if MPT_WSTRING_FORMAT
-bool ConvertStrToBool(const std::wstring &str) { return ConvertStrToHelper<bool>(str); }
-signed char ConvertStrToSignedChar(const std::wstring &str) { return ConvertStrToHelper<signed char>(str); }
-unsigned char ConvertStrToUnsignedChar(const std::wstring &str) { return ConvertStrToHelper<unsigned char>(str); }
-signed short ConvertStrToSignedShort(const std::wstring &str) { return ConvertStrToHelper<signed short>(str); }
-unsigned short ConvertStrToUnsignedShort(const std::wstring &str) { return ConvertStrToHelper<unsigned short>(str); }
-signed int ConvertStrToSignedInt(const std::wstring &str) { return ConvertStrToHelper<signed int>(str); }
-unsigned int ConvertStrToUnsignedInt(const std::wstring &str) { return ConvertStrToHelper<unsigned int>(str); }
-signed long ConvertStrToSignedLong(const std::wstring &str) { return ConvertStrToHelper<signed long>(str); }
-unsigned long ConvertStrToUnsignedLong(const std::wstring &str) { return ConvertStrToHelper<unsigned long>(str); }
-signed long long ConvertStrToSignedLongLong(const std::wstring &str) { return ConvertStrToHelper<signed long long>(str); }
-unsigned long long ConvertStrToUnsignedLongLong(const std::wstring &str) { return ConvertStrToHelper<unsigned long long>(str); }
-float ConvertStrToFloat(const std::wstring &str) { return ConvertStrToHelper<float>(str); }
-double ConvertStrToDouble(const std::wstring &str) { return ConvertStrToHelper<double>(str); }
-long double ConvertStrToLongDouble(const std::wstring &str) { return ConvertStrToHelper<long double>(str); }
-#endif
-
-
-namespace mpt
-{
-namespace String
-{
-namespace Parse
-{
-
-template<typename T>
-T HexToHelper(const std::string &str)
-{
-	std::istringstream i(str);
-	i.imbue(std::locale::classic());
-	T x;
-	if(!(i >> std::hex >> x))
-	{
-		return T();
-	}
-	return x;
-}
-template<> unsigned char HexToHelper(const std::string &str) { return static_cast<unsigned char>(HexToHelper<unsigned int>(str)); }
-
-unsigned char HexToUnsignedChar(const std::string &str) { return HexToHelper<unsigned char>(str); }
-unsigned short HexToUnsignedShort(const std::string &str) { return HexToHelper<unsigned short>(str); }
-unsigned int HexToUnsignedInt(const std::string &str) { return HexToHelper<unsigned int>(str); }
-unsigned long HexToUnsignedLong(const std::string &str) { return HexToHelper<unsigned long>(str); }
-unsigned long long HexToUnsignedLongLong(const std::string &str) { return HexToHelper<unsigned long long>(str); }
-
-} // namespace Parse
-} // namespace String
-} // namespace mpt
-
-
-OPENMPT_NAMESPACE_END

+ 0 - 250
libopenmpt.mod/openmpt/common/mptStringParse.h

@@ -1,250 +0,0 @@
-/*
- * mptStringParse.h
- * ----------------
- * Purpose: Convert strings to other types.
- * Notes  : (currently none)
- * Authors: OpenMPT Devs
- * The OpenMPT source code is released under the BSD license. Read LICENSE for more details.
- */
-
-
-#pragma once
-
-#include "BuildSettings.h"
-
-
-OPENMPT_NAMESPACE_BEGIN
-
-
-bool ConvertStrToBool(const std::string &str);
-signed char ConvertStrToSignedChar(const std::string &str);
-unsigned char ConvertStrToUnsignedChar(const std::string &str);
-signed short ConvertStrToSignedShort(const std::string &str);
-unsigned short ConvertStrToUnsignedShort(const std::string &str);
-signed int ConvertStrToSignedInt(const std::string &str);
-unsigned int ConvertStrToUnsignedInt(const std::string &str);
-signed long ConvertStrToSignedLong(const std::string &str);
-unsigned long ConvertStrToUnsignedLong(const std::string &str);
-signed long long ConvertStrToSignedLongLong(const std::string &str);
-unsigned long long ConvertStrToUnsignedLongLong(const std::string &str);
-float ConvertStrToFloat(const std::string &str);
-double ConvertStrToDouble(const std::string &str);
-long double ConvertStrToLongDouble(const std::string &str);
-template<typename T> inline T ConvertStrTo(const std::string &str); // not defined, generates compiler error for non-specialized types
-template<> inline std::string ConvertStrTo(const std::string &str) { return str; }
-template<> inline bool ConvertStrTo(const std::string &str) { return ConvertStrToBool(str); }
-template<> inline signed char ConvertStrTo(const std::string &str) { return ConvertStrToSignedChar(str); }
-template<> inline unsigned char ConvertStrTo(const std::string &str) { return ConvertStrToUnsignedChar(str); }
-template<> inline signed short ConvertStrTo(const std::string &str) { return ConvertStrToSignedShort(str); }
-template<> inline unsigned short ConvertStrTo(const std::string &str) { return ConvertStrToUnsignedShort(str); }
-template<> inline signed int ConvertStrTo(const std::string &str) { return ConvertStrToSignedInt(str); }
-template<> inline unsigned int ConvertStrTo(const std::string &str) { return ConvertStrToUnsignedInt(str); }
-template<> inline signed long ConvertStrTo(const std::string &str) { return ConvertStrToSignedLong(str); }
-template<> inline unsigned long ConvertStrTo(const std::string &str) { return ConvertStrToUnsignedLong(str); }
-template<> inline signed long long ConvertStrTo(const std::string &str) { return ConvertStrToSignedLongLong(str); }
-template<> inline unsigned long long ConvertStrTo(const std::string &str) { return ConvertStrToUnsignedLongLong(str); }
-template<> inline float ConvertStrTo(const std::string &str) { return ConvertStrToFloat(str); }
-template<> inline double ConvertStrTo(const std::string &str) { return ConvertStrToDouble(str); }
-template<> inline long double ConvertStrTo(const std::string &str) { return ConvertStrToLongDouble(str); }
-
-#if MPT_WSTRING_FORMAT
-bool ConvertStrToBool(const std::wstring &str);
-signed char ConvertStrToSignedChar(const std::wstring &str);
-unsigned char ConvertStrToUnsignedChar(const std::wstring &str);
-signed short ConvertStrToSignedShort(const std::wstring &str);
-unsigned short ConvertStrToUnsignedShort(const std::wstring &str);
-signed int ConvertStrToSignedInt(const std::wstring &str);
-unsigned int ConvertStrToUnsignedInt(const std::wstring &str);
-signed long ConvertStrToSignedLong(const std::wstring &str);
-unsigned long ConvertStrToUnsignedLong(const std::wstring &str);
-signed long long ConvertStrToSignedLongLong(const std::wstring &str);
-unsigned long long ConvertStrToUnsignedLongLong(const std::wstring &str);
-float ConvertStrToFloat(const std::wstring &str);
-double ConvertStrToDouble(const std::wstring &str);
-long double ConvertStrToLongDouble(const std::wstring &str);
-template<typename T> inline T ConvertStrTo(const std::wstring &str); // not defined, generates compiler error for non-specialized types
-template<> inline std::wstring ConvertStrTo(const std::wstring &str) { return str; }
-template<> inline bool ConvertStrTo(const std::wstring &str) { return ConvertStrToBool(str); }
-template<> inline signed char ConvertStrTo(const std::wstring &str) { return ConvertStrToSignedChar(str); }
-template<> inline unsigned char ConvertStrTo(const std::wstring &str) { return ConvertStrToUnsignedChar(str); }
-template<> inline signed short ConvertStrTo(const std::wstring &str) { return ConvertStrToSignedShort(str); }
-template<> inline unsigned short ConvertStrTo(const std::wstring &str) { return ConvertStrToUnsignedShort(str); }
-template<> inline signed int ConvertStrTo(const std::wstring &str) { return ConvertStrToSignedInt(str); }
-template<> inline unsigned int ConvertStrTo(const std::wstring &str) { return ConvertStrToUnsignedInt(str); }
-template<> inline signed long ConvertStrTo(const std::wstring &str) { return ConvertStrToSignedLong(str); }
-template<> inline unsigned long ConvertStrTo(const std::wstring &str) { return ConvertStrToUnsignedLong(str); }
-template<> inline signed long long ConvertStrTo(const std::wstring &str) { return ConvertStrToSignedLongLong(str); }
-template<> inline unsigned long long ConvertStrTo(const std::wstring &str) { return ConvertStrToUnsignedLongLong(str); }
-template<> inline float ConvertStrTo(const std::wstring &str) { return ConvertStrToFloat(str); }
-template<> inline double ConvertStrTo(const std::wstring &str) { return ConvertStrToDouble(str); }
-template<> inline long double ConvertStrTo(const std::wstring &str) { return ConvertStrToLongDouble(str); }
-#endif
-
-#if defined(_MFC_VER)
-template<typename T>
-inline T ConvertStrTo(const CString &str)
-{
-	#if defined(UNICODE) && MPT_WSTRING_FORMAT
-		return ConvertStrTo<T>(mpt::ToWide(str));
-	#elif defined(UNICODE)
-		return ConvertStrTo<T>(mpt::ToCharset(mpt::Charset::UTF8, str));
-	#else // !UNICODE
-		return ConvertStrTo<T>(mpt::ToCharset(mpt::Charset::Locale, str));
-	#endif // UNICODE
-}
-#endif // _MFC_VER
-
-template<typename T>
-inline T ConvertStrTo(const char *str)
-{
-	if(!str)
-	{
-		return T();
-	}
-	return ConvertStrTo<T>(std::string(str));
-}
-
-#if MPT_WSTRING_FORMAT
-#if MPT_USTRING_MODE_UTF8
-template<> inline mpt::ustring ConvertStrTo(const std::wstring &str) { return mpt::ToUnicode(str); }
-#endif
-template<typename T>
-inline T ConvertStrTo(const wchar_t *str)
-{
-	if(!str)
-	{
-		return T();
-	}
-	return ConvertStrTo<T>(std::wstring(str));
-}
-#endif
-
-#if MPT_USTRING_MODE_UTF8
-template<typename T>
-inline T ConvertStrTo(const mpt::ustring &str)
-{
-	return ConvertStrTo<T>(mpt::ToCharset(mpt::Charset::UTF8, str));
-}
-template<> inline mpt::ustring ConvertStrTo(const mpt::ustring &str) { return str; }
-#if MPT_WSTRING_CONVERT
-template<> inline std::wstring ConvertStrTo(const mpt::ustring &str) { return mpt::ToWide(str); }
-#endif
-#endif
-
-#if defined(MPT_ENABLE_CHARSET_LOCALE)
-template<typename T>
-inline T ConvertStrTo(const mpt::lstring &str)
-{
-	return ConvertStrTo<T>(mpt::ToCharset(mpt::Charset::Locale, str));
-}
-template<> inline mpt::lstring ConvertStrTo(const mpt::lstring &str) { return str; }
-#endif
-
-
-namespace mpt
-{
-namespace String
-{
-namespace Parse
-{
-
-unsigned char HexToUnsignedChar(const std::string &str);
-unsigned short HexToUnsignedShort(const std::string &str);
-unsigned int HexToUnsignedInt(const std::string &str);
-unsigned long HexToUnsignedLong(const std::string &str);
-unsigned long long HexToUnsignedLongLong(const std::string &str);
-
-template<typename T> inline T Hex(const std::string &str); // not defined, generates compiler error for non-specialized types
-template<> inline unsigned char Hex(const std::string &str) { return HexToUnsignedChar(str); }
-template<> inline unsigned short Hex(const std::string &str) { return HexToUnsignedShort(str); }
-template<> inline unsigned int Hex(const std::string &str) { return HexToUnsignedInt(str); }
-template<> inline unsigned long Hex(const std::string &str) { return HexToUnsignedLong(str); }
-template<> inline unsigned long long Hex(const std::string &str) { return HexToUnsignedLongLong(str); }
-
-template<typename T>
-inline T Hex(const char *str)
-{
-	if(!str)
-	{
-		return T();
-	}
-	return Hex<T>(std::string(str));
-}
-
-#if MPT_WSTRING_FORMAT
-
-template<typename T>
-inline T Hex(const std::wstring &str)
-{
-	return Hex<T>(mpt::ToCharset(mpt::Charset::UTF8, str));
-}
-
-template<typename T>
-inline T Hex(const wchar_t *str)
-{
-	if(!str)
-	{
-		return T();
-	}
-	return Hex<T>(std::wstring(str));
-}
-
-#endif
-
-#if MPT_USTRING_MODE_UTF8
-template<typename T>
-inline T Hex(const mpt::ustring &str)
-{
-	return Hex<T>(mpt::ToCharset(mpt::Charset::UTF8, str));
-}
-#endif
-
-} // namespace Parse
-} // namespace String
-} // namespace mpt
-
-
-
-namespace mpt { namespace String {
-
-// Split the given string at separator positions into individual values returned as a vector.
-// An empty string results in an empty vector.
-// Leading or trailing separators result in a default-constructed element being inserted before or after the other elements.
-template<typename T>
-std::vector<T> Split(const mpt::ustring &str, const mpt::ustring &sep=U_(","))
-{
-	std::vector<T> vals;
-	std::size_t pos = 0;
-	while(str.find(sep, pos) != std::string::npos)
-	{
-		vals.push_back(ConvertStrTo<T>(str.substr(pos, str.find(sep, pos) - pos)));
-		pos = str.find(sep, pos) + sep.length();
-	}
-	if(!vals.empty() || (str.substr(pos).length() > 0))
-	{
-		vals.push_back(ConvertStrTo<T>(str.substr(pos)));
-	}
-	return vals;
-}
-template<typename T>
-std::vector<T> Split(const std::string &str, const std::string &sep=std::string(","))
-{
-	std::vector<T> vals;
-	std::size_t pos = 0;
-	while(str.find(sep, pos) != std::string::npos)
-	{
-		vals.push_back(ConvertStrTo<T>(str.substr(pos, str.find(sep, pos) - pos)));
-		pos = str.find(sep, pos) + sep.length();
-	}
-	if(!vals.empty() || (str.substr(pos).length() > 0))
-	{
-		vals.push_back(ConvertStrTo<T>(str.substr(pos)));
-	}
-	return vals;
-}
-
-} } // namespace mpt::String
-
-
-
-OPENMPT_NAMESPACE_END

+ 0 - 140
libopenmpt.mod/openmpt/common/mptThread.h

@@ -1,140 +0,0 @@
-/*
- * mptThread.h
- * -----------
- * Purpose: Helper class for running threads, with a more or less platform-independent interface.
- * Notes  : (currently none)
- * Authors: OpenMPT Devs
- * The OpenMPT source code is released under the BSD license. Read LICENSE for more details.
- */
-
-#pragma once
-
-#include "BuildSettings.h"
-
-#if defined(MPT_ENABLE_THREAD)
-
-#include <thread>
-
-#if defined(MODPLUG_TRACKER)
-#if MPT_OS_WINDOWS
-#include <windows.h>
-#endif // MPT_OS_WINDOWS
-#endif // MODPLUG_TRACKER
-
-#endif // MPT_ENABLE_THREAD
-
-
-OPENMPT_NAMESPACE_BEGIN
-
-
-#if defined(MPT_ENABLE_THREAD)
-
-namespace mpt
-{
-
-
-#if defined(MODPLUG_TRACKER)
-
-#if MPT_OS_WINDOWS && (MPT_COMPILER_MSVC || MPT_COMPILER_CLANG)
-
-enum ThreadPriority
-{
-	ThreadPriorityLowest  = THREAD_PRIORITY_LOWEST,
-	ThreadPriorityLower   = THREAD_PRIORITY_BELOW_NORMAL,
-	ThreadPriorityNormal  = THREAD_PRIORITY_NORMAL,
-	ThreadPriorityHigh    = THREAD_PRIORITY_ABOVE_NORMAL,
-	ThreadPriorityHighest = THREAD_PRIORITY_HIGHEST
-};
-
-inline void SetThreadPriority(std::thread &t, mpt::ThreadPriority priority)
-{
-	::SetThreadPriority(t.native_handle(), priority);
-}
-
-inline void SetCurrentThreadPriority(mpt::ThreadPriority priority)
-{
-	::SetThreadPriority(GetCurrentThread(), priority);
-}
-
-#else // !MPT_OS_WINDOWS
-
-enum ThreadPriority
-{
-	ThreadPriorityLowest  = -2,
-	ThreadPriorityLower   = -1,
-	ThreadPriorityNormal  =  0,
-	ThreadPriorityHigh    =  1,
-	ThreadPriorityHighest =  2
-};
-
-inline void SetThreadPriority(std::thread & /*t*/ , mpt::ThreadPriority /*priority*/ )
-{
-	// nothing
-}
-
-inline void SetCurrentThreadPriority(mpt::ThreadPriority /*priority*/ )
-{
-	// nothing
-}
-
-#endif // MPT_OS_WINDOWS && (MPT_COMPILER_MSVC || MPT_COMPILER_CLANG)
-
-#endif // MODPLUG_TRACKER
-
-
-
-#if defined(MODPLUG_TRACKER)
-
-#if MPT_OS_WINDOWS
-
-// Default WinAPI thread
-class UnmanagedThread
-{
-protected:
-	HANDLE threadHandle;
-
-public:
-
-	operator HANDLE& () { return threadHandle; }
-	operator bool () const { return threadHandle != nullptr; }
-
-	UnmanagedThread() : threadHandle(nullptr) { }
-	UnmanagedThread(LPTHREAD_START_ROUTINE function, void *userData = nullptr)
-	{
-		DWORD dummy = 0;	// For Win9x
-		threadHandle = CreateThread(NULL, 0, function, userData, 0, &dummy);
-	}
-};
-
-// Thread that operates on a member function
-template<typename T, void (T::*Fun)()>
-class UnmanagedThreadMember : public mpt::UnmanagedThread
-{
-protected:
-	static DWORD WINAPI wrapperFunc(LPVOID param)
-	{
-		(static_cast<T *>(param)->*Fun)();
-		return 0;
-	}
-
-public:
-
-	UnmanagedThreadMember(T *instance) : mpt::UnmanagedThread(wrapperFunc, instance) { }
-};
-
-inline void SetThreadPriority(mpt::UnmanagedThread &t, mpt::ThreadPriority priority)
-{
-	::SetThreadPriority(t, priority);
-}
-
-#endif // MPT_OS_WINDOWS
-
-#endif // MODPLUG_TRACKER
-
-
-
-}	// namespace mpt
-
-#endif // MPT_ENABLE_THREAD
-
-OPENMPT_NAMESPACE_END

+ 0 - 309
libopenmpt.mod/openmpt/common/mptTime.cpp

@@ -1,309 +0,0 @@
-/*
- * mptTime.cpp
- * -----------
- * Purpose: Various time utility functions.
- * Notes  : (currently none)
- * Authors: OpenMPT Devs
- * The OpenMPT source code is released under the BSD license. Read LICENSE for more details.
- */
-
-
-#include "stdafx.h"
-#include "mptTime.h"
-
-#include "mptStringBuffer.h"
-
-#include <time.h>
-
-#if MPT_OS_WINDOWS
-#include <windows.h>
-#if defined(MODPLUG_TRACKER)
-#include <mmsystem.h>
-#endif
-#endif
-
-
-OPENMPT_NAMESPACE_BEGIN
-
-
-namespace mpt
-{
-namespace Date
-{
-
-#if defined(MODPLUG_TRACKER)
-
-#if MPT_OS_WINDOWS
-
-namespace ANSI
-{
-
-uint64 Now()
-{
-	FILETIME filetime;
-	GetSystemTimeAsFileTime(&filetime);
-	return ((uint64)filetime.dwHighDateTime << 32 | filetime.dwLowDateTime);
-}
-
-mpt::ustring ToUString(uint64 time100ns)
-{
-	static const std::size_t bufsize = 256;
-
-	mpt::ustring result;
-
-	FILETIME filetime;
-	SYSTEMTIME systime;
-	filetime.dwHighDateTime = (DWORD)(((uint64)time100ns) >> 32);
-	filetime.dwLowDateTime = (DWORD)((uint64)time100ns);
-	FileTimeToSystemTime(&filetime, &systime);
-
-	TCHAR buf[bufsize];
-
-	GetDateFormat(LOCALE_SYSTEM_DEFAULT, 0, &systime, TEXT("yyyy-MM-dd"), buf, bufsize);
-	result.append(mpt::ToUnicode(mpt::String::ReadWinBuf(buf)));
-
-	result.append(U_(" "));
-
-	GetTimeFormat(LOCALE_SYSTEM_DEFAULT, TIME_FORCE24HOURFORMAT, &systime, TEXT("HH:mm:ss"), buf, bufsize);
-	result.append(mpt::ToUnicode(mpt::String::ReadWinBuf(buf)));
-
-	result.append(U_("."));
-
-	result.append(mpt::ufmt::dec0<3>((unsigned)systime.wMilliseconds));
-
-	return result;
-
-}
-
-} // namespace ANSI
-
-#endif // MPT_OS_WINDOWS
-
-#endif // MODPLUG_TRACKER
-
-Unix::Unix()
-	: Value(0)
-{
-	return;
-}
-
-Unix::Unix(int64 unixtime)
-	: Value(unixtime)
-{
-	return;
-}
-
-Unix::operator int64 () const
-{
-	return Value;
-}
-
-static int32 ToDaynum(int32 year, int32 month, int32 day)
-{
-	month = (month + 9) % 12;
-	year = year - (month / 10);
-	int32 daynum = year*365 + year/4 - year/100 + year/400 + (month*306 + 5)/10 + (day - 1);
-	return daynum;
-}
-
-static void FromDaynum(int32 d, int32 & year, int32 & month, int32 & day)
-{
-	int64 g = d;
-	int64 y,ddd,mi,mm,dd;
-
-	y = (10000*g + 14780)/3652425;
-	ddd = g - (365*y + y/4 - y/100 + y/400);
-	if(ddd < 0)
-	{
-		y = y - 1;
-		ddd = g - (365*y + y/4 - y/100 + y/400);
-	}
-	mi = (100*ddd + 52)/3060;
-	mm = (mi + 2)%12 + 1;
-	y = y + (mi + 2)/12;
-	dd = ddd - (mi*306 + 5)/10 + 1;
-
-	year = static_cast<int32>(y);
-	month = static_cast<int32>(mm);
-	day = static_cast<int32>(dd);
-}
-
-mpt::Date::Unix Unix::FromUTC(tm timeUtc)
-{
-	int32 daynum = ToDaynum(timeUtc.tm_year+1900, timeUtc.tm_mon+1, timeUtc.tm_mday);
-	int64 seconds = static_cast<int64>(daynum - ToDaynum(1970,1,1))*24*60*60 + timeUtc.tm_hour*60*60 + timeUtc.tm_min*60 + timeUtc.tm_sec;
-	return mpt::Date::Unix(seconds);
-}
-
-tm Unix::AsUTC() const 
-{
-	int64 tmp = Value;
-	int64 seconds = tmp % 60; tmp /= 60;
-	int64 minutes = tmp % 60; tmp /= 60;
-	int64 hours   = tmp % 24; tmp /= 24;
-	int32 year = 0, month = 0, day = 0;
-	FromDaynum(static_cast<int32>(tmp) + ToDaynum(1970,1,1), year, month, day);
-	tm result;
-	MemsetZero(result);
-	result.tm_year = year - 1900;
-	result.tm_mon = month - 1;
-	result.tm_mday = day;
-	result.tm_hour = static_cast<int32>(hours);
-	result.tm_min = static_cast<int32>(minutes);
-	result.tm_sec = static_cast<int32>(seconds);
-	return result;
-}
-
-mpt::ustring ToShortenedISO8601(tm date)
-{
-	// We assume date in UTC here.
-	// There are too many differences in supported format specifiers in strftime()
-	// and strftime does not support reduced precision ISO8601 at all.
-	// Just do the formatting ourselves.
-	mpt::ustring result;
-	mpt::ustring tz = U_("Z");
-	if(date.tm_year == 0)
-	{
-		return result;
-	}
-	result += mpt::ufmt::dec0<4>(date.tm_year + 1900);
-	if(date.tm_mon < 0 || date.tm_mon > 11)
-	{
-		return result;
-	}
-	result += U_("-") + mpt::ufmt::dec0<2>(date.tm_mon + 1);
-	if(date.tm_mday < 1 || date.tm_mday > 31)
-	{
-		return result;
-	}
-	result += U_("-") + mpt::ufmt::dec0<2>(date.tm_mday);
-	if(date.tm_hour == 0 && date.tm_min == 0 && date.tm_sec == 0)
-	{
-		return result;
-	}
-	if(date.tm_hour < 0 || date.tm_hour > 23)
-	{
-		return result;
-	}
-	if(date.tm_min < 0 || date.tm_min > 59)
-	{
-		return result;
-	}
-	result += U_("T");
-	if(date.tm_isdst > 0)
-	{
-		tz = U_("+01:00");
-	}
-	result += mpt::ufmt::dec0<2>(date.tm_hour) + U_(":") + mpt::ufmt::dec0<2>(date.tm_min);
-	if(date.tm_sec < 0 || date.tm_sec > 61)
-	{
-		return result + tz;
-	}
-	result += U_(":") + mpt::ufmt::dec0<2>(date.tm_sec);
-	result += tz;
-	return result;
-}
-
-} // namespace Date
-} // namespace mpt
-
-
-
-#ifdef MODPLUG_TRACKER
-
-namespace Util
-{
-
-#if MPT_OS_WINDOWS
-
-void MultimediaClock::Init()
-{
-	m_CurrentPeriod = 0;
-}
-
-void MultimediaClock::SetPeriod(uint32 ms)
-{
-	TIMECAPS caps;
-	MemsetZero(caps);
-	if(timeGetDevCaps(&caps, sizeof(caps)) != MMSYSERR_NOERROR)
-	{
-		return;
-	}
-	if((caps.wPeriodMax == 0) || (caps.wPeriodMin > caps.wPeriodMax))
-	{
-		return;
-	}
-	ms = std::clamp(mpt::saturate_cast<UINT>(ms), caps.wPeriodMin, caps.wPeriodMax);
-	if(timeBeginPeriod(ms) != MMSYSERR_NOERROR)
-	{
-		return;
-	}
-	m_CurrentPeriod = ms;
-}
-
-void MultimediaClock::Cleanup()
-{
-	if(m_CurrentPeriod > 0)
-	{
-		if(timeEndPeriod(m_CurrentPeriod) != MMSYSERR_NOERROR)
-		{
-			// should not happen
-			MPT_ASSERT_NOTREACHED();
-		}
-		m_CurrentPeriod = 0;
-	}
-}
-
-MultimediaClock::MultimediaClock()
-{
-	Init();
-}
-
-MultimediaClock::MultimediaClock(uint32 ms)
-{
-	Init();
-	SetResolution(ms);
-}
-
-MultimediaClock::~MultimediaClock()
-{
-	Cleanup();
-}
-
-uint32 MultimediaClock::SetResolution(uint32 ms)
-{
-	if(m_CurrentPeriod == ms)
-	{
-		return m_CurrentPeriod;
-	}
-	Cleanup();
-	if(ms != 0)
-	{
-		SetPeriod(ms);
-	}
-	return GetResolution();
-}
-
-uint32 MultimediaClock::GetResolution() const
-{
-	return m_CurrentPeriod;
-}
-
-uint32 MultimediaClock::Now() const
-{
-	return timeGetTime();
-}
-
-uint64 MultimediaClock::NowNanoseconds() const
-{
-	return (uint64)timeGetTime() * (uint64)1000000;
-}
-
-#endif // MPT_OS_WINDOWS
-
-} // namespace Util
-
-#endif // MODPLUG_TRACKER
-
-
-OPENMPT_NAMESPACE_END

+ 0 - 116
libopenmpt.mod/openmpt/common/mptTime.h

@@ -1,116 +0,0 @@
-/*
- * mptTime.h
- * ---------
- * Purpose: Various time utility functions.
- * Notes  : (currently none)
- * Authors: OpenMPT Devs
- * The OpenMPT source code is released under the BSD license. Read LICENSE for more details.
- */
-
-
-#pragma once
-
-#include "BuildSettings.h"
-
-#include <string>
-
-#include <time.h>
-
-
-OPENMPT_NAMESPACE_BEGIN
-
-
-
-namespace mpt
-{
-namespace Date
-{
-
-#if defined(MODPLUG_TRACKER)
-
-#if MPT_OS_WINDOWS
-
-namespace ANSI
-{
-// uint64 counts 100ns since 1601-01-01T00:00Z
-
-uint64 Now();
-
-mpt::ustring ToUString(uint64 time100ns); // i.e. 2015-01-15 18:32:01.718
-
-} // namespacee ANSI
-
-#endif // MPT_OS_WINDOWS
-
-#endif // MODPLUG_TRACKER
-
-class Unix
-{
-// int64 counts 1s since 1970-01-01T00:00Z
-private:
-	int64 Value;
-public:
-	Unix();
-	explicit Unix(int64 unixtime);
-	operator int64 () const;
-public:
-	static mpt::Date::Unix FromUTC(tm timeUtc);
-	tm AsUTC() const;
-};
-
-mpt::ustring ToShortenedISO8601(tm date); // i.e. 2015-01-15T18:32:01Z
-
-} // namespace Date
-} // namespace mpt
-
-
-
-#ifdef MODPLUG_TRACKER
-
-namespace Util
-{
-
-#if MPT_OS_WINDOWS
-
-// RAII wrapper around timeBeginPeriod/timeEndPeriod/timeGetTime (on Windows).
-// This clock is monotonic, even across changing its resolution.
-// This is needed to synchronize time in Steinberg APIs (ASIO and VST).
-class MultimediaClock
-{
-private:
-	uint32 m_CurrentPeriod;
-private:
-	void Init();
-	void SetPeriod(uint32 ms);
-	void Cleanup();
-public:
-	MultimediaClock();
-	MultimediaClock(uint32 ms);
-	~MultimediaClock();
-public:
-	// Sets the desired resolution in milliseconds, returns the obtained resolution in milliseconds.
-	// A parameter of 0 causes the resolution to be reset to system defaults.
-	// A return value of 0 means the resolution is unknown, but timestamps will still be valid.
-	uint32 SetResolution(uint32 ms);
-	// Returns obtained resolution in milliseconds.
-	// A return value of 0 means the resolution is unknown, but timestamps will still be valid.
-	uint32 GetResolution() const; 
-	// Returns current instantaneous timestamp in milliseconds.
-	// The epoch (offset) of the timestamps is undefined but constant until the next system reboot.
-	// The resolution is the value returned from GetResolution().
-	uint32 Now() const;
-	// Returns current instantaneous timestamp in nanoseconds.
-	// The epoch (offset) of the timestamps is undefined but constant until the next system reboot.
-	// The resolution is the value returned from GetResolution() in milliseconds.
-	uint64 NowNanoseconds() const;
-};
-
-#endif // MPT_OS_WINDOWS
-
-} // namespace Util
-
-#endif // MODPLUG_TRACKER
-
-
-
-OPENMPT_NAMESPACE_END

+ 0 - 559
libopenmpt.mod/openmpt/common/mptUUID.cpp

@@ -1,559 +0,0 @@
-/*
- * mptUUID.cpp
- * -----------
- * Purpose: UUID utility functions.
- * Notes  : (currently none)
- * Authors: OpenMPT Devs
- * The OpenMPT source code is released under the BSD license. Read LICENSE for more details.
- */
-
-
-#include "stdafx.h"
-#include "mptUUID.h"
-
-#include "mptRandom.h"
-#include "mptStringFormat.h"
-#include "Endianness.h"
-
-#include <cstdlib>
-
-#if MPT_OS_WINDOWS
-#include <windows.h>
-#include <rpc.h>
-#if defined(MODPLUG_TRACKER) || defined(MPT_WITH_DMO) || MPT_OS_WINDOWS_WINRT
-#include <objbase.h>
-#endif // MODPLUG_TRACKER || MPT_WITH_DMO || MPT_OS_WINDOWS_WINRT
-#endif // MPT_OS_WINDOWS
-
-
-OPENMPT_NAMESPACE_BEGIN
-
-
-#if MPT_OS_WINDOWS
-
-
-namespace Util
-{
-
-
-#if defined(MODPLUG_TRACKER) || defined(MPT_WITH_DMO)
-
-
-mpt::winstring CLSIDToString(CLSID clsid)
-{
-	std::wstring str;
-	LPOLESTR tmp = nullptr;
-	switch(::StringFromCLSID(clsid, &tmp))
-	{
-	case S_OK:
-		break;
-	case E_OUTOFMEMORY:
-		if(tmp)
-		{
-			::CoTaskMemFree(tmp);
-			tmp = nullptr;
-		}
-		MPT_EXCEPTION_THROW_OUT_OF_MEMORY();
-		break;
-	default:
-		if(tmp)
-		{
-			::CoTaskMemFree(tmp);
-			tmp = nullptr;
-		}
-		throw std::logic_error("StringFromCLSID() failed.");
-		break;
-	}
-	if(!tmp)
-	{
-		throw std::logic_error("StringFromCLSID() failed.");
-	}
-	try
-	{
-		str = tmp;
-	} MPT_EXCEPTION_CATCH_OUT_OF_MEMORY(e)
-	{
-		::CoTaskMemFree(tmp);
-		tmp = nullptr;
-		MPT_EXCEPTION_RETHROW_OUT_OF_MEMORY(e);
-	}
-	::CoTaskMemFree(tmp);
-	tmp = nullptr;
-	return mpt::ToWin(str);
-}
-
-
-CLSID StringToCLSID(const mpt::winstring &str_)
-{
-	const std::wstring str = mpt::ToWide(str_);
-	CLSID clsid = CLSID();
-	std::vector<OLECHAR> tmp(str.c_str(), str.c_str() + str.length() + 1);
-	switch(::CLSIDFromString(tmp.data(), &clsid))
-	{
-	case NOERROR:
-		// nothing
-		break;
-	case E_INVALIDARG:
-		clsid = CLSID();
-		break;
-	case CO_E_CLASSSTRING:
-		clsid = CLSID();
-		break;
-	case REGDB_E_CLASSNOTREG:
-		clsid = CLSID();
-		break;
-	case REGDB_E_READREGDB:
-		clsid = CLSID();
-		throw std::runtime_error("CLSIDFromString() failed: REGDB_E_READREGDB.");
-		break;
-	default:
-		clsid = CLSID();
-		throw std::logic_error("CLSIDFromString() failed.");
-		break;
-	}
-	return clsid;
-}
-
-
-bool VerifyStringToCLSID(const mpt::winstring &str_, CLSID &clsid)
-{
-	const std::wstring str = mpt::ToWide(str_);
-	bool result = false;
-	clsid = CLSID();
-	std::vector<OLECHAR> tmp(str.c_str(), str.c_str() + str.length() + 1);
-	switch(::CLSIDFromString(tmp.data(), &clsid))
-	{
-	case NOERROR:
-		result = true;
-		break;
-	case E_INVALIDARG:
-		result = false;
-		break;
-	case CO_E_CLASSSTRING:
-		result = false;
-		break;
-	case REGDB_E_CLASSNOTREG:
-		result = false;
-		break;
-	case REGDB_E_READREGDB:
-		throw std::runtime_error("CLSIDFromString() failed: REGDB_E_READREGDB.");
-		break;
-	default:
-		throw std::logic_error("CLSIDFromString() failed.");
-		break;
-	}
-	return result;
-}
-
-
-bool IsCLSID(const mpt::winstring &str_)
-{
-	const std::wstring str = mpt::ToWide(str_);
-	bool result = false;
-	CLSID clsid = CLSID();
-	std::vector<OLECHAR> tmp(str.c_str(), str.c_str() + str.length() + 1);
-	switch(::CLSIDFromString(tmp.data(), &clsid))
-	{
-	case NOERROR:
-		result = true;
-		break;
-	case E_INVALIDARG:
-		result = false;
-		break;
-	case CO_E_CLASSSTRING:
-		result = false;
-		break;
-	case REGDB_E_CLASSNOTREG:
-		result = false;
-		break;
-	case REGDB_E_READREGDB:
-		result = false;
-		throw std::runtime_error("CLSIDFromString() failed: REGDB_E_READREGDB.");
-		break;
-	default:
-		result = false;
-		throw std::logic_error("CLSIDFromString() failed.");
-		break;
-	}
-	return result;
-}
-
-
-mpt::winstring IIDToString(IID iid)
-{
-	std::wstring str;
-	LPOLESTR tmp = nullptr;
-	switch(::StringFromIID(iid, &tmp))
-	{
-	case S_OK:
-		break;
-	case E_OUTOFMEMORY:
-		if(tmp)
-		{
-			::CoTaskMemFree(tmp);
-			tmp = nullptr;
-		}
-		MPT_EXCEPTION_THROW_OUT_OF_MEMORY();
-		break;
-	default:
-		if(tmp)
-		{
-			::CoTaskMemFree(tmp);
-			tmp = nullptr;
-		}
-		throw std::logic_error("StringFromIID() failed.");
-		break;
-	}
-	if(!tmp)
-	{
-		throw std::logic_error("StringFromIID() failed.");
-	}
-	try
-	{
-		str = tmp;
-	} MPT_EXCEPTION_CATCH_OUT_OF_MEMORY(e)
-	{
-		::CoTaskMemFree(tmp);
-		tmp = nullptr;
-		MPT_EXCEPTION_RETHROW_OUT_OF_MEMORY(e);
-	}
-	return mpt::ToWin(str);
-}
-
-
-IID StringToIID(const mpt::winstring &str_)
-{
-	const std::wstring str = mpt::ToWide(str_);
-	IID iid = IID();
-	std::vector<OLECHAR> tmp(str.c_str(), str.c_str() + str.length() + 1);
-	switch(::IIDFromString(tmp.data(), &iid))
-	{
-	case S_OK:
-		// nothing
-		break;
-	case E_OUTOFMEMORY:
-		iid = IID();
-		MPT_EXCEPTION_THROW_OUT_OF_MEMORY();
-		break;
-	case E_INVALIDARG:
-		iid = IID();
-		break;
-	default:
-		iid = IID();
-		throw std::logic_error("IIDFromString() failed.");
-		break;
-	}
-	return iid;
-}
-
-
-mpt::winstring GUIDToString(GUID guid)
-{
-	std::vector<OLECHAR> tmp(256);
-	if(::StringFromGUID2(guid, tmp.data(), static_cast<int>(tmp.size())) <= 0)
-	{
-		throw std::logic_error("StringFromGUID2() failed.");
-	}
-	return mpt::ToWin(tmp.data());
-}
-
-
-GUID StringToGUID(const mpt::winstring &str)
-{
-	return StringToIID(str);
-}
-
-
-GUID CreateGUID()
-{
-	GUID guid = GUID();
-	switch(::CoCreateGuid(&guid))
-	{
-	case S_OK:
-		// nothing
-		break;
-	default:
-		guid = GUID();
-		throw std::runtime_error("CoCreateGuid() failed.");
-	}
-	return guid;
-}
-
-
-bool IsValid(UUID uuid)
-{
-	return false
-		|| uuid.Data1 != 0
-		|| uuid.Data2 != 0
-		|| uuid.Data3 != 0
-		|| uuid.Data4[0] != 0
-		|| uuid.Data4[1] != 0
-		|| uuid.Data4[2] != 0
-		|| uuid.Data4[3] != 0
-		|| uuid.Data4[4] != 0
-		|| uuid.Data4[5] != 0
-		|| uuid.Data4[6] != 0
-		|| uuid.Data4[7] != 0
-		;
-}
-
-
-#endif // MODPLUG_TRACKER || MPT_WITH_DMO
-
-
-} // namespace Util
-
-
-#endif // MPT_OS_WINDOWS
-
-
-namespace mpt
-{
-
-#if MPT_OS_WINDOWS
-
-mpt::UUID UUIDFromWin32(::UUID uuid)
-{
-	return mpt::UUID
-		( uuid.Data1
-		, uuid.Data2
-		, uuid.Data3
-		, (static_cast<uint64>(0)
-			| (static_cast<uint64>(uuid.Data4[0]) << 56)
-			| (static_cast<uint64>(uuid.Data4[1]) << 48)
-			| (static_cast<uint64>(uuid.Data4[2]) << 40)
-			| (static_cast<uint64>(uuid.Data4[3]) << 32)
-			| (static_cast<uint64>(uuid.Data4[4]) << 24)
-			| (static_cast<uint64>(uuid.Data4[5]) << 16)
-			| (static_cast<uint64>(uuid.Data4[6]) <<  8)
-			| (static_cast<uint64>(uuid.Data4[7]) <<  0)
-			)
-		);
-}
-
-::UUID UUIDToWin32(mpt::UUID uuid)
-{
-	::UUID result = ::UUID();
-	result.Data1 = uuid.GetData1();
-	result.Data2 = uuid.GetData2();
-	result.Data3 = uuid.GetData3();
-	result.Data4[0] = static_cast<uint8>(uuid.GetData4() >> 56);
-	result.Data4[1] = static_cast<uint8>(uuid.GetData4() >> 48);
-	result.Data4[2] = static_cast<uint8>(uuid.GetData4() >> 40);
-	result.Data4[3] = static_cast<uint8>(uuid.GetData4() >> 32);
-	result.Data4[4] = static_cast<uint8>(uuid.GetData4() >> 24);
-	result.Data4[5] = static_cast<uint8>(uuid.GetData4() >> 16);
-	result.Data4[6] = static_cast<uint8>(uuid.GetData4() >>  8);
-	result.Data4[7] = static_cast<uint8>(uuid.GetData4() >>  0);
-	return result;
-}
-
-#if defined(MODPLUG_TRACKER) || defined(MPT_WITH_DMO)
-
-UUID::UUID(::UUID uuid)
-{
-	*this = UUIDFromWin32(uuid);
-}
-
-UUID::operator ::UUID () const
-{
-	return UUIDToWin32(*this);
-}
-
-#endif // MODPLUG_TRACKER || MPT_WITH_DMO
-
-#endif // MPT_OS_WINDOWS
-
-UUID UUID::Generate()
-{
-	#if MPT_OS_WINDOWS && MPT_OS_WINDOWS_WINRT
-		#if (_WIN32_WINNT >= 0x0602)
-			::GUID guid = ::GUID();
-			HRESULT result = CoCreateGuid(&guid);
-			if(result != S_OK)
-			{
-				return mpt::UUID::RFC4122Random();
-			}
-			return mpt::UUIDFromWin32(guid);
-		#else
-			return mpt::UUID::RFC4122Random();
-		#endif
-	#elif MPT_OS_WINDOWS && !MPT_OS_WINDOWS_WINRT
-		::UUID uuid = ::UUID();
-		RPC_STATUS status = ::UuidCreate(&uuid);
-		if(status != RPC_S_OK && status != RPC_S_UUID_LOCAL_ONLY)
-		{
-			return mpt::UUID::RFC4122Random();
-		}
-		status = RPC_S_OK;
-		if(UuidIsNil(&uuid, &status) != FALSE)
-		{
-			return mpt::UUID::RFC4122Random();
-		}
-		if(status != RPC_S_OK)
-		{
-			return mpt::UUID::RFC4122Random();
-		}
-		return mpt::UUIDFromWin32(uuid);
-	#else
-		return RFC4122Random();
-	#endif
-}
-
-UUID UUID::GenerateLocalUseOnly()
-{
-	#if MPT_OS_WINDOWS && MPT_OS_WINDOWS_WINRT
-		#if (_WIN32_WINNT >= 0x0602)
-			::GUID guid = ::GUID();
-			HRESULT result = CoCreateGuid(&guid);
-			if(result != S_OK)
-			{
-				return mpt::UUID::RFC4122Random();
-			}
-			return mpt::UUIDFromWin32(guid);
-		#else
-			return mpt::UUID::RFC4122Random();
-		#endif
-	#elif MPT_OS_WINDOWS && !MPT_OS_WINDOWS_WINRT
-		::UUID uuid = ::UUID();
-		RPC_STATUS status = ::UuidCreateSequential(&uuid);
-		if(status != RPC_S_OK && status != RPC_S_UUID_LOCAL_ONLY)
-		{
-			return Generate();
-		}
-		status = RPC_S_OK;
-		if(UuidIsNil(&uuid, &status) != FALSE)
-		{
-			return mpt::UUID::RFC4122Random();
-		}
-		if(status != RPC_S_OK)
-		{
-			return mpt::UUID::RFC4122Random();
-		}
-		return mpt::UUIDFromWin32(uuid);
-	#else
-		return RFC4122Random();
-	#endif
-}
-
-UUID UUID::RFC4122Random()
-{
-	UUID result;
-	mpt::thread_safe_prng<mpt::default_prng> & prng = mpt::global_prng();
-	result.Data1 = mpt::random<uint32>(prng);
-	result.Data2 = mpt::random<uint16>(prng);
-	result.Data3 = mpt::random<uint16>(prng);
-	result.Data4 = mpt::random<uint64>(prng);
-	result.MakeRFC4122(4);
-	return result;
-}
-
-void UUID::MakeRFC4122(uint8 version) noexcept
-{
-	// variant
-	uint8 Nn = static_cast<uint8>((Data4 >> 56) & 0xffu);
-	Data4 &= 0x00ffffffffffffffull;
-	Nn &= ~(0xc0u);
-	Nn |= 0x80u;
-	Data4 |= static_cast<uint64>(Nn) << 56;
-	// version
-	version &= 0x0fu;
-	uint8 Mm = static_cast<uint8>((Data3 >> 8) & 0xffu);
-	Data3 &= 0x00ffu;
-	Mm &= ~(0xf0u);
-	Mm |= (version << 4u);
-	Data3 |= static_cast<uint16>(Mm) << 8;
-}
-
-UUID UUID::FromString(const mpt::ustring &str)
-{
-	std::vector<mpt::ustring> segments = mpt::String::Split<mpt::ustring>(str, U_("-"));
-	if(segments.size() != 5)
-	{
-		return UUID();
-	}
-	if(segments[0].length() != 8)
-	{
-		return UUID();
-	}
-	if(segments[1].length() != 4)
-	{
-		return UUID();
-	}
-	if(segments[2].length() != 4)
-	{
-		return UUID();
-	}
-	if(segments[3].length() != 4)
-	{
-		return UUID();
-	}
-	if(segments[4].length() != 12)
-	{
-		return UUID();
-	}
-	UUID result;
-	result.Data1 = mpt::String::Parse::Hex<uint32>(segments[0]);
-	result.Data2 = mpt::String::Parse::Hex<uint16>(segments[1]);
-	result.Data3 = mpt::String::Parse::Hex<uint16>(segments[2]);
-	result.Data4 = mpt::String::Parse::Hex<uint64>(segments[3] + segments[4]);
-	return result;
-}
-
-mpt::ustring UUID::ToUString() const
-{
-	return mpt::ustring()
-		+ mpt::ufmt::hex0<8>(GetData1())
-		+ U_("-")
-		+ mpt::ufmt::hex0<4>(GetData2())
-		+ U_("-")
-		+ mpt::ufmt::hex0<4>(GetData3())
-		+ U_("-")
-		+ mpt::ufmt::hex0<4>(static_cast<uint16>(GetData4() >> 48))
-		+ U_("-")
-		+ mpt::ufmt::hex0<4>(static_cast<uint16>(GetData4() >> 32))
-		+ mpt::ufmt::hex0<8>(static_cast<uint32>(GetData4() >>  0))
-		;
-}
-
-UUID::UUID(UUIDbin uuid)
-{
-	Data1 = uuid.Data1.get();
-	Data2 = uuid.Data2.get();
-	Data3 = uuid.Data3.get();
-	Data4 = uuid.Data4.get();
-}
-
-UUID::UUID(GUIDms guid)
-{
-	Data1 = guid.Data1.get();
-	Data2 = guid.Data2.get();
-	Data3 = guid.Data3.get();
-	Data4 = guid.Data4.get();
-}
-
-UUID::operator UUIDbin() const
-{
-	UUIDbin result;
-	result.Data1 = GetData1();
-	result.Data2 = GetData2();
-	result.Data3 = GetData3();
-	result.Data4 = GetData4();
-	return result;
-}
-
-UUID::operator GUIDms() const
-{
-	GUIDms result;
-	result.Data1 = GetData1();
-	result.Data2 = GetData2();
-	result.Data3 = GetData3();
-	result.Data4 = GetData4();
-	return result;
-}
-
-
-} // namespace mpt
-
-
-OPENMPT_NAMESPACE_END

+ 0 - 207
libopenmpt.mod/openmpt/common/mptUUID.h

@@ -1,207 +0,0 @@
-/*
- * mptUUID.h
- * ---------
- * Purpose: UUID utility functions.
- * Notes  : (currently none)
- * Authors: OpenMPT Devs
- * The OpenMPT source code is released under the BSD license. Read LICENSE for more details.
- */
-
-
-#pragma once
-
-#include "BuildSettings.h"
-
-
-#include "Endianness.h"
-
-#if MPT_OS_WINDOWS
-#if defined(MODPLUG_TRACKER) || defined(MPT_WITH_DMO)
-#include <guiddef.h>
-#include <rpc.h>
-#endif // MODPLUG_TRACKER || MPT_WITH_DMO
-#endif // MPT_OS_WINDOWS
-
-
-OPENMPT_NAMESPACE_BEGIN
-
-#if MPT_OS_WINDOWS
-
-namespace Util
-{
-
-#if defined(MODPLUG_TRACKER) || defined(MPT_WITH_DMO)
-
-// COM CLSID<->string conversion
-// A CLSID string is not necessarily a standard UUID string,
-// it might also be a symbolic name for the interface.
-// (see CLSIDFromString ( http://msdn.microsoft.com/en-us/library/windows/desktop/ms680589%28v=vs.85%29.aspx ))
-mpt::winstring CLSIDToString(CLSID clsid);
-CLSID StringToCLSID(const mpt::winstring &str);
-bool VerifyStringToCLSID(const mpt::winstring &str, CLSID &clsid);
-bool IsCLSID(const mpt::winstring &str);
-
-// COM IID<->string conversion
-IID StringToIID(const mpt::winstring &str);
-mpt::winstring IIDToString(IID iid);
-
-// General GUID<->string conversion.
-// The string must/will be in standard GUID format: {4F9A455D-E7EF-4367-B2F0-0C83A38A5C72}
-GUID StringToGUID(const mpt::winstring &str);
-mpt::winstring GUIDToString(GUID guid);
-
-// Create a COM GUID
-GUID CreateGUID();
-
-// Checks the UUID against the NULL UUID. Returns false if it is NULL, true otherwise.
-bool IsValid(UUID uuid);
-
-#endif // MODPLUG_TRACKER || MPT_WITH_DMO
-
-} // namespace Util
-
-#endif // MPT_OS_WINDOWS
-
-// Microsoft on-disk layout
-struct GUIDms
-{
-	uint32le Data1;
-	uint16le Data2;
-	uint16le Data3;
-	uint64be Data4; // yes, big endian here
-};
-MPT_BINARY_STRUCT(GUIDms, 16)
-
-// RFC binary format
-struct UUIDbin
-{
-	uint32be Data1;
-	uint16be Data2;
-	uint16be Data3;
-	uint64be Data4;
-};
-MPT_BINARY_STRUCT(UUIDbin, 16)
-
-namespace mpt {
-
-struct UUID
-{
-private:
-	uint32 Data1;
-	uint16 Data2;
-	uint16 Data3;
-	uint64 Data4;
-public:
-	MPT_CONSTEXPR11_FUN uint32 GetData1() const noexcept { return Data1; }
-	MPT_CONSTEXPR11_FUN uint16 GetData2() const noexcept { return Data2; }
-	MPT_CONSTEXPR11_FUN uint16 GetData3() const noexcept { return Data3; }
-	MPT_CONSTEXPR11_FUN uint64 GetData4() const noexcept { return Data4; }
-public:
-	MPT_CONSTEXPR11_FUN uint64 GetData64_1() const noexcept { return (static_cast<uint64>(Data1) << 32) | (static_cast<uint64>(Data2) << 16) | (static_cast<uint64>(Data3) << 0); }
-	MPT_CONSTEXPR11_FUN uint64 GetData64_2() const noexcept { return Data4; }
-public:
-	// xxxxxxxx-xxxx-Mmxx-Nnxx-xxxxxxxxxxxx
-	// <--32-->-<16>-<16>-<-------64------>
-	MPT_CONSTEXPR11_FUN bool IsNil() const noexcept { return (Data1 == 0) && (Data2 == 0) && (Data3 == 0) && (Data4 == 0); }
-	MPT_CONSTEXPR11_FUN bool IsValid() const noexcept { return (Data1 != 0) || (Data2 != 0) || (Data3 != 0) || (Data4 != 0); }
-	MPT_CONSTEXPR11_FUN uint8 Variant() const noexcept { return Nn() >> 4u; }
-	MPT_CONSTEXPR11_FUN uint8 Version() const noexcept { return Mm() >> 4u; }
-	MPT_CONSTEXPR11_FUN bool IsRFC4122() const noexcept { return (Variant() & 0xcu) == 0x8u; }
-private:
-	MPT_CONSTEXPR11_FUN uint8 Mm() const noexcept { return static_cast<uint8>((Data3 >> 8) & 0xffu); }
-	MPT_CONSTEXPR11_FUN uint8 Nn() const noexcept { return static_cast<uint8>((Data4 >> 56) & 0xffu); }
-	void MakeRFC4122(uint8 version) noexcept;
-public:
-#if MPT_OS_WINDOWS && (defined(MODPLUG_TRACKER) || defined(MPT_WITH_DMO))
-	explicit UUID(::UUID uuid);
-	operator ::UUID () const;
-#endif // MPT_OS_WINDOWS && (MODPLUG_TRACKER || MPT_WITH_DMO)
-private:
-	static MPT_CONSTEXPR11_FUN uint8 NibbleFromChar(char x)
-	{
-		return
-			('0' <= x && x <= '9') ? static_cast<uint8>(x - '0' +  0) :
-			('a' <= x && x <= 'z') ? static_cast<uint8>(x - 'a' + 10) :
-			('A' <= x && x <= 'Z') ? static_cast<uint8>(x - 'A' + 10) :
-			throw std::domain_error("");
-	}
-	static MPT_CONSTEXPR11_FUN uint8 ByteFromHex(char x, char y)
-	{
-		return static_cast<uint8>(uint8(0)
-			| (NibbleFromChar(x) << 4)
-			| (NibbleFromChar(y) << 0)
-			);
-	}
-	static MPT_CONSTEXPR11_FUN uint16 ParseHex16(const char * str)
-	{
-		return static_cast<uint16>(uint16(0)
-			| (static_cast<uint16>(ByteFromHex(str[0], str[1])) << 8)
-			| (static_cast<uint16>(ByteFromHex(str[2], str[3])) << 0)
-			);
-	}
-	static MPT_CONSTEXPR11_FUN uint32 ParseHex32(const char * str)
-	{
-		return static_cast<uint32>(uint32(0)
-			| (static_cast<uint32>(ByteFromHex(str[0], str[1])) << 24)
-			| (static_cast<uint32>(ByteFromHex(str[2], str[3])) << 16)
-			| (static_cast<uint32>(ByteFromHex(str[4], str[5])) <<  8)
-			| (static_cast<uint32>(ByteFromHex(str[6], str[7])) <<  0)
-			);
-	}
-public:
-	static MPT_CONSTEXPR11_FUN UUID ParseLiteral(const char * str, std::size_t len)
-	{
-		return
-			(len == 36 && str[8] == '-' && str[13] == '-' && str[18] == '-' && str[23] == '-') ?
-			mpt::UUID(
-				ParseHex32(str + 0),
-				ParseHex16(str + 9),
-				ParseHex16(str + 14),
-				uint64(0)
-					| (static_cast<uint64>(ParseHex16(str + 19)) << 48)
-					| (static_cast<uint64>(ParseHex16(str + 24)) << 32)
-					| (static_cast<uint64>(ParseHex32(str + 28)) <<  0)
-			)
-			: throw std::domain_error("");
-	}
-public:
-	MPT_CONSTEXPR11_FUN UUID() noexcept : Data1(0), Data2(0), Data3(0), Data4(0) { }
-	MPT_CONSTEXPR11_FUN explicit UUID(uint32 Data1, uint16 Data2, uint16 Data3, uint64 Data4) noexcept : Data1(Data1), Data2(Data2), Data3(Data3), Data4(Data4) { }
-	explicit UUID(UUIDbin uuid);
-	explicit UUID(GUIDms guid);
-	operator UUIDbin () const;
-	operator GUIDms () const;
-public:
-	// Create a UUID
-	static UUID Generate();
-	// Create a UUID that contains local, traceable information.
-	// Safe for local use. May be faster.
-	static UUID GenerateLocalUseOnly();
-	// Create a RFC4122 Random UUID.
-	static UUID RFC4122Random();
-public:
-	// General UUID<->string conversion.
-	// The string must/will be in standard UUID format: 4f9a455d-e7ef-4367-b2f0-0c83a38a5c72
-	static UUID FromString(const mpt::ustring &str);
-	mpt::ustring ToUString() const;
-};
-
-MPT_CONSTEXPR11_FUN bool operator==(const mpt::UUID & a, const mpt::UUID & b) noexcept
-{
-	return (a.GetData1() == b.GetData1()) && (a.GetData2() == b.GetData2()) && (a.GetData3() == b.GetData3()) && (a.GetData4() == b.GetData4());
-}
-MPT_CONSTEXPR11_FUN bool operator!=(const mpt::UUID & a, const mpt::UUID & b) noexcept
-{
-	return (a.GetData1() != b.GetData1()) || (a.GetData2() != b.GetData2()) || (a.GetData3() != b.GetData3()) || (a.GetData4() != b.GetData4());	
-}
-
-} // namespace mpt
-
-
-MPT_CONSTEXPR11_FUN mpt::UUID operator "" _uuid (const char * str, std::size_t len)
-{
-	return mpt::UUID::ParseLiteral(str, len);
-}
-
-
-OPENMPT_NAMESPACE_END

+ 0 - 755
libopenmpt.mod/openmpt/common/mptWine.cpp

@@ -1,755 +0,0 @@
-/*
- * mptWine.cpp
- * -----------
- * Purpose: Wine stuff.
- * Notes  : (currently none)
- * Authors: OpenMPT Devs
- * The OpenMPT source code is released under the BSD license. Read LICENSE for more details.
- */
-
-
-#include "stdafx.h"
-#include "mptWine.h"
-
-#include "mptOS.h"
-#include "mptFileIO.h"
-
-#include <deque>
-#include <map>
-
-#if MPT_OS_WINDOWS
-#include <windows.h>
-#endif
-
-
-OPENMPT_NAMESPACE_BEGIN
-
-
-#if defined(MODPLUG_TRACKER) && MPT_OS_WINDOWS
-
-
-namespace mpt
-{
-namespace Wine
-{
-
-
-
-Context::Context(mpt::Wine::VersionContext versionContext)
-	: m_VersionContext(versionContext)
-	, wine_get_dos_file_name(nullptr)
-	, wine_get_unix_file_name(nullptr)
-{
-	if(!mpt::Windows::IsWine())
-	{
-		throw mpt::Wine::Exception("Wine not detected.");
-	}
-	if(!m_VersionContext.Version().IsValid())
-	{
-		throw mpt::Wine::Exception("Unknown Wine version detected.");
-	}
-	m_Kernel32 = mpt::Library(mpt::LibraryPath::FullPath(P_("kernel32.dll")));
-	if(!m_Kernel32.IsValid())
-	{
-		throw mpt::Wine::Exception("Could not load Wine kernel32.dll.");
-	}
-	if(!m_Kernel32.Bind(wine_get_unix_file_name, "wine_get_unix_file_name"))
-	{
-		throw mpt::Wine::Exception("Could not bind Wine kernel32.dll:wine_get_unix_file_name.");
-	}
-	if(!m_Kernel32.Bind(wine_get_dos_file_name, "wine_get_dos_file_name"))
-	{
-		throw mpt::Wine::Exception("Could not bind Wine kernel32.dll:wine_get_dos_file_name.");
-	}
-	{
-		std::string out;
-		std::string err;
-		try
-		{
-			if(ExecutePosixShellCommand("uname -m", out, err) != 0)
-			{
-				throw mpt::Wine::Exception("Wine 'uname -m' failed.");
-			}
-			if(!err.empty())
-			{
-				throw mpt::Wine::Exception("Wine 'uname -m' failed.");
-			}
-			out = mpt::String::Trim(out, std::string("\r\n"));
-			m_Uname_m = out;
-		} catch(const std::exception &)
-		{
-			m_Uname_m = std::string();
-		}
-	}
-	try
-	{
-		m_HOME = GetPosixEnvVar("HOME");
-	} catch(const std::exception &)
-	{
-		m_HOME = std::string();
-	}
-	try
-	{
-		m_XDG_DATA_HOME = GetPosixEnvVar("XDG_DATA_HOME");
-		if(m_XDG_DATA_HOME.empty())
-		{
-			m_XDG_DATA_HOME = m_HOME + "/.local/share";
-		}
-	} catch(const std::exception &)
-	{
-		m_XDG_DATA_HOME = std::string();
-	}
-	try
-	{
-		m_XDG_CACHE_HOME = GetPosixEnvVar("XDG_CACHE_HOME");
-		if(m_XDG_CACHE_HOME.empty())
-		{
-			m_XDG_CACHE_HOME = m_HOME + "/.cache";
-		}
-	} catch(const std::exception &)
-	{
-		m_XDG_CACHE_HOME = std::string();
-	}
-	try
-	{
-		m_XDG_CONFIG_HOME = GetPosixEnvVar("XDG_CONFIG_HOME");
-		if(m_XDG_CONFIG_HOME.empty())
-		{
-			m_XDG_CONFIG_HOME = m_HOME + "/.config";
-		}
-	} catch(const std::exception &)
-	{
-		m_XDG_CONFIG_HOME = std::string();
-	}
-}
-
-
-std::string Context::PathToPosix(mpt::PathString windowsPath)
-{
-	std::string result;
-	if(windowsPath.empty())
-	{
-		return result;
-	}
-	if(windowsPath.Length() >= 32000)
-	{
-		throw mpt::Wine::Exception("Path too long.");
-	}
-	LPSTR tmp = nullptr;
-	tmp = wine_get_unix_file_name(windowsPath.ToWide().c_str());
-	if(!tmp)
-	{
-		throw mpt::Wine::Exception("Wine kernel32.dll:wine_get_unix_file_name failed.");
-	}
-	result = tmp;
-	HeapFree(GetProcessHeap(), 0, tmp);
-	tmp = nullptr;
-	return result;
-}
-
-mpt::PathString Context::PathToWindows(std::string hostPath)
-{
-	mpt::PathString result;
-	if(hostPath.empty())
-	{
-		return result;
-	}
-	if(hostPath.length() >= 32000)
-	{
-		throw mpt::Wine::Exception("Path too long.");
-	}
-	LPWSTR tmp = nullptr;
-	tmp = wine_get_dos_file_name(hostPath.c_str());
-	if(!tmp)
-	{
-		throw mpt::Wine::Exception("Wine kernel32.dll:wine_get_dos_file_name failed.");
-	}
-	result = mpt::PathString::FromWide(tmp);
-	HeapFree(GetProcessHeap(), 0, tmp);
-	tmp = nullptr;
-	return result;
-}
-
-std::string Context::PathToPosixCanonical(mpt::PathString windowsPath)
-{
-	std::string result;
-	std::string hostPath = PathToPosix(windowsPath);
-	if(hostPath.empty())
-	{
-		return result;
-	}
-	std::string output;
-	std::string error;
-	int exitcode = ExecutePosixShellCommand(std::string() + "readlink -f " + EscapePosixShell(hostPath), output, error);
-	if(!error.empty())
-	{
-		throw mpt::Wine::Exception("Wine readlink failed: " + error);
-	}
-	if(exitcode != 0 && exitcode != 1)
-	{
-		throw mpt::Wine::Exception("Wine readlink failed.");
-	}
-	std::string trimmedOutput = mpt::String::Trim(output, std::string("\r\n"));
-	result = trimmedOutput;
-	return result;
-}
-
-
-static void ExecutePosixCommandProgressDefault(void * /*userdata*/ )
-{
-	::Sleep(10);
-	return;
-}
-
-static ExecuteProgressResult ExecutePosixShellScriptProgressDefault(void * /*userdata*/ )
-{
-	::Sleep(10);
-	return ExecuteProgressContinueWaiting;
-}
-
-
-std::string Context::EscapePosixShell(std::string line)
-{
-	const char escape_chars [] = { '|', '&', ';', '<', '>', '(', ')', '$', '`', '"', '\'', ' ', '\t' };
-	const char maybe_escape_chars [] = { '*', '?', '[', '#', '~', '=', '%' };
-	line = mpt::String::Replace(line, "\\", "\\\\");
-	for(char c : escape_chars)
-	{
-		line = mpt::String::Replace(line, std::string(1, c), "\\" + std::string(1, c));
-	}
-	for(char c : maybe_escape_chars)
-	{
-		line = mpt::String::Replace(line, std::string(1, c), "\\" + std::string(1, c));
-	}
-	return line;
-}
-
-
-ExecResult Context::ExecutePosixShellScript(std::string script, FlagSet<ExecFlags> flags, std::map<std::string, std::vector<char> > filetree, std::string title, ExecutePosixCommandProgress progress, ExecutePosixShellScriptProgress progressCancel, void *userdata)
-{
-	// Relevant documentation:
-	// https://stackoverflow.com/questions/6004070/execute-shell-commands-from-program-running-in-wine
-	// https://www.winehq.org/pipermail/wine-bugs/2014-January/374918.html
-	// https://bugs.winehq.org/show_bug.cgi?id=34730
-
-	if(!progress) progress = &ExecutePosixCommandProgressDefault;
-	if(!progressCancel) progressCancel = &ExecutePosixShellScriptProgressDefault;
-
-	if(flags[ExecFlagInteractive]) flags.reset(ExecFlagSilent);
-	if(flags[ExecFlagSplitOutput]) flags.set(ExecFlagSilent);
-
-	std::vector<mpt::PathString> tempfiles;
-
-	progress(userdata);
-
-	mpt::TempDirGuard dirWindowsTemp(mpt::CreateTempFileName());
-	if(dirWindowsTemp.GetDirname().empty())
-	{
-		throw mpt::Wine::Exception("Creating temporary directoy failed.");
-	}
-	const std::string dirPosix = PathToPosix(dirWindowsTemp.GetDirname());
-	if(dirPosix.empty())
-	{
-		throw mpt::Wine::Exception("mpt::Wine::ConvertWindowsPathToHost returned empty path.");
-	}
-	const std::string dirPosixEscape = EscapePosixShell(dirPosix);
-	const mpt::PathString dirWindows = dirWindowsTemp.GetDirname();
-
-	progress(userdata);
-
-	// write the script to disk
-	mpt::PathString scriptFilenameWindows = dirWindows + P_("script.sh");
-	{
-		mpt::ofstream tempfile(scriptFilenameWindows, std::ios::binary);
-		tempfile << script;
-		tempfile.flush();
-		if(!tempfile)
-		{
-			throw mpt::Wine::Exception("Error writing script.sh.");
-		}
-	}
-	const std::string scriptFilenamePosix = PathToPosix(scriptFilenameWindows);
-	if(scriptFilenamePosix.empty())
-	{
-		throw mpt::Wine::Exception("Error converting script.sh path.");
-	}
-	const std::string scriptFilenamePosixEscape = EscapePosixShell(scriptFilenamePosix);
-
-	progress(userdata);
-
-	// create a wrapper that will call the script and gather result.
-	mpt::PathString wrapperstarterFilenameWindows = dirWindows + P_("wrapperstarter.sh");
-	{
-		mpt::ofstream tempfile(wrapperstarterFilenameWindows, std::ios::binary);
-		std::string wrapperstarterscript;
-		wrapperstarterscript += std::string() + "#!/usr/bin/env sh" "\n";
-		wrapperstarterscript += std::string() + "exec /usr/bin/env sh " + dirPosixEscape + "wrapper.sh" "\n";
-		tempfile << wrapperstarterscript;
-		tempfile.flush();
-		if(!tempfile)
-		{
-			throw mpt::Wine::Exception("Error writing wrapper.sh.");
-		}
-	}
-	mpt::PathString wrapperFilenameWindows = dirWindows + P_("wrapper.sh");
-	std::string cleanupscript;
-	{
-		mpt::ofstream tempfile(wrapperFilenameWindows, std::ios::binary);
-		std::string wrapperscript;
-		if(!flags[ExecFlagSilent])
-		{
-			wrapperscript += "printf \"\\033]0;" + title + "\\a\"" "\n";
-		}
-		wrapperscript += "chmod u+x " + scriptFilenamePosixEscape + "\n";
-		wrapperscript += "cd " + dirPosixEscape + "filetree" "\n";
-		if(flags[ExecFlagInteractive])
-		{ // no stdout/stderr capturing for interactive scripts
-			wrapperscript += scriptFilenamePosixEscape + "\n";
-			wrapperscript += "MPT_RESULT=$?" "\n";
-			wrapperscript += "echo ${MPT_RESULT} > " + dirPosixEscape + "exit" "\n";
-		} else if(flags[ExecFlagSplitOutput])
-		{
-			wrapperscript += "(" + scriptFilenamePosixEscape + "; echo $? >&4) 4>" + dirPosixEscape + "exit 1>" + dirPosixEscape + "out 2>" + dirPosixEscape + "err" "\n";
-		} else
-		{
-			wrapperscript += "(" + scriptFilenamePosixEscape + "; echo $? >&4) 2>&1 4>" + dirPosixEscape + "exit | tee " + dirPosixEscape + "out" "\n";
-		}
-		wrapperscript += "echo done > " + dirPosixEscape + "done" "\n";
-		cleanupscript += "rm " + dirPosixEscape + "done" "\n";
-		cleanupscript += "rm " + dirPosixEscape + "exit" "\n";
-		if(flags[ExecFlagInteractive])
-		{
-			// nothing
-		} else if(flags[ExecFlagSplitOutput])
-		{
-			cleanupscript += "rm " + dirPosixEscape + "out" "\n";
-			cleanupscript += "rm " + dirPosixEscape + "err" "\n";
-		} else
-		{
-			cleanupscript += "rm " + dirPosixEscape + "out" "\n";
-		}
-		cleanupscript += "rm -r " + dirPosixEscape + "filetree" "\n";
-		cleanupscript += "rm " + dirPosixEscape + "script.sh" "\n";
-		cleanupscript += "rm " + dirPosixEscape + "wrapper.sh" "\n";
-		cleanupscript += "rm " + dirPosixEscape + "wrapperstarter.sh" "\n";
-		cleanupscript += "rm " + dirPosixEscape + "terminal.sh" "\n";
-		if(flags[ExecFlagAsync])
-		{
-			wrapperscript += cleanupscript;
-			cleanupscript.clear();
-		}
-		tempfile << wrapperscript;
-		tempfile.flush();
-		if(!tempfile)
-		{
-			throw mpt::Wine::Exception("Error writing wrapper.sh.");
-		}
-	}
-
-	progress(userdata);
-
-	::CreateDirectory((dirWindows + P_("filetree")).AsNative().c_str(), nullptr);
-	for(const auto &file : filetree)
-	{
-		std::vector<mpt::ustring> path = mpt::String::Split<mpt::ustring>(mpt::ToUnicode(mpt::Charset::UTF8, file.first), U_("/"));
-		mpt::PathString combinedPath = dirWindows + P_("filetree") + P_("\\");
-		if(path.size() > 1)
-		{
-			for(std::size_t singlepath = 0; singlepath < path.size() - 1; ++singlepath)
-			{
-				if(path[singlepath].empty())
-				{
-					continue;
-				}
-				combinedPath += mpt::PathString::FromUnicode(path[singlepath]);
-				if(!combinedPath.IsDirectory())
-				{
-					if(::CreateDirectory(combinedPath.AsNative().c_str(), nullptr) == 0)
-					{
-						throw mpt::Wine::Exception("Error writing filetree.");
-					}
-				}
-				combinedPath += P_("\\");
-			}
-		}
-		try
-		{
-			mpt::LazyFileRef out(dirWindows + P_("filetree") + P_("\\") + mpt::PathString::FromUTF8(mpt::String::Replace(file.first, "/", "\\")));
-			out = file.second;
-		} catch(std::exception &)
-		{
-			throw mpt::Wine::Exception("Error writing filetree.");
-		}
-	}
-
-	progress(userdata);
-
-	// create a wrapper that will find a suitable terminal and run the wrapper script in the terminal window.
-	mpt::PathString terminalWrapperFilenameWindows = dirWindows + P_("terminal.sh");
-	{
-		mpt::ofstream tempfile(terminalWrapperFilenameWindows, std::ios::binary);
-		// NOTE:
-		// Modern terminals detach themselves from the invoking shell if another instance is already present.
-		// This means we cannot rely on terminal invocation being syncronous.
-		static constexpr const char * terminals[] =
-		{
-			"x-terminal-emulator",
-			"konsole",
-			"mate-terminal",
-			"xfce4-terminal",
-			"gnome-terminal",
-			"uxterm",
-			"xterm",
-			"rxvt",
-		};
-		std::string terminalscript = "\n";
-		for(const std::string terminal : terminals)
-		{
-			// mate-terminal on Debian 8 cannot execute commands with arguments,
-			// thus we use a separate script that requires no arguments to execute.
-			terminalscript += "if command -v " + terminal + " 2>/dev/null 1>/dev/null ; then" "\n";
-			terminalscript += " chmod u+x " + dirPosixEscape + "wrapperstarter.sh" "\n";
-			terminalscript += " exec `command -v " + terminal + "` -e \"" + dirPosixEscape + "wrapperstarter.sh\"" "\n";
-			terminalscript += "fi" "\n";
-		}
-
-		tempfile << terminalscript;
-		tempfile.flush();
-		if(!tempfile)
-		{
-			return ExecResult::Error();
-		}
-	}
-
-	progress(userdata);
-
-	// build unix command line
-	std::string unixcommand;
-	bool createProcessSuccess = false;
-
-	if(!createProcessSuccess)
-	{
-
-		if(flags[ExecFlagSilent])
-		{
-			unixcommand = "/usr/bin/env sh \"" + dirPosixEscape + "wrapper.sh\"";
-		} else
-		{
-			unixcommand = "/usr/bin/env sh \"" + dirPosixEscape + "terminal.sh\"";
-		}
-
-		progress(userdata);
-
-		std::wstring unixcommandW = mpt::ToWide(mpt::Charset::UTF8, unixcommand);
-		std::wstring titleW = mpt::ToWide(mpt::Charset::UTF8, title);
-		STARTUPINFOW startupInfo;
-		MemsetZero(startupInfo);
-		startupInfo.lpTitle = titleW.data();
-		startupInfo.cb = sizeof(startupInfo);
-		PROCESS_INFORMATION processInformation;
-		MemsetZero(processInformation);
-
-		progress(userdata);
-
-		BOOL success = FALSE;
-		if(flags[ExecFlagSilent])
-		{
-			success = CreateProcessW(NULL, unixcommandW.data(), NULL, NULL, FALSE, DETACHED_PROCESS, NULL, NULL, &startupInfo, &processInformation);
-		} else
-		{
-			success = CreateProcessW(NULL, unixcommandW.data(), NULL, NULL, FALSE, CREATE_NEW_CONSOLE, NULL, NULL, &startupInfo, &processInformation);
-		}
-
-		progress(userdata);
-
-		createProcessSuccess = (success != FALSE);
-
-		progress(userdata);
-
-		if(success)
-		{
-
-			if(!flags[ExecFlagAsync])
-			{
-				// note: execution is not syncronous with all Wine versions,
-				// we additionally explicitly wait for "done" later
-				while(WaitForSingleObject(processInformation.hProcess, 0) == WAIT_TIMEOUT)
-				{ // wait
-					if(progressCancel(userdata) != ExecuteProgressContinueWaiting)
-					{
-						CloseHandle(processInformation.hThread);
-						CloseHandle(processInformation.hProcess);
-						throw mpt::Wine::Exception("Canceled.");
-					}
-				}
-			}
-
-			progress(userdata);
-
-			CloseHandle(processInformation.hThread);
-			CloseHandle(processInformation.hProcess);
-
-		}
-
-	}
-
-	progress(userdata);
-
-	// Work around Wine being unable to execute PIE binaries on Debian 9.
-	// Luckily, /bin/bash is still non-PIE on Debian 9.
-
-	if(!createProcessSuccess)
-	{
-		if(flags[ExecFlagSilent])
-		{
-			unixcommand = "/bin/bash \"" + dirPosixEscape + "wrapper.sh\"";
-		} else
-		{
-			unixcommand = "/bin/bash \"" + dirPosixEscape + "terminal.sh\"";
-		}
-
-		progress(userdata);
-
-		std::wstring unixcommandW = mpt::ToWide(mpt::Charset::UTF8, unixcommand);
-		std::wstring titleW = mpt::ToWide(mpt::Charset::UTF8, title);
-		STARTUPINFOW startupInfo;
-		MemsetZero(startupInfo);
-		startupInfo.lpTitle = titleW.data();
-		startupInfo.cb = sizeof(startupInfo);
-		PROCESS_INFORMATION processInformation;
-		MemsetZero(processInformation);
-
-		progress(userdata);
-
-		BOOL success = FALSE;
-		if(flags[ExecFlagSilent])
-		{
-			success = CreateProcessW(NULL, unixcommandW.data(), NULL, NULL, FALSE, DETACHED_PROCESS, NULL, NULL, &startupInfo, &processInformation);
-		} else
-		{
-			success = CreateProcessW(NULL, unixcommandW.data(), NULL, NULL, FALSE, CREATE_NEW_CONSOLE, NULL, NULL, &startupInfo, &processInformation);
-		}
-
-		progress(userdata);
-
-		createProcessSuccess = (success != FALSE);
-
-		progress(userdata);
-
-		if(success)
-		{
-			if(!flags[ExecFlagAsync])
-			{
-				// note: execution is not syncronous with all Wine versions,
-				// we additionally explicitly wait for "done" later
-				while(WaitForSingleObject(processInformation.hProcess, 0) == WAIT_TIMEOUT)
-				{ // wait
-					if(progressCancel(userdata) != ExecuteProgressContinueWaiting)
-					{
-						CloseHandle(processInformation.hThread);
-						CloseHandle(processInformation.hProcess);
-						throw mpt::Wine::Exception("Canceled.");
-					}
-				}
-			}
-
-			progress(userdata);
-
-			CloseHandle(processInformation.hThread);
-			CloseHandle(processInformation.hProcess);
-		}
-
-	}
-
-	progress(userdata);
-
-	if(!createProcessSuccess)
-	{
-		throw mpt::Wine::Exception("CreateProcess failed.");
-	}
-
-	progress(userdata);
-
-	if(flags[ExecFlagAsync])
-	{
-		ExecResult result;
-		result.exitcode = 0;
-		return result;
-	}
-
-	while(!(dirWindows + P_("done")).IsFile())
-	{ // wait
-		if(progressCancel(userdata) != ExecuteProgressContinueWaiting)
-		{
-			throw mpt::Wine::Exception("Canceled.");
-		}
-	}
-
-	progress(userdata);
-
-	int exitCode = 0;
-	{
-		mpt::ifstream exitFile(dirWindows + P_("exit"), std::ios::binary);
-		if(!exitFile)
-		{
-			throw mpt::Wine::Exception("Script .exit file not found.");
-		}
-		std::string exitString;
-		exitFile >> exitString;
-		if(exitString.empty())
-		{
-			throw mpt::Wine::Exception("Script .exit file empty.");
-		}
-		exitCode = ConvertStrTo<int>(exitString);
-	}
-
-	progress(userdata);
-
-	std::string outputString;
-	if(!flags[ExecFlagInteractive])
-	{
-		mpt::ifstream outputFile(dirWindows + P_("out"), std::ios::binary);
-		if(outputFile)
-		{
-			outputFile.seekg(0, std::ios::end);
-			std::streampos outputFileSize = outputFile.tellg();
-			outputFile.seekg(0, std::ios::beg);
-			std::vector<char> outputFileBuf(mpt::saturate_cast<std::size_t>(static_cast<std::streamoff>(outputFileSize)));
-			outputFile.read(&outputFileBuf[0], outputFileBuf.size());
-			outputString = std::string(outputFileBuf.begin(), outputFileBuf.end());
-		}
-	}
-
-	progress(userdata);
-
-	std::string errorString;
-	if(flags[ExecFlagSplitOutput])
-	{
-		mpt::ifstream errorFile(dirWindows + P_("err"), std::ios::binary);
-		if(errorFile)
-		{
-			errorFile.seekg(0, std::ios::end);
-			std::streampos errorFileSize = errorFile.tellg();
-			errorFile.seekg(0, std::ios::beg);
-			std::vector<char> errorFileBuf(mpt::saturate_cast<std::size_t>(static_cast<std::streamoff>(errorFileSize)));
-			errorFile.read(&errorFileBuf[0], errorFileBuf.size());
-			errorString = std::string(errorFileBuf.begin(), errorFileBuf.end());
-		}
-	}
-
-	progress(userdata);
-
-	ExecResult result;
-	result.exitcode = exitCode;
-	result.output = outputString;
-	result.error = errorString;
-
-	std::deque<mpt::PathString> paths;
-	paths.push_back(dirWindows + P_("filetree"));
-	mpt::PathString basePath = (dirWindows + P_("filetree")).EnsureTrailingSlash();
-	while(!paths.empty())
-	{
-		mpt::PathString path = paths.front();
-		paths.pop_front();
-		path.EnsureTrailingSlash();
-		HANDLE hFind = NULL;
-		WIN32_FIND_DATA wfd;
-		MemsetZero(wfd);
-		hFind = FindFirstFile((path + P_("*.*")).AsNative().c_str(), &wfd);
-		if(hFind != NULL && hFind != INVALID_HANDLE_VALUE)
-		{
-			do
-			{
-				mpt::PathString filename = mpt::PathString::FromNative(wfd.cFileName);
-				if(filename != P_(".") && filename != P_(".."))
-				{
-					filename = path + filename;
-					filetree[filename.ToUTF8()] = std::vector<char>();
-					if(filename.IsDirectory())
-					{
-						paths.push_back(filename);
-					} else if(filename.IsFile())
-					{
-						try
-						{
-							mpt::LazyFileRef f(filename);
-							std::vector<char> buf = f;
-							mpt::PathString treeFilename = mpt::PathString::FromNative(filename.AsNative().substr(basePath.AsNative().length()));
-							result.filetree[treeFilename.ToUTF8()] = buf;
-						} catch (std::exception &)
-						{
-							// nothing?!
-						}
-					}
-				}
-			} while(FindNextFile(hFind, &wfd));
-			FindClose(hFind);
-		}
-	}
-
-	mpt::DeleteWholeDirectoryTree(dirWindows);
-
-	return result;
-
-}
-
-
-int Context::ExecutePosixShellCommand(std::string command, std::string & output, std::string & error)
-{
-	std::string script;
-	script += "#!/usr/bin/env sh" "\n";
-	script += "exec " + command + "\n";
-	mpt::Wine::ExecResult execResult = ExecutePosixShellScript
-		( script
-		, mpt::Wine::ExecFlagSilent | mpt::Wine::ExecFlagSplitOutput, std::map<std::string, std::vector<char> >()
-		, std::string()
-		, nullptr
-		, nullptr
-		, nullptr
-		);
-	output = execResult.output;
-	error = execResult.error;
-	return execResult.exitcode;
-}
-
-
-std::string Context::GetPosixEnvVar(std::string var, std::string def)
-{
-	// We cannot use std::getenv here because Wine overrides SOME env vars,
-	// in particular, HOME is unset in the Wine environment.
-	// Instead, we just spawn a shell that will catch up a sane environment on
-	// its own.
-	std::string output;
-	std::string error;
-	int exitcode = ExecutePosixShellCommand(std::string() + "echo $" + var, output, error);
-	if(!error.empty())
-	{
-		throw mpt::Wine::Exception("Wine echo $var failed: " + error);
-	}
-	if(exitcode != 0)
-	{
-		throw mpt::Wine::Exception("Wine echo $var failed.");
-	}
-	std::string result = mpt::String::RTrim(output, std::string("\r\n"));
-	if(result.empty())
-	{
-		result = def;
-	}
-	return result;
-}
-
-
-} // namespace Wine
-} // namespace mpt
-
-
-#else // !(MODPLUG_TRACKER && MPT_OS_WINDOWS)
-
-
-MPT_MSVC_WORKAROUND_LNK4221(mptWine)
-
-
-#endif // MODPLUG_TRACKER && MPT_OS_WINDOWS
-
-
-OPENMPT_NAMESPACE_END

+ 0 - 129
libopenmpt.mod/openmpt/common/mptWine.h

@@ -1,129 +0,0 @@
-/*
- * mptWine.h
- * ---------
- * Purpose: Wine stuff.
- * Notes  : (currently none)
- * Authors: OpenMPT Devs
- * The OpenMPT source code is released under the BSD license. Read LICENSE for more details.
- */
-
-
-#pragma once
-
-#include "BuildSettings.h"
-
-#include "mptOS.h"
-#include "FlagSet.h"
-
-#include <map>
-#include <string>
-#include <vector>
-
-
-OPENMPT_NAMESPACE_BEGIN
-
-
-#if defined(MODPLUG_TRACKER) && MPT_OS_WINDOWS
-
-
-namespace mpt
-{
-
-namespace Wine
-{
-
-
-class Exception
- : public std::runtime_error
-{
-public:
-	Exception(const std::string &text)
-	 : std::runtime_error(text)
-	{
-		return;
-	}
-};
-
-
-typedef void (*ExecutePosixCommandProgress)(void *userdata);
-
-enum ExecuteProgressResult
-{
-	ExecuteProgressContinueWaiting = 0,
-	ExecuteProgressAsyncCancel = -1,
-};
-
-typedef ExecuteProgressResult (*ExecutePosixShellScriptProgress)(void *userdata);
-
-
-enum ExecFlags
-{
-	ExecFlagNone           = 0,
-	ExecFlagSilent         = 1<<0, // do not show a terminal window
-	ExecFlagInteractive    = 1<<1, // allow interaction (prevents stdout and stderr capturing and implies !silent)
-	ExecFlagAsync          = 1<<2, // do not wait for the script to finish
-	ExecFlagProgressWindow = 1<<3, // not implemented by mptOS
-	ExecFlagSplitOutput    = 1<<4, // split stdout and stderr (implies silent)
-	ExecFlagsDefault       = ExecFlagNone
-};
-MPT_DECLARE_ENUM(ExecFlags)
-
-struct ExecResult
-{
-	int exitcode;
-	std::string output;
-	std::string error;
-	std::map<std::string, std::vector<char> > filetree;
-	static ExecResult Error()
-	{
-		ExecResult result;
-		result.exitcode = -1;
-		return result;
-	}
-};
-
-
-class Context
-{
-protected:
-	mpt::Wine::VersionContext m_VersionContext;
-	mpt::Library m_Kernel32;
-private:
-	LPWSTR (*CDECL wine_get_dos_file_name)(LPCSTR str);
-	LPSTR (*CDECL wine_get_unix_file_name)(LPCWSTR str);
-protected:
-	std::string m_Uname_m;
-	std::string m_HOME;
-	std::string m_XDG_DATA_HOME;
-	std::string m_XDG_CACHE_HOME;
-	std::string m_XDG_CONFIG_HOME;
-public:
-	Context(mpt::Wine::VersionContext versionContext);
-public:
-	std::string EscapePosixShell(std::string line);
-	std::string PathToPosix(mpt::PathString windowsPath);
-	mpt::PathString PathToWindows(std::string hostPath);
-	ExecResult ExecutePosixShellScript(std::string script, FlagSet<ExecFlags> flags, std::map<std::string, std::vector<char> > filetree, std::string title, ExecutePosixCommandProgress progress, ExecutePosixShellScriptProgress progressCancel, void *userdata);
-	int ExecutePosixShellCommand(std::string command, std::string & output, std::string & error);
-	std::string PathToPosixCanonical(mpt::PathString windowsPath);
-	std::string GetPosixEnvVar(std::string var, std::string def = std::string());
-public:
-	mpt::Wine::VersionContext VersionContext() const { return m_VersionContext; }
-	mpt::Library Kernel32() const { return m_Kernel32; }
-	std::string Uname_m() const { return m_Uname_m; }
-	std::string HOME() const { return m_HOME; }
-	std::string XDG_DATA_HOME() const { return m_XDG_DATA_HOME; }
-	std::string XDG_CACHE_HOME() const { return m_XDG_CACHE_HOME; }
-	std::string XDG_CONFIG_HOME() const { return m_XDG_CONFIG_HOME; }
-};
-
-
-} // namespace Wine
-
-} // namespace mpt
-
-
-#endif // MODPLUG_TRACKER && MPT_OS_WINDOWS
-
-
-OPENMPT_NAMESPACE_END

+ 0 - 731
libopenmpt.mod/openmpt/common/serialization_utils.cpp

@@ -1,731 +0,0 @@
-/*
- * serialization_utils.cpp
- * -----------------------
- * Purpose: Serializing data to and from MPTM files.
- * Notes  : (currently none)
- * Authors: OpenMPT Devs
- * The OpenMPT source code is released under the BSD license. Read LICENSE for more details.
- */
-
-
-#include "stdafx.h"
-
-#include "serialization_utils.h"
-
-#include <istream>
-#include <ostream>
-#include <sstream>
-
-#include "misc_util.h"
-
-
-OPENMPT_NAMESPACE_BEGIN
-
-
-namespace srlztn
-{
-
-
-#ifdef MPT_ALL_LOGGING
-#define SSB_LOGGING
-#endif
-
-
-#ifdef SSB_LOGGING
-#define SSB_LOG(x) MPT_LOG(LogDebug, "serialization", x)
-#else
-#define SSB_LOG(x) MPT_DO { } MPT_WHILE_0
-#endif
-
-
-static const uint8 HeaderId_FlagByte = 0;
-
-// Indexing starts from 0.
-static inline bool Testbit(uint8 val, uint8 bitindex) {return ((val & (1 << bitindex)) != 0);}
-
-static inline void Setbit(uint8& val, uint8 bitindex, bool newval)
-{
-	if(newval) val |= (1 << bitindex);
-	else val &= ~(1 << bitindex);
-}
-
-
-bool ID::IsPrintable() const
-{
-	for(std::size_t i = 0; i < m_ID.length(); ++i)
-	{
-		if(m_ID[i] <= 0 || isprint(static_cast<unsigned char>(m_ID[i])) == 0)
-		{
-			return false;
-		}
-	}
-	return true;
-}
-
-
-//Format: First bit tells whether the size indicator is 1 or 2 bytes.
-static void WriteAdaptive12String(std::ostream& oStrm, const std::string& str)
-{
-	uint16 s = static_cast<uint16>(str.size());
-	LimitMax(s, uint16(uint16_max / 2));
-	mpt::IO::WriteAdaptiveInt16LE(oStrm, s);
-	oStrm.write(str.c_str(), s);
-}
-
-
-void WriteItemString(std::ostream& oStrm, const std::string &str)
-{
-	uint32 id = static_cast<uint32>(std::min(str.size(), static_cast<std::size_t>((uint32_max >> 4)))) << 4;
-	id |= 12; // 12 == 1100b
-	Binarywrite<uint32>(oStrm, id);
-	id >>= 4;
-	if(id > 0)
-		oStrm.write(str.data(), id);
-}
-
-
-void ReadItemString(std::istream& iStrm, std::string& str, const DataSize)
-{
-	// bits 0,1: Bytes per char type: 1,2,3,4.
-	// bits 2,3: Bytes in size indicator, 1,2,3,4
-	uint32 id = 0;
-	Binaryread(iStrm, id, 1);
-	const uint8 nSizeBytes = (id & 12) >> 2; // 12 == 1100b
-	if (nSizeBytes > 0)
-	{
-		uint8 bytes = std::min(uint8(3), nSizeBytes);
-		uint8 v2 = 0;
-		uint8 v3 = 0;
-		uint8 v4 = 0;
-		if(bytes >= 1) Binaryread(iStrm, v2);
-		if(bytes >= 2) Binaryread(iStrm, v3);
-		if(bytes >= 3) Binaryread(iStrm, v4);
-		id &= 0xff;
-		id |= (v2 << 8) | (v3 << 16) | (v4 << 24);
-	}
-	// Limit to 1 MB.
-	str.resize(std::min(id >> 4, uint32(1000000)));
-	for(size_t i = 0; i < str.size(); i++)
-		iStrm.read(&str[i], 1);
-
-	id = (id >> 4) - static_cast<uint32>(str.size());
-	if(id > 0)
-		iStrm.ignore(id);
-}
-
-
-mpt::ustring ID::AsString() const
-{
-	if(IsPrintable())
-	{
-		return mpt::ToUnicode(mpt::Charset::ISO8859_1, m_ID);
-	}
-	if(m_ID.length() > 8)
-	{
-		return mpt::ustring();
-	}
-	uint64le val;
-	val.set(0);
-	std::memcpy(&val, m_ID.data(), m_ID.length());
-	return mpt::ufmt::val(val);
-}
-
-
-const char Ssb::s_EntryID[3] = {'2','2','8'};
-
-
-#ifdef SSB_LOGGING
-static const mpt::uchar tstrWriteHeader[] = UL_("Write header with ID = %1\n");
-static const mpt::uchar tstrWriteProgress[] = UL_("Wrote entry: {num, id, rpos, size} = {%1, %2, %3, %4}\n");
-static const mpt::uchar tstrWritingMap[] = UL_("Writing map to rpos: %1\n");
-static const mpt::uchar tstrMapEntryWrite[] = UL_("Writing map entry: id=%1, rpos=%2, size=%3\n");
-static const mpt::uchar strWriteNote[] = UL_("Write note: ");
-static const mpt::uchar tstrEndOfStream[] = UL_("End of stream(rpos): %1\n");
-
-static const mpt::uchar tstrReadingHeader[] = UL_("Read header with expected ID = %1\n");
-static const mpt::uchar strNoMapInFile[] = UL_("No map in the file.\n");
-static const mpt::uchar strIdMismatch[] = UL_("ID mismatch, terminating read.\n");
-static const mpt::uchar strIdMatch[] = UL_("ID match, continuing reading.\n");
-static const mpt::uchar tstrReadingMap[] = UL_("Reading map from rpos: %1\n");
-static const mpt::uchar tstrEndOfMap[] = UL_("End of map(rpos): %1\n");
-static const mpt::uchar tstrReadProgress[] = UL_("Read entry: {num, id, rpos, size, desc} = {%1, %2, %3, %4, %5}\n");
-static const mpt::uchar tstrNoEntryFound[] = UL_("No entry with id %1 found.\n");
-static const mpt::uchar strReadNote[] = UL_("Read note: ");
-#endif
-
-
-Ssb::Ssb()
-	: m_Status(SNT_NONE)
-	, m_nFixedEntrySize(0)
-	, m_posStart(0)
-	, m_nIdbytes(IdSizeVariable)
-	, m_nCounter(0)
-	, m_Flags((1 << RwfWMapStartPosEntry) + (1 << RwfWMapSizeEntry) + (1 << RwfWVersionNum))
-{
-	return;
-}
-
-
-SsbWrite::SsbWrite(std::ostream& os)
-	: oStrm(os)
-	, m_posEntrycount(0)
-	, m_posMapPosField(0)
-{
-	return;
-}
-
-
-SsbRead::SsbRead(std::istream& is)
-	: iStrm(is)
-	, m_nReadVersion(0)
-	, m_rposMapBegin(0)
-	, m_posMapEnd(0)
-	, m_posDataBegin(0)
-	, m_rposEndofHdrData(0)
-	, m_nReadEntrycount(0)
-	, m_nNextReadHint(0)
-{
-	return;
-}
-
-
-void SsbWrite::AddWriteNote(const SsbStatus s)
-{
-	m_Status |= s;
-	SSB_LOG(mpt::format(U_("%1: 0x%2\n"))(strWriteNote, mpt::ufmt::hex(s)));
-}
-
-void SsbRead::AddReadNote(const SsbStatus s)
-{
-	m_Status |= s;
-	SSB_LOG(mpt::format(U_("%1: 0x%2\n"))(strReadNote, mpt::ufmt::hex(s)));
-}
-
-void SsbRead::AddReadNote(const ReadEntry* const pRe, const NumType nNum)
-{
-	m_Status |= SNT_PROGRESS;
-	SSB_LOG(mpt::format(mpt::ustring(tstrReadProgress))(
-				 nNum,
-				 (pRe && pRe->nIdLength < 30 && m_Idarray.size() > 0) ?  ID(&m_Idarray[pRe->nIdpos], pRe->nIdLength).AsString() : U_(""),
-				 (pRe) ? pRe->rposStart : 0,
-				 (pRe && pRe->nSize != invalidDatasize) ? mpt::ufmt::val(pRe->nSize) : U_(""),
-				 U_("")));
-#ifndef SSB_LOGGING
-	MPT_UNREFERENCED_PARAMETER(pRe);
-	MPT_UNREFERENCED_PARAMETER(nNum);
-#endif
-}
-
-// Called after writing an entry.
-void SsbWrite::AddWriteNote(const ID &id, const NumType nEntryNum, const DataSize nBytecount, const RposType rposStart)
-{
-	m_Status |= SNT_PROGRESS;
-	SSB_LOG(mpt::format(mpt::ustring(tstrWriteProgress))(nEntryNum, id.AsString(), rposStart, nBytecount));
-#ifndef SSB_LOGGING
-	MPT_UNREFERENCED_PARAMETER(id);
-	MPT_UNREFERENCED_PARAMETER(nEntryNum);
-	MPT_UNREFERENCED_PARAMETER(nBytecount);
-	MPT_UNREFERENCED_PARAMETER(rposStart);
-#endif
-}
-
-
-void SsbRead::ResetReadstatus()
-{
-	m_Status = SNT_NONE;
-	m_Idarray.reserve(32);
-	m_Idarray.push_back(0);
-}
-
-
-void SsbWrite::WriteMapItem(const ID &id,
-						const RposType& rposDataStart,
-						const DataSize& nDatasize,
-						const char* pszDesc)
-{
-	SSB_LOG(mpt::format(mpt::ustring(tstrMapEntryWrite))(
-					(id.GetSize() > 0) ? id.AsString() : U_(""),
-					rposDataStart,
-					nDatasize));
-
-	std::ostringstream mapStream;
-
-	if(m_nIdbytes > 0)
-	{
-		if (m_nIdbytes != IdSizeVariable && id.GetSize() != m_nIdbytes)
-			{ AddWriteNote(SNW_CHANGING_IDSIZE_WITH_FIXED_IDSIZESETTING); return; }
-
-		if (m_nIdbytes == IdSizeVariable) //Variablesize ID?
-			mpt::IO::WriteAdaptiveInt16LE(mapStream, static_cast<uint16>(id.GetSize()));
-
-		if(id.GetSize() > 0)
-			mapStream.write(id.GetBytes(), id.GetSize());
-	}
-
-	if (GetFlag(RwfWMapStartPosEntry)) //Startpos
-		mpt::IO::WriteAdaptiveInt64LE(mapStream, rposDataStart);
-	if (GetFlag(RwfWMapSizeEntry)) //Entrysize
-		mpt::IO::WriteAdaptiveInt64LE(mapStream, nDatasize);
-	if (GetFlag(RwfWMapDescEntry)) //Entry descriptions
-		WriteAdaptive12String(mapStream, std::string(pszDesc));
-
-	m_MapStreamString.append(mapStream.str());
-
-}
-
-
-void SsbWrite::IncrementWriteCounter()
-{
-	m_nCounter++;
-	if (m_nCounter >= (uint16_max >> 2))
-	{
-		FinishWrite();
-		AddWriteNote(SNW_MAX_WRITE_COUNT_REACHED);
-	}
-}
-
-
-void SsbWrite::BeginWrite(const ID &id, const uint64& nVersion)
-{
-	SSB_LOG(mpt::format(mpt::ustring(tstrWriteHeader))(id.AsString()));
-
-	ResetWritestatus();
-
-	if(!oStrm.good())
-		{ AddWriteNote(SNRW_BADGIVEN_STREAM); return; }
-
-	// Start bytes.
-	oStrm.write(s_EntryID, sizeof(s_EntryID));
-
-	m_posStart = oStrm.tellp() - Offtype(sizeof(s_EntryID));
-	
-	// Object ID.
-	{
-		uint8 idsize = static_cast<uint8>(id.GetSize());
-		Binarywrite<uint8>(oStrm, idsize);
-		if(idsize > 0) oStrm.write(id.GetBytes(), id.GetSize());
-	}
-
-	// Form header.
-	uint8 header = 0;
-
-	SetFlag(RwfWMapStartPosEntry, GetFlag(RwfWMapStartPosEntry) && m_nFixedEntrySize == 0);
-	SetFlag(RwfWMapSizeEntry, GetFlag(RwfWMapSizeEntry) && m_nFixedEntrySize == 0);
-
-	header = (m_nIdbytes != 4) ? (m_nIdbytes & 3) : 3;	//0,1 : Bytes per IDtype, 0,1,2,4
-	Setbit(header, 2, GetFlag(RwfWMapStartPosEntry));	//2   : Startpos in map?
-	Setbit(header, 3, GetFlag(RwfWMapSizeEntry));		//3   : Datasize in map?
-	Setbit(header, 4, GetFlag(RwfWVersionNum));			//4   : Version numeric field?
-	Setbit(header, 7, GetFlag(RwfWMapDescEntry));		//7   : Entrydescriptions in map?
-
-	// Write header
-	Binarywrite<uint8>(oStrm, header);
-
-	// Additional options.
-	uint8 tempU8 = 0;
-	Setbit(tempU8, 0, (m_nIdbytes == IdSizeVariable) || (m_nIdbytes == 3) || (m_nIdbytes > 4));
-	Setbit(tempU8, 1, m_nFixedEntrySize != 0);
-	
-	const uint8 flags = tempU8;
-	if(flags != s_DefaultFlagbyte)
-	{
-		mpt::IO::WriteAdaptiveInt32LE(oStrm, 2); //Headersize - now it is 2.
-		Binarywrite<uint8>(oStrm, HeaderId_FlagByte);
-		Binarywrite<uint8>(oStrm, flags);
-	}
-	else
-		mpt::IO::WriteAdaptiveInt32LE(oStrm, 0);
-
-	if(Testbit(header, 4)) // Version(numeric)?
-		mpt::IO::WriteAdaptiveInt64LE(oStrm, nVersion);
-
-	if(Testbit(flags, 0)) // Custom IDbytecount?
-	{
-		uint8 n = (m_nIdbytes == IdSizeVariable) ? 1 : static_cast<uint8>((m_nIdbytes << 1));
-		Binarywrite<uint8>(oStrm, n);
-	}
-
-	if(Testbit(flags, 1)) // Fixedsize entries?
-		mpt::IO::WriteAdaptiveInt32LE(oStrm, m_nFixedEntrySize);
-
-	//Entrycount. Reserve two bytes(max uint16_max / 4 entries), actual value is written after writing data.
-	m_posEntrycount = oStrm.tellp();
-	Binarywrite<uint16>(oStrm, 0);
-
-	SetFlag(RwfRwHasMap, (m_nIdbytes != 0 || GetFlag(RwfWMapStartPosEntry) || GetFlag(RwfWMapSizeEntry) || GetFlag(RwfWMapDescEntry)));
-
-	m_posMapPosField = oStrm.tellp();
-	if (GetFlag(RwfRwHasMap)) //Mapping begin pos(reserve space - actual value is written after writing data)
-		Binarywrite<uint64>(oStrm, 0);
-}
-
-
-SsbRead::ReadRv SsbRead::OnReadEntry(const ReadEntry* pE, const ID &id, const Postype& posReadBegin)
-{
-	if (pE != nullptr)
-		AddReadNote(pE, m_nCounter);
-	else if (GetFlag(RwfRMapHasId) == false) // Not ID's in map.
-	{
-		ReadEntry e;
-		e.rposStart = static_cast<RposType>(posReadBegin - m_posStart);
-		e.nSize = static_cast<DataSize>(iStrm.tellg() - posReadBegin);
-		AddReadNote(&e, m_nCounter);
-	}
-	else // Entry not found.
-	{
-		SSB_LOG(mpt::format(mpt::ustring(tstrNoEntryFound))(id.AsString()));
-#ifndef SSB_LOGGING
-		MPT_UNREFERENCED_PARAMETER(id);
-#endif
-		return EntryNotFound;
-	}
-	m_nCounter++;
-	return EntryRead;
-}
-
-
-void SsbWrite::OnWroteItem(const ID &id, const Postype& posBeforeWrite)
-{
-	const Offtype nRawEntrySize = oStrm.tellp() - posBeforeWrite;
-
-	if (nRawEntrySize < 0 || static_cast<uint64>(nRawEntrySize) > std::numeric_limits<DataSize>::max())
-		{ AddWriteNote(SNW_INSUFFICIENT_DATASIZETYPE); return; }
-
-	if(GetFlag(RwfRMapHasSize) && (nRawEntrySize < 0 || static_cast<uint64>(nRawEntrySize) > (std::numeric_limits<DataSize>::max() >> 2)))
-		{ AddWriteNote(SNW_DATASIZETYPE_OVERFLOW); return; }
-
-	DataSize nEntrySize = static_cast<DataSize>(nRawEntrySize);
-
-	// Handle fixed size entries:
-	if (m_nFixedEntrySize > 0)
-	{
-		if(nEntrySize <= m_nFixedEntrySize)
-		{
-			for(uint32 i = 0; i<m_nFixedEntrySize-nEntrySize; i++)
-				oStrm.put(0);
-			nEntrySize = m_nFixedEntrySize;
-		}
-		else
-			{ AddWriteNote(SNW_INSUFFICIENT_FIXEDSIZE); return; }
-	}
-	if (GetFlag(RwfRwHasMap))
-		WriteMapItem(id, static_cast<RposType>(posBeforeWrite - m_posStart), nEntrySize, "");
-
-	AddWriteNote(id, m_nCounter, nEntrySize, static_cast<RposType>(posBeforeWrite - m_posStart));
-	IncrementWriteCounter();
-}
-
-
-void SsbRead::BeginRead(const ID &id, const uint64& nVersion)
-{
-	SSB_LOG(mpt::format(mpt::ustring(tstrReadingHeader))(id.AsString()));
-
-	ResetReadstatus();
-
-	if (!iStrm.good())
-		{ AddReadNote(SNRW_BADGIVEN_STREAM); return; }
-
-	m_posStart = iStrm.tellg();
-
-	// Start bytes.
-	{
-		char temp[sizeof(s_EntryID)];
-		ArrayReader<char>(sizeof(s_EntryID))(iStrm, temp, sizeof(s_EntryID));
-		if(std::memcmp(temp, s_EntryID, sizeof(s_EntryID)))
-		{
-			AddReadNote(SNR_STARTBYTE_MISMATCH);
-			return;
-		}
-	}
-	
-	// Compare IDs.
-	uint8 storedIdLen = 0;
-	Binaryread<uint8>(iStrm, storedIdLen);
-	char storedIdBuf[256];
-	Clear(storedIdBuf);
-	if(storedIdLen > 0)
-	{
-		iStrm.read(storedIdBuf, storedIdLen);
-	}
-	if(!(id == ID(storedIdBuf, storedIdLen)))
-	{
-		AddReadNote(SNR_OBJECTCLASS_IDMISMATCH);
-	}
-	if ((m_Status & SNT_FAILURE) != 0)
-	{
-		SSB_LOG(mpt::ustring(strIdMismatch));
-		return;
-	}
-
-	SSB_LOG(mpt::ustring(strIdMatch));
-	
-	// Header
-	uint8 tempU8;
-	Binaryread<uint8>(iStrm, tempU8);
-	const uint8 header = tempU8;
-	m_nIdbytes = ((header & 3) == 3) ? 4 : (header & 3);
-	if (Testbit(header, 6))
-		SetFlag(RwfRTwoBytesDescChar, true);
-
-	// Read headerdata size
-	uint32 tempU32 = 0;
-	mpt::IO::ReadAdaptiveInt32LE(iStrm, tempU32);
-	const uint32 headerdatasize = tempU32;
-
-	// If headerdatasize != 0, read known headerdata and ignore rest.
-	uint8 flagbyte = s_DefaultFlagbyte;
-	if(headerdatasize >= 2)
-	{
-		Binaryread<uint8>(iStrm, tempU8);
-		if(tempU8 == HeaderId_FlagByte)
-			Binaryread<uint8>(iStrm, flagbyte);
-
-		iStrm.ignore( (tempU8 == HeaderId_FlagByte) ? headerdatasize - 2 : headerdatasize - 1);
-	}
-
-	uint64 tempU64 = 0;
-
-	// Read version numeric if available.
-	if (Testbit(header, 4))
-	{
-		mpt::IO::ReadAdaptiveInt64LE(iStrm, tempU64);
-		m_nReadVersion = tempU64;
-		if(tempU64 > nVersion)
-			AddReadNote(SNR_LOADING_OBJECT_WITH_LARGER_VERSION);
-	}
-
-	if (Testbit(header, 5))
-	{
-		Binaryread<uint8>(iStrm, tempU8);
-		iStrm.ignore(tempU8);
-	}
-
-	if(Testbit(flagbyte, 0)) // Custom ID?
-	{
-		Binaryread<uint8>(iStrm, tempU8);
-		if ((tempU8 & 1) != 0)
-			m_nIdbytes = IdSizeVariable;
-		else
-			m_nIdbytes = (tempU8 >> 1);
-		if(m_nIdbytes == 0)
-			AddReadNote(SNR_NO_ENTRYIDS_WITH_CUSTOMID_DEFINED);
-	}
-
-	m_nFixedEntrySize = 0;
-	if(Testbit(flagbyte, 1)) // Fixedsize entries?
-		mpt::IO::ReadAdaptiveInt32LE(iStrm, m_nFixedEntrySize);
-
-	SetFlag(RwfRMapHasStartpos, Testbit(header, 2));
-	SetFlag(RwfRMapHasSize, Testbit(header, 3));
-	SetFlag(RwfRMapHasId, (m_nIdbytes > 0));
-	SetFlag(RwfRMapHasDesc, Testbit(header, 7));
-	SetFlag(RwfRwHasMap, GetFlag(RwfRMapHasId) || GetFlag(RwfRMapHasStartpos) || GetFlag(RwfRMapHasSize) || GetFlag(RwfRMapHasDesc));
-	
-	if (GetFlag(RwfRwHasMap) == false)
-	{
-		SSB_LOG(mpt::ustring(strNoMapInFile));
-	}
-
-	if (Testbit(flagbyte, 2)) // Object description?
-	{
-		uint16 size = 0;
-		mpt::IO::ReadAdaptiveInt16LE(iStrm, size);
-		iStrm.ignore(size * (GetFlag(RwfRTwoBytesDescChar) ? 2 : 1));
-	}
-
-	if(Testbit(flagbyte, 3))
-		iStrm.ignore(5);
-
-	// Read entrycount
-	mpt::IO::ReadAdaptiveInt64LE(iStrm, tempU64);
-	if(tempU64 > 16000)
-		// The current code can only write 16383 entries because it uses a Adaptive64LE with a fixed size=2
-		// Additionally, 16000 is an arbitrary limit to avoid an out-of-memory DoS when caching the map.
-		{ AddReadNote(SNR_TOO_MANY_ENTRIES_TO_READ); return; }
-
-	m_nReadEntrycount = static_cast<NumType>(tempU64);
-	if(m_nReadEntrycount == 0)
-		AddReadNote(SNR_ZEROENTRYCOUNT);
-
-	// Read map rpos if map exists.
-	if (GetFlag(RwfRwHasMap))
-	{
-		mpt::IO::ReadAdaptiveInt64LE(iStrm, tempU64);
-		if(tempU64 > static_cast<uint64>(std::numeric_limits<Offtype>::max()))
-			{ AddReadNote(SNR_INSUFFICIENT_STREAM_OFFTYPE); return; }
-	}
-
-	const Offtype rawEndOfHdrData = iStrm.tellg() - m_posStart;
-
-	if (rawEndOfHdrData < 0 || static_cast<uint64>(rawEndOfHdrData) > std::numeric_limits<RposType>::max())
-		{ AddReadNote(SNR_INSUFFICIENT_RPOSTYPE); return; }
-
-	m_rposEndofHdrData = static_cast<RposType>(rawEndOfHdrData);
-	m_rposMapBegin = (GetFlag(RwfRwHasMap)) ? static_cast<RposType>(tempU64) : m_rposEndofHdrData;
-
-	if (GetFlag(RwfRwHasMap) == false)
-		m_posMapEnd = m_posStart + m_rposEndofHdrData;
-
-	SetFlag(RwfRHeaderIsRead, true);
-}
-
-
-void SsbRead::CacheMap()
-{
-	if(GetFlag(RwfRwHasMap) || m_nFixedEntrySize > 0)
-	{
-		iStrm.seekg(m_posStart + m_rposMapBegin);
-
-		if(iStrm.fail())
-			{ AddReadNote(SNR_BADSTREAM_AFTER_MAPHEADERSEEK); return; }
-
-		SSB_LOG(mpt::format(mpt::ustring(tstrReadingMap))(m_rposMapBegin));
-
-		mapData.resize(m_nReadEntrycount);
-		m_Idarray.reserve(m_nReadEntrycount * 4);
-
-		//Read map
-		for(NumType i = 0; i<m_nReadEntrycount; i++)
-		{
-			if(iStrm.fail())
-				{ AddReadNote(SNR_BADSTREAM_AT_MAP_READ); return; }
-
-			// Read ID.
-			uint16 nIdsize = m_nIdbytes;
-			if(nIdsize == IdSizeVariable) //Variablesize ID
-				mpt::IO::ReadAdaptiveInt16LE(iStrm, nIdsize);
-			const size_t nOldEnd = m_Idarray.size();
-			if (nIdsize > 0 && (Util::MaxValueOfType(nOldEnd) - nOldEnd >= nIdsize))
-			{
-				m_Idarray.resize(nOldEnd + nIdsize);
-				iStrm.read(&m_Idarray[nOldEnd], nIdsize);
-			}
-			mapData[i].nIdLength = nIdsize;
-			mapData[i].nIdpos = nOldEnd;
-
-			// Read position.
-			if(GetFlag(RwfRMapHasStartpos))
-			{
-				uint64 tempU64;
-				mpt::IO::ReadAdaptiveInt64LE(iStrm, tempU64);
-				if(tempU64 > static_cast<uint64>(std::numeric_limits<Offtype>::max()))
-					{ AddReadNote(SNR_INSUFFICIENT_STREAM_OFFTYPE); return; }
-				mapData[i].rposStart = static_cast<RposType>(tempU64);
-			}
-
-			// Read entry size.
-			if (m_nFixedEntrySize > 0)
-				mapData[i].nSize = m_nFixedEntrySize;
-			else if(GetFlag(RwfRMapHasSize)) // Map has datasize field.
-			{
-				uint64 tempU64;
-				mpt::IO::ReadAdaptiveInt64LE(iStrm, tempU64);
-				if(tempU64 > static_cast<uint64>(std::numeric_limits<Offtype>::max()))
-					{ AddReadNote(SNR_INSUFFICIENT_STREAM_OFFTYPE); return; }
-				mapData[i].nSize = static_cast<DataSize>(tempU64);
-			}
-
-			// If there's no entry startpos in map, count start pos from datasizes.
-			// Here readentry.rposStart is set to relative position from databegin.
-			if (mapData[i].nSize != invalidDatasize && GetFlag(RwfRMapHasStartpos) == false)
-				mapData[i].rposStart = (i > 0) ? mapData[i-1].rposStart + mapData[i-1].nSize : 0;
-
-			if(GetFlag(RwfRMapHasDesc)) //Map has entrydescriptions?
-			{
-				uint16 size = 0;
-				mpt::IO::ReadAdaptiveInt16LE(iStrm, size);
-				if(GetFlag(RwfRTwoBytesDescChar))
-					iStrm.ignore(size * 2);
-				else
-					iStrm.ignore(size);
-			}
-		}
-		m_posMapEnd = iStrm.tellg();
-		SSB_LOG(mpt::format(mpt::ustring(tstrEndOfMap))(m_posMapEnd - m_posStart));
-	}
-
-	SetFlag(RwfRMapCached, true);
-	m_posDataBegin = (m_rposMapBegin == m_rposEndofHdrData) ? m_posMapEnd : m_posStart + Postype(m_rposEndofHdrData);
-	iStrm.seekg(m_posDataBegin);
-
-	// If there are no positions in the map but there are entry sizes, rposStart will
-	// be relative to data start. Now that posDataBegin is known, make them relative to 
-	// startpos.
-	if (GetFlag(RwfRMapHasStartpos) == false && (GetFlag(RwfRMapHasSize) || m_nFixedEntrySize > 0))
-	{
-		const RposType offset = static_cast<RposType>(m_posDataBegin - m_posStart);
-		for(size_t i = 0; i < m_nReadEntrycount; i++)
-			mapData[i].rposStart += offset;
-	}
-}
-
-
-const ReadEntry* SsbRead::Find(const ID &id)
-{
-	iStrm.clear();
-	if (GetFlag(RwfRMapCached) == false)
-		CacheMap();
-	
-	if (m_nFixedEntrySize > 0 && GetFlag(RwfRMapHasStartpos) == false && GetFlag(RwfRMapHasSize) == false)
-		iStrm.seekg(m_posDataBegin + Postype(m_nFixedEntrySize * m_nCounter));
-
-	if (GetFlag(RwfRMapHasId) == true)
-	{
-		const size_t nEntries = mapData.size();
-		for(size_t i0 = 0; i0 < nEntries; i0++)
-		{
-			const size_t i = (i0 + m_nNextReadHint) % nEntries;
-			if(mapData[i].nIdpos < m_Idarray.size() && id == ID(&m_Idarray[mapData[i].nIdpos], mapData[i].nIdLength))
-			{
-				m_nNextReadHint = (i + 1) % nEntries;
-				if (mapData[i].rposStart != 0)
-					iStrm.seekg(m_posStart + Postype(mapData[i].rposStart));
-				return &mapData[i];
-			}
-		}
-	}
-	return nullptr;
-}
-
-
-void SsbWrite::FinishWrite()
-{
-	const Postype posDataEnd = oStrm.tellp();
-		
-	Postype posMapStart = oStrm.tellp();
-
-	SSB_LOG(mpt::format(mpt::ustring(tstrWritingMap))(posMapStart - m_posStart));
-
-	if (GetFlag(RwfRwHasMap)) //Write map
-	{
-		oStrm.write(m_MapStreamString.c_str(), m_MapStreamString.length());
-	}
-
-	const Postype posMapEnd = oStrm.tellp();
-	
-	// Write entry count.
-	oStrm.seekp(m_posEntrycount);
-
-	// Write a fixed size=2 Adaptive64LE because space for this value has already been reserved berforehand.
-	mpt::IO::WriteAdaptiveInt64LE(oStrm, m_nCounter, 2);
-
-	if (GetFlag(RwfRwHasMap))
-	{	// Write map start position.
-		oStrm.seekp(m_posMapPosField);
-		const uint64 rposMap = posMapStart - m_posStart;
-
-		// Write a fixed size=8 Adaptive64LE because space for this value has already been reserved berforehand.
-		mpt::IO::WriteAdaptiveInt64LE(oStrm, rposMap, 8);
-
-	}
-
-	// Seek to end.
-	oStrm.seekp(std::max(posMapEnd, posDataEnd)); 
-
-	SSB_LOG(mpt::format(mpt::ustring(tstrEndOfStream))(oStrm.tellp() - m_posStart));
-}
-
-} // namespace srlztn 
-
-
-OPENMPT_NAMESPACE_END

+ 0 - 553
libopenmpt.mod/openmpt/common/serialization_utils.h

@@ -1,553 +0,0 @@
-/*
- * serialization_utils.h
- * ---------------------
- * Purpose: Serializing data to and from MPTM files.
- * Notes  : (currently none)
- * Authors: OpenMPT Devs
- * The OpenMPT source code is released under the BSD license. Read LICENSE for more details.
- */
-
-
-#pragma once
-
-#include "BuildSettings.h"
-
-#include "../common/mptBaseTypes.h"
-#include "../common/mptIO.h"
-#include "../common/Endianness.h"
-
-#include <algorithm>
-#include <bitset>
-#include <ios>
-#include <iosfwd>
-#include <limits>
-#include <string>
-#include <vector>
-
-#include <istream>
-#include <ostream>
-
-#include <cstring>
-
-OPENMPT_NAMESPACE_BEGIN
-
-namespace srlztn //SeRiaLiZaTioN
-{
-
-typedef std::ios::off_type Offtype;
-typedef Offtype Postype;
-
-typedef uintptr_t	DataSize;	// Data size type.
-typedef uintptr_t	RposType;	// Relative position type.
-typedef uintptr_t	NumType;	// Entry count type.
-
-const DataSize invalidDatasize = DataSize(-1);
-
-enum 
-{
-	SNT_PROGRESS =		0x08000000, // = 1 << 27
-	SNT_FAILURE =		0x40000000, // = 1 << 30
-	SNT_NOTE =			0x20000000, // = 1 << 29
-	SNT_WARNING =		0x10000000, // = 1 << 28
-	SNT_NONE = 0,
-
-	SNRW_BADGIVEN_STREAM =								1	| SNT_FAILURE,
-
-	// Read failures.
-	SNR_BADSTREAM_AFTER_MAPHEADERSEEK =					2	| SNT_FAILURE,
-	SNR_STARTBYTE_MISMATCH =							3	| SNT_FAILURE,
-	SNR_BADSTREAM_AT_MAP_READ =							4	| SNT_FAILURE,
-	SNR_INSUFFICIENT_STREAM_OFFTYPE =					5	| SNT_FAILURE,
-	SNR_OBJECTCLASS_IDMISMATCH =						6	| SNT_FAILURE,
-	SNR_TOO_MANY_ENTRIES_TO_READ =						7	| SNT_FAILURE,
-	SNR_INSUFFICIENT_RPOSTYPE =							8	| SNT_FAILURE,
-
-	// Read notes and warnings.
-	SNR_ZEROENTRYCOUNT =								0x80	| SNT_NOTE, // 0x80 == 1 << 7
-	SNR_NO_ENTRYIDS_WITH_CUSTOMID_DEFINED =				0x100	| SNT_NOTE,
-	SNR_LOADING_OBJECT_WITH_LARGER_VERSION =			0x200	| SNT_NOTE,
-	
-	// Write failures.
-	SNW_INSUFFICIENT_FIXEDSIZE =						(0x10)	| SNT_FAILURE,
-	SNW_CHANGING_IDSIZE_WITH_FIXED_IDSIZESETTING =		(0x11)	| SNT_FAILURE,
-	SNW_DATASIZETYPE_OVERFLOW =							(0x13)	| SNT_FAILURE,
-	SNW_MAX_WRITE_COUNT_REACHED =						(0x14)	| SNT_FAILURE,
-	SNW_INSUFFICIENT_DATASIZETYPE =						(0x16)	| SNT_FAILURE
-};
-
-
-enum
-{
-	IdSizeVariable = uint16_max,
-	IdSizeMaxFixedSize = (uint8_max >> 1)
-};
-
-typedef int32 SsbStatus;
-
-
-struct ReadEntry
-{
-	ReadEntry() : nIdpos(0), rposStart(0), nSize(invalidDatasize), nIdLength(0) {}
-
-	uintptr_t nIdpos;	// Index of id start in ID array.
-	RposType rposStart;	// Entry start position.
-	DataSize nSize;		// Entry size.
-	uint16 nIdLength;	// Length of id.
-};
-
-
-enum Rwf
-{
-	RwfWMapStartPosEntry,	// Write. True to include data start pos entry to map.
-	RwfWMapSizeEntry,		// Write. True to include data size entry to map.
-	RwfWMapDescEntry,		// Write. True to include description entry to map.
-	RwfWVersionNum,			// Write. True to include version numeric.
-	RwfRMapCached,			// Read. True if map has been cached.
-	RwfRMapHasId,			// Read. True if map has IDs
-	RwfRMapHasStartpos,		// Read. True if map data start pos.
-	RwfRMapHasSize,			// Read. True if map has entry size.
-	RwfRMapHasDesc,			// Read. True if map has entry description.
-	RwfRTwoBytesDescChar,	// Read. True if map description characters are two bytes.
-	RwfRHeaderIsRead,		// Read. True when header is read.
-	RwfRwHasMap,			// Read/write. True if map exists.
-	RwfNumFlags
-};
-
-
-template<class T>
-inline void Binarywrite(std::ostream& oStrm, const T& data)
-{
-	mpt::IO::WriteIntLE(oStrm, data);
-}
-
-template<>
-inline void Binarywrite(std::ostream& oStrm, const float& data)
-{
-	IEEE754binary32LE tmp = IEEE754binary32LE(data);
-	mpt::IO::Write(oStrm, tmp);
-}
-
-template<>
-inline void Binarywrite(std::ostream& oStrm, const double& data)
-{
-	IEEE754binary64LE tmp = IEEE754binary64LE(data);
-	mpt::IO::Write(oStrm, tmp);
-}
-
-template <class T>
-inline void WriteItem(std::ostream& oStrm, const T& data)
-{
-	static_assert(std::is_trivial<T>::value == true, "");
-	Binarywrite(oStrm, data);
-}
-
-void WriteItemString(std::ostream& oStrm, const std::string &str);
-
-template <>
-inline void WriteItem<std::string>(std::ostream& oStrm, const std::string& str) {WriteItemString(oStrm, str);}
-
-
-template<class T>
-inline void Binaryread(std::istream& iStrm, T& data)
-{
-	mpt::IO::ReadIntLE(iStrm, data);
-}
-
-template<>
-inline void Binaryread(std::istream& iStrm, float& data)
-{
-	IEEE754binary32LE tmp = IEEE754binary32LE(0.0f);
-	mpt::IO::Read(iStrm, tmp);
-	data = tmp;
-}
-
-template<>
-inline void Binaryread(std::istream& iStrm, double& data)
-{
-	IEEE754binary64LE tmp = IEEE754binary64LE(0.0);
-	mpt::IO::Read(iStrm, tmp);
-	data = tmp;
-}
-
-//Read only given number of bytes to the beginning of data; data bytes are memset to 0 before reading.
-template <class T>
-inline void Binaryread(std::istream& iStrm, T& data, const Offtype bytecount)
-{
-	mpt::IO::ReadBinaryTruncatedLE(iStrm, data, static_cast<std::size_t>(bytecount));
-}
-
-template <>
-inline void Binaryread<float>(std::istream& iStrm, float& data, const Offtype bytecount)
-{
-	typedef IEEE754binary32LE T;
-	std::byte bytes[sizeof(T)];
-	std::memset(bytes, 0, sizeof(T));
-	mpt::IO::ReadRaw(iStrm, bytes, std::min(static_cast<std::size_t>(bytecount), sizeof(T)));
-	// There is not much we can sanely do for truncated floats,
-	// thus we ignore what we just read and return 0.
-	data = 0.0f;
-}
-
-template <>
-inline void Binaryread<double>(std::istream& iStrm, double& data, const Offtype bytecount)
-{
-	typedef IEEE754binary64LE T;
-	std::byte bytes[sizeof(T)];
-	std::memset(bytes, 0, sizeof(T));
-	mpt::IO::ReadRaw(iStrm, bytes, std::min(static_cast<std::size_t>(bytecount), sizeof(T)));
-	// There is not much we can sanely do for truncated floats,
-	// thus we ignore what we just read and return 0.
-	data = 0.0;
-}
-
-
-template <class T>
-inline void ReadItem(std::istream& iStrm, T& data, const DataSize nSize)
-{
-	static_assert(std::is_trivial<T>::value == true, "");
-	if (nSize == sizeof(T) || nSize == invalidDatasize)
-		Binaryread(iStrm, data);
-	else
-		Binaryread(iStrm, data, nSize);
-}
-
-void ReadItemString(std::istream& iStrm, std::string& str, const DataSize);
-
-template <>
-inline void ReadItem<std::string>(std::istream& iStrm, std::string& str, const DataSize nSize)
-{
-	ReadItemString(iStrm, str, nSize);
-}
-
-
-
-class ID
-{
-private:
-	std::string m_ID; // NOTE: can contain null characters ('\0')
-public:
-	ID() { }
-	ID(const std::string &id) : m_ID(id) { }
-	ID(const char *beg, const char *end) : m_ID(beg, end) { }
-	ID(const char *id) : m_ID(id?id:"") { }
-	ID(const char * str, std::size_t len) : m_ID(str, str + len) { }
-	template <typename T>
-	static ID FromInt(const T &val)
-	{
-		static_assert(std::numeric_limits<T>::is_integer);
-		typename mpt::make_le<T>::type valle;
-		valle = val;
-		return ID(std::string(mpt::byte_cast<const char*>(mpt::as_raw_memory(valle).data()), mpt::byte_cast<const char*>(mpt::as_raw_memory(valle).data() + sizeof(valle))));
-	}
-	bool IsPrintable() const;
-	mpt::ustring AsString() const;
-	const char *GetBytes() const { return m_ID.c_str(); }
-	std::size_t GetSize() const { return m_ID.length(); }
-	bool operator == (const ID &other) const { return m_ID == other.m_ID; }
-	bool operator != (const ID &other) const { return m_ID != other.m_ID; }
-};
-
-
-
-class Ssb
-{
-
-protected:
-
-	Ssb();
-
-public:
-
-	SsbStatus GetStatus() const
-	{
-		return m_Status;
-	}
-
-protected:
-
-	// When writing, returns the number of entries written.
-	// When reading, returns the number of entries read not including unrecognized entries.
-	NumType GetCounter() const {return m_nCounter;}
-
-	void SetFlag(Rwf flag, bool val) {m_Flags.set(flag, val);}
-	bool GetFlag(Rwf flag) const {return m_Flags[flag];}
-
-protected:
-
-	SsbStatus m_Status;
-
-	uint32 m_nFixedEntrySize;			// Read/write: If > 0, data entries have given fixed size.
-
-	Postype m_posStart;					// Read/write: Stream position at the beginning of object.
-
-	uint16 m_nIdbytes;					// Read/Write: Tells map ID entry size in bytes. If size is variable, value is IdSizeVariable.
-	NumType m_nCounter;					// Read/write: Keeps count of entries written/read.
-
-	std::bitset<RwfNumFlags> m_Flags;	// Read/write: Various flags.
-
-protected:
-
-	enum : uint8 { s_DefaultFlagbyte = 0 };
-	static const char s_EntryID[3];
-
-};
-
-
-
-class SsbRead
-	: public Ssb
-{
-
-public:
-
-	enum ReadRv // Read return value.
-	{
-		EntryRead,
-		EntryNotFound
-	};
-	enum IdMatchStatus
-	{
-		IdMatch, IdMismatch
-	};
-	typedef std::vector<ReadEntry>::const_iterator ReadIterator;
-
-	SsbRead(std::istream& iStrm);
-
-	// Call this to begin reading: must be called before other read functions.
-	void BeginRead(const ID &id, const uint64& nVersion);
-
-	// After calling BeginRead(), this returns number of entries in the file.
-	NumType GetNumEntries() const {return m_nReadEntrycount;}
-
-	// Returns read iterator to the beginning of entries.
-	// The behaviour of read iterators is undefined if map doesn't
-	// contain entry ids or data begin positions.
-	ReadIterator GetReadBegin();
-
-	// Returns read iterator to the end(one past last) of entries.
-	ReadIterator GetReadEnd();
-
-	// Compares given id with read entry id 
-	IdMatchStatus CompareId(const ReadIterator& iter, const ID &id);
-
-	uint64 GetReadVersion() {return m_nReadVersion;}
-
-	// Read item using default read implementation.
-	template <class T>
-	ReadRv ReadItem(T& obj, const ID &id) {return ReadItem(obj, id, srlztn::ReadItem<T>);}
-
-	// Read item using given function.
-	template <class T, class FuncObj>
-	ReadRv ReadItem(T& obj, const ID &id, FuncObj);
-
-	// Read item using read iterator.
-	template <class T>
-	ReadRv ReadIterItem(const ReadIterator& iter, T& obj) {return ReadIterItem(iter, obj, srlztn::ReadItem<T>);}
-	template <class T, class FuncObj>
-	ReadRv ReadIterItem(const ReadIterator& iter, T& obj, FuncObj func);
-
-private:
-
-	// Reads map to cache.
-	void CacheMap();
-
-	// Searches for entry with given ID. If found, returns pointer to corresponding entry, else
-	// returns nullptr.
-	const ReadEntry* Find(const ID &id);
-
-	// Called after reading an object.
-	ReadRv OnReadEntry(const ReadEntry* pE, const ID &id, const Postype& posReadBegin);
-
-	void AddReadNote(const SsbStatus s);
-
-	// Called after reading entry. pRe is a pointer to associated map entry if exists.
-	void AddReadNote(const ReadEntry* const pRe, const NumType nNum);
-
-	void ResetReadstatus();
-
-private:
-
-	//  mapData is a cache that facilitates faster access to the stored data
-	// without having to reparse on every access.
-	//  Iterator invalidation in CacheMap() is not a problem because every code
-	// path that ever returns an iterator into mapData does CacheMap exactly once
-	// beforehand. Following calls use this already cached map. As the data is
-	// immutable when reading, there is no need to ever invalidate the cache and
-	// redo CacheMap().
-
-	std::istream& iStrm;
-
-	std::vector<char> m_Idarray;		// Read: Holds entry ids.
-
-	std::vector<ReadEntry> mapData;		// Read: Contains map information.
-	uint64 m_nReadVersion;				// Read: Version is placed here when reading.
-	RposType m_rposMapBegin;			// Read: If map exists, rpos of map begin, else m_rposEndofHdrData.
-	Postype m_posMapEnd;				// Read: If map exists, map end position, else pos of end of hdrData.
-	Postype m_posDataBegin;				// Read: Data begin position.
-	RposType m_rposEndofHdrData;		// Read: rpos of end of header data.
-	NumType m_nReadEntrycount;			// Read: Number of entries.
-
-	NumType m_nNextReadHint;			// Read: Hint where to start looking for the next read entry.
-
-};
-
-
-
-class SsbWrite
-	: public Ssb
-{
-
-public:
-
-	SsbWrite(std::ostream& oStrm);
-
-	// Write header
-	void BeginWrite(const ID &id, const uint64& nVersion);
-
-	// Write item using default write implementation.
-	template <class T>
-	void WriteItem(const T& obj, const ID &id) {WriteItem(obj, id, &srlztn::WriteItem<T>);}
-
-	// Write item using given function.
-	template <class T, class FuncObj>
-	void WriteItem(const T& obj, const ID &id, FuncObj);
-
-	// Writes mapping.
-	void FinishWrite();
-
-private:
-
-	// Called after writing an item.
-	void OnWroteItem(const ID &id, const Postype& posBeforeWrite);
-
-	void AddWriteNote(const SsbStatus s);
-	void AddWriteNote(const ID &id,
-		const NumType nEntryNum,
-		const DataSize nBytecount,
-		const RposType rposStart);
-
-	// Writes mapping item to mapstream.
-	void WriteMapItem(const ID &id,
-		const RposType& rposDataStart,
-		const DataSize& nDatasize,
-		const char* pszDesc);
-
-	void ResetWritestatus() {m_Status = SNT_NONE;}
-
-	void IncrementWriteCounter();
-
-private:
-
-	std::ostream& oStrm;
-
-	Postype m_posEntrycount;			// Write: Pos of entrycount field. 
-	Postype m_posMapPosField;			// Write: Pos of map position field.
-	std::string m_MapStreamString;				// Write: Map stream string.
-
-};
-
-
-template <class T, class FuncObj>
-void SsbWrite::WriteItem(const T& obj, const ID &id, FuncObj Func)
-{
-	const Postype pos = oStrm.tellp();
-	Func(oStrm, obj);
-	OnWroteItem(id, pos);
-}
-
-template <class T, class FuncObj>
-SsbRead::ReadRv SsbRead::ReadItem(T& obj, const ID &id, FuncObj Func)
-{
-	const ReadEntry* pE = Find(id);
-	const Postype pos = iStrm.tellg();
-	if (pE != nullptr || GetFlag(RwfRMapHasId) == false)
-		Func(iStrm, obj, (pE) ? (pE->nSize) : invalidDatasize);
-	return OnReadEntry(pE, id, pos);
-}
-
-
-template <class T, class FuncObj>
-SsbRead::ReadRv SsbRead::ReadIterItem(const ReadIterator& iter, T& obj, FuncObj func)
-{
-	iStrm.clear();
-	if (iter->rposStart != 0)
-		iStrm.seekg(m_posStart + Postype(iter->rposStart));
-	const Postype pos = iStrm.tellg();
-	func(iStrm, obj, iter->nSize);
-	return OnReadEntry(&(*iter), ID(&m_Idarray[iter->nIdpos], iter->nIdLength), pos);
-}
-
-
-inline SsbRead::IdMatchStatus SsbRead::CompareId(const ReadIterator& iter, const ID &id)
-{
-	if(iter->nIdpos >= m_Idarray.size()) return IdMismatch;
-	return (id == ID(&m_Idarray[iter->nIdpos], iter->nIdLength)) ? IdMatch : IdMismatch;
-}
-
-
-inline SsbRead::ReadIterator SsbRead::GetReadBegin()
-{
-	MPT_ASSERT(GetFlag(RwfRMapHasId) && (GetFlag(RwfRMapHasStartpos) || GetFlag(RwfRMapHasSize) || m_nFixedEntrySize > 0));
-	if (GetFlag(RwfRMapCached) == false)
-		CacheMap();
-	return mapData.begin();
-}
-
-
-inline SsbRead::ReadIterator SsbRead::GetReadEnd()
-{
-	if (GetFlag(RwfRMapCached) == false)
-		CacheMap();
-	return mapData.end();
-}
-
-
-template <class T>
-struct VectorWriter
-{
-	VectorWriter(size_t nCount) : m_nCount(nCount) {}
-	void operator()(std::ostream &oStrm, const std::vector<T> &vec)
-	{
-		for(size_t i = 0; i < m_nCount; i++)
-		{
-			Binarywrite(oStrm, vec[i]);
-		}
-	}
-	size_t m_nCount;
-};
-
-template <class T>
-struct VectorReader
-{
-	VectorReader(size_t nCount) : m_nCount(nCount) {}
-	void operator()(std::istream& iStrm, std::vector<T> &vec, const size_t)
-	{
-		vec.resize(m_nCount);
-		for(std::size_t i = 0; i < m_nCount; ++i)
-		{
-			Binaryread(iStrm, vec[i]);
-		}
-	}
-	size_t m_nCount;
-};
-
-template <class T>
-struct ArrayReader
-{
-	ArrayReader(size_t nCount) : m_nCount(nCount) {}
-	void operator()(std::istream& iStrm, T* pData, const size_t)
-	{
-		for(std::size_t i=0; i<m_nCount; ++i)
-		{
-			Binaryread(iStrm, pData[i]);
-		}
-	} 
-	size_t m_nCount;
-};
-
-
-
-} //namespace srlztn.
-
-
-OPENMPT_NAMESPACE_END

+ 0 - 145
libopenmpt.mod/openmpt/common/stdafx.h

@@ -1,145 +0,0 @@
-/*
- * StdAfx.h
- * --------
- * Purpose: Include file for standard system include files, or project specific include files that are used frequently, but are changed infrequently. Also includes the global build settings from BuildSettings.h.
- * Notes  : (currently none)
- * Authors: Olivier Lapicque
- *          OpenMPT Devs
- * The OpenMPT source code is released under the BSD license. Read LICENSE for more details.
- */
-
-
-#pragma once
-
-
-// has to be first
-#include "BuildSettings.h"
-
-
-#if defined(MODPLUG_TRACKER)
-
-#if MPT_OS_WINDOWS
-
-#if !defined(MPT_BUILD_WINESUPPORT)
-
-// cppcheck-suppress missingInclude
-#include <afx.h>            // MFC core
-// cppcheck-suppress missingInclude
-#include <afxwin.h>         // MFC standard components
-// cppcheck-suppress missingInclude
-#include <afxext.h>         // MFC extensions
-// cppcheck-suppress missingInclude
-#include <afxcmn.h>         // MFC support for Windows Common Controls
-// cppcheck-suppress missingInclude
-#include <afxcview.h>
-// cppcheck-suppress missingInclude
-#include <afxdlgs.h>
-#ifdef MPT_MFC_FULL
-// cppcheck-suppress missingInclude
-#include <afxlistctrl.h>
-#endif // MPT_MFC_FULL
-// cppcheck-suppress missingInclude
-#include <afxole.h>
-
-#endif // !MPT_BUILD_WINESUPPORT
-
-#include <windows.h>
-#include <windowsx.h>
-#include <shlwapi.h>
-#include <mmsystem.h>
-
-#endif // MPT_OS_WINDOWS
-
-#endif // MODPLUG_TRACKER
-
-
-#if MPT_COMPILER_MSVC
-#include <intrin.h>
-#endif
-
-
-// this will be available everywhere
-
-#include "../common/mptBaseMacros.h"
-// <array>
-// <iterator>
-// <type_traits>
-// <cstddef>
-// <cstdint>
-
-#include "../common/mptBaseTypes.h"
-// "mptBaseMacros.h"
-// <array>
-// <limits>
-// <type_traits>
-// <cstdint>
-
-#include "../common/mptAssert.h"
-// "mptBaseMacros.h"
-
-#include "../common/mptBaseUtils.h"
-// <algorithm>
-// <bit>
-// <limits>
-// <numeric>
-// <utility>
-
-#include "../common/mptException.h"
-// <exception>
-// <new>
-// <afx.h>
-
-#include "../common/mptSpan.h"
-// "mptBaseTypes.h"
-// <array>
-// <iterator>
-
-#include "../common/mptMemory.h"
-// "mptAssert.h"
-// "mptBaseTypes.h"
-// "mptSpan.h"
-// <utility>
-// <type_traits>
-// <cstring>
-
-#include "../common/mptAlloc.h"
-// "mptBaseMacros.h"
-// "mptMemory.h"
-// "mptSpan.h"
-// <array>
-// <memory>
-// <new>
-// <vector>
-
-#include "../common/mptString.h"
-// <algorithm>
-// <limits>
-// <string>
-// <type_traits>
-// <cstring>
-
-#include "../common/mptStringBuffer.h"
-
-#include "../common/mptExceptionText.h"
-// "mptException.h"
-// "mptString.h"
-// <exception>
-
-#include "../common/mptStringFormat.h"
-
-#include "../common/mptPathString.h"
-
-#include "../common/Logging.h"
-// <atomic>
-
-#include "../common/misc_util.h"
-
-// for std::abs
-#include <cstdlib>
-#include <stdlib.h>
-#include <cmath>
-#include <math.h>
-
-
-//{{AFX_INSERT_LOCATION}}
-// Microsoft Developer Studio will insert additional declarations immediately before the previous line.

+ 0 - 808
libopenmpt.mod/openmpt/common/version.cpp

@@ -1,808 +0,0 @@
-/*
- * version.cpp
- * -----------
- * Purpose: OpenMPT version handling.
- * Notes  : (currently none)
- * Authors: OpenMPT Devs
- * The OpenMPT source code is released under the BSD license. Read LICENSE for more details.
- */
-
-#include "stdafx.h"
-#include "version.h"
-
-#include "mptString.h"
-#include "mptStringFormat.h"
-#include "mptStringParse.h" 
-
-#include "versionNumber.h"
-#include "svn_version.h"
-
-
-
-OPENMPT_NAMESPACE_BEGIN
-
-
-
-static_assert((MPT_VERSION_CURRENT.GetRawVersion() & 0xffffu) != 0x0000u, "Version numbers ending in .00.00 shall never exist again, as they make interpreting the version number ambiguous for file formats which can only store the two major parts of the version number (e.g. IT and S3M).");
-
-
-
-Version Version::Current() noexcept
-{
-	return MPT_VERSION_CURRENT;
-}
-
-mpt::ustring Version::GetOpenMPTVersionString() const
-{
-	return U_("OpenMPT ") + ToUString();
-}
-
-Version Version::Parse(const mpt::ustring &s)
-{
-	uint32 result = 0;
-	std::vector<mpt::ustring> numbers = mpt::String::Split<mpt::ustring>(s, U_("."));
-	for (std::size_t i = 0; i < numbers.size() && i < 4; ++i)
-	{
-		result |= (mpt::String::Parse::Hex<unsigned int>(numbers[i]) & 0xff) << ((3 - i) * 8);
-	}
-	return Version(result);
-}
-
-mpt::ustring Version::ToUString() const
-{
-	uint32 v = m_Version;
-	if(v == 0)
-	{
-		// Unknown version
-		return U_("Unknown");
-	} else if((v & 0xFFFF) == 0)
-	{
-		// Only parts of the version number are known (e.g. when reading the version from the IT or S3M file header)
-		return mpt::format(U_("%1.%2"))(mpt::ufmt::HEX((v >> 24) & 0xFF), mpt::ufmt::HEX0<2>((v >> 16) & 0xFF));
-	} else
-	{
-		// Full version info available
-		return mpt::format(U_("%1.%2.%3.%4"))(mpt::ufmt::HEX((v >> 24) & 0xFF), mpt::ufmt::HEX0<2>((v >> 16) & 0xFF), mpt::ufmt::HEX0<2>((v >> 8) & 0xFF), mpt::ufmt::HEX0<2>((v) & 0xFF));
-	}
-}
-
-Version Version::WithoutTestNumber() const noexcept
-{
-	return Version(m_Version & 0xFFFFFF00u);
-}
-
-Version Version::WithoutPatchOrTestNumbers() const noexcept
-{
-	return Version(m_Version & 0xFFFF0000u);
-}
-
-bool Version::IsTestVersion() const noexcept
-{
-	return (
-			// Legacy
-			(*this > MPT_V("1.17.02.54") && *this < MPT_V("1.18.02.00") && *this != MPT_V("1.18.00.00"))
-		||
-			// Test builds have non-zero VER_MINORMINOR
-			(*this > MPT_V("1.18.02.00") && ((m_Version & 0xFFFFFF00u) != m_Version))
-		);
-}
-
-
-
-namespace Source {
-
-static mpt::ustring GetUrl()
-{
-	#ifdef OPENMPT_VERSION_URL
-		return mpt::ToUnicode(mpt::Charset::ASCII, OPENMPT_VERSION_URL);
-	#else
-		return mpt::ustring();
-	#endif
-}
-
-static int GetRevision()
-{
-	#if defined(OPENMPT_VERSION_REVISION)
-		return OPENMPT_VERSION_REVISION;
-	#elif defined(OPENMPT_VERSION_SVNVERSION)
-		std::string svnversion = OPENMPT_VERSION_SVNVERSION;
-		if(svnversion.length() == 0)
-		{
-			return 0;
-		}
-		if(svnversion.find(":") != std::string::npos)
-		{
-			svnversion = svnversion.substr(svnversion.find(":") + 1);
-		}
-		if(svnversion.find("-") != std::string::npos)
-		{
-			svnversion = svnversion.substr(svnversion.find("-") + 1);
-		}
-		if(svnversion.find("M") != std::string::npos)
-		{
-			svnversion = svnversion.substr(0, svnversion.find("M"));
-		}
-		if(svnversion.find("S") != std::string::npos)
-		{
-			svnversion = svnversion.substr(0, svnversion.find("S"));
-		}
-		if(svnversion.find("P") != std::string::npos)
-		{
-			svnversion = svnversion.substr(0, svnversion.find("P"));
-		}
-		return ConvertStrTo<int>(svnversion);
-	#else
-		#if MPT_COMPILER_MSVC
-			#pragma message("SVN revision unknown. Please check your build system.")
-		#elif MPT_COMPILER_GCC || MPT_COMPILER_CLANG
-			#warning "SVN revision unknown. Please check your build system."
-		#else
-			// There is no portable way to display a warning.
-			// Try to provoke a warning with an unused variable.
-			int SVN_revision_unknown__Please_check_your_build_system;
-		#endif
-		return 0;
-	#endif
-}
-
-static bool IsDirty()
-{
-	#if defined(OPENMPT_VERSION_DIRTY)
-		return OPENMPT_VERSION_DIRTY != 0;
-	#elif defined(OPENMPT_VERSION_SVNVERSION)
-		std::string svnversion = OPENMPT_VERSION_SVNVERSION;
-		if(svnversion.length() == 0)
-		{
-			return false;
-		}
-		if(svnversion.find("M") != std::string::npos)
-		{
-			return true;
-		}
-		return false;
-	#else
-		return false;
-	#endif
-}
-
-static bool HasMixedRevisions()
-{
-	#if defined(OPENMPT_VERSION_MIXEDREVISIONS)
-		return OPENMPT_VERSION_MIXEDREVISIONS != 0;
-	#elif defined(OPENMPT_VERSION_SVNVERSION)
-		std::string svnversion = OPENMPT_VERSION_SVNVERSION;
-		if(svnversion.length() == 0)
-		{
-			return false;
-		}
-		if(svnversion.find(":") != std::string::npos)
-		{
-			return true;
-		}
-		if(svnversion.find("-") != std::string::npos)
-		{
-			return true;
-		}
-		if(svnversion.find("S") != std::string::npos)
-		{
-			return true;
-		}
-		if(svnversion.find("P") != std::string::npos)
-		{
-			return true;
-		}
-		return false;
-	#else
-		return false;
-	#endif
-}
-
-static bool IsPackage()
-{
-	#if defined(OPENMPT_VERSION_IS_PACKAGE)
-		return OPENMPT_VERSION_IS_PACKAGE != 0;
-	#else
-		return false;
-	#endif
-}
-
-static mpt::ustring GetSourceDate()
-{
-	#if defined(OPENMPT_VERSION_DATE)
-		return mpt::ToUnicode(mpt::Charset::ASCII, OPENMPT_VERSION_DATE);
-	#else
-		return mpt::ustring();
-	#endif
-}
-
-} // namespace Source
-
-SourceInfo::SourceInfo()
-	: m_Url(Source::GetUrl())
-	, m_Revision(Source::GetRevision())
-	, m_IsDirty(Source::IsDirty())
-	, m_HasMixedRevisions(Source::HasMixedRevisions())
-	, m_IsPackage(Source::IsPackage())
-	, m_Date(Source::GetSourceDate())
-{
-}
-
-mpt::ustring SourceInfo::GetUrlWithRevision() const
-{
-	if(m_Url.empty() || (m_Revision == 0))
-	{
-		return mpt::ustring();
-	}
-	return m_Url + UL_("@") + mpt::ufmt::val(m_Revision);
-}
-
-mpt::ustring SourceInfo::GetStateString() const
-{
-	mpt::ustring retval;
-	if(m_IsDirty)
-	{
-		retval += UL_("+dirty");
-	}
-	if(m_HasMixedRevisions)
-	{
-		retval += UL_("+mixed");
-	}
-	if(retval.empty())
-	{
-		retval += UL_("clean");
-	}
-	if(m_IsPackage)
-	{
-		retval += UL_("-pkg");
-	}
-	return retval;
-}
-
-SourceInfo SourceInfo::Current()
-{
-	return SourceInfo();
-}
-
-
-
-namespace Build {
-
-bool IsReleasedBuild()
-{
-	return !(Version::Current().IsTestVersion() || IsDebugBuild() || Source::IsDirty() || Source::HasMixedRevisions());
-}
-
-bool IsDebugBuild()
-{
-	#if defined(MPT_BUILD_DEBUG) || defined(DEBUG) || defined(_DEBUG)
-		return true;
-	#else
-		return false;
-	#endif
-}
-
-mpt::ustring GetBuildDateString()
-{
-	mpt::ustring result;
-	#ifdef MODPLUG_TRACKER
-		#if defined(OPENMPT_BUILD_DATE)
-			result = mpt::ToUnicode(mpt::Charset::ASCII, OPENMPT_BUILD_DATE );
-		#else
-			result = mpt::ToUnicode(mpt::Charset::ASCII, __DATE__ " " __TIME__ );
-		#endif
-	#else // !MODPLUG_TRACKER
-		result = SourceInfo::Current().Date();
-	#endif // MODPLUG_TRACKER
-	return result;
-}
-
-static mpt::ustring GetBuildFlagsString()
-{
-	mpt::ustring retval;
-	#ifdef MODPLUG_TRACKER
-		if(Version::Current().IsTestVersion())
-		{
-			retval += UL_(" TEST");
-		}
-	#endif // MODPLUG_TRACKER
-	if(IsDebugBuild())
-	{
-		retval += UL_(" DEBUG");
-	}
-	return retval;
-}
-
-mpt::ustring GetBuildFeaturesString()
-{
-	mpt::ustring retval;
-	#ifdef LIBOPENMPT_BUILD
-		retval = UL_("")
-		#if defined(MPT_WITH_ZLIB)
-			UL_(" +ZLIB")
-		#endif
-		#if defined(MPT_WITH_MINIZ)
-			UL_(" +MINIZ")
-		#endif
-		#if !defined(MPT_WITH_ZLIB) && !defined(MPT_WITH_MINIZ)
-			UL_(" -INFLATE")
-		#endif
-		#if defined(MPT_WITH_MPG123)
-			UL_(" +MPG123")
-		#endif
-		#if defined(MPT_WITH_MINIMP3)
-			UL_(" +MINIMP3")
-		#endif
-		#if defined(MPT_WITH_MEDIAFOUNDATION)
-			UL_(" +MF")
-		#endif
-		#if !defined(MPT_WITH_MPG123) && !defined(MPT_WITH_MINIMP3) && !defined(MPT_WITH_MEDIAFOUNDATION)
-			UL_(" -MP3")
-		#endif
-		#if defined(MPT_WITH_OGG) && defined(MPT_WITH_VORBIS) && defined(MPT_WITH_VORBISFILE)
-			UL_(" +VORBIS")
-		#endif
-		#if defined(MPT_WITH_STBVORBIS)
-			UL_(" +STBVORBIS")
-		#endif
-		#if !(defined(MPT_WITH_OGG) && defined(MPT_WITH_VORBIS) && defined(MPT_WITH_VORBISFILE)) && !defined(MPT_WITH_STBVORBIS)
-			UL_(" -VORBIS")
-		#endif
-		#if !defined(NO_PLUGINS)
-			UL_(" +PLUGINS")
-		#else
-			UL_(" -PLUGINS")
-		#endif
-		#if defined(MPT_WITH_DMO)
-			UL_(" +DMO")
-		#endif
-		;
-	#endif
-	#ifdef MODPLUG_TRACKER
-		if constexpr(mpt::arch_bits == 64)
-		{
-			if (true
-				&& (mpt::Windows::Version::GetMinimumKernelLevel() <= mpt::Windows::Version::WinXP64)
-				&& (mpt::Windows::Version::GetMinimumAPILevel() <= mpt::Windows::Version::WinXP64)
-			) {
-				retval += UL_(" WIN64OLD");
-			}
-		} else if constexpr(mpt::arch_bits == 32)
-		{
-			if (true
-				&& (mpt::Windows::Version::GetMinimumKernelLevel() <= mpt::Windows::Version::WinXP)
-				&& (mpt::Windows::Version::GetMinimumAPILevel() <= mpt::Windows::Version::WinXP)
-			) {
-				retval += UL_(" WIN32OLD");
-			}
-		}
-		retval += UL_("")
-		#if defined(UNICODE)
-			UL_(" UNICODE")
-		#else
-			UL_(" ANSI")
-		#endif
-		#ifdef NO_VST
-			UL_(" NO_VST")
-		#endif
-		#ifndef MPT_WITH_DMO
-			UL_(" NO_DMO")
-		#endif
-		#ifdef NO_PLUGINS
-			UL_(" NO_PLUGINS")
-		#endif
-		#ifndef MPT_WITH_ASIO
-			UL_(" NO_ASIO")
-		#endif
-			;
-	#endif
-	return retval;
-}
-
-mpt::ustring GetBuildCompilerString()
-{
-	mpt::ustring retval;
-	#if MPT_COMPILER_GENERIC
-		retval += U_("Generic C++11 Compiler");
-	#elif MPT_COMPILER_MSVC
-		#if defined(_MSC_FULL_VER) && defined(_MSC_BUILD) && (_MSC_BUILD > 0)
-			retval += mpt::format(U_("Microsoft Compiler %1.%2.%3.%4"))
-				( _MSC_FULL_VER / 10000000
-				, mpt::ufmt::dec0<2>((_MSC_FULL_VER / 100000) % 100)
-				, mpt::ufmt::dec0<5>(_MSC_FULL_VER % 100000)
-				, mpt::ufmt::dec0<2>(_MSC_BUILD)
-				);
-		#elif defined(_MSC_FULL_VER)
-			retval += mpt::format(U_("Microsoft Compiler %1.%2.%3"))
-				( _MSC_FULL_VER / 10000000
-				, mpt::ufmt::dec0<2>((_MSC_FULL_VER / 100000) % 100)
-				, mpt::ufmt::dec0<5>(_MSC_FULL_VER % 100000)
-				);
-		#else
-			retval += mpt::format(U_("Microsoft Compiler %1.%2"))(MPT_COMPILER_MSVC_VERSION / 100, MPT_COMPILER_MSVC_VERSION % 100);
-		#endif
-	#elif MPT_COMPILER_GCC
-		retval += mpt::format(U_("GNU Compiler Collection %1.%2.%3"))(MPT_COMPILER_GCC_VERSION / 10000, (MPT_COMPILER_GCC_VERSION / 100) % 100, MPT_COMPILER_GCC_VERSION % 100);
-	#elif MPT_COMPILER_CLANG
-		retval += mpt::format(U_("Clang %1.%2.%3"))(MPT_COMPILER_CLANG_VERSION / 10000, (MPT_COMPILER_CLANG_VERSION / 100) % 100, MPT_COMPILER_CLANG_VERSION % 100);
-	#else
-		retval += U_("unknown");
-	#endif
-	return retval;
-}
-
-static mpt::ustring GetRevisionString()
-{
-	mpt::ustring result;
-	if(Source::GetRevision() == 0)
-	{
-		return result;
-	}
-	result = U_("-r") + mpt::ufmt::val(Source::GetRevision());
-	if(Source::HasMixedRevisions())
-	{
-		result += UL_("!");
-	}
-	if(Source::IsDirty())
-	{
-		result += UL_("+");
-	}
-	if(Source::IsPackage())
-	{
-		result += UL_("p");
-	}
-	return result;
-}
-
-mpt::ustring GetVersionString(FlagSet<Build::Strings> strings)
-{
-	std::vector<mpt::ustring> result;
-	if(strings[StringVersion])
-	{
-		result.push_back(mpt::ufmt::val(Version::Current()));
-	}
-	if(strings[StringRevision])
-	{
-		if(!IsReleasedBuild())
-		{
-			result.push_back(GetRevisionString());
-		}
-	}
-	if(strings[StringBitness])
-	{
-		result.push_back(mpt::format(U_(" %1 bit"))(mpt::arch_bits));
-	}
-	if(strings[StringSourceInfo])
-	{
-		const SourceInfo sourceInfo = SourceInfo::Current();
-		if(!sourceInfo.GetUrlWithRevision().empty())
-		{
-			result.push_back(mpt::format(U_(" %1"))(sourceInfo.GetUrlWithRevision()));
-		}
-		if(!sourceInfo.Date().empty())
-		{
-			result.push_back(mpt::format(U_(" (%1)"))(sourceInfo.Date()));
-		}
-		if(!sourceInfo.GetStateString().empty())
-		{
-			result.push_back(mpt::format(U_(" %1"))(sourceInfo.GetStateString()));
-		}
-	}
-	if(strings[StringBuildFlags])
-	{
-		if(!IsReleasedBuild())
-		{
-			result.push_back(GetBuildFlagsString());
-		}
-	}
-	if(strings[StringBuildFeatures])
-	{
-		result.push_back(GetBuildFeaturesString());
-	}
-	return mpt::String::Trim(mpt::String::Combine<mpt::ustring>(result, U_("")));
-}
-
-mpt::ustring GetVersionStringPure()
-{
-	FlagSet<Build::Strings> strings;
-	strings |= Build::StringVersion;
-	strings |= Build::StringRevision;
-	#ifdef MODPLUG_TRACKER
-		strings |= Build::StringBitness;
-	#endif
-	return GetVersionString(strings);
-}
-
-mpt::ustring GetVersionStringSimple()
-{
-	FlagSet<Build::Strings> strings;
-	strings |= Build::StringVersion;
-	strings |= Build::StringRevision;
-	strings |= Build::StringBuildFlags;
-	return GetVersionString(strings);
-}
-
-mpt::ustring GetVersionStringExtended()
-{
-	FlagSet<Build::Strings> strings;
-	strings |= Build::StringVersion;
-	strings |= Build::StringRevision;
-	#ifdef MODPLUG_TRACKER
-		strings |= Build::StringBitness;
-	#endif
-	#ifndef MODPLUG_TRACKER
-		strings |= Build::StringSourceInfo;
-	#endif
-	strings |= Build::StringBuildFlags;
-	#ifdef MODPLUG_TRACKER
-		strings |= Build::StringBuildFeatures;
-	#endif
-	return GetVersionString(strings);
-}
-
-mpt::ustring GetURL(Build::Url key)
-{
-	mpt::ustring result;
-	switch(key)
-	{
-		case Url::Website:
-			#ifdef LIBOPENMPT_BUILD
-				result = U_("https://lib.openmpt.org/");
-			#else
-				result = U_("https://openmpt.org/");
-			#endif
-			break;
-		case Url::Download:
-			#ifdef MODPLUG_TRACKER
-				result = IsReleasedBuild() ? U_("https://openmpt.org/download") : U_("https://builds.openmpt.org/builds/");
-			#else
-				result = U_("https://lib.openmpt.org/libopenmpt/download/");
-			#endif
-			break;
-		case Url::Forum:
-			result = U_("https://forum.openmpt.org/");
-			break;
-		case Url::Bugtracker:
-			result = U_("https://bugs.openmpt.org/");
-			break;
-		case Url::Updates:
-			result = U_("https://openmpt.org/download");
-			break;
-		case Url::TopPicks:
-			result = U_("https://openmpt.org/top_picks");
-			break;
-	}
-	return result;
-}
-
-mpt::ustring GetFullCreditsString()
-{
-	return mpt::ToUnicode(mpt::Charset::UTF8,
-#ifdef MODPLUG_TRACKER
-		"OpenMPT / ModPlug Tracker\n"
-#else
-		"libopenmpt (based on OpenMPT / ModPlug Tracker)\n"
-#endif
-		"\n"
-		"Copyright \xC2\xA9 2004-2019 Contributors\n"
-		"Copyright \xC2\xA9 1997-2003 Olivier Lapicque\n"
-		"\n"
-		"Contributors:\n"
-		"Johannes Schultz (2008-2019)\n"
-		"J\xC3\xB6rn Heusipp (2012-2019)\n"
-		"Ahti Lepp\xC3\xA4nen (2005-2011)\n"
-		"Robin Fernandes (2004-2007)\n"
-		"Sergiy Pylypenko (2007)\n"
-		"Eric Chavanon (2004-2005)\n"
-		"Trevor Nunes (2004)\n"
-		"Olivier Lapicque (1997-2003)\n"
-		"\n"
-		"Additional patch submitters:\n"
-		"coda (https://coda.s3m.us/)\n"
-		"kode54 (https://kode54.net/)\n"
-		"Revenant (https://revenant1.net/)\n"
-		"xaimus (http://xaimus.com/)\n"
-		"\n"
-		"Thanks to:\n"
-		"\n"
-		"Konstanty for the XMMS-ModPlug resampling implementation\n"
-		"http://modplug-xmms.sourceforge.net/\n"
-		"\n"
-#ifdef MODPLUG_TRACKER
-		"Stephan M. Bernsee for pitch shifting source code\n"
-		"http://www.dspdimension.com/\n"
-		"\n"
-		"Aleksey Vaneev of Voxengo for r8brain sample rate converter\n"
-		"https://github.com/avaneev/r8brain-free-src\n"
-		"\n"
-		"Olli Parviainen for SoundTouch Library (time stretching)\n"
-		"https://www.surina.net/soundtouch/\n"
-		"\n"
-#endif
-#ifndef NO_VST
-		"Hermann Seib for his example VST Host implementation\n"
-		"http://www.hermannseib.com/english/vsthost.htm\n"
-		"\n"
-		"Benjamin \"BeRo\" Rosseaux for his independent VST header\n"
-		"https://blog.rosseaux.net/\n"
-		"\n"
-#endif
-		"Storlek for all the IT compatibility hints and testcases\n"
-		"as well as the IMF, MDL, OKT and ULT loaders\n"
-		"http://schismtracker.org/\n"
-		"\n"
-		"Sergei \"x0r\" Kolzun for various hints on Scream Tracker 2 compatibility\n"
-		"https://github.com/viiri/st2play\n"
-		"\n"
-		"Laurent Cl\xc3\xA9vy for unofficial MO3 documentation and decompression code\n"
-		"https://github.com/lclevy/unmo3\n"
-		"\n"
-		"Ben \"GreaseMonkey\" Russell for IT sample compression code\n"
-		"https://github.com/iamgreaser/it2everything/\n"
-		"\n"
-		"Antti S. Lankila for Amiga resampler implementation\n"
-		"https://bel.fi/alankila/modguide/interpolate.txt\n"
-		"\n"
-		"Shayde / Reality Productions for Opal OPL3 emulator\n"
-		"https://www.3eality.com/\n"
-		"\n"
-#ifdef MPT_WITH_ZLIB
-		"Jean-loup Gailly and Mark Adler for zlib\n"
-		"https://zlib.net/\n"
-		"\n"
-#endif
-#ifdef MPT_WITH_MINIZ
-		"Rich Geldreich et al. for miniz\n"
-		"https://github.com/richgel999/miniz\n"
-		"\n"
-#endif
-#ifdef MPT_WITH_LHASA
-		"Simon Howard for lhasa\n"
-		"https://fragglet.github.io/lhasa/\n"
-		"\n"
-#endif
-#ifdef MPT_WITH_UNRAR
-		"Alexander L. Roshal for UnRAR\n"
-		"https://rarlab.com/\n"
-		"\n"
-#endif
-#ifdef MPT_WITH_PORTAUDIO
-		"PortAudio contributors\n"
-		"http://www.portaudio.com/\n"
-		"\n"
-#endif
-#ifdef MPT_WITH_RTAUDIO
-		"Gary P. Scavone, McGill University\n"
-		"https://www.music.mcgill.ca/~gary/rtaudio/\n"
-		"\n"
-#endif
-#ifdef MPT_WITH_FLAC
-		"Josh Coalson / Xiph.Org Foundation for libFLAC\n"
-		"https://xiph.org/flac/\n"
-		"\n"
-#endif
-#if defined(MPT_WITH_MPG123)
-		"The mpg123 project for libmpg123\n"
-		"https://mpg123.de/\n"
-		"\n"
-#endif
-#ifdef MPT_WITH_MINIMP3
-		"Lion (github.com/lieff) for minimp3\n"
-		"https://github.com/lieff/minimp3/\n"
-		"\n"
-#endif
-#ifdef MPT_WITH_STBVORBIS
-		"Sean Barrett for stb_vorbis\n"
-		"https://github.com/nothings/stb/\n"
-		"\n"
-#endif
-#ifdef MPT_WITH_OGG
-		"Xiph.Org Foundation for libogg\n"
-		"https://xiph.org/ogg/\n"
-		"\n"
-#endif
-#if defined(MPT_WITH_VORBIS) || defined(MPT_WITH_LIBVORBISFILE)
-		"Xiph.Org Foundation for libvorbis\n"
-		"https://xiph.org/vorbis/\n"
-		"\n"
-#endif
-#if defined(MPT_WITH_OPUS)
-		"Xiph.Org, Skype Limited, Octasic, Jean-Marc Valin, Timothy B. Terriberry,\n"
-		"CSIRO, Gregory Maxwell, Mark Borgerding, Erik de Castro Lopo,\n"
-		"Xiph.Org Foundation, Microsoft Corporation, Broadcom Corporation for libopus\n"
-		"https://opus-codec.org/\n"
-		"\n"
-#endif
-#if defined(MPT_WITH_OPUSFILE)
-		"Xiph.Org Foundation and contributors for libopusfile\n"
-		"https://opus-codec.org/\n"
-		"\n"
-#endif
-#if defined(MPT_WITH_OPUSENC)
-		"Xiph.Org Foundation, Jean-Marc Valin and contributors for libopusenc\n"
-		"https://git.xiph.org/?p=libopusenc.git;a=summary\n"
-		"\n"
-#endif
-#if defined(MPT_WITH_LAME)
-		"The LAME project for LAME\n"
-		"http://lame.sourceforge.net/\n"
-#endif
-#if defined(MPT_WITH_NLOHMANNJSON)
-		"Niels Lohmann et al. for nlohmann-json\n"
-		"https://github.com/nlohmann/json\n"
-		"\n"
-#endif
-#ifdef MODPLUG_TRACKER
-		"Lennart Poettering and David Henningsson for RealtimeKit\n"
-		"http://git.0pointer.net/rtkit.git/\n"
-		"\n"
-		"Gary P. Scavone for RtMidi\n"
-		"https://www.music.mcgill.ca/~gary/rtmidi/\n"
-		"\n"
-		"Alexander Uckun for decimal input field\n"
-		"https://www.codeproject.com/Articles/21257/_\n"
-		"\n"
-		"\xc3\x9alfur Kolka for application icon, splash and about screen\n"
-		"https://www.behance.net/ulfurkolka\n"
-		"\n"
-		"Nobuyuki for file icon\n"
-		"https://twitter.com/nobuyukinyuu\n"
-		"\n"
-#endif
-		"Daniel Collin (emoon/TBL) for providing test infrastructure\n"
-		"https://twitter.com/daniel_collin\n"
-		"\n"
-		"The people at ModPlug forums for crucial contribution\n"
-		"in the form of ideas, testing and support;\n"
-		"thanks particularly to:\n"
-		"33, 8bitbubsy, Anboi, BooT-SectoR-ViruZ, Bvanoudtshoorn\n"
-		"christofori, cubaxd, Diamond, Ganja, Georg, Goor00,\n"
-		"Harbinger, jmkz, KrazyKatz, LPChip, Nofold, Rakib, Sam Zen\n"
-		"Skaven, Skilletaudio, Snu, Squirrel Havoc, Teimoso, Waxhead\n"
-		"\n"
-#ifndef NO_VST
-		"VST PlugIn Technology by Steinberg Media Technologies GmbH\n"
-		"\n"
-#endif
-#ifdef MPT_WITH_ASIO
-		"ASIO Technology by Steinberg Media Technologies GmbH\n"
-		"\n"
-#endif
-		);
-}
-
-mpt::ustring GetLicenseString()
-{
-	return MPT_UTF8(
-		"Copyright (c) 2004-2019, OpenMPT contributors" "\n"
-		"Copyright (c) 1997-2003, Olivier Lapicque" "\n"
-		"All rights reserved." "\n"
-		"" "\n"
-		"Redistribution and use in source and binary forms, with or without" "\n"
-		"modification, are permitted provided that the following conditions are met:" "\n"
-		"    * Redistributions of source code must retain the above copyright" "\n"
-		"      notice, this list of conditions and the following disclaimer." "\n"
-		"    * Redistributions in binary form must reproduce the above copyright" "\n"
-		"      notice, this list of conditions and the following disclaimer in the" "\n"
-		"      documentation and/or other materials provided with the distribution." "\n"
-		"    * Neither the name of the OpenMPT project nor the" "\n"
-		"      names of its contributors may be used to endorse or promote products" "\n"
-		"      derived from this software without specific prior written permission." "\n"
-		"" "\n"
-		"THIS SOFTWARE IS PROVIDED BY THE CONTRIBUTORS ``AS IS'' AND ANY" "\n"
-		"EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED" "\n"
-		"WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE" "\n"
-		"DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY" "\n"
-		"DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES" "\n"
-		"(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;" "\n"
-		"LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND" "\n"
-		"ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT" "\n"
-		"(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS" "\n"
-		"SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." "\n"
-		);
-}
-
-} // namespace Build
-
-
-
-OPENMPT_NAMESPACE_END

+ 0 - 308
libopenmpt.mod/openmpt/common/version.h

@@ -1,308 +0,0 @@
-/*
- * version.h
- * ---------
- * Purpose: OpenMPT version handling.
- * Notes  : (currently none)
- * Authors: OpenMPT Devs
- * The OpenMPT source code is released under the BSD license. Read LICENSE for more details.
- */
-
-
-#pragma once
-
-#include "BuildSettings.h"
-
-#include "FlagSet.h"
-
-
-OPENMPT_NAMESPACE_BEGIN
-
-
-class Version
-{
-
-private:
-
-	uint32 m_Version; // e.g. 0x01170208
-
-public:
-
-	enum class Field
-	{
-		Major,
-		Minor,
-		Patch,
-		Test,
-	};
-
-public:
-
-	static Version Current() noexcept;
-
-public:
-
-	MPT_CONSTEXPR11_FUN Version() noexcept
-		: m_Version(0)
-	{}
-
-	explicit MPT_CONSTEXPR11_FUN Version(uint32 version) noexcept
-		: m_Version(version)
-	{}
-
-	explicit MPT_CONSTEXPR11_FUN Version(uint8 v1, uint8 v2, uint8 v3, uint8 v4) noexcept
-		: m_Version((static_cast<uint32>(v1) << 24) | (static_cast<uint32>(v2) << 16) | (static_cast<uint32>(v3) << 8) | (static_cast<uint32>(v4) << 0))
-	{}
-
-public:
-
-	mpt::ustring ToUString() const; // e.g "1.17.02.08"
-
-	// Returns numerical version value from given version string.
-	static Version Parse(const mpt::ustring &s);
-
-public:
-
-	explicit MPT_CONSTEXPR11_FUN operator bool () const noexcept
-	{
-		return m_Version != 0;
-	}
-	MPT_CONSTEXPR11_FUN bool operator ! () const noexcept
-	{
-		return m_Version == 0;
-	}
-
-	MPT_CONSTEXPR11_FUN uint32 GetRawVersion() const noexcept
-	{
-		return m_Version;
-	}
-
-	MPT_FORCEINLINE Version Masked(uint32 mask) const noexcept
-	{
-		return Version(m_Version & mask);
-	}
-
-	MPT_CONSTEXPR11_FUN uint8 GetField(Field field) const noexcept
-	{
-		return
-			(field == Field::Major) ? static_cast<uint8>((m_Version >> 24) & 0xffu) :
-			(field == Field::Minor) ? static_cast<uint8>((m_Version >> 16) & 0xffu) :
-			(field == Field::Patch) ? static_cast<uint8>((m_Version >>  8) & 0xffu) :
-			(field == Field::Test ) ? static_cast<uint8>((m_Version >>  0) & 0xffu) :
-			0u;
-	}
-
-	// Return a version without build number (the last number in the version).
-	// The current versioning scheme uses this number only for test builds, and it should be 00 for official builds,
-	// So sometimes it might be wanted to do comparisons without the build number.
-	Version WithoutTestNumber() const noexcept;
-
-	Version WithoutPatchOrTestNumbers() const noexcept;
-
-public:
-
-	// Return a OpenMPT version string suitable for file format tags 
-	mpt::ustring GetOpenMPTVersionString() const; // e.g. "OpenMPT 1.17.02.08"
-
-	// Returns true if a given version number is from a test build, false if it's a release build.
-	bool IsTestVersion() const noexcept;
-
-public:
-
-	struct LiteralParser
-	{
-	
-	public:
-
-		// Work-around for GCC 5 which complains about instanciating non-literal type inside a constexpr function when using mpt::constexpr_throw(std::runtime_error("")).
-		struct ParseException {};
-
-	private:
-
-		static MPT_CONSTEXPR11_FUN uint8 NibbleFromChar(char x)
-		{
-			return
-				('0' <= x && x <= '9') ? static_cast<uint8>(x - '0' +  0) :
-				('a' <= x && x <= 'z') ? static_cast<uint8>(x - 'a' + 10) :
-				('A' <= x && x <= 'Z') ? static_cast<uint8>(x - 'A' + 10) :
-				throw std::domain_error("");
-		}
-
-	public:
-
-		static MPT_CONSTEXPR14_FUN Version Parse(const char * str, std::size_t len)
-		{
-			// 0123456789
-			// 1.23.45.67
-			uint8 v[4] = {0, 0, 0, 0};
-			std::size_t field = 0;
-			std::size_t fieldlen = 0;
-			for(std::size_t i = 0; i < len; ++i)
-			{
-				char c = str[i];
-				if(c == '.')
-				{
-					if(field >= 3)
-					{
-						mpt::constexpr_throw(ParseException());
-					}
-					if(fieldlen == 0)
-					{
-						mpt::constexpr_throw(ParseException());
-					}
-					field++;
-					fieldlen = 0;
-				} else if(('0' <= c && c <= '9') || ('a' <= c && c <= 'z') || ('A' <= c && c <= 'Z'))
-				{
-					fieldlen++;
-					if(fieldlen > 2)
-					{
-						mpt::constexpr_throw(ParseException());
-					}
-					v[field] <<= 4;
-					v[field] |= NibbleFromChar(c);
-				} else
-				{
-					mpt::constexpr_throw(ParseException());
-				}
-			}
-			if(fieldlen == 0)
-			{
-				mpt::constexpr_throw(ParseException());
-			}
-			return Version(v[0], v[1], v[2], v[3]);
-		}
-
-	};
-
-};
-
-MPT_CONSTEXPR11_FUN bool operator == (const Version &a, const Version &b) noexcept
-{
-	return a.GetRawVersion() == b.GetRawVersion();
-}
-MPT_CONSTEXPR11_FUN bool operator != (const Version &a, const Version &b) noexcept
-{
-	return a.GetRawVersion() != b.GetRawVersion();
-}
-MPT_CONSTEXPR11_FUN bool operator <= (const Version &a, const Version &b) noexcept
-{
-	return a.GetRawVersion() <= b.GetRawVersion();
-}
-MPT_CONSTEXPR11_FUN bool operator >= (const Version &a, const Version &b) noexcept
-{
-	return a.GetRawVersion() >= b.GetRawVersion();
-}
-MPT_CONSTEXPR11_FUN bool operator < (const Version &a, const Version &b) noexcept
-{
-	return a.GetRawVersion() < b.GetRawVersion();
-}
-MPT_CONSTEXPR11_FUN bool operator > (const Version &a, const Version &b) noexcept
-{
-	return a.GetRawVersion() > b.GetRawVersion();
-}
-
-
-MPT_CONSTEXPR14_FUN Version operator "" _LiteralVersionImpl (const char * str, std::size_t len)
-{
-	return Version::LiteralParser::Parse(str, len);
-}
-
-// Create Version object from version string and check syntax, all at compile time.
-// cppcheck false-positive
-// cppcheck-suppress preprocessorErrorDirective
-#define MPT_V(strver) Version{MPT_FORCE_CONSTEXPR(( strver ## _LiteralVersionImpl ).GetRawVersion())}
-
-
-
-class SourceInfo
-{
-private:
-	mpt::ustring m_Url; // svn repository url (or empty string)
-	int m_Revision; // svn revision (or 0)
-	bool m_IsDirty; // svn working copy is dirty (or false)
-	bool m_HasMixedRevisions; // svn working copy has mixed revisions (or false)
-	bool m_IsPackage; // source code originates from a packaged version of the source code
-	mpt::ustring m_Date; // svn date (or empty string)
-private:
-	SourceInfo();
-public:
-	static SourceInfo Current();
-public:
-	const mpt::ustring & Url() const { return m_Url; }
-	int Revision() const { return m_Revision; }
-	bool IsDirty() const { return m_IsDirty; }
-	bool HasMixedRevisions() const { return m_HasMixedRevisions; }
-	bool IsPackage() const { return m_IsPackage; }
-	const mpt::ustring & Date() const { return m_Date; }
-public:
-	mpt::ustring GetUrlWithRevision() const; // i.e. "https://source.openmpt.org/svn/openmpt/trunk/OpenMPT@1234" or empty string
-	mpt::ustring GetStateString() const; // i.e. "+dirty" or "clean"
-};
-
-
-
-namespace Build
-{
-
-	// Returns true if all conditions for an official release build are met
-	bool IsReleasedBuild();
-
-	// Return true if this is a debug build with no optimizations
-	bool IsDebugBuild();
-
-	// Return a string decribing the time of the build process (if built from a svn working copy and tsvn was available during build, otherwise it returns the time version.cpp was last rebuild which could be unreliable as it does not get rebuild every time without tsvn)
-	mpt::ustring GetBuildDateString();
-
-	// Return a string decribing some of the build features
-	mpt::ustring GetBuildFeaturesString(); // e.g. " NO_VST NO_DSOUND"
-
-	// Return a string describing the compiler version used for building.
-	mpt::ustring GetBuildCompilerString(); // e.g. "Microsoft Compiler 15.00.20706.01"
-
-	enum Strings
-	{
-		StringsNone         = 0,
-		StringVersion       = 1<<0, // "1.23.35.45"
-		StringRevision      = 1<<2, // "-r1234+"
-		StringBitness       = 1<<3, // "32 bit"
-		StringSourceInfo    = 1<<4, // "https://source.openmpt.org/svn/openmpt/trunk/OpenMPT@1234 (2016-01-02) +dirty"
-		StringBuildFlags    = 1<<5, // "TEST DEBUG"
-		StringBuildFeatures = 1<<6, // "NO_VST NO_DSOUND"
-	};
-	MPT_DECLARE_ENUM(Strings)
-
-	// Returns a versions string with the fields selected via @strings.
-	mpt::ustring GetVersionString(FlagSet<Build::Strings> strings);
-
-	// Returns a pure version string
-	mpt::ustring GetVersionStringPure(); // e.g. "1.17.02.08-r1234+ 32 bit"
-
-	// Returns a simple version string
-	mpt::ustring GetVersionStringSimple(); // e.g. "1.17.02.08-r1234+ TEST"
-
-	// Returns Version::CurrentAsString() if the build is a clean release build straight from the repository or an extended string otherwise (if built from a svn working copy and tsvn was available during build)
-	mpt::ustring GetVersionStringExtended(); // e.g. "1.17.02.08-r1234+ 32 bit DEBUG"
-
-	enum class Url
-	{
-		Website,
-		Download,
-		Forum,
-		Bugtracker,
-		Updates,
-		TopPicks,
-	};
-	// Returns a URL for the respective key.
-	mpt::ustring GetURL(Build::Url key);
-
-	// Returns a multi-line string containing the full credits for the code base
-	mpt::ustring GetFullCreditsString();
-
-	// Returns the OpenMPT license text
-	mpt::ustring GetLicenseString();
-
-} //namespace Build
-
-
-
-OPENMPT_NAMESPACE_END

+ 0 - 32
libopenmpt.mod/openmpt/common/versionNumber.h

@@ -1,32 +0,0 @@
-/*
- * versionNumber.h
- * ---------------
- * Purpose: OpenMPT version handling.
- * Notes  : (currently none)
- * Authors: OpenMPT Devs
- * The OpenMPT source code is released under the BSD license. Read LICENSE for more details.
- */
-
-
-#pragma once
-
-#include "BuildSettings.h"
-
-OPENMPT_NAMESPACE_BEGIN
-
-#define VER_HELPER_STRINGIZE(x) #x
-#define VER_STRINGIZE(x)        VER_HELPER_STRINGIZE(x)
-
-#define MPT_MAKE_VERSION_NUMERIC_HELPER(prefix,v0,v1,v2,v3) Version( prefix ## v0 , prefix ## v1 , prefix ## v2 , prefix ## v3 )
-#define MPT_MAKE_VERSION_NUMERIC(v0,v1,v2,v3) MPT_MAKE_VERSION_NUMERIC_HELPER(0x, v0, v1, v2, v3)
-
-// Version definitions. The only thing that needs to be changed when changing version number.
-#define VER_MAJORMAJOR  1
-#define VER_MAJOR      29
-#define VER_MINOR      00
-#define VER_MINORMINOR 35
-
-// Numerical value of the version.
-#define MPT_VERSION_CURRENT MPT_MAKE_VERSION_NUMERIC(VER_MAJORMAJOR,VER_MAJOR,VER_MINOR,VER_MINORMINOR)
-
-OPENMPT_NAMESPACE_END

+ 0 - 36
libopenmpt.mod/openmpt/doc/backporting_patches.md

@@ -1,36 +0,0 @@
-
-Backporting patches
-===================
-
-This document tries to list all changes that must be made to individual
-patches when backporting them to earlier branches of the codebase.
-
-This list is incomplete.
-
-OpenMPT 1.28 / libopenmpt 0.4
------------------------------
-
- *  Replace `std::abs` by `mpt::abs`.
- *  Replace `std::byte` by `mpt::byte`.
- *  Replace `std::clamp` by `mpt::clamp`.
- *  Replace `std::data` by `mpt::data`.
- *  Replace `std::gcd` by `mpt::gcd`.
- *  Replace `std::lcm` by `mpt::lcm`.
- *  Replace `std::make_unique` by `mpt::make_unique`.
- *  Replace `std::size` by `mpt::size`.
- *  Replace `if constexpr` by `MPT_CONSTANT_IF`.
- *  Replace `static_assert` by `MPT_STATIC_ASSERT`.
- *  Replace `[[nodiscard]]` by `MPT_NODISCARD`.
- *  Replace `[[fallthrough]]` by `MPT_FALLTHROUGH`.
-
-OpenMPT 1.27 / libopenmpt 0.3 
------------------------------
-
- *  Replace string macros with longer versions:
-     *  U_("foo") --> MPT_USTRING("foo")
-     *  UL_("foo") --> MPT_ULITERAL("foo")
-     *  UC_('x') --> MPT_UCHAR('x')
-     *  P_("foo") --> MPT_PATHSTRING("foo")
-     *  PL_("foo") --> MPT_PATHSTRING_LITERAL("foo")
-     *  PC_('x') --> MPT_PATHSTRING_LITERAL('x')
-    See <https://bugs.openmpt.org/view.php?id=1107>.

+ 0 - 43
libopenmpt.mod/openmpt/doc/contributing.md

@@ -1,43 +0,0 @@
-
-Contributing
-============
-
-OpenMPT, libopenmpt, openmpt123, xmp-openmpt and in_openmpt are developed in
-the Subversion repository at
-[https://source.openmpt.org/browse/openmpt/trunk/OpenMPT/](https://source.openmpt.org/browse/openmpt/trunk/OpenMPT/).
-Patches can be provided either against this Subversion repository or against our
-GitHub mirror at
-[https://github.com/OpenMPT/openmpt/](https://github.com/OpenMPT/openmpt/).
-
-We do not have a developer mailing list. Discussions about new features or
-problems can happen at:
- *  [Issue Tracker](https://bugs.openmpt.org/), preferred for specific bug
-    reports or bug fixes and feature development discussion
- *  [Forum](https://forum.openmpt.org/), preferred for long-term discussion of
-    new features or specific questions about development
- *  [IRC channel (`EsperNET/#modplug`)](irc://irc.esper.net:5555/#modplug),
-    preferred for shorter questions
- *  [GitHub pull requests](https://github.com/OpenMPT/openmpt/pulls), please
-    only use for rather tiny fixes, see below
-
-For patch submissions, please also see
-[OpenMPT style guide](openmpt_styleguide.md) and
-[libopenmpt style guide](libopenmpt_styleguide.md).
-
-### Contributing via GitHub
-
-As OpenMPT is developed in a Subversion repository and the GitHub repository is
-just mirrored from that, we cannot directly take pull requests via GitHub. We
-recognize that, especially for tiny bug fixes, the burden to choose a different
-way than GitHub for contributing can be too high. Thus, we will of course react,
-give feedback, and take patches also via GitHub pull requests. However, as the
-GitHub repository is strictly downstream from our Subversion repository (and
-this will not change, due to considerable complications when synchronizing this
-two-way), we cannot directly merge pull requests on GitHub. We will merge
-contributions to our Subversion repository, which will then in turn be mirrored
-to GitHub automatically, after which we will close the pull request. Authorship
-attribution in git relies on the email address used in the commit header, which
-is not how it usually works in Subversion. We will thus add an additional line
-to the commit message in the form of `Patch-by: John Doe <[email protected]>`. If
-you prefer to be attributed with your nickname and/or without your email
-address, that would also be fine for us.

+ 0 - 41
libopenmpt.mod/openmpt/doc/libopenmpt_release.md

@@ -1,41 +0,0 @@
-libopenmpt release process
-==========================
-
-0.2
----
-
-For libopenmpt 0.2, see
-https://source.openmpt.org/svn/openmpt/branches/OpenMPT-1.26/doc/libopenmpt_release.txt
-.
-
-0.3
----
-
-For libopenmpt 0.3, see
-https://source.openmpt.org/svn/openmpt/branches/OpenMPT-1.27/doc/libopenmpt_release.txt
-.
-
-0.4
----
-
-For libopenmpt 0.4, see
-https://source.openmpt.org/svn/openmpt/branches/OpenMPT-1.28/doc/libopenmpt_release.txt
-.
-
-0.5
----
-
- 1. ensure that the OpenMPT version is preferrably at a aa.bb.cc.00 version,
-    otherwise increment the minorminor part to a new value used specifically for
-    the libopenmpt release
- 2. from a clean checkout, run (requires xpath!!!)
-        ./build/svn/do_libopenmpt_release.sh
- 3. website: add release announcement
- 4. website: update download links
- 5. wait for buildbot
- 6. in a website checkout, run (as printed by the release script)
-        ./release-0.5.sh $NEWVER +release
- 7. increment OpenMPT version minorminor in `common/versionNumber.h` when all
-    releases are done on the svn side (either libopenmpt only, or both
-    libopenmpt and OpenMPT)
-

+ 0 - 104
libopenmpt.mod/openmpt/doc/libopenmpt_styleguide.md

@@ -1,104 +0,0 @@
-
-Coding conventions
-------------------
-
-
-### libopenmpt
-
-**Note:**
-**This applies to `libopenmpt/` and `openmpt123/` directories only.**
-**Use OpenMPT style otherwise.**
-
-The code generally tries to follow these conventions, but they are not
-strictly enforced and there are valid reasons to diverge from these
-conventions. Using common sense is recommended.
-
- -  In general, the most important thing is to keep style consistent with
-    directly surrounding code.
- -  Use C++ std types when possible, prefer `std::size_t` and `std::int32_t`
-    over `long` or `int`. Do not use C99 std types (e.g. no pure `int32_t`)
- -  Qualify namespaces explicitly, do not use `using`.
-    Members of `namespace openmpt` can be named without full namespace
-    qualification.
- -  Prefer the C++ version in `namespace std` if the same functionality is
-    provided by the C standard library as well. Also, include the C++
-    version of C standard library headers (e.g. use `<cstdio>` instead of
-    `<stdio.h>`.
- -  Do not use ANY locale-dependant C functions. For locale-dependant C++
-    functionaly (especially iostream), always imbue the
-    `std::locale::classic()` locale.
- -  Prefer kernel_style_names over CamelCaseNames.
- -  If a folder (or one of its parent folders) contains .clang-format,
-    use clang-format v3.5 for indenting C++ and C files, otherwise:
-     -  `{` are placed at the end of the opening line.
-     -  Enclose even single statements in curly braces.
-     -  Avoid placing single statements on the same line as the `if`.
-     -  Opening parentheses are separated from keywords with a space.
-     -  Opening parentheses are not separated from function names.
-     -  Place spaces around operators and inside parentheses.
-     -  Align `:` and `,` when inheriting or initializing members in a
-        constructor.
-     -  The pointer `*` is separated from both the type and the variable name.
-     -  Use tabs for identation, spaces for formatting.
-        Tabs should only appear at the very beginning of a line.
-        Do not assume any particular width of the TAB character. If width is
-        important for formatting reasons, use spaces.
-     -  Use empty lines at will.
- -  API documentation is done with doxygen.
-    Use general C doxygen for the C API.
-    Use QT-style doxygen for the C++ API.
-
-#### libopenmpt indentation example
-
-~~~~{.cpp}
-namespace openmpt {
-
-// This is totally meaningless code and just illustrates indentation.
-
-class foo
-	: public base
-	, public otherbase
-{
-
-private:
-
-	std::int32_t x;
-	std::int16_t y;
-
-public:
-
-	foo()
-		: x(0)
-		, y(-1)
-	{
-		return;
-	}
-
-	int bar() const;
-
-}; // class foo
-
-int foo::bar() const {
-
-	for ( int i = 0; i < 23; ++i ) {
-		switch ( x ) {
-			case 2:
-				something( y );
-				break;
-			default:
-				something( ( y - 1 ) * 2 );
-				break;
-		}
-	}
-	if ( x == 12 ) {
-		return -1;
-	} else if ( x == 42 ) {
-		return 1;
-	}
-	return 42;
-
-}
-
-} // namespace openmpt
-~~~~
-

+ 0 - 106
libopenmpt.mod/openmpt/doc/module_formats.md

@@ -1,106 +0,0 @@
-How to add support for new module formats
-=========================================
-
-This document describes the basics of writing a new module loader and related
-work that has to be done. We will not discuss in detail how to write the loader,
-have a look at existing loaders to get an idea how they work in general.
-
-General hints
--------------
-* We strive for quality over quantity. The goal is not to support as many module
-  formats as possible, but to support them as well as possible. 
-* Write defensive code. Guard against out-of-bound values, division by zero and
-  similar stuff. libopenmpt is constantly fuzz-tested to catch any crashes, but
-  of course we want our code to be reliable from the start.
-* Every format should have its own `MODTYPE` flag, unless it can be reasonably
-  represented as a subset of another format (like Ice Tracker ICE files being
-  a subset of ProTracker MOD).
-* When reading binary structs from the file, use our data types with defined
-  endianness, which can be found in `common/Endianness.h`:
-  * Big-Endian: (u)int8/16/32/64be, float32be, float64be
-  * Little-Endian: (u)int8/16/32/64le, float32le, float64le
-
-  Entire structs containing integers with defined endianness can be read in one
-  go if they are tagged with `MPT_BINARY_STRUCT` (see existing loaders for an
-  example).
-* `m_nChannels` **MUST NOT** be changed after a pattern has been created, as
-  existing patterns will be interpreted incorrectly. For module formats that
-  support per-pattern channel amounts, the maximum number of channels must be
-  determined beforehand.
-* Strings can be safely handled using:
-  * `FileReader::ReadString` and friends for reading them directly from a file
-  * `mpt::String::Read` for reading them from a struct or char array,
-  * `mpt::String::Copy` for copying between char arrays or `std::string`.
-
-  "Read" functions take care of string padding (zero / space padding), so those
-  should be used when extracting strings from files. "Copy" should only be used
-  on strings that have previously been read using the "Read" functions.
-  If the target is a char array rather than a `std::string`, these will take
-  care of properly null-terminating the target char array, and prevent reading
-  past the end of a (supposedly null-terminated) source char array.
-* Do not use non-const static variables in your loader. Loaders need to be
-  thread-safe for libopenmpt.
-* `FileReader` instances may be used to treat a portion of another file as its
-  own independent file (through `FileReader::ReadChunk`). This can be useful
-  with "embedded files" such as WAV or Ogg samples. Container formats are
-  another good example for this usage.
-* Samples *either* use middle-C frequency *or* finetune + transpose. For the few
-  weird formats that use both, it may make sense to translate everything into
-  middle-C frequency.
-* Add the new `MODTYPE` to `CSoundFile::UseFinetuneAndTranspose` if applicable,
-  and see if any effect handlers in `soundlib/Snd_fx.cpp` need to know the new
-  `MODTYPE`.
-* Do not rely on hard-coded magic numbers. For example, when comparing if an
-  index is valid for a given array, do not hard-code the array size but rather
-  use `mpt::size` or, for ensuring that char arrays are null-terminated,
-  `mpt::String::SetNullTerminator`. Similarly, do not assume any specific
-  quantities for OpenMPT's constants like MAX_SAMPLES, MAX_PATTERN_ROWS, etc.
-  These may change at any time.
-* Pay attention to off-by-one errors when comparing against MAX_SAMPLES and
-  MAX_INSTRUMENTS, since sample and instrument numbers are 1-based. 
-* Placement of the loader function in `CSoundFile::Create` depends on various
-  factors. In general, module formats that have very bad magic numbers (and thus
-  might cause other formats to get mis-interpreted) should be placed at the
-  bottom of the list. Two notable examples are 669 files, where the first two
-  bytes of the file are "if" (which may e.g. cause a song title starting with
-  "if ..." in various other formats to be interpreted as a 669 module), and of
-  course Ultimate SoundTracker modules, which have no magic bytes at all.
-* Avoid use of functions tagged with MPT_DEPRECATED.
-
-Probing
--------
-libopenmpt provides fast probing functions that can be used by library users
-to quickly check if a file is most likely playable with libopenmpt, even if only
-a fraction of the file is available (e.g. when streaming from the internet).
-
-In order to satisfy these requirements, probing functions should do as little
-work as possible (e.g. only parse the header of the file), but as much as
-required to tell with some certainty that the file is really of a certain mod
-format. However, probing functions should not rely on having access to more than
-the first `CSoundFile::ProbeRecommendedSize` bytes of the file.
-
-* Probing functions **must not** allocate any memory on the heap.
-* Probing functions **must not** return ProbeFailure or ProbeWantMoreData for
-  any file that would normally be accepted by the loader. In particular, this
-  means that any header checks must not be any more aggressive than they would
-  be in the real loader (hence it is a good idea to not copy-paste this code but
-  rather put it in a separate function), and the minimum additional size passed
-  to `CSoundFile::ProbeAdditionalSize` must not be higher than the biggest size
-  that would cause a hard failure (i.e. returning `false`) in the module loader.
-* Probing functions **may** return ProbeSuccess for files that would be rejected
-  by a loader after a more thorough inspection. For example, probing functions
-  do not need to verify that all required chunks of an IFF-like file format are
-  actually present, if the header makes it obvious enough that the file is
-  highly likely to be a module.
-
-Adding loader to the build systems and various other locations
---------------------------------------------------------------
-Apart from writing the module loader itself, there are a couple of other places
-that need to be updated:
-* Add loader file to `build/android_ndk/Android.mk`.
-* Add loader file to `build/autotools/Makefile.am`.
-* Run `build/regenerate_vs_projects.sh` / `build/regenerate_vs_projects.cmd`
-  (depending on your platform)
-* Add file extension to `installer/filetypes.iss` (in four places).
-* Add file extension to `CTrackApp::OpenModulesDialog` in `mptrack/Mptrack.cpp`.
-* Add format information to `soundlib/Tables.cpp`.

+ 0 - 70
libopenmpt.mod/openmpt/doc/openmpt_release.md

@@ -1,70 +0,0 @@
-OpenMPT release process
-=======================
-
-0. A day or so before the release, restart all fuzzers with the latest binaries
-   and check if any unexpected crashes occur. Module loaders should not be
-   touched in this phase to prevent the introduction of unexpected crashes.
-1. Update `OMPT_X.YY_ReleaseNotes.html`, `History.txt`, `readme.txt` and
-   `versionNumber.h`
-   * Update version number in all files
-   * Check if any files have to be added to or removed from the listing in
-     `readme.txt`
-   * If year changed, see `doc/year_changed.md`
-2. Download latest pinned externals via build/download_externals.cmd.
-3. Compile OpenMPT.
-4. Run `build/auto/build_openmpt_release_packages.cmd` to build the manual and
-   release packages.
-5. Upload release packages (openmpt.org, ftp.untergrund.net, SourceForge)
-6. Upload `OMPT_X.YY_ReleaseNotes.html` and `History.txt` to
-   https://openmpt.org/release_notes/ (update DirectoryIndex!)
-7. Update https://openmpt.org/download
-8. Write news entry for front page
-9. Update stable.php version information for update checker
-10. Create SVN tag
-11. Update forum pre-announcement post, if there was one
-12. Update release status on issue tracker, add new test version and upcoming
-    stable version.
-13. Update IRC topic
-14. Write BitFellas news article
-15. Clear https://wiki.openmpt.org/Special:WhatLinksHere/Template:NewVersion
-16. Backup PDB files
-
-Order of sections in History.txt
---------------------------------
- *  General tab
- *  Pattern tab
- *  Pattern Tab::Note Properties
- *  Pattern tab::Find/Replace
- *  Sample tab
- *  Instrument tab
- *  Comments tab
- *  Tree view
- *  Mod Conversion
- *  MIDI Macros
- *  VST / DMO Plugins
- *  VST::Specific Plugin Fixes
- *  VST::Plugin Bridge
- *  Playback
- *  MPTM
- *  MPTM::Custom Tuning
- *  IT / MPTM
- *  IT
- *  IT:Loading (and Saving)
- *  IT::Compatible Playback Mode
- *  XM
- *  XM::Loading (and Saving)
- *  XM::Compatible Playback Mode
- *  S3M
- *  S3M:Loading (and Saving)
- *  MOD
- *  MOD::ProTracker 1/2 Mode
- *  MOD::Loading (and Saving)
- *  Other formats
- *  Stream Export
- *  Module cleanup
- *  Audio I/O
- *  Misc
- *  Bundled plugins
- *  Third-Party Libraries
- *  Installer/release package
-

+ 0 - 35
libopenmpt.mod/openmpt/doc/openmpt_styleguide.md

@@ -1,35 +0,0 @@
-
-Coding conventions
-------------------
-
-
-### OpenMPT
-
-**Note:**
-**This applies to all source code *except* for `libopenmpt/` and `openmpt123/`**
-**directories.**
-**Use libopenmpt style otherwise.**
-
-(see below for an example)
-
- *  Place curly braces at the beginning of the line, not at the end
- *  Generally make use of the custom index types like `SAMPLEINDEX` or
-    `ORDERINDEX` when referring to samples, orders, etc.
- *  When changing playback behaviour, make sure that you use the function
-    `CSoundFile::IsCompatibleMode()` so that modules made with previous versions
-    of MPT still sound correct (if the change is extremely small, this might be
-    unnecessary)
- *  `CamelCase` function and variable names are preferred.
-
-#### OpenMPT code example
-
-~~~~{.cpp}
-void Foo::Bar(int foobar)
-{
-    while(true)
-    {
-        // some code
-    }
-}
-~~~~
-

+ 0 - 24
libopenmpt.mod/openmpt/doc/release_branches.md

@@ -1,24 +0,0 @@
-branching release braches
-=========================
-
- 1. adjust buildbot configuration by copying current trunk configuration to a
-    new branch configuration and replace `trunk` with the branch version (i.e.
-    `127`), remember to also adjust url of nondist externals
- 2. add release build configuration to the buildbot branch configuration file,
-    adjust buildbot config of release build configurations to output to the
-    separate auto-release directory and change the archive format from 7z to zip
-    for windows binaries
- 3. branch the nondist externals repository
- 4. branch the current trunk HEAD (`$VER` is the branch version):
-    `svn copy -m "branch OpenMPT-$VER" https://source.openmpt.org/svn/openmpt/trunk/OpenMPT https://source.openmpt.org/svn/openmpt/branches/OpenMPT-$VER`
- 5. update versions in trunk
-    `https://source.openmpt.org/svn/openmpt/trunk/OpenMPT`:
-     1. set OpenMPT version in `common/versionNumber.h` to
-        `1.$(($VER + 1)).00.01`
-     2. run `build/update_libopenmpt_version.sh bumpminor`
- 6. update versions in branch
-    `https://source.openmpt.org/svn/openmpt/branches/OpenMPT-$VER`:
-     1. set OpenMPT version in `common/versionNumber.h` to
-        `1.$VER.00.$MINORMINOR+1`
-     2. run `build/update_libopenmpt_version.sh bumpprerel`
-

+ 0 - 14
libopenmpt.mod/openmpt/doc/year_changed.md

@@ -1,14 +0,0 @@
-
-Things to update when the year has changed
-==========================================
-
- *  `LICENSE` (1 occurrence)
- *  `common/version.cpp` (2 occurrences plus 1 for each current contributor)
- *  `mptrack/res/MPTRACK.RC2` (1 occurence)
- *  `libopenmpt/libopenmpt_version.rc`) (1 occurrence)
- *  `openmpt123/openmpt123.cpp` (3 occurrences)
- *  `libopenmpt/xmp-openmpt.cpp` (1 occurrence)
- *  `libopenmpt/in_openmpt.cpp` (1 occurrence)
- *  [https://wiki.openmpt.org/Manual:_Acknowledgments](https://wiki.openmpt.org/Manual:_Acknowledgments)
- *  [https://lib.openmpt.org/libopenmpt/license/](https://lib.openmpt.org/libopenmpt/license/)
-

+ 0 - 63
libopenmpt.mod/openmpt/examples/.clang-format

@@ -1,63 +0,0 @@
-AccessModifierOffset: -2
-AlignAfterOpenBracket: true
-AlignConsecutiveAssignments: false
-AlignEscapedNewlinesLeft: true
-AlignOperands:   true
-AlignTrailingComments: false
-AllowAllParametersOfDeclarationOnNextLine: false
-AllowShortBlocksOnASingleLine: false
-AllowShortCaseLabelsOnASingleLine: false
-AllowShortFunctionsOnASingleLine: All
-AllowShortIfStatementsOnASingleLine: false
-AllowShortLoopsOnASingleLine: false
-AlwaysBreakAfterDefinitionReturnType: None
-AlwaysBreakBeforeMultilineStrings: false
-AlwaysBreakTemplateDeclarations: false
-BinPackArguments: false
-BinPackParameters: false
-BreakBeforeBinaryOperators: None
-BreakBeforeBraces: Attach
-BreakBeforeTernaryOperators: false
-BreakConstructorInitializersBeforeComma: true
-ColumnLimit:     0
-CommentPragmas:  '^ IWYU pragma:'
-ConstructorInitializerAllOnOneLineOrOnePerLine: true
-ConstructorInitializerIndentWidth: 2
-ContinuationIndentWidth: 2
-Cpp11BracedListStyle: false
-DerivePointerAlignment: false
-DisableFormat:   false
-ExperimentalAutoDetectBinPacking: false
-ForEachMacros:   [ foreach, Q_FOREACH, BOOST_FOREACH ]
-IndentCaseLabels: false
-IndentWidth:     2
-IndentWrappedFunctionNames: false
-KeepEmptyLinesAtTheStartOfBlocks: true
-Language:        Cpp
-MacroBlockBegin: ''
-MacroBlockEnd:   ''
-MaxEmptyLinesToKeep: 3
-NamespaceIndentation: None
-ObjCBlockIndentWidth: 2
-ObjCSpaceAfterProperty: false
-ObjCSpaceBeforeProtocolList: true
-PenaltyBreakBeforeFirstCallParameter: 1
-PenaltyBreakComment: 60
-PenaltyBreakFirstLessLess: 120
-PenaltyBreakString: 1000
-PenaltyExcessCharacter: 1000000
-PenaltyReturnTypeOnItsOwnLine: 200
-PointerAlignment: Middle
-SpaceAfterCStyleCast: false
-SpaceBeforeAssignmentOperators: true
-SpaceBeforeParens: ControlStatements
-SpaceInEmptyParentheses: false
-SpacesBeforeTrailingComments: 1
-SpacesInAngles:  false
-SpacesInContainerLiterals: true
-SpacesInCStyleCastParentheses: false
-SpacesInParentheses: true
-SpacesInSquareBrackets: false
-Standard:        Cpp03
-TabWidth:        2
-UseTab:          ForIndentation

+ 0 - 203
libopenmpt.mod/openmpt/examples/libopenmpt_example_c.c

@@ -1,203 +0,0 @@
-/*
- * libopenmpt_example_c.c
- * ----------------------
- * Purpose: libopenmpt C API example
- * Notes  : PortAudio is used for sound output.
- * Authors: OpenMPT Devs
- * The OpenMPT source code is released under the BSD license. Read LICENSE for more details.
- */
-
-/*
- * Usage: libopenmpt_example_c SOMEMODULE
- */
-
-#include <memory.h>
-#include <stdint.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include <libopenmpt/libopenmpt.h>
-#include <libopenmpt/libopenmpt_stream_callbacks_file.h>
-
-#include <portaudio.h>
-
-#define BUFFERSIZE 480
-#define SAMPLERATE 48000
-
-static int16_t left[BUFFERSIZE];
-static int16_t right[BUFFERSIZE];
-static int16_t * const buffers[2] = { left, right };
-
-static void libopenmpt_example_logfunc( const char * message, void * userdata ) {
-	(void)userdata;
-	if ( message ) {
-		fprintf( stderr, "openmpt: %s\n", message );
-	}
-}
-
-static int libopenmpt_example_errfunc( int error, void * userdata ) {
-	(void)userdata;
-	(void)error;
-	return OPENMPT_ERROR_FUNC_RESULT_DEFAULT & ~OPENMPT_ERROR_FUNC_RESULT_LOG;
-}
-
-static void libopenmpt_example_print_error( const char * func_name, int mod_err, const char * mod_err_str ) {
-	if ( !func_name ) {
-		func_name = "unknown function";
-	}
-	if ( mod_err == OPENMPT_ERROR_OUT_OF_MEMORY ) {
-		mod_err_str = openmpt_error_string( mod_err );
-		if ( !mod_err_str ) {
-			fprintf( stderr, "Error: %s\n", "OPENMPT_ERROR_OUT_OF_MEMORY" );
-		} else {
-			fprintf( stderr, "Error: %s\n", mod_err_str );
-			openmpt_free_string( mod_err_str );
-			mod_err_str = NULL;
-		}
-	} else {
-		if ( !mod_err_str ) {
-			mod_err_str = openmpt_error_string( mod_err );
-			if ( !mod_err_str ) {
-				fprintf( stderr, "Error: %s failed.\n", func_name );
-			} else {
-				fprintf( stderr, "Error: %s failed: %s\n", func_name, mod_err_str );
-			}
-			openmpt_free_string( mod_err_str );
-			mod_err_str = NULL;
-		}
-		fprintf( stderr, "Error: %s failed: %s\n", func_name, mod_err_str );
-	}
-}
-
-#if ( defined( _WIN32 ) || defined( WIN32 ) ) && ( defined( _UNICODE ) || defined( UNICODE ) )
-int wmain( int argc, wchar_t * argv[] ) {
-#else
-int main( int argc, char * argv[] ) {
-#endif
-
-	int result = 0;
-	FILE * file = 0;
-	openmpt_module * mod = 0;
-	int mod_err = OPENMPT_ERROR_OK;
-	const char * mod_err_str = NULL;
-	size_t count = 0;
-	PaError pa_error = paNoError;
-	int pa_initialized = 0;
-	PaStream * stream = 0;
-
-	if ( argc != 2 ) {
-		fprintf( stderr, "Error: %s\n", "Wrong invocation. Use 'libopenmpt_example_c SOMEMODULE'." );
-		goto fail;
-	}
-
-#if ( defined( _WIN32 ) || defined( WIN32 ) ) && ( defined( _UNICODE ) || defined( UNICODE ) )
-	if ( wcslen( argv[1] ) == 0 ) {
-		fprintf( stderr, "Error: %s\n", "Wrong invocation. Use 'libopenmpt_example_c SOMEMODULE'." );
-		goto fail;
-	}
-	file = _wfopen( argv[1], L"rb" );
-#else
-	if ( strlen( argv[1] ) == 0 ) {
-		fprintf( stderr, "Error: %s\n", "Wrong invocation. Use 'libopenmpt_example_c SOMEMODULE'." );
-		goto fail;
-	}
-	file = fopen( argv[1], "rb" );
-#endif
-	if ( !file ) {
-		fprintf( stderr, "Error: %s\n", "fopen() failed." );
-		goto fail;
-	}
-
-	mod = openmpt_module_create2( openmpt_stream_get_file_callbacks(), file, &libopenmpt_example_logfunc, NULL, &libopenmpt_example_errfunc, NULL, &mod_err, &mod_err_str, NULL );
-	if ( !mod ) {
-		libopenmpt_example_print_error( "openmpt_module_create2()", mod_err, mod_err_str );
-		openmpt_free_string( mod_err_str );
-		mod_err_str = NULL;
-		goto fail;
-	}
-	openmpt_module_set_error_func( mod, NULL, NULL );
-
-	pa_error = Pa_Initialize();
-	if ( pa_error != paNoError ) {
-		fprintf( stderr, "Error: %s\n", "Pa_Initialize() failed." );
-		goto fail;
-	}
-	pa_initialized = 1;
-
-	pa_error = Pa_OpenDefaultStream( &stream, 0, 2, paInt16 | paNonInterleaved, SAMPLERATE, paFramesPerBufferUnspecified, NULL, NULL );
-	if ( pa_error != paNoError ) {
-		fprintf( stderr, "Error: %s\n", "Pa_OpenStream() failed." );
-		goto fail;
-	}
-	if ( !stream ) {
-		fprintf( stderr, "Error: %s\n", "Pa_OpenStream() failed." );
-		goto fail;
-	}
-
-	pa_error = Pa_StartStream( stream );
-	if ( pa_error != paNoError ) {
-		fprintf( stderr, "Error: %s\n", "Pa_StartStream() failed." );
-		goto fail;
-	}
-
-	while ( 1 ) {
-
-		openmpt_module_error_clear( mod );
-		count = openmpt_module_read_stereo( mod, SAMPLERATE, BUFFERSIZE, left, right );
-		mod_err = openmpt_module_error_get_last( mod );
-		mod_err_str = openmpt_module_error_get_last_message( mod );
-		if ( mod_err != OPENMPT_ERROR_OK ) {
-			libopenmpt_example_print_error( "openmpt_module_read_stereo()", mod_err, mod_err_str );
-			openmpt_free_string( mod_err_str );
-			mod_err_str = NULL;
-		}
-		if ( count == 0 ) {
-			break;
-		}
-
-		pa_error = Pa_WriteStream( stream, buffers, (unsigned long)count );
-		if ( pa_error == paOutputUnderflowed ) {
-			pa_error = paNoError;
-		}
-		if ( pa_error != paNoError ) {
-			fprintf( stderr, "Error: %s\n", "Pa_WriteStream() failed." );
-			goto fail;
-		}
-	}
-
-	result = 0;
-
-	goto cleanup;
-
-fail:
-
-	result = 1;
-
-cleanup:
-
-	if ( stream ) {
-		if ( Pa_IsStreamActive( stream ) == 1 ) {
-			Pa_StopStream( stream );
-		}
-		Pa_CloseStream( stream );
-		stream = 0;
-	}
-
-	if ( pa_initialized ) {
-		Pa_Terminate();
-		pa_initialized = 0;
-	}
-
-	if ( mod ) {
-		openmpt_module_destroy( mod );
-		mod = 0;
-	}
-
-	if ( file ) {
-		fclose( file );
-		file = 0;
-	}
-
-	return result;
-}

+ 0 - 292
libopenmpt.mod/openmpt/examples/libopenmpt_example_c_mem.c

@@ -1,292 +0,0 @@
-/*
- * libopenmpt_example_c_mem.c
- * --------------------------
- * Purpose: libopenmpt C API example
- * Notes  : PortAudio is used for sound output.
- * Authors: OpenMPT Devs
- * The OpenMPT source code is released under the BSD license. Read LICENSE for more details.
- */
-
-/*
- * Usage: libopenmpt_example_c_mem SOMEMODULE
- */
-
-#include <memory.h>
-#include <stdint.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include <libopenmpt/libopenmpt.h>
-
-#include <portaudio.h>
-
-#define BUFFERSIZE 480
-#define SAMPLERATE 48000
-
-static int16_t left[BUFFERSIZE];
-static int16_t right[BUFFERSIZE];
-static int16_t * const buffers[2] = { left, right };
-
-static void libopenmpt_example_logfunc( const char * message, void * userdata ) {
-	(void)userdata;
-	if ( message ) {
-		fprintf( stderr, "openmpt: %s\n", message );
-	}
-}
-
-static int libopenmpt_example_errfunc( int error, void * userdata ) {
-	(void)userdata;
-	(void)error;
-	return OPENMPT_ERROR_FUNC_RESULT_DEFAULT & ~OPENMPT_ERROR_FUNC_RESULT_LOG;
-}
-
-static void libopenmpt_example_print_error( const char * func_name, int mod_err, const char * mod_err_str ) {
-	if ( !func_name ) {
-		func_name = "unknown function";
-	}
-	if ( mod_err == OPENMPT_ERROR_OUT_OF_MEMORY ) {
-		mod_err_str = openmpt_error_string( mod_err );
-		if ( !mod_err_str ) {
-			fprintf( stderr, "Error: %s\n", "OPENMPT_ERROR_OUT_OF_MEMORY" );
-		} else {
-			fprintf( stderr, "Error: %s\n", mod_err_str );
-			openmpt_free_string( mod_err_str );
-			mod_err_str = NULL;
-		}
-	} else {
-		if ( !mod_err_str ) {
-			mod_err_str = openmpt_error_string( mod_err );
-			if ( !mod_err_str ) {
-				fprintf( stderr, "Error: %s failed.\n", func_name );
-			} else {
-				fprintf( stderr, "Error: %s failed: %s\n", func_name, mod_err_str );
-			}
-			openmpt_free_string( mod_err_str );
-			mod_err_str = NULL;
-		}
-		fprintf( stderr, "Error: %s failed: %s\n", func_name, mod_err_str );
-	}
-}
-
-typedef struct blob_t {
-	size_t size;
-	void * data;
-} blob_t;
-
-static void free_blob( blob_t * blob ) {
-	if ( blob ) {
-		if ( blob->data ) {
-			free( blob->data );
-			blob->data = 0;
-		}
-		blob->size = 0;
-		free( blob );
-	}
-}
-
-#if ( defined( _WIN32 ) || defined( WIN32 ) ) && ( defined( _UNICODE ) || defined( UNICODE ) )
-static blob_t * load_file( const wchar_t * filename ) {
-#else
-static blob_t * load_file( const char * filename ) {
-#endif
-	blob_t * result = 0;
-
-	blob_t * blob = 0;
-	FILE * file = 0;
-	long tell_result = 0;
-
-	blob = malloc( sizeof( blob_t ) );
-	if ( !blob ) {
-		goto fail;
-	}
-	memset( blob, 0, sizeof( blob_t ) );
-
-#if ( defined( _WIN32 ) || defined( WIN32 ) ) && ( defined( _UNICODE ) || defined( UNICODE ) )
-	file = _wfopen( filename, L"rb" );
-#else
-	file = fopen( filename, "rb" );
-#endif
-	if ( !file ) {
-		goto fail;
-	}
-
-	if ( fseek( file, 0, SEEK_END ) != 0 ) {
-		goto fail;
-	}
-
-	tell_result = ftell( file );
-	if ( tell_result < 0 ) {
-		goto fail;
-	}
-	if ( (unsigned long)tell_result > SIZE_MAX ) {
-		goto fail;
-	}
-	blob->size = (size_t)tell_result;
-
-	if ( fseek( file, 0, SEEK_SET ) != 0 ) {
-		goto fail;
-	}
-
-	blob->data = malloc( blob->size );
-	if ( !blob->data ) {
-		goto fail;
-	}
-	memset( blob->data, 0, blob->size );
-
-	if ( fread( blob->data, 1, blob->size, file ) != blob->size ) {
-		goto fail;
-	}
-
-	result = blob;
-	blob = 0;
-	goto cleanup;
-
-fail:
-
-	result = 0;
-
-cleanup:
-
-	if ( blob ) {
-		free_blob( blob );
-		blob = 0;
-	}
-
-	if ( file ) {
-		fclose( file );
-		file = 0;
-	}
-
-	return result;
-}
-
-#if ( defined( _WIN32 ) || defined( WIN32 ) ) && ( defined( _UNICODE ) || defined( UNICODE ) )
-int wmain( int argc, wchar_t * argv[] ) {
-#else
-int main( int argc, char * argv[] ) {
-#endif
-
-	int result = 0;
-	blob_t * blob = 0;
-	openmpt_module * mod = 0;
-	int mod_err = OPENMPT_ERROR_OK;
-	const char * mod_err_str = NULL;
-	size_t count = 0;
-	PaError pa_error = paNoError;
-	int pa_initialized = 0;
-	PaStream * stream = 0;
-
-	if ( argc != 2 ) {
-		fprintf( stderr, "Error: %s\n", "Wrong invocation. Use 'libopenmpt_example_c_mem SOMEMODULE'." );
-		goto fail;
-	}
-
-#if ( defined( _WIN32 ) || defined( WIN32 ) ) && ( defined( _UNICODE ) || defined( UNICODE ) )
-	if ( wcslen( argv[1] ) == 0 ) {
-		fprintf( stderr, "Error: %s\n", "Wrong invocation. Use 'libopenmpt_example_c_mem SOMEMODULE'." );
-		goto fail;
-	}
-#else
-	if ( strlen( argv[1] ) == 0 ) {
-		fprintf( stderr, "Error: %s\n", "Wrong invocation. Use 'libopenmpt_example_c_mem SOMEMODULE'." );
-		goto fail;
-	}
-#endif
-	blob = load_file( argv[1] );
-	if ( !blob ) {
-		fprintf( stderr, "Error: %s\n", "load_file() failed." );
-		goto fail;
-	}
-
-	mod = openmpt_module_create_from_memory2( blob->data, blob->size, &libopenmpt_example_logfunc, NULL, &libopenmpt_example_errfunc, NULL, &mod_err, &mod_err_str, NULL );
-	if ( !mod ) {
-		libopenmpt_example_print_error( "openmpt_module_create_from_memory2()", mod_err, mod_err_str );
-		openmpt_free_string( mod_err_str );
-		mod_err_str = NULL;
-		goto fail;
-	}
-
-	pa_error = Pa_Initialize();
-	if ( pa_error != paNoError ) {
-		fprintf( stderr, "Error: %s\n", "Pa_Initialize() failed." );
-		goto fail;
-	}
-	pa_initialized = 1;
-
-	pa_error = Pa_OpenDefaultStream( &stream, 0, 2, paInt16 | paNonInterleaved, SAMPLERATE, paFramesPerBufferUnspecified, NULL, NULL );
-	if ( pa_error != paNoError ) {
-		fprintf( stderr, "Error: %s\n", "Pa_OpenStream() failed." );
-		goto fail;
-	}
-	if ( !stream ) {
-		fprintf( stderr, "Error: %s\n", "Pa_OpenStream() failed." );
-		goto fail;
-	}
-
-	pa_error = Pa_StartStream( stream );
-	if ( pa_error != paNoError ) {
-		fprintf( stderr, "Error: %s\n", "Pa_StartStream() failed." );
-		goto fail;
-	}
-
-	while ( 1 ) {
-
-		openmpt_module_error_clear( mod );
-		count = openmpt_module_read_stereo( mod, SAMPLERATE, BUFFERSIZE, left, right );
-		mod_err = openmpt_module_error_get_last( mod );
-		mod_err_str = openmpt_module_error_get_last_message( mod );
-		if ( mod_err != OPENMPT_ERROR_OK ) {
-			libopenmpt_example_print_error( "openmpt_module_read_stereo()", mod_err, mod_err_str );
-			openmpt_free_string( mod_err_str );
-			mod_err_str = NULL;
-		}
-		if ( count == 0 ) {
-			break;
-		}
-
-		pa_error = Pa_WriteStream( stream, buffers, (unsigned long)count );
-		if ( pa_error == paOutputUnderflowed ) {
-			pa_error = paNoError;
-		}
-		if ( pa_error != paNoError ) {
-			fprintf( stderr, "Error: %s\n", "Pa_WriteStream() failed." );
-			goto fail;
-		}
-	}
-
-	result = 0;
-
-	goto cleanup;
-
-fail:
-
-	result = 1;
-
-cleanup:
-
-	if ( stream ) {
-		if ( Pa_IsStreamActive( stream ) == 1 ) {
-			Pa_StopStream( stream );
-		}
-		Pa_CloseStream( stream );
-		stream = 0;
-	}
-
-	if ( pa_initialized ) {
-		Pa_Terminate();
-		pa_initialized = 0;
-	}
-
-	if ( mod ) {
-		openmpt_module_destroy( mod );
-		mod = 0;
-	}
-
-	if ( blob ) {
-		free_blob( blob );
-		blob = 0;
-	}
-
-	return result;
-}

+ 0 - 152
libopenmpt.mod/openmpt/examples/libopenmpt_example_c_pipe.c

@@ -1,152 +0,0 @@
-/*
- * libopenmpt_example_c_pipe.c
- * ---------------------------
- * Purpose: libopenmpt C API simple pipe example
- * Notes  : This example writes raw 48000Hz / stereo / 16bit native endian PCM data to stdout.
- * Authors: OpenMPT Devs
- * The OpenMPT source code is released under the BSD license. Read LICENSE for more details.
- */
-
-/*
- * Usage: cat SOMEMODULE | libopenmpt_example_c_pipe | aplay --file-type raw --format=dat
- */
-
-#include <memory.h>
-#include <stdint.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include <errno.h>
-#include <unistd.h>
-
-#include <libopenmpt/libopenmpt.h>
-#include <libopenmpt/libopenmpt_stream_callbacks_fd.h>
-
-#define BUFFERSIZE 480
-#define SAMPLERATE 48000
-
-static void libopenmpt_example_logfunc( const char * message, void * userdata ) {
-	(void)userdata;
-	if ( message ) {
-		fprintf( stderr, "openmpt: %s\n", message );
-	}
-}
-
-static int libopenmpt_example_errfunc( int error, void * userdata ) {
-	(void)userdata;
-	(void)error;
-	return OPENMPT_ERROR_FUNC_RESULT_DEFAULT & ~OPENMPT_ERROR_FUNC_RESULT_LOG;
-}
-
-static void libopenmpt_example_print_error( const char * func_name, int mod_err, const char * mod_err_str ) {
-	if ( !func_name ) {
-		func_name = "unknown function";
-	}
-	if ( mod_err == OPENMPT_ERROR_OUT_OF_MEMORY ) {
-		mod_err_str = openmpt_error_string( mod_err );
-		if ( !mod_err_str ) {
-			fprintf( stderr, "Error: %s\n", "OPENMPT_ERROR_OUT_OF_MEMORY" );
-		} else {
-			fprintf( stderr, "Error: %s\n", mod_err_str );
-			openmpt_free_string( mod_err_str );
-			mod_err_str = NULL;
-		}
-	} else {
-		if ( !mod_err_str ) {
-			mod_err_str = openmpt_error_string( mod_err );
-			if ( !mod_err_str ) {
-				fprintf( stderr, "Error: %s failed.\n", func_name );
-			} else {
-				fprintf( stderr, "Error: %s failed: %s\n", func_name, mod_err_str );
-			}
-			openmpt_free_string( mod_err_str );
-			mod_err_str = NULL;
-		}
-		fprintf( stderr, "Error: %s failed: %s\n", func_name, mod_err_str );
-	}
-}
-
-static ssize_t xwrite( int fd, const void * buffer, size_t size ) {
-	size_t written = 0;
-	ssize_t retval = 0;
-	while ( written < size ) {
-		retval = write( fd, (const char *)buffer + written, size - written );
-		if ( retval < 0 ) {
-			if ( errno != EINTR ) {
-				break;
-			}
-			retval = 0;
-		}
-		written += retval;
-	}
-	return written;
-}
-
-static int16_t buffer[BUFFERSIZE * 2];
-
-#if ( defined( _WIN32 ) || defined( WIN32 ) ) && ( defined( _UNICODE ) || defined( UNICODE ) )
-int wmain( int argc, wchar_t * argv[] ) {
-#else
-int main( int argc, char * argv[] ) {
-#endif
-
-	int result = 0;
-	openmpt_module * mod = 0;
-	int mod_err = OPENMPT_ERROR_OK;
-	const char * mod_err_str = NULL;
-	size_t count = 0;
-	size_t written = 0;
-	(void)argv;
-
-	if ( argc != 1 ) {
-		fprintf( stderr, "Error: %s\n", "Wrong invocation. Use 'libopenmpt_example_c_pipe' and connect stdin and stdout." );
-		goto fail;
-	}
-
-	mod = openmpt_module_create2( openmpt_stream_get_fd_callbacks(), (void*)(uintptr_t)STDIN_FILENO, &libopenmpt_example_logfunc, NULL, &libopenmpt_example_errfunc, NULL, &mod_err, &mod_err_str, NULL );
-	if ( !mod ) {
-		libopenmpt_example_print_error( "openmpt_module_create2()", mod_err, mod_err_str );
-		openmpt_free_string( mod_err_str );
-		mod_err_str = NULL;
-		goto fail;
-	}
-
-	while ( 1 ) {
-
-		openmpt_module_error_clear( mod );
-		count = openmpt_module_read_interleaved_stereo( mod, SAMPLERATE, BUFFERSIZE, buffer );
-		mod_err = openmpt_module_error_get_last( mod );
-		mod_err_str = openmpt_module_error_get_last_message( mod );
-		if ( mod_err != OPENMPT_ERROR_OK ) {
-			libopenmpt_example_print_error( "openmpt_module_read_interleaved_stereo()", mod_err, mod_err_str );
-			openmpt_free_string( mod_err_str );
-			mod_err_str = NULL;
-		}
-		if ( count == 0 ) {
-			break;
-		}
-
-		written = xwrite( STDOUT_FILENO, buffer, count * 2 * sizeof( int16_t ) );
-		if ( written == 0 ) {
-			fprintf( stderr, "Error: %s\n", "write() failed." );
-			goto fail;
-		}
-	}
-
-	result = 0;
-
-	goto cleanup;
-
-fail:
-
-	result = 1;
-
-cleanup:
-
-	if ( mod ) {
-		openmpt_module_destroy( mod );
-		mod = 0;
-	}
-
-	return result;
-}

+ 0 - 181
libopenmpt.mod/openmpt/examples/libopenmpt_example_c_probe.c

@@ -1,181 +0,0 @@
-/*
- * libopenmpt_example_c_probe.c
- * ----------------------------
- * Purpose: libopenmpt C API probing example
- * Notes  : (currently none)
- * Authors: OpenMPT Devs
- * The OpenMPT source code is released under the BSD license. Read LICENSE for more details.
- */
-
-/*
- * Usage: libopenmpt_example_c_probe SOMEMODULE ...
- * Returns 0 on successful probing for all files.
- * Returns 1 on failed probing for 1 or more files.
- * Returns 2 on error.
- */
-
-#define LIBOPENMPT_EXAMPLE_PROBE_RESULT_BINARY 1
-#define LIBOPENMPT_EXAMPLE_PROBE_RESULT_FLOAT  2
-
-#define LIBOPENMPT_EXAMPLE_PROBE_RESULT LIBOPENMPT_EXAMPLE_PROBE_RESULT_BINARY
-
-#include <memory.h>
-#include <stdint.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include <libopenmpt/libopenmpt.h>
-#include <libopenmpt/libopenmpt_stream_callbacks_file.h>
-
-static void libopenmpt_example_logfunc( const char * message, void * userdata ) {
-	(void)userdata;
-
-	if ( message ) {
-		fprintf( stderr, "%s\n", message );
-	}
-}
-
-#if ( defined( _WIN32 ) || defined( WIN32 ) ) && ( defined( _UNICODE ) || defined( UNICODE ) )
-static int probe_file( const wchar_t * filename ) {
-#else
-static int probe_file( const char * filename ) {
-#endif
-
-	int result = 0;
-	int mod_err = OPENMPT_ERROR_OK;
-	FILE * file = NULL;
-
-#if ( LIBOPENMPT_EXAMPLE_PROBE_RESULT == LIBOPENMPT_EXAMPLE_PROBE_RESULT_BINARY )
-	int result_binary = 0;
-	int probe_file_header_result = OPENMPT_PROBE_FILE_HEADER_RESULT_FAILURE;
-	const char * probe_file_header_result_str = NULL;
-#endif
-#if ( LIBOPENMPT_EXAMPLE_PROBE_RESULT == LIBOPENMPT_EXAMPLE_PROBE_RESULT_FLOAT )
-	double probability = 0.0;
-#endif
-
-#if ( defined( _WIN32 ) || defined( WIN32 ) ) && ( defined( _UNICODE ) || defined( UNICODE ) )
-	if ( wcslen( filename ) == 0 ) {
-		fprintf( stderr, "Error: %s\n", "Wrong invocation. Use 'libopenmpt_example_c_probe SOMEMODULE'." );
-		goto fail;
-	}
-#else
-	if ( strlen( filename ) == 0 ) {
-		fprintf( stderr, "Error: %s\n", "Wrong invocation. Use 'libopenmpt_example_c_probe SOMEMODULE'." );
-		goto fail;
-	}
-#endif
-
-#if ( defined( _WIN32 ) || defined( WIN32 ) ) && ( defined( _UNICODE ) || defined( UNICODE ) )
-	file = _wfopen( filename, L"rb" );
-#else
-	file = fopen( filename, "rb" );
-#endif
-	if ( !file ) {
-		fprintf( stderr, "Error: %s\n", "fopen() failed." );
-		goto fail;
-	}
-
-	#if ( LIBOPENMPT_EXAMPLE_PROBE_RESULT == LIBOPENMPT_EXAMPLE_PROBE_RESULT_BINARY )
-		probe_file_header_result = openmpt_probe_file_header_from_stream( OPENMPT_PROBE_FILE_HEADER_FLAGS_DEFAULT, openmpt_stream_get_file_callbacks(), file, &libopenmpt_example_logfunc, NULL, &openmpt_error_func_default, NULL, &mod_err, NULL );
-		probe_file_header_result_str = NULL;
-		result_binary = 0;
-		switch ( probe_file_header_result ) {
-			case OPENMPT_PROBE_FILE_HEADER_RESULT_SUCCESS:
-				probe_file_header_result_str = "Success     ";
-				result_binary = 1;
-				break;
-			case OPENMPT_PROBE_FILE_HEADER_RESULT_FAILURE:
-				probe_file_header_result_str = "Failure     ";
-				result_binary = 0;
-				break;
-			case OPENMPT_PROBE_FILE_HEADER_RESULT_WANTMOREDATA:
-				probe_file_header_result_str = "WantMoreData";
-				result_binary = 0;
-				break;
-			case OPENMPT_PROBE_FILE_HEADER_RESULT_ERROR:
-				result_binary = 0;
-				fprintf( stderr, "Error: %s\n", "openmpt_probe_file_header() failed." );
-				goto fail;
-				break;
-			default:
-				result_binary = 0;
-				fprintf( stderr, "Error: %s\n", "openmpt_probe_file_header() failed." );
-				goto fail;
-				break;
-		}
-#if ( defined( _WIN32 ) || defined( WIN32 ) ) && ( defined( _UNICODE ) || defined( UNICODE ) )
-		fprintf( stdout, "%s - %ls\n", probe_file_header_result_str, filename );
-#else
-		fprintf( stdout, "%s - %s\n", probe_file_header_result_str, filename );
-#endif
-		if ( result_binary ) {
-			result = 0;
-		} else {
-			result = 1;
-		}
-	#elif ( LIBOPENMPT_EXAMPLE_PROBE_RESULT == LIBOPENMPT_EXAMPLE_PROBE_RESULT_FLOAT )
-		probability = openmpt_could_open_probability2( openmpt_stream_get_file_callbacks(), file, 0.25, &libopenmpt_example_logfunc, NULL, &openmpt_error_func_default, NULL, &mod_err, NULL );
-#if ( defined( _WIN32 ) || defined( WIN32 ) ) && ( defined( _UNICODE ) || defined( UNICODE ) )
-		fprintf( stdout, "%s: %f - %ls\n", "Result", probability, filename );
-#else
-		fprintf( stdout, "%s: %f - %s\n", "Result", probability, filename );
-#endif
-		if ( probability >= 0.5 ) {
-			result = 0;
-		} else {
-			result = 1;
-		}
-	#else
-		#error "LIBOPENMPT_EXAMPLE_PROBE_RESULT is wrong"
-	#endif
-
-	goto cleanup;
-
-fail:
-
-	result = 2;
-
-cleanup:
-
-	if ( file ) {
-		fclose( file );
-		file = 0;
-	}
-
-	return result;
-}
-
-#if ( defined( _WIN32 ) || defined( WIN32 ) ) && ( defined( _UNICODE ) || defined( UNICODE ) )
-int wmain( int argc, wchar_t * argv[] ) {
-#else
-int main( int argc, char * argv[] ) {
-#endif
-
-	int global_result = 0;
-
-	if ( argc <= 1 ) {
-		fprintf( stderr, "Error: %s\n", "Wrong invocation. Use 'libopenmpt_example_c_probe SOMEMODULE ...'." );
-		goto fail;
-	}
-
-	for ( int i = 1; i < argc; ++i ) {
-		int result = probe_file( argv[i] );
-		if ( result > global_result ) {
-			global_result = result;
-		}
-	}
-
-	goto cleanup;
-
-fail:
-
-	global_result = 2;
-
-cleanup:
-
-	return global_result;
-
-}
-

+ 0 - 176
libopenmpt.mod/openmpt/examples/libopenmpt_example_c_stdout.c

@@ -1,176 +0,0 @@
-/*
- * libopenmpt_example_c_stdout.c
- * -----------------------------
- * Purpose: libopenmpt C API simple example
- * Notes  : This example writes raw 48000Hz / stereo / 16bit native endian PCM data to stdout.
- * Authors: OpenMPT Devs
- * The OpenMPT source code is released under the BSD license. Read LICENSE for more details.
- */
-
-/*
- * Usage: libopenmpt_example_c_stdout SOMEMODULE | aplay --file-type raw --format=dat
- */
-
-#include <memory.h>
-#include <stdint.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include <errno.h>
-#include <unistd.h>
-
-#include <libopenmpt/libopenmpt.h>
-#include <libopenmpt/libopenmpt_stream_callbacks_file.h>
-
-#define BUFFERSIZE 480
-#define SAMPLERATE 48000
-
-static void libopenmpt_example_logfunc( const char * message, void * userdata ) {
-	(void)userdata;
-	if ( message ) {
-		fprintf( stderr, "openmpt: %s\n", message );
-	}
-}
-
-static int libopenmpt_example_errfunc( int error, void * userdata ) {
-	(void)userdata;
-	(void)error;
-	return OPENMPT_ERROR_FUNC_RESULT_DEFAULT & ~OPENMPT_ERROR_FUNC_RESULT_LOG;
-}
-
-static void libopenmpt_example_print_error( const char * func_name, int mod_err, const char * mod_err_str ) {
-	if ( !func_name ) {
-		func_name = "unknown function";
-	}
-	if ( mod_err == OPENMPT_ERROR_OUT_OF_MEMORY ) {
-		mod_err_str = openmpt_error_string( mod_err );
-		if ( !mod_err_str ) {
-			fprintf( stderr, "Error: %s\n", "OPENMPT_ERROR_OUT_OF_MEMORY" );
-		} else {
-			fprintf( stderr, "Error: %s\n", mod_err_str );
-			openmpt_free_string( mod_err_str );
-			mod_err_str = NULL;
-		}
-	} else {
-		if ( !mod_err_str ) {
-			mod_err_str = openmpt_error_string( mod_err );
-			if ( !mod_err_str ) {
-				fprintf( stderr, "Error: %s failed.\n", func_name );
-			} else {
-				fprintf( stderr, "Error: %s failed: %s\n", func_name, mod_err_str );
-			}
-			openmpt_free_string( mod_err_str );
-			mod_err_str = NULL;
-		}
-		fprintf( stderr, "Error: %s failed: %s\n", func_name, mod_err_str );
-	}
-}
-
-static ssize_t xwrite( int fd, const void * buffer, size_t size ) {
-	size_t written = 0;
-	ssize_t retval = 0;
-	while ( written < size ) {
-		retval = write( fd, (const char *)buffer + written, size - written );
-		if ( retval < 0 ) {
-			if ( errno != EINTR ) {
-				break;
-			}
-			retval = 0;
-		}
-		written += retval;
-	}
-	return written;
-}
-
-static int16_t buffer[BUFFERSIZE * 2];
-
-#if ( defined( _WIN32 ) || defined( WIN32 ) ) && ( defined( _UNICODE ) || defined( UNICODE ) )
-int wmain( int argc, wchar_t * argv[] ) {
-#else
-int main( int argc, char * argv[] ) {
-#endif
-
-	int result = 0;
-	FILE * file = 0;
-	openmpt_module * mod = 0;
-	int mod_err = OPENMPT_ERROR_OK;
-	const char * mod_err_str = NULL;
-	size_t count = 0;
-	size_t written = 0;
-
-	if ( argc != 2 ) {
-		fprintf( stderr, "Error: %s\n", "Wrong invocation. Use 'libopenmpt_example_c_stdout SOMEMODULE'." );
-		goto fail;
-	}
-
-#if ( defined( _WIN32 ) || defined( WIN32 ) ) && ( defined( _UNICODE ) || defined( UNICODE ) )
-	if ( wcslen( argv[1] ) == 0 ) {
-		fprintf( stderr, "Error: %s\n", "Wrong invocation. Use 'libopenmpt_example_c_stdout SOMEMODULE'." );
-		goto fail;
-	}
-	file = _wfopen( argv[1], L"rb" );
-#else
-	if ( strlen( argv[1] ) == 0 ) {
-		fprintf( stderr, "Error: %s\n", "Wrong invocation. Use 'libopenmpt_example_c_stdout SOMEMODULE'." );
-		goto fail;
-	}
-	file = fopen( argv[1], "rb" );
-#endif
-	if ( !file ) {
-		fprintf( stderr, "Error: %s\n", "fopen() failed." );
-		goto fail;
-	}
-
-	mod = openmpt_module_create2( openmpt_stream_get_file_callbacks(), file, &libopenmpt_example_logfunc, NULL, &libopenmpt_example_errfunc, NULL, &mod_err, &mod_err_str, NULL );
-	if ( !mod ) {
-		libopenmpt_example_print_error( "openmpt_module_create2()", mod_err, mod_err_str );
-		openmpt_free_string( mod_err_str );
-		mod_err_str = NULL;
-		goto fail;
-	}
-
-	while ( 1 ) {
-
-		openmpt_module_error_clear( mod );
-		count = openmpt_module_read_interleaved_stereo( mod, SAMPLERATE, BUFFERSIZE, buffer );
-		mod_err = openmpt_module_error_get_last( mod );
-		mod_err_str = openmpt_module_error_get_last_message( mod );
-		if ( mod_err != OPENMPT_ERROR_OK ) {
-			libopenmpt_example_print_error( "openmpt_module_read_interleaved_stereo()", mod_err, mod_err_str );
-			openmpt_free_string( mod_err_str );
-			mod_err_str = NULL;
-		}
-		if ( count == 0 ) {
-			break;
-		}
-
-		written = xwrite( STDOUT_FILENO, buffer, count * 2 * sizeof( int16_t ) );
-		if ( written == 0 ) {
-			fprintf( stderr, "Error: %s\n", "write() failed." );
-			goto fail;
-		}
-	}
-
-	result = 0;
-
-	goto cleanup;
-
-fail:
-
-	result = 1;
-
-cleanup:
-
-	if ( mod ) {
-		openmpt_module_destroy( mod );
-		mod = 0;
-	}
-
-	if ( file ) {
-		fclose( file );
-		file = 0;
-	}
-
-	return result;
-}

+ 0 - 65
libopenmpt.mod/openmpt/examples/libopenmpt_example_c_unsafe.c

@@ -1,65 +0,0 @@
-/*
- * libopenmpt_example_c_unsafe.c
- * -----------------------------
- * Purpose: libopenmpt C API simplified example
- * Notes  : PortAudio is used for sound output.
- * Authors: OpenMPT Devs
- * The OpenMPT source code is released under the BSD license. Read LICENSE for more details.
- */
-
-/*
- * Usage: libopenmpt_example_c_unsafe SOMEMODULE
- * CAUTION: This simple example does no error cheking at all.
- */
-
-#include <memory.h>
-#include <stdint.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include <libopenmpt/libopenmpt.h>
-#include <libopenmpt/libopenmpt_stream_callbacks_file.h>
-
-#include <portaudio.h>
-
-#define BUFFERSIZE 480
-#define SAMPLERATE 48000
-
-static int16_t left[BUFFERSIZE];
-static int16_t right[BUFFERSIZE];
-static int16_t * const buffers[2] = { left, right };
-
-#if ( defined( _WIN32 ) || defined( WIN32 ) ) && ( defined( _UNICODE ) || defined( UNICODE ) )
-int wmain( int argc, wchar_t * argv[] ) {
-#else
-int main( int argc, char * argv[] ) {
-#endif
-	FILE * file = 0;
-	openmpt_module * mod = 0;
-	size_t count = 0;
-	PaStream * stream = 0;
-	(void)argc;
-#if ( defined( _WIN32 ) || defined( WIN32 ) ) && ( defined( _UNICODE ) || defined( UNICODE ) )
-	file = _wfopen( argv[1], L"rb" );
-#else
-	file = fopen( argv[1], "rb" );
-#endif
-	mod = openmpt_module_create2( openmpt_stream_get_file_callbacks(), file, NULL, NULL, NULL, NULL, NULL, NULL, NULL );
-	fclose( file );
-	Pa_Initialize();
-	Pa_OpenDefaultStream( &stream, 0, 2, paInt16 | paNonInterleaved, SAMPLERATE, paFramesPerBufferUnspecified, NULL, NULL );
-	Pa_StartStream( stream );
-	while ( 1 ) {
-		count = openmpt_module_read_stereo( mod, SAMPLERATE, BUFFERSIZE, left, right );
-		if ( count == 0 ) {
-			break;
-		}
-		Pa_WriteStream( stream, buffers, (unsigned long)count );
-	}
-	Pa_StopStream( stream );
-	Pa_CloseStream( stream );
-	Pa_Terminate();
-	openmpt_module_destroy( mod );
-	return 0;
-}

+ 0 - 85
libopenmpt.mod/openmpt/examples/libopenmpt_example_cxx.cpp

@@ -1,85 +0,0 @@
-/*
- * libopenmpt_example_cxx.cpp
- * --------------------------
- * Purpose: libopenmpt C++ API example
- * Notes  : PortAudio C++ is used for sound output.
- * Authors: OpenMPT Devs
- * The OpenMPT source code is released under the BSD license. Read LICENSE for more details.
- */
-
-/*
- * Usage: libopenmpt_example_cxx SOMEMODULE
- */
-
-#include <exception>
-#include <fstream>
-#include <iostream>
-#include <new>
-#include <stdexcept>
-#include <vector>
-
-#include <libopenmpt/libopenmpt.hpp>
-
-#if defined(__clang__)
-#if ((__clang_major__ * 10000 + __clang_minor__ * 100 + __clang_patchlevel__) >= 40000)
-#pragma clang diagnostic push
-#pragma clang diagnostic ignored "-Wdeprecated-dynamic-exception-spec"
-#endif
-#endif
-#include <portaudiocpp/PortAudioCpp.hxx>
-#if defined(__clang__)
-#if ((__clang_major__ * 10000 + __clang_minor__ * 100 + __clang_patchlevel__) >= 40000)
-#pragma clang diagnostic pop
-#endif
-#endif
-
-#if ( defined( _WIN32 ) || defined( WIN32 ) ) && ( defined( _UNICODE ) || defined( UNICODE ) )
-#if defined( __GNUC__ )
-// mingw-w64 g++ does only default to special C linkage for "main", but not for "wmain" (see <https://sourceforge.net/p/mingw-w64/wiki2/Unicode%20apps/>).
-extern "C" int wmain( int argc, wchar_t * argv[] ) {
-#else
-int wmain( int argc, wchar_t * argv[] ) {
-#endif
-#else
-int main( int argc, char * argv[] ) {
-#endif
-	try {
-		if ( argc != 2 ) {
-			throw std::runtime_error( "Usage: libopenmpt_example_cxx SOMEMODULE" );
-		}
-		constexpr std::size_t buffersize = 480;
-		constexpr std::int32_t samplerate = 48000;
-		std::vector<float> left( buffersize );
-		std::vector<float> right( buffersize );
-		std::ifstream file( argv[1], std::ios::binary );
-		openmpt::module mod( file );
-		portaudio::AutoSystem portaudio_initializer;
-		portaudio::System & portaudio = portaudio::System::instance();
-		portaudio::DirectionSpecificStreamParameters outputstream_parameters( portaudio.defaultOutputDevice(), 2, portaudio::FLOAT32, false, portaudio.defaultOutputDevice().defaultHighOutputLatency(), 0 );
-		portaudio::StreamParameters stream_parameters( portaudio::DirectionSpecificStreamParameters::null(), outputstream_parameters, samplerate, paFramesPerBufferUnspecified, paNoFlag );
-		portaudio::BlockingStream stream( stream_parameters );
-		stream.start();
-		while ( true ) {
-			std::size_t count = mod.read( samplerate, buffersize, left.data(), right.data() );
-			if ( count == 0 ) {
-				break;
-			}
-			try {
-				const float * const buffers[2] = { left.data(), right.data() };
-				stream.write( buffers, static_cast<unsigned long>( count ) );
-			} catch ( const portaudio::PaException & pa_exception ) {
-				if ( pa_exception.paError() != paOutputUnderflowed ) {
-					throw;
-				}
-			}
-		}
-		stream.stop();
-	} catch ( const std::bad_alloc & ) {
-		std::cerr << "Error: " << std::string( "out of memory" ) << std::endl;
-		return 1;
-	} catch ( const std::exception & e ) {
-		std::cerr << "Error: " << std::string( e.what() ? e.what() : "unknown error" ) << std::endl;
-		return 1;
-	}
-	return 0;
-}

+ 0 - 45
libopenmpt.mod/openmpt/libopenmpt/.clang-format

@@ -1,45 +0,0 @@
-Language: Cpp
-AccessModifierOffset: -2
-AlignEscapedNewlines: DontAlign
-AllowShortFunctionsOnASingleLine: Empty
-AlwaysBreakBeforeMultilineStrings: true
-AlwaysBreakTemplateDeclarations: true
-BinPackArguments: false
-BinPackParameters: false
-BraceWrapping:
- AfterClass: false
- AfterControlStatement: false
- AfterEnum: false
- AfterFunction: false
- AfterNamespace: false
- AfterObjCDeclaration: false
- AfterStruct: false
- AfterUnion: false
- BeforeCatch: false
- BeforeElse: false
- IndentBraces: false
-BreakBeforeBinaryOperators: NonAssignment
-BreakBeforeBraces: Custom
-BreakBeforeInheritanceComma: true
-BreakConstructorInitializersBeforeComma: true
-BreakStringLiterals: false
-ColumnLimit: 0
-CompactNamespaces: true
-ConstructorInitializerAllOnOneLineOrOnePerLine: true
-ConstructorInitializerIndentWidth: 2
-ContinuationIndentWidth: 2
-IndentCaseLabels: true
-IndentWidth: 2
-MaxEmptyLinesToKeep: 3
-PointerAlignment: Middle
-ReflowComments: false
-SortIncludes: false
-SortUsingDeclarations: false
-SpaceBeforeParens: ControlStatements
-SpacesBeforeTrailingComments: 2
-SpacesInContainerLiterals: false
-SpacesInParentheses: true
-SpacesInSquareBrackets: true
-Standard: Cpp11
-TabWidth: 2
-UseTab: ForIndentation

+ 0 - 2469
libopenmpt.mod/openmpt/libopenmpt/Doxyfile

@@ -1,2469 +0,0 @@
-# Doxyfile 1.8.13
-
-# This file describes the settings to be used by the documentation system
-# doxygen (www.doxygen.org) for a project.
-#
-# All text after a double hash (##) is considered a comment and is placed in
-# front of the TAG it is preceding.
-#
-# All text after a single hash (#) is considered a comment and will be ignored.
-# The format is:
-# TAG = value [value, ...]
-# For lists, items can also be appended using:
-# TAG += value [value, ...]
-# Values that contain spaces should be placed between quotes (\" \").
-
-#---------------------------------------------------------------------------
-# Project related configuration options
-#---------------------------------------------------------------------------
-
-# This tag specifies the encoding used for all characters in the config file
-# that follow. The default is UTF-8 which is also the encoding used for all text
-# before the first occurrence of this tag. Doxygen uses libiconv (or the iconv
-# built into libc) for the transcoding. See http://www.gnu.org/software/libiconv
-# for the list of possible encodings.
-# The default value is: UTF-8.
-
-DOXYFILE_ENCODING      = UTF-8
-
-# The PROJECT_NAME tag is a single word (or a sequence of words surrounded by
-# double-quotes, unless you are using Doxywizard) that should identify the
-# project for which the documentation is generated. This name is used in the
-# title of most generated pages and in a few other places.
-# The default value is: My Project.
-
-PROJECT_NAME           = "libopenmpt"
-
-# The PROJECT_NUMBER tag can be used to enter a project or revision number. This
-# could be handy for archiving the generated documentation or if some version
-# control system is used.
-
-PROJECT_NUMBER         = "unknown"
-
-# Using the PROJECT_BRIEF tag one can provide an optional one line description
-# for a project that appears at the top of each page and should give viewer a
-# quick idea about the purpose of the project. Keep the description short.
-
-PROJECT_BRIEF          = "cross-platform C++ and C library to decode tracked music files"
-
-# With the PROJECT_LOGO tag one can specify a logo or an icon that is included
-# in the documentation. The maximum height of the logo should not exceed 55
-# pixels and the maximum width should not exceed 200 pixels. Doxygen will copy
-# the logo to the output directory.
-
-PROJECT_LOGO           =
-
-# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) path
-# into which the generated documentation will be written. If a relative path is
-# entered, it will be relative to the location where doxygen was started. If
-# left blank the current directory will be used.
-
-OUTPUT_DIRECTORY       = bin/docs
-
-# If the CREATE_SUBDIRS tag is set to YES then doxygen will create 4096 sub-
-# directories (in 2 levels) under the output directory of each output format and
-# will distribute the generated files over these directories. Enabling this
-# option can be useful when feeding doxygen a huge amount of source files, where
-# putting all generated files in the same directory would otherwise causes
-# performance problems for the file system.
-# The default value is: NO.
-
-CREATE_SUBDIRS         = NO
-
-# If the ALLOW_UNICODE_NAMES tag is set to YES, doxygen will allow non-ASCII
-# characters to appear in the names of generated files. If set to NO, non-ASCII
-# characters will be escaped, for example _xE3_x81_x84 will be used for Unicode
-# U+3044.
-# The default value is: NO.
-
-ALLOW_UNICODE_NAMES    = NO
-
-# The OUTPUT_LANGUAGE tag is used to specify the language in which all
-# documentation generated by doxygen is written. Doxygen will use this
-# information to generate all constant output in the proper language.
-# Possible values are: Afrikaans, Arabic, Armenian, Brazilian, Catalan, Chinese,
-# Chinese-Traditional, Croatian, Czech, Danish, Dutch, English (United States),
-# Esperanto, Farsi (Persian), Finnish, French, German, Greek, Hungarian,
-# Indonesian, Italian, Japanese, Japanese-en (Japanese with English messages),
-# Korean, Korean-en (Korean with English messages), Latvian, Lithuanian,
-# Macedonian, Norwegian, Persian (Farsi), Polish, Portuguese, Romanian, Russian,
-# Serbian, Serbian-Cyrillic, Slovak, Slovene, Spanish, Swedish, Turkish,
-# Ukrainian and Vietnamese.
-# The default value is: English.
-
-OUTPUT_LANGUAGE        = English
-
-# If the BRIEF_MEMBER_DESC tag is set to YES, doxygen will include brief member
-# descriptions after the members that are listed in the file and class
-# documentation (similar to Javadoc). Set to NO to disable this.
-# The default value is: YES.
-
-BRIEF_MEMBER_DESC      = YES
-
-# If the REPEAT_BRIEF tag is set to YES, doxygen will prepend the brief
-# description of a member or function before the detailed description
-#
-# Note: If both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the
-# brief descriptions will be completely suppressed.
-# The default value is: YES.
-
-REPEAT_BRIEF           = YES
-
-# This tag implements a quasi-intelligent brief description abbreviator that is
-# used to form the text in various listings. Each string in this list, if found
-# as the leading text of the brief description, will be stripped from the text
-# and the result, after processing the whole list, is used as the annotated
-# text. Otherwise, the brief description is used as-is. If left blank, the
-# following values are used ($name is automatically replaced with the name of
-# the entity):The $name class, The $name widget, The $name file, is, provides,
-# specifies, contains, represents, a, an and the.
-
-ABBREVIATE_BRIEF       =
-
-# If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then
-# doxygen will generate a detailed section even if there is only a brief
-# description.
-# The default value is: NO.
-
-ALWAYS_DETAILED_SEC    = NO
-
-# If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all
-# inherited members of a class in the documentation of that class as if those
-# members were ordinary class members. Constructors, destructors and assignment
-# operators of the base classes will not be shown.
-# The default value is: NO.
-
-INLINE_INHERITED_MEMB  = NO
-
-# If the FULL_PATH_NAMES tag is set to YES, doxygen will prepend the full path
-# before files name in the file list and in the header files. If set to NO the
-# shortest path that makes the file name unique will be used
-# The default value is: YES.
-
-FULL_PATH_NAMES        = YES
-
-# The STRIP_FROM_PATH tag can be used to strip a user-defined part of the path.
-# Stripping is only done if one of the specified strings matches the left-hand
-# part of the path. The tag can be used to show relative paths in the file list.
-# If left blank the directory from which doxygen is run is used as the path to
-# strip.
-#
-# Note that you can specify absolute paths here, but also relative paths, which
-# will be relative from the directory where doxygen is started.
-# This tag requires that the tag FULL_PATH_NAMES is set to YES.
-
-STRIP_FROM_PATH        =
-
-# The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of the
-# path mentioned in the documentation of a class, which tells the reader which
-# header file to include in order to use a class. If left blank only the name of
-# the header file containing the class definition is used. Otherwise one should
-# specify the list of include paths that are normally passed to the compiler
-# using the -I flag.
-
-STRIP_FROM_INC_PATH    = .
-
-# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter (but
-# less readable) file names. This can be useful is your file systems doesn't
-# support long names like on DOS, Mac, or CD-ROM.
-# The default value is: NO.
-
-SHORT_NAMES            = NO
-
-# If the JAVADOC_AUTOBRIEF tag is set to YES then doxygen will interpret the
-# first line (until the first dot) of a Javadoc-style comment as the brief
-# description. If set to NO, the Javadoc-style will behave just like regular Qt-
-# style comments (thus requiring an explicit @brief command for a brief
-# description.)
-# The default value is: NO.
-
-JAVADOC_AUTOBRIEF      = NO
-
-# If the QT_AUTOBRIEF tag is set to YES then doxygen will interpret the first
-# line (until the first dot) of a Qt-style comment as the brief description. If
-# set to NO, the Qt-style will behave just like regular Qt-style comments (thus
-# requiring an explicit \brief command for a brief description.)
-# The default value is: NO.
-
-QT_AUTOBRIEF           = NO
-
-# The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make doxygen treat a
-# multi-line C++ special comment block (i.e. a block of //! or /// comments) as
-# a brief description. This used to be the default behavior. The new default is
-# to treat a multi-line C++ comment block as a detailed description. Set this
-# tag to YES if you prefer the old behavior instead.
-#
-# Note that setting this tag to YES also means that rational rose comments are
-# not recognized any more.
-# The default value is: NO.
-
-MULTILINE_CPP_IS_BRIEF = NO
-
-# If the INHERIT_DOCS tag is set to YES then an undocumented member inherits the
-# documentation from any documented member that it re-implements.
-# The default value is: YES.
-
-INHERIT_DOCS           = YES
-
-# If the SEPARATE_MEMBER_PAGES tag is set to YES then doxygen will produce a new
-# page for each member. If set to NO, the documentation of a member will be part
-# of the file/class/namespace that contains it.
-# The default value is: NO.
-
-SEPARATE_MEMBER_PAGES  = NO
-
-# The TAB_SIZE tag can be used to set the number of spaces in a tab. Doxygen
-# uses this value to replace tabs by spaces in code fragments.
-# Minimum value: 1, maximum value: 16, default value: 4.
-
-TAB_SIZE               = 2
-
-# This tag can be used to specify a number of aliases that act as commands in
-# the documentation. An alias has the form:
-# name=value
-# For example adding
-# "sideeffect=@par Side Effects:\n"
-# will allow you to put the command \sideeffect (or @sideeffect) in the
-# documentation, which will result in a user-defined paragraph with heading
-# "Side Effects:". You can put \n's in the value part of an alias to insert
-# newlines.
-
-ALIASES                =
-
-# This tag can be used to specify a number of word-keyword mappings (TCL only).
-# A mapping has the form "name=value". For example adding "class=itcl::class"
-# will allow you to use the command class in the itcl::class meaning.
-
-TCL_SUBST              =
-
-# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C sources
-# only. Doxygen will then generate output that is more tailored for C. For
-# instance, some of the names that are used will be different. The list of all
-# members will be omitted, etc.
-# The default value is: NO.
-
-OPTIMIZE_OUTPUT_FOR_C  = NO
-
-# Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java or
-# Python sources only. Doxygen will then generate output that is more tailored
-# for that language. For instance, namespaces will be presented as packages,
-# qualified scopes will look different, etc.
-# The default value is: NO.
-
-OPTIMIZE_OUTPUT_JAVA   = NO
-
-# Set the OPTIMIZE_FOR_FORTRAN tag to YES if your project consists of Fortran
-# sources. Doxygen will then generate output that is tailored for Fortran.
-# The default value is: NO.
-
-OPTIMIZE_FOR_FORTRAN   = NO
-
-# Set the OPTIMIZE_OUTPUT_VHDL tag to YES if your project consists of VHDL
-# sources. Doxygen will then generate output that is tailored for VHDL.
-# The default value is: NO.
-
-OPTIMIZE_OUTPUT_VHDL   = NO
-
-# Doxygen selects the parser to use depending on the extension of the files it
-# parses. With this tag you can assign which parser to use for a given
-# extension. Doxygen has a built-in mapping, but you can override or extend it
-# using this tag. The format is ext=language, where ext is a file extension, and
-# language is one of the parsers supported by doxygen: IDL, Java, Javascript,
-# C#, C, C++, D, PHP, Objective-C, Python, Fortran (fixed format Fortran:
-# FortranFixed, free formatted Fortran: FortranFree, unknown formatted Fortran:
-# Fortran. In the later case the parser tries to guess whether the code is fixed
-# or free formatted code, this is the default for Fortran type files), VHDL. For
-# instance to make doxygen treat .inc files as Fortran files (default is PHP),
-# and .f files as C (default is Fortran), use: inc=Fortran f=C.
-#
-# Note: For files without extension you can use no_extension as a placeholder.
-#
-# Note that for custom extensions you also need to set FILE_PATTERNS otherwise
-# the files are not read by doxygen.
-
-EXTENSION_MAPPING      =
-
-# If the MARKDOWN_SUPPORT tag is enabled then doxygen pre-processes all comments
-# according to the Markdown format, which allows for more readable
-# documentation. See http://daringfireball.net/projects/markdown/ for details.
-# The output of markdown processing is further processed by doxygen, so you can
-# mix doxygen, HTML, and XML commands with Markdown formatting. Disable only in
-# case of backward compatibilities issues.
-# The default value is: YES.
-
-MARKDOWN_SUPPORT       = YES
-
-# When the TOC_INCLUDE_HEADINGS tag is set to a non-zero value, all headings up
-# to that level are automatically included in the table of contents, even if
-# they do not have an id attribute.
-# Note: This feature currently applies only to Markdown headings.
-# Minimum value: 0, maximum value: 99, default value: 0.
-# This tag requires that the tag MARKDOWN_SUPPORT is set to YES.
-
-TOC_INCLUDE_HEADINGS   = 0
-
-# When enabled doxygen tries to link words that correspond to documented
-# classes, or namespaces to their corresponding documentation. Such a link can
-# be prevented in individual cases by putting a % sign in front of the word or
-# globally by setting AUTOLINK_SUPPORT to NO.
-# The default value is: YES.
-
-AUTOLINK_SUPPORT       = YES
-
-# If you use STL classes (i.e. std::string, std::vector, etc.) but do not want
-# to include (a tag file for) the STL sources as input, then you should set this
-# tag to YES in order to let doxygen match functions declarations and
-# definitions whose arguments contain STL classes (e.g. func(std::string);
-# versus func(std::string) {}). This also make the inheritance and collaboration
-# diagrams that involve STL classes more complete and accurate.
-# The default value is: NO.
-
-BUILTIN_STL_SUPPORT    = YES
-
-# If you use Microsoft's C++/CLI language, you should set this option to YES to
-# enable parsing support.
-# The default value is: NO.
-
-CPP_CLI_SUPPORT        = NO
-
-# Set the SIP_SUPPORT tag to YES if your project consists of sip (see:
-# http://www.riverbankcomputing.co.uk/software/sip/intro) sources only. Doxygen
-# will parse them like normal C++ but will assume all classes use public instead
-# of private inheritance when no explicit protection keyword is present.
-# The default value is: NO.
-
-SIP_SUPPORT            = NO
-
-# For Microsoft's IDL there are propget and propput attributes to indicate
-# getter and setter methods for a property. Setting this option to YES will make
-# doxygen to replace the get and set methods by a property in the documentation.
-# This will only work if the methods are indeed getting or setting a simple
-# type. If this is not the case, or you want to show the methods anyway, you
-# should set this option to NO.
-# The default value is: YES.
-
-IDL_PROPERTY_SUPPORT   = YES
-
-# If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC
-# tag is set to YES then doxygen will reuse the documentation of the first
-# member in the group (if any) for the other members of the group. By default
-# all members of a group must be documented explicitly.
-# The default value is: NO.
-
-DISTRIBUTE_GROUP_DOC   = NO
-
-# If one adds a struct or class to a group and this option is enabled, then also
-# any nested class or struct is added to the same group. By default this option
-# is disabled and one has to add nested compounds explicitly via \ingroup.
-# The default value is: NO.
-
-GROUP_NESTED_COMPOUNDS = NO
-
-# Set the SUBGROUPING tag to YES to allow class member groups of the same type
-# (for instance a group of public functions) to be put as a subgroup of that
-# type (e.g. under the Public Functions section). Set it to NO to prevent
-# subgrouping. Alternatively, this can be done per class using the
-# \nosubgrouping command.
-# The default value is: YES.
-
-SUBGROUPING            = YES
-
-# When the INLINE_GROUPED_CLASSES tag is set to YES, classes, structs and unions
-# are shown inside the group in which they are included (e.g. using \ingroup)
-# instead of on a separate page (for HTML and Man pages) or section (for LaTeX
-# and RTF).
-#
-# Note that this feature does not work in combination with
-# SEPARATE_MEMBER_PAGES.
-# The default value is: NO.
-
-INLINE_GROUPED_CLASSES = NO
-
-# When the INLINE_SIMPLE_STRUCTS tag is set to YES, structs, classes, and unions
-# with only public data fields or simple typedef fields will be shown inline in
-# the documentation of the scope in which they are defined (i.e. file,
-# namespace, or group documentation), provided this scope is documented. If set
-# to NO, structs, classes, and unions are shown on a separate page (for HTML and
-# Man pages) or section (for LaTeX and RTF).
-# The default value is: NO.
-
-INLINE_SIMPLE_STRUCTS  = NO
-
-# When TYPEDEF_HIDES_STRUCT tag is enabled, a typedef of a struct, union, or
-# enum is documented as struct, union, or enum with the name of the typedef. So
-# typedef struct TypeS {} TypeT, will appear in the documentation as a struct
-# with name TypeT. When disabled the typedef will appear as a member of a file,
-# namespace, or class. And the struct will be named TypeS. This can typically be
-# useful for C code in case the coding convention dictates that all compound
-# types are typedef'ed and only the typedef is referenced, never the tag name.
-# The default value is: NO.
-
-TYPEDEF_HIDES_STRUCT   = NO
-
-# The size of the symbol lookup cache can be set using LOOKUP_CACHE_SIZE. This
-# cache is used to resolve symbols given their name and scope. Since this can be
-# an expensive process and often the same symbol appears multiple times in the
-# code, doxygen keeps a cache of pre-resolved symbols. If the cache is too small
-# doxygen will become slower. If the cache is too large, memory is wasted. The
-# cache size is given by this formula: 2^(16+LOOKUP_CACHE_SIZE). The valid range
-# is 0..9, the default is 0, corresponding to a cache size of 2^16=65536
-# symbols. At the end of a run doxygen will report the cache usage and suggest
-# the optimal cache size from a speed point of view.
-# Minimum value: 0, maximum value: 9, default value: 0.
-
-LOOKUP_CACHE_SIZE      = 0
-
-#---------------------------------------------------------------------------
-# Build related configuration options
-#---------------------------------------------------------------------------
-
-# If the EXTRACT_ALL tag is set to YES, doxygen will assume all entities in
-# documentation are documented, even if no documentation was available. Private
-# class members and static file members will be hidden unless the
-# EXTRACT_PRIVATE respectively EXTRACT_STATIC tags are set to YES.
-# Note: This will also disable the warnings about undocumented members that are
-# normally produced when WARNINGS is set to YES.
-# The default value is: NO.
-
-EXTRACT_ALL            = YES
-
-# If the EXTRACT_PRIVATE tag is set to YES, all private members of a class will
-# be included in the documentation.
-# The default value is: NO.
-
-EXTRACT_PRIVATE        = NO
-
-# If the EXTRACT_PACKAGE tag is set to YES, all members with package or internal
-# scope will be included in the documentation.
-# The default value is: NO.
-
-EXTRACT_PACKAGE        = NO
-
-# If the EXTRACT_STATIC tag is set to YES, all static members of a file will be
-# included in the documentation.
-# The default value is: NO.
-
-EXTRACT_STATIC         = YES
-
-# If the EXTRACT_LOCAL_CLASSES tag is set to YES, classes (and structs) defined
-# locally in source files will be included in the documentation. If set to NO,
-# only classes defined in header files are included. Does not have any effect
-# for Java sources.
-# The default value is: YES.
-
-EXTRACT_LOCAL_CLASSES  = YES
-
-# This flag is only useful for Objective-C code. If set to YES, local methods,
-# which are defined in the implementation section but not in the interface are
-# included in the documentation. If set to NO, only methods in the interface are
-# included.
-# The default value is: NO.
-
-EXTRACT_LOCAL_METHODS  = NO
-
-# If this flag is set to YES, the members of anonymous namespaces will be
-# extracted and appear in the documentation as a namespace called
-# 'anonymous_namespace{file}', where file will be replaced with the base name of
-# the file that contains the anonymous namespace. By default anonymous namespace
-# are hidden.
-# The default value is: NO.
-
-EXTRACT_ANON_NSPACES   = NO
-
-# If the HIDE_UNDOC_MEMBERS tag is set to YES, doxygen will hide all
-# undocumented members inside documented classes or files. If set to NO these
-# members will be included in the various overviews, but no documentation
-# section is generated. This option has no effect if EXTRACT_ALL is enabled.
-# The default value is: NO.
-
-HIDE_UNDOC_MEMBERS     = NO
-
-# If the HIDE_UNDOC_CLASSES tag is set to YES, doxygen will hide all
-# undocumented classes that are normally visible in the class hierarchy. If set
-# to NO, these classes will be included in the various overviews. This option
-# has no effect if EXTRACT_ALL is enabled.
-# The default value is: NO.
-
-HIDE_UNDOC_CLASSES     = NO
-
-# If the HIDE_FRIEND_COMPOUNDS tag is set to YES, doxygen will hide all friend
-# (class|struct|union) declarations. If set to NO, these declarations will be
-# included in the documentation.
-# The default value is: NO.
-
-HIDE_FRIEND_COMPOUNDS  = NO
-
-# If the HIDE_IN_BODY_DOCS tag is set to YES, doxygen will hide any
-# documentation blocks found inside the body of a function. If set to NO, these
-# blocks will be appended to the function's detailed documentation block.
-# The default value is: NO.
-
-HIDE_IN_BODY_DOCS      = NO
-
-# The INTERNAL_DOCS tag determines if documentation that is typed after a
-# \internal command is included. If the tag is set to NO then the documentation
-# will be excluded. Set it to YES to include the internal documentation.
-# The default value is: NO.
-
-INTERNAL_DOCS          = NO
-
-# If the CASE_SENSE_NAMES tag is set to NO then doxygen will only generate file
-# names in lower-case letters. If set to YES, upper-case letters are also
-# allowed. This is useful if you have classes or files whose names only differ
-# in case and if your file system supports case sensitive file names. Windows
-# and Mac users are advised to set this option to NO.
-# The default value is: system dependent.
-
-CASE_SENSE_NAMES       = YES
-
-# If the HIDE_SCOPE_NAMES tag is set to NO then doxygen will show members with
-# their full class and namespace scopes in the documentation. If set to YES, the
-# scope will be hidden.
-# The default value is: NO.
-
-HIDE_SCOPE_NAMES       = NO
-
-# If the HIDE_COMPOUND_REFERENCE tag is set to NO (default) then doxygen will
-# append additional text to a page's title, such as Class Reference. If set to
-# YES the compound reference will be hidden.
-# The default value is: NO.
-
-HIDE_COMPOUND_REFERENCE= NO
-
-# If the SHOW_INCLUDE_FILES tag is set to YES then doxygen will put a list of
-# the files that are included by a file in the documentation of that file.
-# The default value is: YES.
-
-SHOW_INCLUDE_FILES     = YES
-
-# If the SHOW_GROUPED_MEMB_INC tag is set to YES then Doxygen will add for each
-# grouped member an include statement to the documentation, telling the reader
-# which file to include in order to use the member.
-# The default value is: NO.
-
-SHOW_GROUPED_MEMB_INC  = NO
-
-# If the FORCE_LOCAL_INCLUDES tag is set to YES then doxygen will list include
-# files with double quotes in the documentation rather than with sharp brackets.
-# The default value is: NO.
-
-FORCE_LOCAL_INCLUDES   = NO
-
-# If the INLINE_INFO tag is set to YES then a tag [inline] is inserted in the
-# documentation for inline members.
-# The default value is: YES.
-
-INLINE_INFO            = YES
-
-# If the SORT_MEMBER_DOCS tag is set to YES then doxygen will sort the
-# (detailed) documentation of file and class members alphabetically by member
-# name. If set to NO, the members will appear in declaration order.
-# The default value is: YES.
-
-SORT_MEMBER_DOCS       = YES
-
-# If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the brief
-# descriptions of file, namespace and class members alphabetically by member
-# name. If set to NO, the members will appear in declaration order. Note that
-# this will also influence the order of the classes in the class list.
-# The default value is: NO.
-
-SORT_BRIEF_DOCS        = NO
-
-# If the SORT_MEMBERS_CTORS_1ST tag is set to YES then doxygen will sort the
-# (brief and detailed) documentation of class members so that constructors and
-# destructors are listed first. If set to NO the constructors will appear in the
-# respective orders defined by SORT_BRIEF_DOCS and SORT_MEMBER_DOCS.
-# Note: If SORT_BRIEF_DOCS is set to NO this option is ignored for sorting brief
-# member documentation.
-# Note: If SORT_MEMBER_DOCS is set to NO this option is ignored for sorting
-# detailed member documentation.
-# The default value is: NO.
-
-SORT_MEMBERS_CTORS_1ST = NO
-
-# If the SORT_GROUP_NAMES tag is set to YES then doxygen will sort the hierarchy
-# of group names into alphabetical order. If set to NO the group names will
-# appear in their defined order.
-# The default value is: NO.
-
-SORT_GROUP_NAMES       = NO
-
-# If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be sorted by
-# fully-qualified names, including namespaces. If set to NO, the class list will
-# be sorted only by class name, not including the namespace part.
-# Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES.
-# Note: This option applies only to the class list, not to the alphabetical
-# list.
-# The default value is: NO.
-
-SORT_BY_SCOPE_NAME     = NO
-
-# If the STRICT_PROTO_MATCHING option is enabled and doxygen fails to do proper
-# type resolution of all parameters of a function it will reject a match between
-# the prototype and the implementation of a member function even if there is
-# only one candidate or it is obvious which candidate to choose by doing a
-# simple string match. By disabling STRICT_PROTO_MATCHING doxygen will still
-# accept a match between prototype and implementation in such cases.
-# The default value is: NO.
-
-STRICT_PROTO_MATCHING  = NO
-
-# The GENERATE_TODOLIST tag can be used to enable (YES) or disable (NO) the todo
-# list. This list is created by putting \todo commands in the documentation.
-# The default value is: YES.
-
-GENERATE_TODOLIST      = YES
-
-# The GENERATE_TESTLIST tag can be used to enable (YES) or disable (NO) the test
-# list. This list is created by putting \test commands in the documentation.
-# The default value is: YES.
-
-GENERATE_TESTLIST      = YES
-
-# The GENERATE_BUGLIST tag can be used to enable (YES) or disable (NO) the bug
-# list. This list is created by putting \bug commands in the documentation.
-# The default value is: YES.
-
-GENERATE_BUGLIST       = YES
-
-# The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or disable (NO)
-# the deprecated list. This list is created by putting \deprecated commands in
-# the documentation.
-# The default value is: YES.
-
-GENERATE_DEPRECATEDLIST= YES
-
-# The ENABLED_SECTIONS tag can be used to enable conditional documentation
-# sections, marked by \if <section_label> ... \endif and \cond <section_label>
-# ... \endcond blocks.
-
-ENABLED_SECTIONS       =
-
-# The MAX_INITIALIZER_LINES tag determines the maximum number of lines that the
-# initial value of a variable or macro / define can have for it to appear in the
-# documentation. If the initializer consists of more lines than specified here
-# it will be hidden. Use a value of 0 to hide initializers completely. The
-# appearance of the value of individual variables and macros / defines can be
-# controlled using \showinitializer or \hideinitializer command in the
-# documentation regardless of this setting.
-# Minimum value: 0, maximum value: 10000, default value: 30.
-
-MAX_INITIALIZER_LINES  = 30
-
-# Set the SHOW_USED_FILES tag to NO to disable the list of files generated at
-# the bottom of the documentation of classes and structs. If set to YES, the
-# list will mention the files that were used to generate the documentation.
-# The default value is: YES.
-
-SHOW_USED_FILES        = YES
-
-# Set the SHOW_FILES tag to NO to disable the generation of the Files page. This
-# will remove the Files entry from the Quick Index and from the Folder Tree View
-# (if specified).
-# The default value is: YES.
-
-SHOW_FILES             = YES
-
-# Set the SHOW_NAMESPACES tag to NO to disable the generation of the Namespaces
-# page. This will remove the Namespaces entry from the Quick Index and from the
-# Folder Tree View (if specified).
-# The default value is: YES.
-
-SHOW_NAMESPACES        = YES
-
-# The FILE_VERSION_FILTER tag can be used to specify a program or script that
-# doxygen should invoke to get the current version for each file (typically from
-# the version control system). Doxygen will invoke the program by executing (via
-# popen()) the command command input-file, where command is the value of the
-# FILE_VERSION_FILTER tag, and input-file is the name of an input file provided
-# by doxygen. Whatever the program writes to standard output is used as the file
-# version. For an example see the documentation.
-
-FILE_VERSION_FILTER    =
-
-# The LAYOUT_FILE tag can be used to specify a layout file which will be parsed
-# by doxygen. The layout file controls the global structure of the generated
-# output files in an output format independent way. To create the layout file
-# that represents doxygen's defaults, run doxygen with the -l option. You can
-# optionally specify a file name after the option, if omitted DoxygenLayout.xml
-# will be used as the name of the layout file.
-#
-# Note that if you run doxygen from a directory containing a file called
-# DoxygenLayout.xml, doxygen will parse it automatically even if the LAYOUT_FILE
-# tag is left empty.
-
-LAYOUT_FILE            =
-
-# The CITE_BIB_FILES tag can be used to specify one or more bib files containing
-# the reference definitions. This must be a list of .bib files. The .bib
-# extension is automatically appended if omitted. This requires the bibtex tool
-# to be installed. See also http://en.wikipedia.org/wiki/BibTeX for more info.
-# For LaTeX the style of the bibliography can be controlled using
-# LATEX_BIB_STYLE. To use this feature you need bibtex and perl available in the
-# search path. See also \cite for info how to create references.
-
-CITE_BIB_FILES         =
-
-#---------------------------------------------------------------------------
-# Configuration options related to warning and progress messages
-#---------------------------------------------------------------------------
-
-# The QUIET tag can be used to turn on/off the messages that are generated to
-# standard output by doxygen. If QUIET is set to YES this implies that the
-# messages are off.
-# The default value is: NO.
-
-QUIET                  = YES
-
-# The WARNINGS tag can be used to turn on/off the warning messages that are
-# generated to standard error (stderr) by doxygen. If WARNINGS is set to YES
-# this implies that the warnings are on.
-#
-# Tip: Turn warnings on while writing the documentation.
-# The default value is: YES.
-
-WARNINGS               = YES
-
-# If the WARN_IF_UNDOCUMENTED tag is set to YES then doxygen will generate
-# warnings for undocumented members. If EXTRACT_ALL is set to YES then this flag
-# will automatically be disabled.
-# The default value is: YES.
-
-WARN_IF_UNDOCUMENTED   = YES
-
-# If the WARN_IF_DOC_ERROR tag is set to YES, doxygen will generate warnings for
-# potential errors in the documentation, such as not documenting some parameters
-# in a documented function, or documenting parameters that don't exist or using
-# markup commands wrongly.
-# The default value is: YES.
-
-WARN_IF_DOC_ERROR      = YES
-
-# This WARN_NO_PARAMDOC option can be enabled to get warnings for functions that
-# are documented, but have no documentation for their parameters or return
-# value. If set to NO, doxygen will only warn about wrong or incomplete
-# parameter documentation, but not about the absence of documentation.
-# The default value is: NO.
-
-WARN_NO_PARAMDOC       = NO
-
-# If the WARN_AS_ERROR tag is set to YES then doxygen will immediately stop when
-# a warning is encountered.
-# The default value is: NO.
-
-WARN_AS_ERROR          = NO
-
-# The WARN_FORMAT tag determines the format of the warning messages that doxygen
-# can produce. The string should contain the $file, $line, and $text tags, which
-# will be replaced by the file and line number from which the warning originated
-# and the warning text. Optionally the format may contain $version, which will
-# be replaced by the version of the file (if it could be obtained via
-# FILE_VERSION_FILTER)
-# The default value is: $file:$line: $text.
-
-WARN_FORMAT            = "$file:$line: $text"
-
-# The WARN_LOGFILE tag can be used to specify a file to which warning and error
-# messages should be written. If left blank the output is written to standard
-# error (stderr).
-
-WARN_LOGFILE           =
-
-#---------------------------------------------------------------------------
-# Configuration options related to the input files
-#---------------------------------------------------------------------------
-
-# The INPUT tag is used to specify the files and/or directories that contain
-# documented source files. You may enter file names like myfile.cpp or
-# directories like /usr/src/myproject. Separate the files or directories with
-# spaces. See also FILE_PATTERNS and EXTENSION_MAPPING
-# Note: If this tag is empty the current directory is searched.
-
-INPUT                  = libopenmpt/dox/index.dox \
-                         libopenmpt/dox/quickstart.md \
-                         README.md \
-                         libopenmpt/dox/dependencies.md \
-                         libopenmpt/dox/packaging.md \
-                         doc/contributing.md \
-                         doc/libopenmpt_styleguide.md \
-                         libopenmpt/dox/tests.md \
-                         libopenmpt/dox/changelog.md \
-                         libopenmpt/dox/todo.md \
-                         doc/module_formats.md \
-                         libopenmpt/libopenmpt.hpp \
-                         libopenmpt/libopenmpt.h \
-                         libopenmpt/libopenmpt_stream_callbacks_buffer.h \
-                         libopenmpt/libopenmpt_stream_callbacks_fd.h \
-                         libopenmpt/libopenmpt_stream_callbacks_file.h \
-                         libopenmpt/libopenmpt_config.h \
-                         libopenmpt/libopenmpt_version.h \
-                         libopenmpt/libopenmpt_ext.hpp \
-                         libopenmpt/libopenmpt_ext.h
-
-# This tag can be used to specify the character encoding of the source files
-# that doxygen parses. Internally doxygen uses the UTF-8 encoding. Doxygen uses
-# libiconv (or the iconv built into libc) for the transcoding. See the libiconv
-# documentation (see: http://www.gnu.org/software/libiconv) for the list of
-# possible encodings.
-# The default value is: UTF-8.
-
-INPUT_ENCODING         = UTF-8
-
-# If the value of the INPUT tag contains directories, you can use the
-# FILE_PATTERNS tag to specify one or more wildcard patterns (like *.cpp and
-# *.h) to filter out the source-files in the directories.
-#
-# Note that for custom extensions or not directly supported extensions you also
-# need to set EXTENSION_MAPPING for the extension otherwise the files are not
-# read by doxygen.
-#
-# If left blank the following patterns are tested:*.c, *.cc, *.cxx, *.cpp,
-# *.c++, *.java, *.ii, *.ixx, *.ipp, *.i++, *.inl, *.idl, *.ddl, *.odl, *.h,
-# *.hh, *.hxx, *.hpp, *.h++, *.cs, *.d, *.php, *.php4, *.php5, *.phtml, *.inc,
-# *.m, *.markdown, *.md, *.mm, *.dox, *.py, *.pyw, *.f90, *.f95, *.f03, *.f08,
-# *.f, *.for, *.tcl, *.vhd, *.vhdl, *.ucf and *.qsf.
-
-FILE_PATTERNS          =
-
-# The RECURSIVE tag can be used to specify whether or not subdirectories should
-# be searched for input files as well.
-# The default value is: NO.
-
-RECURSIVE              = NO
-
-# The EXCLUDE tag can be used to specify files and/or directories that should be
-# excluded from the INPUT source files. This way you can easily exclude a
-# subdirectory from a directory tree whose root is specified with the INPUT tag.
-#
-# Note that relative paths are relative to the directory from which doxygen is
-# run.
-
-EXCLUDE                =
-
-# The EXCLUDE_SYMLINKS tag can be used to select whether or not files or
-# directories that are symbolic links (a Unix file system feature) are excluded
-# from the input.
-# The default value is: NO.
-
-EXCLUDE_SYMLINKS       = NO
-
-# If the value of the INPUT tag contains directories, you can use the
-# EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude
-# certain files from those directories.
-#
-# Note that the wildcards are matched against the file with absolute path, so to
-# exclude all test directories for example use the pattern */test/*
-
-EXCLUDE_PATTERNS       =
-
-# The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names
-# (namespaces, classes, functions, etc.) that should be excluded from the
-# output. The symbol name can be a fully qualified name, a word, or if the
-# wildcard * is used, a substring. Examples: ANamespace, AClass,
-# AClass::ANamespace, ANamespace::*Test
-#
-# Note that the wildcards are matched against the file with absolute path, so to
-# exclude all test directories use the pattern */test/*
-
-EXCLUDE_SYMBOLS        = LIBOPENMPT_API \
-                         LIBOPENMPT_CXX_API \
-                         LIBOPENMPT_API_HELPER_EXPORT \
-                         LIBOPENMPT_API_HELPER_IMPORT \
-                         LIBOPENMPT_API_HELPER_PUBLIC \
-                         LIBOPENMPT_API_HELPER_LOCAL \
-                         OPENMPT_API_VERSION_HELPER_STRINGIZE \
-                         OPENMPT_API_VERSION_STRINGIZE \
-                         openmpt::detail
-
-# The EXAMPLE_PATH tag can be used to specify one or more files or directories
-# that contain example code fragments that are included (see the \include
-# command).
-
-EXAMPLE_PATH           = examples/ \
-                         LICENSE
-
-# If the value of the EXAMPLE_PATH tag contains directories, you can use the
-# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp and
-# *.h) to filter out the source-files in the directories. If left blank all
-# files are included.
-
-EXAMPLE_PATTERNS       =
-
-# If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be
-# searched for input files to be used with the \include or \dontinclude commands
-# irrespective of the value of the RECURSIVE tag.
-# The default value is: NO.
-
-EXAMPLE_RECURSIVE      = NO
-
-# The IMAGE_PATH tag can be used to specify one or more files or directories
-# that contain images that are to be included in the documentation (see the
-# \image command).
-
-IMAGE_PATH             =
-
-# The INPUT_FILTER tag can be used to specify a program that doxygen should
-# invoke to filter for each input file. Doxygen will invoke the filter program
-# by executing (via popen()) the command:
-#
-# <filter> <input-file>
-#
-# where <filter> is the value of the INPUT_FILTER tag, and <input-file> is the
-# name of an input file. Doxygen will then use the output that the filter
-# program writes to standard output. If FILTER_PATTERNS is specified, this tag
-# will be ignored.
-#
-# Note that the filter must not add or remove lines; it is applied before the
-# code is scanned, but not when the output code is generated. If lines are added
-# or removed, the anchors will not be placed correctly.
-#
-# Note that for custom extensions or not directly supported extensions you also
-# need to set EXTENSION_MAPPING for the extension otherwise the files are not
-# properly processed by doxygen.
-
-INPUT_FILTER           =
-
-# The FILTER_PATTERNS tag can be used to specify filters on a per file pattern
-# basis. Doxygen will compare the file name with each pattern and apply the
-# filter if there is a match. The filters are a list of the form: pattern=filter
-# (like *.cpp=my_cpp_filter). See INPUT_FILTER for further information on how
-# filters are used. If the FILTER_PATTERNS tag is empty or if none of the
-# patterns match the file name, INPUT_FILTER is applied.
-#
-# Note that for custom extensions or not directly supported extensions you also
-# need to set EXTENSION_MAPPING for the extension otherwise the files are not
-# properly processed by doxygen.
-
-FILTER_PATTERNS        =
-
-# If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using
-# INPUT_FILTER) will also be used to filter the input files that are used for
-# producing the source files to browse (i.e. when SOURCE_BROWSER is set to YES).
-# The default value is: NO.
-
-FILTER_SOURCE_FILES    = NO
-
-# The FILTER_SOURCE_PATTERNS tag can be used to specify source filters per file
-# pattern. A pattern will override the setting for FILTER_PATTERN (if any) and
-# it is also possible to disable source filtering for a specific pattern using
-# *.ext= (so without naming a filter).
-# This tag requires that the tag FILTER_SOURCE_FILES is set to YES.
-
-FILTER_SOURCE_PATTERNS =
-
-# If the USE_MDFILE_AS_MAINPAGE tag refers to the name of a markdown file that
-# is part of the input, its contents will be placed on the main page
-# (index.html). This can be useful if you have a project on for instance GitHub
-# and want to reuse the introduction page also for the doxygen output.
-
-USE_MDFILE_AS_MAINPAGE =
-
-#---------------------------------------------------------------------------
-# Configuration options related to source browsing
-#---------------------------------------------------------------------------
-
-# If the SOURCE_BROWSER tag is set to YES then a list of source files will be
-# generated. Documented entities will be cross-referenced with these sources.
-#
-# Note: To get rid of all source code in the generated output, make sure that
-# also VERBATIM_HEADERS is set to NO.
-# The default value is: NO.
-
-SOURCE_BROWSER         = NO
-
-# Setting the INLINE_SOURCES tag to YES will include the body of functions,
-# classes and enums directly into the documentation.
-# The default value is: NO.
-
-INLINE_SOURCES         = NO
-
-# Setting the STRIP_CODE_COMMENTS tag to YES will instruct doxygen to hide any
-# special comment blocks from generated source code fragments. Normal C, C++ and
-# Fortran comments will always remain visible.
-# The default value is: YES.
-
-STRIP_CODE_COMMENTS    = YES
-
-# If the REFERENCED_BY_RELATION tag is set to YES then for each documented
-# function all documented functions referencing it will be listed.
-# The default value is: NO.
-
-REFERENCED_BY_RELATION = NO
-
-# If the REFERENCES_RELATION tag is set to YES then for each documented function
-# all documented entities called/used by that function will be listed.
-# The default value is: NO.
-
-REFERENCES_RELATION    = NO
-
-# If the REFERENCES_LINK_SOURCE tag is set to YES and SOURCE_BROWSER tag is set
-# to YES then the hyperlinks from functions in REFERENCES_RELATION and
-# REFERENCED_BY_RELATION lists will link to the source code. Otherwise they will
-# link to the documentation.
-# The default value is: YES.
-
-REFERENCES_LINK_SOURCE = YES
-
-# If SOURCE_TOOLTIPS is enabled (the default) then hovering a hyperlink in the
-# source code will show a tooltip with additional information such as prototype,
-# brief description and links to the definition and documentation. Since this
-# will make the HTML file larger and loading of large files a bit slower, you
-# can opt to disable this feature.
-# The default value is: YES.
-# This tag requires that the tag SOURCE_BROWSER is set to YES.
-
-SOURCE_TOOLTIPS        = YES
-
-# If the USE_HTAGS tag is set to YES then the references to source code will
-# point to the HTML generated by the htags(1) tool instead of doxygen built-in
-# source browser. The htags tool is part of GNU's global source tagging system
-# (see http://www.gnu.org/software/global/global.html). You will need version
-# 4.8.6 or higher.
-#
-# To use it do the following:
-# - Install the latest version of global
-# - Enable SOURCE_BROWSER and USE_HTAGS in the config file
-# - Make sure the INPUT points to the root of the source tree
-# - Run doxygen as normal
-#
-# Doxygen will invoke htags (and that will in turn invoke gtags), so these
-# tools must be available from the command line (i.e. in the search path).
-#
-# The result: instead of the source browser generated by doxygen, the links to
-# source code will now point to the output of htags.
-# The default value is: NO.
-# This tag requires that the tag SOURCE_BROWSER is set to YES.
-
-USE_HTAGS              = NO
-
-# If the VERBATIM_HEADERS tag is set the YES then doxygen will generate a
-# verbatim copy of the header file for each class for which an include is
-# specified. Set to NO to disable this.
-# See also: Section \class.
-# The default value is: YES.
-
-VERBATIM_HEADERS       = YES
-
-# If the CLANG_ASSISTED_PARSING tag is set to YES then doxygen will use the
-# clang parser (see: http://clang.llvm.org/) for more accurate parsing at the
-# cost of reduced performance. This can be particularly helpful with template
-# rich C++ code for which doxygen's built-in parser lacks the necessary type
-# information.
-# Note: The availability of this option depends on whether or not doxygen was
-# generated with the -Duse-libclang=ON option for CMake.
-# The default value is: NO.
-
-CLANG_ASSISTED_PARSING = NO
-
-# If clang assisted parsing is enabled you can provide the compiler with command
-# line options that you would normally use when invoking the compiler. Note that
-# the include paths will already be set by doxygen for the files and directories
-# specified with INPUT and INCLUDE_PATH.
-# This tag requires that the tag CLANG_ASSISTED_PARSING is set to YES.
-
-CLANG_OPTIONS          =
-
-#---------------------------------------------------------------------------
-# Configuration options related to the alphabetical class index
-#---------------------------------------------------------------------------
-
-# If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index of all
-# compounds will be generated. Enable this if the project contains a lot of
-# classes, structs, unions or interfaces.
-# The default value is: YES.
-
-ALPHABETICAL_INDEX     = YES
-
-# The COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns in
-# which the alphabetical index list will be split.
-# Minimum value: 1, maximum value: 20, default value: 5.
-# This tag requires that the tag ALPHABETICAL_INDEX is set to YES.
-
-COLS_IN_ALPHA_INDEX    = 5
-
-# In case all classes in a project start with a common prefix, all classes will
-# be put under the same header in the alphabetical index. The IGNORE_PREFIX tag
-# can be used to specify a prefix (or a list of prefixes) that should be ignored
-# while generating the index headers.
-# This tag requires that the tag ALPHABETICAL_INDEX is set to YES.
-
-IGNORE_PREFIX          =
-
-#---------------------------------------------------------------------------
-# Configuration options related to the HTML output
-#---------------------------------------------------------------------------
-
-# If the GENERATE_HTML tag is set to YES, doxygen will generate HTML output
-# The default value is: YES.
-
-GENERATE_HTML          = YES
-
-# The HTML_OUTPUT tag is used to specify where the HTML docs will be put. If a
-# relative path is entered the value of OUTPUT_DIRECTORY will be put in front of
-# it.
-# The default directory is: html.
-# This tag requires that the tag GENERATE_HTML is set to YES.
-
-HTML_OUTPUT            = html
-
-# The HTML_FILE_EXTENSION tag can be used to specify the file extension for each
-# generated HTML page (for example: .htm, .php, .asp).
-# The default value is: .html.
-# This tag requires that the tag GENERATE_HTML is set to YES.
-
-HTML_FILE_EXTENSION    = .html
-
-# The HTML_HEADER tag can be used to specify a user-defined HTML header file for
-# each generated HTML page. If the tag is left blank doxygen will generate a
-# standard header.
-#
-# To get valid HTML the header file that includes any scripts and style sheets
-# that doxygen needs, which is dependent on the configuration options used (e.g.
-# the setting GENERATE_TREEVIEW). It is highly recommended to start with a
-# default header using
-# doxygen -w html new_header.html new_footer.html new_stylesheet.css
-# YourConfigFile
-# and then modify the file new_header.html. See also section "Doxygen usage"
-# for information on how to generate the default header that doxygen normally
-# uses.
-# Note: The header is subject to change so you typically have to regenerate the
-# default header when upgrading to a newer version of doxygen. For a description
-# of the possible markers and block names see the documentation.
-# This tag requires that the tag GENERATE_HTML is set to YES.
-
-HTML_HEADER            =
-
-# The HTML_FOOTER tag can be used to specify a user-defined HTML footer for each
-# generated HTML page. If the tag is left blank doxygen will generate a standard
-# footer. See HTML_HEADER for more information on how to generate a default
-# footer and what special commands can be used inside the footer. See also
-# section "Doxygen usage" for information on how to generate the default footer
-# that doxygen normally uses.
-# This tag requires that the tag GENERATE_HTML is set to YES.
-
-HTML_FOOTER            =
-
-# The HTML_STYLESHEET tag can be used to specify a user-defined cascading style
-# sheet that is used by each HTML page. It can be used to fine-tune the look of
-# the HTML output. If left blank doxygen will generate a default style sheet.
-# See also section "Doxygen usage" for information on how to generate the style
-# sheet that doxygen normally uses.
-# Note: It is recommended to use HTML_EXTRA_STYLESHEET instead of this tag, as
-# it is more robust and this tag (HTML_STYLESHEET) will in the future become
-# obsolete.
-# This tag requires that the tag GENERATE_HTML is set to YES.
-
-HTML_STYLESHEET        =
-
-# The HTML_EXTRA_STYLESHEET tag can be used to specify additional user-defined
-# cascading style sheets that are included after the standard style sheets
-# created by doxygen. Using this option one can overrule certain style aspects.
-# This is preferred over using HTML_STYLESHEET since it does not replace the
-# standard style sheet and is therefore more robust against future updates.
-# Doxygen will copy the style sheet files to the output directory.
-# Note: The order of the extra style sheet files is of importance (e.g. the last
-# style sheet in the list overrules the setting of the previous ones in the
-# list). For an example see the documentation.
-# This tag requires that the tag GENERATE_HTML is set to YES.
-
-HTML_EXTRA_STYLESHEET  =
-
-# The HTML_EXTRA_FILES tag can be used to specify one or more extra images or
-# other source files which should be copied to the HTML output directory. Note
-# that these files will be copied to the base HTML output directory. Use the
-# $relpath^ marker in the HTML_HEADER and/or HTML_FOOTER files to load these
-# files. In the HTML_STYLESHEET file, use the file name only. Also note that the
-# files will be copied as-is; there are no commands or markers available.
-# This tag requires that the tag GENERATE_HTML is set to YES.
-
-HTML_EXTRA_FILES       =
-
-# The HTML_COLORSTYLE_HUE tag controls the color of the HTML output. Doxygen
-# will adjust the colors in the style sheet and background images according to
-# this color. Hue is specified as an angle on a colorwheel, see
-# http://en.wikipedia.org/wiki/Hue for more information. For instance the value
-# 0 represents red, 60 is yellow, 120 is green, 180 is cyan, 240 is blue, 300
-# purple, and 360 is red again.
-# Minimum value: 0, maximum value: 359, default value: 220.
-# This tag requires that the tag GENERATE_HTML is set to YES.
-
-HTML_COLORSTYLE_HUE    = 220
-
-# The HTML_COLORSTYLE_SAT tag controls the purity (or saturation) of the colors
-# in the HTML output. For a value of 0 the output will use grayscales only. A
-# value of 255 will produce the most vivid colors.
-# Minimum value: 0, maximum value: 255, default value: 100.
-# This tag requires that the tag GENERATE_HTML is set to YES.
-
-HTML_COLORSTYLE_SAT    = 100
-
-# The HTML_COLORSTYLE_GAMMA tag controls the gamma correction applied to the
-# luminance component of the colors in the HTML output. Values below 100
-# gradually make the output lighter, whereas values above 100 make the output
-# darker. The value divided by 100 is the actual gamma applied, so 80 represents
-# a gamma of 0.8, The value 220 represents a gamma of 2.2, and 100 does not
-# change the gamma.
-# Minimum value: 40, maximum value: 240, default value: 80.
-# This tag requires that the tag GENERATE_HTML is set to YES.
-
-HTML_COLORSTYLE_GAMMA  = 80
-
-# If the HTML_TIMESTAMP tag is set to YES then the footer of each generated HTML
-# page will contain the date and time when the page was generated. Setting this
-# to YES can help to show when doxygen was last run and thus if the
-# documentation is up to date.
-# The default value is: NO.
-# This tag requires that the tag GENERATE_HTML is set to YES.
-
-HTML_TIMESTAMP         = YES
-
-# If the HTML_DYNAMIC_SECTIONS tag is set to YES then the generated HTML
-# documentation will contain sections that can be hidden and shown after the
-# page has loaded.
-# The default value is: NO.
-# This tag requires that the tag GENERATE_HTML is set to YES.
-
-HTML_DYNAMIC_SECTIONS  = NO
-
-# With HTML_INDEX_NUM_ENTRIES one can control the preferred number of entries
-# shown in the various tree structured indices initially; the user can expand
-# and collapse entries dynamically later on. Doxygen will expand the tree to
-# such a level that at most the specified number of entries are visible (unless
-# a fully collapsed tree already exceeds this amount). So setting the number of
-# entries 1 will produce a full collapsed tree by default. 0 is a special value
-# representing an infinite number of entries and will result in a full expanded
-# tree by default.
-# Minimum value: 0, maximum value: 9999, default value: 100.
-# This tag requires that the tag GENERATE_HTML is set to YES.
-
-HTML_INDEX_NUM_ENTRIES = 100
-
-# If the GENERATE_DOCSET tag is set to YES, additional index files will be
-# generated that can be used as input for Apple's Xcode 3 integrated development
-# environment (see: http://developer.apple.com/tools/xcode/), introduced with
-# OSX 10.5 (Leopard). To create a documentation set, doxygen will generate a
-# Makefile in the HTML output directory. Running make will produce the docset in
-# that directory and running make install will install the docset in
-# ~/Library/Developer/Shared/Documentation/DocSets so that Xcode will find it at
-# startup. See http://developer.apple.com/tools/creatingdocsetswithdoxygen.html
-# for more information.
-# The default value is: NO.
-# This tag requires that the tag GENERATE_HTML is set to YES.
-
-GENERATE_DOCSET        = NO
-
-# This tag determines the name of the docset feed. A documentation feed provides
-# an umbrella under which multiple documentation sets from a single provider
-# (such as a company or product suite) can be grouped.
-# The default value is: Doxygen generated docs.
-# This tag requires that the tag GENERATE_DOCSET is set to YES.
-
-DOCSET_FEEDNAME        = "Doxygen generated docs"
-
-# This tag specifies a string that should uniquely identify the documentation
-# set bundle. This should be a reverse domain-name style string, e.g.
-# com.mycompany.MyDocSet. Doxygen will append .docset to the name.
-# The default value is: org.doxygen.Project.
-# This tag requires that the tag GENERATE_DOCSET is set to YES.
-
-DOCSET_BUNDLE_ID       = org.doxygen.Project
-
-# The DOCSET_PUBLISHER_ID tag specifies a string that should uniquely identify
-# the documentation publisher. This should be a reverse domain-name style
-# string, e.g. com.mycompany.MyDocSet.documentation.
-# The default value is: org.doxygen.Publisher.
-# This tag requires that the tag GENERATE_DOCSET is set to YES.
-
-DOCSET_PUBLISHER_ID    = org.doxygen.Publisher
-
-# The DOCSET_PUBLISHER_NAME tag identifies the documentation publisher.
-# The default value is: Publisher.
-# This tag requires that the tag GENERATE_DOCSET is set to YES.
-
-DOCSET_PUBLISHER_NAME  = Publisher
-
-# If the GENERATE_HTMLHELP tag is set to YES then doxygen generates three
-# additional HTML index files: index.hhp, index.hhc, and index.hhk. The
-# index.hhp is a project file that can be read by Microsoft's HTML Help Workshop
-# (see: http://www.microsoft.com/en-us/download/details.aspx?id=21138) on
-# Windows.
-#
-# The HTML Help Workshop contains a compiler that can convert all HTML output
-# generated by doxygen into a single compiled HTML file (.chm). Compiled HTML
-# files are now used as the Windows 98 help format, and will replace the old
-# Windows help format (.hlp) on all Windows platforms in the future. Compressed
-# HTML files also contain an index, a table of contents, and you can search for
-# words in the documentation. The HTML workshop also contains a viewer for
-# compressed HTML files.
-# The default value is: NO.
-# This tag requires that the tag GENERATE_HTML is set to YES.
-
-GENERATE_HTMLHELP      = NO
-
-# The CHM_FILE tag can be used to specify the file name of the resulting .chm
-# file. You can add a path in front of the file if the result should not be
-# written to the html output directory.
-# This tag requires that the tag GENERATE_HTMLHELP is set to YES.
-
-CHM_FILE               =
-
-# The HHC_LOCATION tag can be used to specify the location (absolute path
-# including file name) of the HTML help compiler (hhc.exe). If non-empty,
-# doxygen will try to run the HTML help compiler on the generated index.hhp.
-# The file has to be specified with full path.
-# This tag requires that the tag GENERATE_HTMLHELP is set to YES.
-
-HHC_LOCATION           =
-
-# The GENERATE_CHI flag controls if a separate .chi index file is generated
-# (YES) or that it should be included in the master .chm file (NO).
-# The default value is: NO.
-# This tag requires that the tag GENERATE_HTMLHELP is set to YES.
-
-GENERATE_CHI           = NO
-
-# The CHM_INDEX_ENCODING is used to encode HtmlHelp index (hhk), content (hhc)
-# and project file content.
-# This tag requires that the tag GENERATE_HTMLHELP is set to YES.
-
-CHM_INDEX_ENCODING     =
-
-# The BINARY_TOC flag controls whether a binary table of contents is generated
-# (YES) or a normal table of contents (NO) in the .chm file. Furthermore it
-# enables the Previous and Next buttons.
-# The default value is: NO.
-# This tag requires that the tag GENERATE_HTMLHELP is set to YES.
-
-BINARY_TOC             = NO
-
-# The TOC_EXPAND flag can be set to YES to add extra items for group members to
-# the table of contents of the HTML help documentation and to the tree view.
-# The default value is: NO.
-# This tag requires that the tag GENERATE_HTMLHELP is set to YES.
-
-TOC_EXPAND             = NO
-
-# If the GENERATE_QHP tag is set to YES and both QHP_NAMESPACE and
-# QHP_VIRTUAL_FOLDER are set, an additional index file will be generated that
-# can be used as input for Qt's qhelpgenerator to generate a Qt Compressed Help
-# (.qch) of the generated HTML documentation.
-# The default value is: NO.
-# This tag requires that the tag GENERATE_HTML is set to YES.
-
-GENERATE_QHP           = NO
-
-# If the QHG_LOCATION tag is specified, the QCH_FILE tag can be used to specify
-# the file name of the resulting .qch file. The path specified is relative to
-# the HTML output folder.
-# This tag requires that the tag GENERATE_QHP is set to YES.
-
-QCH_FILE               =
-
-# The QHP_NAMESPACE tag specifies the namespace to use when generating Qt Help
-# Project output. For more information please see Qt Help Project / Namespace
-# (see: http://qt-project.org/doc/qt-4.8/qthelpproject.html#namespace).
-# The default value is: org.doxygen.Project.
-# This tag requires that the tag GENERATE_QHP is set to YES.
-
-QHP_NAMESPACE          = org.doxygen.Project
-
-# The QHP_VIRTUAL_FOLDER tag specifies the namespace to use when generating Qt
-# Help Project output. For more information please see Qt Help Project / Virtual
-# Folders (see: http://qt-project.org/doc/qt-4.8/qthelpproject.html#virtual-
-# folders).
-# The default value is: doc.
-# This tag requires that the tag GENERATE_QHP is set to YES.
-
-QHP_VIRTUAL_FOLDER     = doc
-
-# If the QHP_CUST_FILTER_NAME tag is set, it specifies the name of a custom
-# filter to add. For more information please see Qt Help Project / Custom
-# Filters (see: http://qt-project.org/doc/qt-4.8/qthelpproject.html#custom-
-# filters).
-# This tag requires that the tag GENERATE_QHP is set to YES.
-
-QHP_CUST_FILTER_NAME   =
-
-# The QHP_CUST_FILTER_ATTRS tag specifies the list of the attributes of the
-# custom filter to add. For more information please see Qt Help Project / Custom
-# Filters (see: http://qt-project.org/doc/qt-4.8/qthelpproject.html#custom-
-# filters).
-# This tag requires that the tag GENERATE_QHP is set to YES.
-
-QHP_CUST_FILTER_ATTRS  =
-
-# The QHP_SECT_FILTER_ATTRS tag specifies the list of the attributes this
-# project's filter section matches. Qt Help Project / Filter Attributes (see:
-# http://qt-project.org/doc/qt-4.8/qthelpproject.html#filter-attributes).
-# This tag requires that the tag GENERATE_QHP is set to YES.
-
-QHP_SECT_FILTER_ATTRS  =
-
-# The QHG_LOCATION tag can be used to specify the location of Qt's
-# qhelpgenerator. If non-empty doxygen will try to run qhelpgenerator on the
-# generated .qhp file.
-# This tag requires that the tag GENERATE_QHP is set to YES.
-
-QHG_LOCATION           =
-
-# If the GENERATE_ECLIPSEHELP tag is set to YES, additional index files will be
-# generated, together with the HTML files, they form an Eclipse help plugin. To
-# install this plugin and make it available under the help contents menu in
-# Eclipse, the contents of the directory containing the HTML and XML files needs
-# to be copied into the plugins directory of eclipse. The name of the directory
-# within the plugins directory should be the same as the ECLIPSE_DOC_ID value.
-# After copying Eclipse needs to be restarted before the help appears.
-# The default value is: NO.
-# This tag requires that the tag GENERATE_HTML is set to YES.
-
-GENERATE_ECLIPSEHELP   = NO
-
-# A unique identifier for the Eclipse help plugin. When installing the plugin
-# the directory name containing the HTML and XML files should also have this
-# name. Each documentation set should have its own identifier.
-# The default value is: org.doxygen.Project.
-# This tag requires that the tag GENERATE_ECLIPSEHELP is set to YES.
-
-ECLIPSE_DOC_ID         = org.doxygen.Project
-
-# If you want full control over the layout of the generated HTML pages it might
-# be necessary to disable the index and replace it with your own. The
-# DISABLE_INDEX tag can be used to turn on/off the condensed index (tabs) at top
-# of each HTML page. A value of NO enables the index and the value YES disables
-# it. Since the tabs in the index contain the same information as the navigation
-# tree, you can set this option to YES if you also set GENERATE_TREEVIEW to YES.
-# The default value is: NO.
-# This tag requires that the tag GENERATE_HTML is set to YES.
-
-DISABLE_INDEX          = NO
-
-# The GENERATE_TREEVIEW tag is used to specify whether a tree-like index
-# structure should be generated to display hierarchical information. If the tag
-# value is set to YES, a side panel will be generated containing a tree-like
-# index structure (just like the one that is generated for HTML Help). For this
-# to work a browser that supports JavaScript, DHTML, CSS and frames is required
-# (i.e. any modern browser). Windows users are probably better off using the
-# HTML help feature. Via custom style sheets (see HTML_EXTRA_STYLESHEET) one can
-# further fine-tune the look of the index. As an example, the default style
-# sheet generated by doxygen has an example that shows how to put an image at
-# the root of the tree instead of the PROJECT_NAME. Since the tree basically has
-# the same information as the tab index, you could consider setting
-# DISABLE_INDEX to YES when enabling this option.
-# The default value is: NO.
-# This tag requires that the tag GENERATE_HTML is set to YES.
-
-GENERATE_TREEVIEW      = YES
-
-# The ENUM_VALUES_PER_LINE tag can be used to set the number of enum values that
-# doxygen will group on one line in the generated HTML documentation.
-#
-# Note that a value of 0 will completely suppress the enum values from appearing
-# in the overview section.
-# Minimum value: 0, maximum value: 20, default value: 4.
-# This tag requires that the tag GENERATE_HTML is set to YES.
-
-ENUM_VALUES_PER_LINE   = 4
-
-# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be used
-# to set the initial width (in pixels) of the frame in which the tree is shown.
-# Minimum value: 0, maximum value: 1500, default value: 250.
-# This tag requires that the tag GENERATE_HTML is set to YES.
-
-TREEVIEW_WIDTH         = 250
-
-# If the EXT_LINKS_IN_WINDOW option is set to YES, doxygen will open links to
-# external symbols imported via tag files in a separate window.
-# The default value is: NO.
-# This tag requires that the tag GENERATE_HTML is set to YES.
-
-EXT_LINKS_IN_WINDOW    = NO
-
-# Use this tag to change the font size of LaTeX formulas included as images in
-# the HTML documentation. When you change the font size after a successful
-# doxygen run you need to manually remove any form_*.png images from the HTML
-# output directory to force them to be regenerated.
-# Minimum value: 8, maximum value: 50, default value: 10.
-# This tag requires that the tag GENERATE_HTML is set to YES.
-
-FORMULA_FONTSIZE       = 10
-
-# Use the FORMULA_TRANPARENT tag to determine whether or not the images
-# generated for formulas are transparent PNGs. Transparent PNGs are not
-# supported properly for IE 6.0, but are supported on all modern browsers.
-#
-# Note that when changing this option you need to delete any form_*.png files in
-# the HTML output directory before the changes have effect.
-# The default value is: YES.
-# This tag requires that the tag GENERATE_HTML is set to YES.
-
-FORMULA_TRANSPARENT    = YES
-
-# Enable the USE_MATHJAX option to render LaTeX formulas using MathJax (see
-# http://www.mathjax.org) which uses client side Javascript for the rendering
-# instead of using pre-rendered bitmaps. Use this if you do not have LaTeX
-# installed or if you want to formulas look prettier in the HTML output. When
-# enabled you may also need to install MathJax separately and configure the path
-# to it using the MATHJAX_RELPATH option.
-# The default value is: NO.
-# This tag requires that the tag GENERATE_HTML is set to YES.
-
-USE_MATHJAX            = NO
-
-# When MathJax is enabled you can set the default output format to be used for
-# the MathJax output. See the MathJax site (see:
-# http://docs.mathjax.org/en/latest/output.html) for more details.
-# Possible values are: HTML-CSS (which is slower, but has the best
-# compatibility), NativeMML (i.e. MathML) and SVG.
-# The default value is: HTML-CSS.
-# This tag requires that the tag USE_MATHJAX is set to YES.
-
-MATHJAX_FORMAT         = HTML-CSS
-
-# When MathJax is enabled you need to specify the location relative to the HTML
-# output directory using the MATHJAX_RELPATH option. The destination directory
-# should contain the MathJax.js script. For instance, if the mathjax directory
-# is located at the same level as the HTML output directory, then
-# MATHJAX_RELPATH should be ../mathjax. The default value points to the MathJax
-# Content Delivery Network so you can quickly see the result without installing
-# MathJax. However, it is strongly recommended to install a local copy of
-# MathJax from http://www.mathjax.org before deployment.
-# The default value is: http://cdn.mathjax.org/mathjax/latest.
-# This tag requires that the tag USE_MATHJAX is set to YES.
-
-MATHJAX_RELPATH        = http://www.mathjax.org/mathjax
-
-# The MATHJAX_EXTENSIONS tag can be used to specify one or more MathJax
-# extension names that should be enabled during MathJax rendering. For example
-# MATHJAX_EXTENSIONS = TeX/AMSmath TeX/AMSsymbols
-# This tag requires that the tag USE_MATHJAX is set to YES.
-
-MATHJAX_EXTENSIONS     =
-
-# The MATHJAX_CODEFILE tag can be used to specify a file with javascript pieces
-# of code that will be used on startup of the MathJax code. See the MathJax site
-# (see: http://docs.mathjax.org/en/latest/output.html) for more details. For an
-# example see the documentation.
-# This tag requires that the tag USE_MATHJAX is set to YES.
-
-MATHJAX_CODEFILE       =
-
-# When the SEARCHENGINE tag is enabled doxygen will generate a search box for
-# the HTML output. The underlying search engine uses javascript and DHTML and
-# should work on any modern browser. Note that when using HTML help
-# (GENERATE_HTMLHELP), Qt help (GENERATE_QHP), or docsets (GENERATE_DOCSET)
-# there is already a search function so this one should typically be disabled.
-# For large projects the javascript based search engine can be slow, then
-# enabling SERVER_BASED_SEARCH may provide a better solution. It is possible to
-# search using the keyboard; to jump to the search box use <access key> + S
-# (what the <access key> is depends on the OS and browser, but it is typically
-# <CTRL>, <ALT>/<option>, or both). Inside the search box use the <cursor down
-# key> to jump into the search results window, the results can be navigated
-# using the <cursor keys>. Press <Enter> to select an item or <escape> to cancel
-# the search. The filter options can be selected when the cursor is inside the
-# search box by pressing <Shift>+<cursor down>. Also here use the <cursor keys>
-# to select a filter and <Enter> or <escape> to activate or cancel the filter
-# option.
-# The default value is: YES.
-# This tag requires that the tag GENERATE_HTML is set to YES.
-
-SEARCHENGINE           = YES
-
-# When the SERVER_BASED_SEARCH tag is enabled the search engine will be
-# implemented using a web server instead of a web client using Javascript. There
-# are two flavors of web server based searching depending on the EXTERNAL_SEARCH
-# setting. When disabled, doxygen will generate a PHP script for searching and
-# an index file used by the script. When EXTERNAL_SEARCH is enabled the indexing
-# and searching needs to be provided by external tools. See the section
-# "External Indexing and Searching" for details.
-# The default value is: NO.
-# This tag requires that the tag SEARCHENGINE is set to YES.
-
-SERVER_BASED_SEARCH    = NO
-
-# When EXTERNAL_SEARCH tag is enabled doxygen will no longer generate the PHP
-# script for searching. Instead the search results are written to an XML file
-# which needs to be processed by an external indexer. Doxygen will invoke an
-# external search engine pointed to by the SEARCHENGINE_URL option to obtain the
-# search results.
-#
-# Doxygen ships with an example indexer (doxyindexer) and search engine
-# (doxysearch.cgi) which are based on the open source search engine library
-# Xapian (see: http://xapian.org/).
-#
-# See the section "External Indexing and Searching" for details.
-# The default value is: NO.
-# This tag requires that the tag SEARCHENGINE is set to YES.
-
-EXTERNAL_SEARCH        = NO
-
-# The SEARCHENGINE_URL should point to a search engine hosted by a web server
-# which will return the search results when EXTERNAL_SEARCH is enabled.
-#
-# Doxygen ships with an example indexer (doxyindexer) and search engine
-# (doxysearch.cgi) which are based on the open source search engine library
-# Xapian (see: http://xapian.org/). See the section "External Indexing and
-# Searching" for details.
-# This tag requires that the tag SEARCHENGINE is set to YES.
-
-SEARCHENGINE_URL       =
-
-# When SERVER_BASED_SEARCH and EXTERNAL_SEARCH are both enabled the unindexed
-# search data is written to a file for indexing by an external tool. With the
-# SEARCHDATA_FILE tag the name of this file can be specified.
-# The default file is: searchdata.xml.
-# This tag requires that the tag SEARCHENGINE is set to YES.
-
-SEARCHDATA_FILE        = searchdata.xml
-
-# When SERVER_BASED_SEARCH and EXTERNAL_SEARCH are both enabled the
-# EXTERNAL_SEARCH_ID tag can be used as an identifier for the project. This is
-# useful in combination with EXTRA_SEARCH_MAPPINGS to search through multiple
-# projects and redirect the results back to the right project.
-# This tag requires that the tag SEARCHENGINE is set to YES.
-
-EXTERNAL_SEARCH_ID     =
-
-# The EXTRA_SEARCH_MAPPINGS tag can be used to enable searching through doxygen
-# projects other than the one defined by this configuration file, but that are
-# all added to the same external search index. Each project needs to have a
-# unique id set via EXTERNAL_SEARCH_ID. The search mapping then maps the id of
-# to a relative location where the documentation can be found. The format is:
-# EXTRA_SEARCH_MAPPINGS = tagname1=loc1 tagname2=loc2 ...
-# This tag requires that the tag SEARCHENGINE is set to YES.
-
-EXTRA_SEARCH_MAPPINGS  =
-
-#---------------------------------------------------------------------------
-# Configuration options related to the LaTeX output
-#---------------------------------------------------------------------------
-
-# If the GENERATE_LATEX tag is set to YES, doxygen will generate LaTeX output.
-# The default value is: YES.
-
-GENERATE_LATEX         = NO
-
-# The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put. If a
-# relative path is entered the value of OUTPUT_DIRECTORY will be put in front of
-# it.
-# The default directory is: latex.
-# This tag requires that the tag GENERATE_LATEX is set to YES.
-
-LATEX_OUTPUT           = latex
-
-# The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be
-# invoked.
-#
-# Note that when enabling USE_PDFLATEX this option is only used for generating
-# bitmaps for formulas in the HTML output, but not in the Makefile that is
-# written to the output directory.
-# The default file is: latex.
-# This tag requires that the tag GENERATE_LATEX is set to YES.
-
-LATEX_CMD_NAME         = latex
-
-# The MAKEINDEX_CMD_NAME tag can be used to specify the command name to generate
-# index for LaTeX.
-# The default file is: makeindex.
-# This tag requires that the tag GENERATE_LATEX is set to YES.
-
-MAKEINDEX_CMD_NAME     = makeindex
-
-# If the COMPACT_LATEX tag is set to YES, doxygen generates more compact LaTeX
-# documents. This may be useful for small projects and may help to save some
-# trees in general.
-# The default value is: NO.
-# This tag requires that the tag GENERATE_LATEX is set to YES.
-
-COMPACT_LATEX          = NO
-
-# The PAPER_TYPE tag can be used to set the paper type that is used by the
-# printer.
-# Possible values are: a4 (210 x 297 mm), letter (8.5 x 11 inches), legal (8.5 x
-# 14 inches) and executive (7.25 x 10.5 inches).
-# The default value is: a4.
-# This tag requires that the tag GENERATE_LATEX is set to YES.
-
-PAPER_TYPE             = a4
-
-# The EXTRA_PACKAGES tag can be used to specify one or more LaTeX package names
-# that should be included in the LaTeX output. The package can be specified just
-# by its name or with the correct syntax as to be used with the LaTeX
-# \usepackage command. To get the times font for instance you can specify :
-# EXTRA_PACKAGES=times or EXTRA_PACKAGES={times}
-# To use the option intlimits with the amsmath package you can specify:
-# EXTRA_PACKAGES=[intlimits]{amsmath}
-# If left blank no extra packages will be included.
-# This tag requires that the tag GENERATE_LATEX is set to YES.
-
-EXTRA_PACKAGES         =
-
-# The LATEX_HEADER tag can be used to specify a personal LaTeX header for the
-# generated LaTeX document. The header should contain everything until the first
-# chapter. If it is left blank doxygen will generate a standard header. See
-# section "Doxygen usage" for information on how to let doxygen write the
-# default header to a separate file.
-#
-# Note: Only use a user-defined header if you know what you are doing! The
-# following commands have a special meaning inside the header: $title,
-# $datetime, $date, $doxygenversion, $projectname, $projectnumber,
-# $projectbrief, $projectlogo. Doxygen will replace $title with the empty
-# string, for the replacement values of the other commands the user is referred
-# to HTML_HEADER.
-# This tag requires that the tag GENERATE_LATEX is set to YES.
-
-LATEX_HEADER           =
-
-# The LATEX_FOOTER tag can be used to specify a personal LaTeX footer for the
-# generated LaTeX document. The footer should contain everything after the last
-# chapter. If it is left blank doxygen will generate a standard footer. See
-# LATEX_HEADER for more information on how to generate a default footer and what
-# special commands can be used inside the footer.
-#
-# Note: Only use a user-defined footer if you know what you are doing!
-# This tag requires that the tag GENERATE_LATEX is set to YES.
-
-LATEX_FOOTER           =
-
-# The LATEX_EXTRA_STYLESHEET tag can be used to specify additional user-defined
-# LaTeX style sheets that are included after the standard style sheets created
-# by doxygen. Using this option one can overrule certain style aspects. Doxygen
-# will copy the style sheet files to the output directory.
-# Note: The order of the extra style sheet files is of importance (e.g. the last
-# style sheet in the list overrules the setting of the previous ones in the
-# list).
-# This tag requires that the tag GENERATE_LATEX is set to YES.
-
-LATEX_EXTRA_STYLESHEET =
-
-# The LATEX_EXTRA_FILES tag can be used to specify one or more extra images or
-# other source files which should be copied to the LATEX_OUTPUT output
-# directory. Note that the files will be copied as-is; there are no commands or
-# markers available.
-# This tag requires that the tag GENERATE_LATEX is set to YES.
-
-LATEX_EXTRA_FILES      =
-
-# If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated is
-# prepared for conversion to PDF (using ps2pdf or pdflatex). The PDF file will
-# contain links (just like the HTML output) instead of page references. This
-# makes the output suitable for online browsing using a PDF viewer.
-# The default value is: YES.
-# This tag requires that the tag GENERATE_LATEX is set to YES.
-
-PDF_HYPERLINKS         = YES
-
-# If the USE_PDFLATEX tag is set to YES, doxygen will use pdflatex to generate
-# the PDF file directly from the LaTeX files. Set this option to YES, to get a
-# higher quality PDF documentation.
-# The default value is: YES.
-# This tag requires that the tag GENERATE_LATEX is set to YES.
-
-USE_PDFLATEX           = YES
-
-# If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \batchmode
-# command to the generated LaTeX files. This will instruct LaTeX to keep running
-# if errors occur, instead of asking the user for help. This option is also used
-# when generating formulas in HTML.
-# The default value is: NO.
-# This tag requires that the tag GENERATE_LATEX is set to YES.
-
-LATEX_BATCHMODE        = NO
-
-# If the LATEX_HIDE_INDICES tag is set to YES then doxygen will not include the
-# index chapters (such as File Index, Compound Index, etc.) in the output.
-# The default value is: NO.
-# This tag requires that the tag GENERATE_LATEX is set to YES.
-
-LATEX_HIDE_INDICES     = NO
-
-# If the LATEX_SOURCE_CODE tag is set to YES then doxygen will include source
-# code with syntax highlighting in the LaTeX output.
-#
-# Note that which sources are shown also depends on other settings such as
-# SOURCE_BROWSER.
-# The default value is: NO.
-# This tag requires that the tag GENERATE_LATEX is set to YES.
-
-LATEX_SOURCE_CODE      = NO
-
-# The LATEX_BIB_STYLE tag can be used to specify the style to use for the
-# bibliography, e.g. plainnat, or ieeetr. See
-# http://en.wikipedia.org/wiki/BibTeX and \cite for more info.
-# The default value is: plain.
-# This tag requires that the tag GENERATE_LATEX is set to YES.
-
-LATEX_BIB_STYLE        = plain
-
-# If the LATEX_TIMESTAMP tag is set to YES then the footer of each generated
-# page will contain the date and time when the page was generated. Setting this
-# to NO can help when comparing the output of multiple runs.
-# The default value is: NO.
-# This tag requires that the tag GENERATE_LATEX is set to YES.
-
-LATEX_TIMESTAMP        = NO
-
-#---------------------------------------------------------------------------
-# Configuration options related to the RTF output
-#---------------------------------------------------------------------------
-
-# If the GENERATE_RTF tag is set to YES, doxygen will generate RTF output. The
-# RTF output is optimized for Word 97 and may not look too pretty with other RTF
-# readers/editors.
-# The default value is: NO.
-
-GENERATE_RTF           = NO
-
-# The RTF_OUTPUT tag is used to specify where the RTF docs will be put. If a
-# relative path is entered the value of OUTPUT_DIRECTORY will be put in front of
-# it.
-# The default directory is: rtf.
-# This tag requires that the tag GENERATE_RTF is set to YES.
-
-RTF_OUTPUT             = rtf
-
-# If the COMPACT_RTF tag is set to YES, doxygen generates more compact RTF
-# documents. This may be useful for small projects and may help to save some
-# trees in general.
-# The default value is: NO.
-# This tag requires that the tag GENERATE_RTF is set to YES.
-
-COMPACT_RTF            = NO
-
-# If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated will
-# contain hyperlink fields. The RTF file will contain links (just like the HTML
-# output) instead of page references. This makes the output suitable for online
-# browsing using Word or some other Word compatible readers that support those
-# fields.
-#
-# Note: WordPad (write) and others do not support links.
-# The default value is: NO.
-# This tag requires that the tag GENERATE_RTF is set to YES.
-
-RTF_HYPERLINKS         = NO
-
-# Load stylesheet definitions from file. Syntax is similar to doxygen's config
-# file, i.e. a series of assignments. You only have to provide replacements,
-# missing definitions are set to their default value.
-#
-# See also section "Doxygen usage" for information on how to generate the
-# default style sheet that doxygen normally uses.
-# This tag requires that the tag GENERATE_RTF is set to YES.
-
-RTF_STYLESHEET_FILE    =
-
-# Set optional variables used in the generation of an RTF document. Syntax is
-# similar to doxygen's config file. A template extensions file can be generated
-# using doxygen -e rtf extensionFile.
-# This tag requires that the tag GENERATE_RTF is set to YES.
-
-RTF_EXTENSIONS_FILE    =
-
-# If the RTF_SOURCE_CODE tag is set to YES then doxygen will include source code
-# with syntax highlighting in the RTF output.
-#
-# Note that which sources are shown also depends on other settings such as
-# SOURCE_BROWSER.
-# The default value is: NO.
-# This tag requires that the tag GENERATE_RTF is set to YES.
-
-RTF_SOURCE_CODE        = NO
-
-#---------------------------------------------------------------------------
-# Configuration options related to the man page output
-#---------------------------------------------------------------------------
-
-# If the GENERATE_MAN tag is set to YES, doxygen will generate man pages for
-# classes and files.
-# The default value is: NO.
-
-GENERATE_MAN           = NO
-
-# The MAN_OUTPUT tag is used to specify where the man pages will be put. If a
-# relative path is entered the value of OUTPUT_DIRECTORY will be put in front of
-# it. A directory man3 will be created inside the directory specified by
-# MAN_OUTPUT.
-# The default directory is: man.
-# This tag requires that the tag GENERATE_MAN is set to YES.
-
-MAN_OUTPUT             = man
-
-# The MAN_EXTENSION tag determines the extension that is added to the generated
-# man pages. In case the manual section does not start with a number, the number
-# 3 is prepended. The dot (.) at the beginning of the MAN_EXTENSION tag is
-# optional.
-# The default value is: .3.
-# This tag requires that the tag GENERATE_MAN is set to YES.
-
-MAN_EXTENSION          = .3
-
-# The MAN_SUBDIR tag determines the name of the directory created within
-# MAN_OUTPUT in which the man pages are placed. If defaults to man followed by
-# MAN_EXTENSION with the initial . removed.
-# This tag requires that the tag GENERATE_MAN is set to YES.
-
-MAN_SUBDIR             =
-
-# If the MAN_LINKS tag is set to YES and doxygen generates man output, then it
-# will generate one additional man file for each entity documented in the real
-# man page(s). These additional files only source the real man page, but without
-# them the man command would be unable to find the correct page.
-# The default value is: NO.
-# This tag requires that the tag GENERATE_MAN is set to YES.
-
-MAN_LINKS              = YES
-
-#---------------------------------------------------------------------------
-# Configuration options related to the XML output
-#---------------------------------------------------------------------------
-
-# If the GENERATE_XML tag is set to YES, doxygen will generate an XML file that
-# captures the structure of the code including all documentation.
-# The default value is: NO.
-
-GENERATE_XML           = NO
-
-# The XML_OUTPUT tag is used to specify where the XML pages will be put. If a
-# relative path is entered the value of OUTPUT_DIRECTORY will be put in front of
-# it.
-# The default directory is: xml.
-# This tag requires that the tag GENERATE_XML is set to YES.
-
-XML_OUTPUT             = xml
-
-# If the XML_PROGRAMLISTING tag is set to YES, doxygen will dump the program
-# listings (including syntax highlighting and cross-referencing information) to
-# the XML output. Note that enabling this will significantly increase the size
-# of the XML output.
-# The default value is: YES.
-# This tag requires that the tag GENERATE_XML is set to YES.
-
-XML_PROGRAMLISTING     = YES
-
-#---------------------------------------------------------------------------
-# Configuration options related to the DOCBOOK output
-#---------------------------------------------------------------------------
-
-# If the GENERATE_DOCBOOK tag is set to YES, doxygen will generate Docbook files
-# that can be used to generate PDF.
-# The default value is: NO.
-
-GENERATE_DOCBOOK       = NO
-
-# The DOCBOOK_OUTPUT tag is used to specify where the Docbook pages will be put.
-# If a relative path is entered the value of OUTPUT_DIRECTORY will be put in
-# front of it.
-# The default directory is: docbook.
-# This tag requires that the tag GENERATE_DOCBOOK is set to YES.
-
-DOCBOOK_OUTPUT         = docbook
-
-# If the DOCBOOK_PROGRAMLISTING tag is set to YES, doxygen will include the
-# program listings (including syntax highlighting and cross-referencing
-# information) to the DOCBOOK output. Note that enabling this will significantly
-# increase the size of the DOCBOOK output.
-# The default value is: NO.
-# This tag requires that the tag GENERATE_DOCBOOK is set to YES.
-
-DOCBOOK_PROGRAMLISTING = NO
-
-#---------------------------------------------------------------------------
-# Configuration options for the AutoGen Definitions output
-#---------------------------------------------------------------------------
-
-# If the GENERATE_AUTOGEN_DEF tag is set to YES, doxygen will generate an
-# AutoGen Definitions (see http://autogen.sf.net) file that captures the
-# structure of the code including all documentation. Note that this feature is
-# still experimental and incomplete at the moment.
-# The default value is: NO.
-
-GENERATE_AUTOGEN_DEF   = NO
-
-#---------------------------------------------------------------------------
-# Configuration options related to the Perl module output
-#---------------------------------------------------------------------------
-
-# If the GENERATE_PERLMOD tag is set to YES, doxygen will generate a Perl module
-# file that captures the structure of the code including all documentation.
-#
-# Note that this feature is still experimental and incomplete at the moment.
-# The default value is: NO.
-
-GENERATE_PERLMOD       = NO
-
-# If the PERLMOD_LATEX tag is set to YES, doxygen will generate the necessary
-# Makefile rules, Perl scripts and LaTeX code to be able to generate PDF and DVI
-# output from the Perl module output.
-# The default value is: NO.
-# This tag requires that the tag GENERATE_PERLMOD is set to YES.
-
-PERLMOD_LATEX          = NO
-
-# If the PERLMOD_PRETTY tag is set to YES, the Perl module output will be nicely
-# formatted so it can be parsed by a human reader. This is useful if you want to
-# understand what is going on. On the other hand, if this tag is set to NO, the
-# size of the Perl module output will be much smaller and Perl will parse it
-# just the same.
-# The default value is: YES.
-# This tag requires that the tag GENERATE_PERLMOD is set to YES.
-
-PERLMOD_PRETTY         = YES
-
-# The names of the make variables in the generated doxyrules.make file are
-# prefixed with the string contained in PERLMOD_MAKEVAR_PREFIX. This is useful
-# so different doxyrules.make files included by the same Makefile don't
-# overwrite each other's variables.
-# This tag requires that the tag GENERATE_PERLMOD is set to YES.
-
-PERLMOD_MAKEVAR_PREFIX =
-
-#---------------------------------------------------------------------------
-# Configuration options related to the preprocessor
-#---------------------------------------------------------------------------
-
-# If the ENABLE_PREPROCESSING tag is set to YES, doxygen will evaluate all
-# C-preprocessor directives found in the sources and include files.
-# The default value is: YES.
-
-ENABLE_PREPROCESSING   = YES
-
-# If the MACRO_EXPANSION tag is set to YES, doxygen will expand all macro names
-# in the source code. If set to NO, only conditional compilation will be
-# performed. Macro expansion can be done in a controlled way by setting
-# EXPAND_ONLY_PREDEF to YES.
-# The default value is: NO.
-# This tag requires that the tag ENABLE_PREPROCESSING is set to YES.
-
-MACRO_EXPANSION        = YES
-
-# If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES then
-# the macro expansion is limited to the macros specified with the PREDEFINED and
-# EXPAND_AS_DEFINED tags.
-# The default value is: NO.
-# This tag requires that the tag ENABLE_PREPROCESSING is set to YES.
-
-EXPAND_ONLY_PREDEF     = NO
-
-# If the SEARCH_INCLUDES tag is set to YES, the include files in the
-# INCLUDE_PATH will be searched if a #include is found.
-# The default value is: YES.
-# This tag requires that the tag ENABLE_PREPROCESSING is set to YES.
-
-SEARCH_INCLUDES        = YES
-
-# The INCLUDE_PATH tag can be used to specify one or more directories that
-# contain include files that are not input files but should be processed by the
-# preprocessor.
-# This tag requires that the tag SEARCH_INCLUDES is set to YES.
-
-INCLUDE_PATH           =
-
-# You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard
-# patterns (like *.h and *.hpp) to filter out the header-files in the
-# directories. If left blank, the patterns specified with FILE_PATTERNS will be
-# used.
-# This tag requires that the tag ENABLE_PREPROCESSING is set to YES.
-
-INCLUDE_FILE_PATTERNS  =
-
-# The PREDEFINED tag can be used to specify one or more macro names that are
-# defined before the preprocessor is started (similar to the -D option of e.g.
-# gcc). The argument of the tag is a list of macros of the form: name or
-# name=definition (no spaces). If the definition and the "=" are omitted, "=1"
-# is assumed. To prevent a macro definition from being undefined via #undef or
-# recursively expanded use the := operator instead of the = operator.
-# This tag requires that the tag ENABLE_PREPROCESSING is set to YES.
-
-PREDEFINED             = DOXYGEN
-
-# If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then this
-# tag can be used to specify a list of macro names that should be expanded. The
-# macro definition that is found in the sources will be used. Use the PREDEFINED
-# tag if you want to use a different macro definition that overrules the
-# definition found in the source code.
-# This tag requires that the tag ENABLE_PREPROCESSING is set to YES.
-
-EXPAND_AS_DEFINED      =
-
-# If the SKIP_FUNCTION_MACROS tag is set to YES then doxygen's preprocessor will
-# remove all references to function-like macros that are alone on a line, have
-# an all uppercase name, and do not end with a semicolon. Such function macros
-# are typically used for boiler-plate code, and will confuse the parser if not
-# removed.
-# The default value is: YES.
-# This tag requires that the tag ENABLE_PREPROCESSING is set to YES.
-
-SKIP_FUNCTION_MACROS   = YES
-
-#---------------------------------------------------------------------------
-# Configuration options related to external references
-#---------------------------------------------------------------------------
-
-# The TAGFILES tag can be used to specify one or more tag files. For each tag
-# file the location of the external documentation should be added. The format of
-# a tag file without this location is as follows:
-# TAGFILES = file1 file2 ...
-# Adding location for the tag files is done as follows:
-# TAGFILES = file1=loc1 "file2 = loc2" ...
-# where loc1 and loc2 can be relative or absolute paths or URLs. See the
-# section "Linking to external documentation" for more information about the use
-# of tag files.
-# Note: Each tag file must have a unique name (where the name does NOT include
-# the path). If a tag file is not located in the directory in which doxygen is
-# run, you must also specify the path to the tagfile here.
-
-TAGFILES               =
-
-# When a file name is specified after GENERATE_TAGFILE, doxygen will create a
-# tag file that is based on the input files it reads. See section "Linking to
-# external documentation" for more information about the usage of tag files.
-
-GENERATE_TAGFILE       =
-
-# If the ALLEXTERNALS tag is set to YES, all external class will be listed in
-# the class index. If set to NO, only the inherited external classes will be
-# listed.
-# The default value is: NO.
-
-ALLEXTERNALS           = NO
-
-# If the EXTERNAL_GROUPS tag is set to YES, all external groups will be listed
-# in the modules index. If set to NO, only the current project's groups will be
-# listed.
-# The default value is: YES.
-
-EXTERNAL_GROUPS        = YES
-
-# If the EXTERNAL_PAGES tag is set to YES, all external pages will be listed in
-# the related pages index. If set to NO, only the current project's pages will
-# be listed.
-# The default value is: YES.
-
-EXTERNAL_PAGES         = YES
-
-# The PERL_PATH should be the absolute path and name of the perl script
-# interpreter (i.e. the result of 'which perl').
-# The default file (with absolute path) is: /usr/bin/perl.
-
-PERL_PATH              = /usr/bin/perl
-
-#---------------------------------------------------------------------------
-# Configuration options related to the dot tool
-#---------------------------------------------------------------------------
-
-# If the CLASS_DIAGRAMS tag is set to YES, doxygen will generate a class diagram
-# (in HTML and LaTeX) for classes with base or super classes. Setting the tag to
-# NO turns the diagrams off. Note that this option also works with HAVE_DOT
-# disabled, but it is recommended to install and use dot, since it yields more
-# powerful graphs.
-# The default value is: YES.
-
-CLASS_DIAGRAMS         = YES
-
-# You can define message sequence charts within doxygen comments using the \msc
-# command. Doxygen will then run the mscgen tool (see:
-# http://www.mcternan.me.uk/mscgen/)) to produce the chart and insert it in the
-# documentation. The MSCGEN_PATH tag allows you to specify the directory where
-# the mscgen tool resides. If left empty the tool is assumed to be found in the
-# default search path.
-
-MSCGEN_PATH            =
-
-# You can include diagrams made with dia in doxygen documentation. Doxygen will
-# then run dia to produce the diagram and insert it in the documentation. The
-# DIA_PATH tag allows you to specify the directory where the dia binary resides.
-# If left empty dia is assumed to be found in the default search path.
-
-DIA_PATH               =
-
-# If set to YES the inheritance and collaboration graphs will hide inheritance
-# and usage relations if the target is undocumented or is not a class.
-# The default value is: YES.
-
-HIDE_UNDOC_RELATIONS   = YES
-
-# If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is
-# available from the path. This tool is part of Graphviz (see:
-# http://www.graphviz.org/), a graph visualization toolkit from AT&T and Lucent
-# Bell Labs. The other options in this section have no effect if this option is
-# set to NO
-# The default value is: YES.
-
-HAVE_DOT               = NO
-
-# The DOT_NUM_THREADS specifies the number of dot invocations doxygen is allowed
-# to run in parallel. When set to 0 doxygen will base this on the number of
-# processors available in the system. You can set it explicitly to a value
-# larger than 0 to get control over the balance between CPU load and processing
-# speed.
-# Minimum value: 0, maximum value: 32, default value: 0.
-# This tag requires that the tag HAVE_DOT is set to YES.
-
-DOT_NUM_THREADS        = 0
-
-# When you want a differently looking font in the dot files that doxygen
-# generates you can specify the font name using DOT_FONTNAME. You need to make
-# sure dot is able to find the font, which can be done by putting it in a
-# standard location or by setting the DOTFONTPATH environment variable or by
-# setting DOT_FONTPATH to the directory containing the font.
-# The default value is: Helvetica.
-# This tag requires that the tag HAVE_DOT is set to YES.
-
-DOT_FONTNAME           = Helvetica
-
-# The DOT_FONTSIZE tag can be used to set the size (in points) of the font of
-# dot graphs.
-# Minimum value: 4, maximum value: 24, default value: 10.
-# This tag requires that the tag HAVE_DOT is set to YES.
-
-DOT_FONTSIZE           = 10
-
-# By default doxygen will tell dot to use the default font as specified with
-# DOT_FONTNAME. If you specify a different font using DOT_FONTNAME you can set
-# the path where dot can find it using this tag.
-# This tag requires that the tag HAVE_DOT is set to YES.
-
-DOT_FONTPATH           =
-
-# If the CLASS_GRAPH tag is set to YES then doxygen will generate a graph for
-# each documented class showing the direct and indirect inheritance relations.
-# Setting this tag to YES will force the CLASS_DIAGRAMS tag to NO.
-# The default value is: YES.
-# This tag requires that the tag HAVE_DOT is set to YES.
-
-CLASS_GRAPH            = YES
-
-# If the COLLABORATION_GRAPH tag is set to YES then doxygen will generate a
-# graph for each documented class showing the direct and indirect implementation
-# dependencies (inheritance, containment, and class references variables) of the
-# class with other documented classes.
-# The default value is: YES.
-# This tag requires that the tag HAVE_DOT is set to YES.
-
-COLLABORATION_GRAPH    = YES
-
-# If the GROUP_GRAPHS tag is set to YES then doxygen will generate a graph for
-# groups, showing the direct groups dependencies.
-# The default value is: YES.
-# This tag requires that the tag HAVE_DOT is set to YES.
-
-GROUP_GRAPHS           = YES
-
-# If the UML_LOOK tag is set to YES, doxygen will generate inheritance and
-# collaboration diagrams in a style similar to the OMG's Unified Modeling
-# Language.
-# The default value is: NO.
-# This tag requires that the tag HAVE_DOT is set to YES.
-
-UML_LOOK               = NO
-
-# If the UML_LOOK tag is enabled, the fields and methods are shown inside the
-# class node. If there are many fields or methods and many nodes the graph may
-# become too big to be useful. The UML_LIMIT_NUM_FIELDS threshold limits the
-# number of items for each type to make the size more manageable. Set this to 0
-# for no limit. Note that the threshold may be exceeded by 50% before the limit
-# is enforced. So when you set the threshold to 10, up to 15 fields may appear,
-# but if the number exceeds 15, the total amount of fields shown is limited to
-# 10.
-# Minimum value: 0, maximum value: 100, default value: 10.
-# This tag requires that the tag HAVE_DOT is set to YES.
-
-UML_LIMIT_NUM_FIELDS   = 10
-
-# If the TEMPLATE_RELATIONS tag is set to YES then the inheritance and
-# collaboration graphs will show the relations between templates and their
-# instances.
-# The default value is: NO.
-# This tag requires that the tag HAVE_DOT is set to YES.
-
-TEMPLATE_RELATIONS     = NO
-
-# If the INCLUDE_GRAPH, ENABLE_PREPROCESSING and SEARCH_INCLUDES tags are set to
-# YES then doxygen will generate a graph for each documented file showing the
-# direct and indirect include dependencies of the file with other documented
-# files.
-# The default value is: YES.
-# This tag requires that the tag HAVE_DOT is set to YES.
-
-INCLUDE_GRAPH          = YES
-
-# If the INCLUDED_BY_GRAPH, ENABLE_PREPROCESSING and SEARCH_INCLUDES tags are
-# set to YES then doxygen will generate a graph for each documented file showing
-# the direct and indirect include dependencies of the file with other documented
-# files.
-# The default value is: YES.
-# This tag requires that the tag HAVE_DOT is set to YES.
-
-INCLUDED_BY_GRAPH      = YES
-
-# If the CALL_GRAPH tag is set to YES then doxygen will generate a call
-# dependency graph for every global function or class method.
-#
-# Note that enabling this option will significantly increase the time of a run.
-# So in most cases it will be better to enable call graphs for selected
-# functions only using the \callgraph command. Disabling a call graph can be
-# accomplished by means of the command \hidecallgraph.
-# The default value is: NO.
-# This tag requires that the tag HAVE_DOT is set to YES.
-
-CALL_GRAPH             = NO
-
-# If the CALLER_GRAPH tag is set to YES then doxygen will generate a caller
-# dependency graph for every global function or class method.
-#
-# Note that enabling this option will significantly increase the time of a run.
-# So in most cases it will be better to enable caller graphs for selected
-# functions only using the \callergraph command. Disabling a caller graph can be
-# accomplished by means of the command \hidecallergraph.
-# The default value is: NO.
-# This tag requires that the tag HAVE_DOT is set to YES.
-
-CALLER_GRAPH           = NO
-
-# If the GRAPHICAL_HIERARCHY tag is set to YES then doxygen will graphical
-# hierarchy of all classes instead of a textual one.
-# The default value is: YES.
-# This tag requires that the tag HAVE_DOT is set to YES.
-
-GRAPHICAL_HIERARCHY    = YES
-
-# If the DIRECTORY_GRAPH tag is set to YES then doxygen will show the
-# dependencies a directory has on other directories in a graphical way. The
-# dependency relations are determined by the #include relations between the
-# files in the directories.
-# The default value is: YES.
-# This tag requires that the tag HAVE_DOT is set to YES.
-
-DIRECTORY_GRAPH        = YES
-
-# The DOT_IMAGE_FORMAT tag can be used to set the image format of the images
-# generated by dot. For an explanation of the image formats see the section
-# output formats in the documentation of the dot tool (Graphviz (see:
-# http://www.graphviz.org/)).
-# Note: If you choose svg you need to set HTML_FILE_EXTENSION to xhtml in order
-# to make the SVG files visible in IE 9+ (other browsers do not have this
-# requirement).
-# Possible values are: png, png:cairo, png:cairo:cairo, png:cairo:gd, png:gd,
-# png:gd:gd, jpg, jpg:cairo, jpg:cairo:gd, jpg:gd, jpg:gd:gd, gif, gif:cairo,
-# gif:cairo:gd, gif:gd, gif:gd:gd, svg, png:gd, png:gd:gd, png:cairo,
-# png:cairo:gd, png:cairo:cairo, png:cairo:gdiplus, png:gdiplus and
-# png:gdiplus:gdiplus.
-# The default value is: png.
-# This tag requires that the tag HAVE_DOT is set to YES.
-
-DOT_IMAGE_FORMAT       = png
-
-# If DOT_IMAGE_FORMAT is set to svg, then this option can be set to YES to
-# enable generation of interactive SVG images that allow zooming and panning.
-#
-# Note that this requires a modern browser other than Internet Explorer. Tested
-# and working are Firefox, Chrome, Safari, and Opera.
-# Note: For IE 9+ you need to set HTML_FILE_EXTENSION to xhtml in order to make
-# the SVG files visible. Older versions of IE do not have SVG support.
-# The default value is: NO.
-# This tag requires that the tag HAVE_DOT is set to YES.
-
-INTERACTIVE_SVG        = NO
-
-# The DOT_PATH tag can be used to specify the path where the dot tool can be
-# found. If left blank, it is assumed the dot tool can be found in the path.
-# This tag requires that the tag HAVE_DOT is set to YES.
-
-DOT_PATH               =
-
-# The DOTFILE_DIRS tag can be used to specify one or more directories that
-# contain dot files that are included in the documentation (see the \dotfile
-# command).
-# This tag requires that the tag HAVE_DOT is set to YES.
-
-DOTFILE_DIRS           =
-
-# The MSCFILE_DIRS tag can be used to specify one or more directories that
-# contain msc files that are included in the documentation (see the \mscfile
-# command).
-
-MSCFILE_DIRS           =
-
-# The DIAFILE_DIRS tag can be used to specify one or more directories that
-# contain dia files that are included in the documentation (see the \diafile
-# command).
-
-DIAFILE_DIRS           =
-
-# When using plantuml, the PLANTUML_JAR_PATH tag should be used to specify the
-# path where java can find the plantuml.jar file. If left blank, it is assumed
-# PlantUML is not used or called during a preprocessing step. Doxygen will
-# generate a warning when it encounters a \startuml command in this case and
-# will not generate output for the diagram.
-
-PLANTUML_JAR_PATH      =
-
-# When using plantuml, the PLANTUML_CFG_FILE tag can be used to specify a
-# configuration file for plantuml.
-
-PLANTUML_CFG_FILE      =
-
-# When using plantuml, the specified paths are searched for files specified by
-# the !include statement in a plantuml block.
-
-PLANTUML_INCLUDE_PATH  =
-
-# The DOT_GRAPH_MAX_NODES tag can be used to set the maximum number of nodes
-# that will be shown in the graph. If the number of nodes in a graph becomes
-# larger than this value, doxygen will truncate the graph, which is visualized
-# by representing a node as a red box. Note that doxygen if the number of direct
-# children of the root node in a graph is already larger than
-# DOT_GRAPH_MAX_NODES then the graph will not be shown at all. Also note that
-# the size of a graph can be further restricted by MAX_DOT_GRAPH_DEPTH.
-# Minimum value: 0, maximum value: 10000, default value: 50.
-# This tag requires that the tag HAVE_DOT is set to YES.
-
-DOT_GRAPH_MAX_NODES    = 50
-
-# The MAX_DOT_GRAPH_DEPTH tag can be used to set the maximum depth of the graphs
-# generated by dot. A depth value of 3 means that only nodes reachable from the
-# root by following a path via at most 3 edges will be shown. Nodes that lay
-# further from the root node will be omitted. Note that setting this option to 1
-# or 2 may greatly reduce the computation time needed for large code bases. Also
-# note that the size of a graph can be further restricted by
-# DOT_GRAPH_MAX_NODES. Using a depth of 0 means no depth restriction.
-# Minimum value: 0, maximum value: 1000, default value: 0.
-# This tag requires that the tag HAVE_DOT is set to YES.
-
-MAX_DOT_GRAPH_DEPTH    = 0
-
-# Set the DOT_TRANSPARENT tag to YES to generate images with a transparent
-# background. This is disabled by default, because dot on Windows does not seem
-# to support this out of the box.
-#
-# Warning: Depending on the platform used, enabling this option may lead to
-# badly anti-aliased labels on the edges of a graph (i.e. they become hard to
-# read).
-# The default value is: NO.
-# This tag requires that the tag HAVE_DOT is set to YES.
-
-DOT_TRANSPARENT        = NO
-
-# Set the DOT_MULTI_TARGETS tag to YES to allow dot to generate multiple output
-# files in one run (i.e. multiple -o and -T options on the command line). This
-# makes dot run faster, but since only newer versions of dot (>1.8.10) support
-# this, this feature is disabled by default.
-# The default value is: NO.
-# This tag requires that the tag HAVE_DOT is set to YES.
-
-DOT_MULTI_TARGETS      = YES
-
-# If the GENERATE_LEGEND tag is set to YES doxygen will generate a legend page
-# explaining the meaning of the various boxes and arrows in the dot generated
-# graphs.
-# The default value is: YES.
-# This tag requires that the tag HAVE_DOT is set to YES.
-
-GENERATE_LEGEND        = YES
-
-# If the DOT_CLEANUP tag is set to YES, doxygen will remove the intermediate dot
-# files that are used to generate the various graphs.
-# The default value is: YES.
-# This tag requires that the tag HAVE_DOT is set to YES.
-
-DOT_CLEANUP            = YES

+ 0 - 1622
libopenmpt.mod/openmpt/libopenmpt/bindings/freebasic/libopenmpt.bi

@@ -1,1622 +0,0 @@
-/'
- ' libopenmpt.bi
- ' -------------
- ' Purpose: libopenmpt public interface for FreeBASIC
- ' Notes  : (currently none)
- ' Authors: Johannes Schultz
- '          OpenMPT Devs
- ' The OpenMPT source code is released under the BSD license. Read LICENSE for more details.
- '/
-
-#Include Once "crt/stdio.bi"
-#Include Once "file.bi"
-
-#Inclib "openmpt"
-
-/'*
-  \page libopenmpt_freebasic_overview FreeBASIC API
-
-  \section libopenmpt_freebasic_error Error Handling
-
-  - Functions with no return value in the corresponding C++ API return 0 on
-  failure and 1 on success.
-  - Functions that return integer values signal error condition by returning
-  an invalid value (-1 in most cases, 0 in some cases).
-  - All functions that work on an openmpt_module object will call an
-  openmpt_error_func and depending on the value returned by this function log
-  the error code and/xor/or store it inside the openmpt_module object. Stored
-  error codes can be accessed with the openmpt_module_error_get_last() and
-  openmpt_module_error_get_last_message(). Stored errors will not get cleared
-  automatically and should be reset with openmpt_module_error_clear().
-  - Some functions not directly related to an openmpt_module object take an
-  explicit openmpt_error_func error function callback and a pointer to an int
-  and behave analog to the functions working on an openmpt_module object.
-
-  \section libopenmpt_freebasic_strings Strings
-
-  - All strings returned from libopenmpt are encoded in UTF-8.
-  - All strings passed to libopenmpt should also be encoded in UTF-8.
-  Behaviour in case of invalid UTF-8 is unspecified.
-  - libopenmpt does not enforce or expect any particular Unicode
-  normalization form.
-  - Some libopenmpt functions return strings and are provided in two flavours:
-  The raw libopenmpt function (with a trailing underscore) and a FreeBASIC
-  wrapper function that completely takes care of memory handling (recommended).
-  All strings returned from raw libopenmpt functions are dynamically
-  allocated and must be freed with openmpt_free_string().
-  When using the FreeBASIC wrappers (which is the recommended way), FreeBASIC
-  automatically takes care of this.
-  - All strings passed to libopenmpt are copied. No ownership is assumed or
-  transferred.
-
-  \section libopenmpt_freebasic_outputformat Output Format
-
-  libopenmpt supports a wide range of PCM output formats:
-  [8000..192000]/[mono|stereo|quad]/[f32|i16].
-
-  Unless you have some very specific requirements demanding a particular aspect
-  of the output format, you should always prefer 48000/stereo/f32 as the
-  libopenmpt PCM format.
-
-  - Please prefer 48000Hz unless the user explicitly demands something else.
-  Practically all audio equipment and file formats use 48000Hz nowadays.
-  - Practically all module formats are made for stereo output. Mono will not
-  give you any measurable speed improvements and can trivially be obtained from
-  the stereo output anyway. Quad is not expected by almost all modules and even
-  if they do use surround effects, they expect the effects to be mixed to
-  stereo.
-  - Floating point output provides headroom instead of hard clipping if the
-  module is louder than 0dBFs, will give you a better signal-to-noise ratio
-  than int16 output, and avoid the need to apply an additional dithering to the
-  output by libopenmpt. Unless your platform has no floating point unit at all,
-  floating point will thus also be slightly faster.
-
-  \section libopenmpt_freebasic_threads libopenmpt in multi-threaded environments
-
-  - libopenmpt is thread-aware.
-  - Individual libopenmpt objects are not thread-safe.
-  - libopenmpt itself does not spawn any user-visible threads but may spawn
-  threads for internal use.
-  - You must ensure to only ever access a particular libopenmpt object from a
-  single thread at a time.
-  - Consecutive accesses can happen from different threads.
-  - Different objects can be accessed concurrently from different threads.
-
-  \section libopenmpt_freebasic_detailed Detailed documentation
-
-  \ref libopenmpt_freebasic
-'/
-
-Extern "C"
-
-'* API version of this header file
-Const OPENMPT_API_VERSION_MAJOR = 0
-Const OPENMPT_API_VERSION_MINOR = 3
-Const OPENMPT_API_VERSION_PATCH = 0
-Const OPENMPT_API_VERSION = (OPENMPT_API_VERSION_MAJOR Shl 24) Or (OPENMPT_API_VERSION_MINOR Shl 16) Or (OPENMPT_API_VERSION_PATCH Shl 0)
-#Define OPENMPT_API_VERSION_STRING (OPENMPT_API_VERSION_MAJOR & "." & OPENMPT_API_VERSION_MINOR & "." & OPENMPT_API_VERSION_PATCH)
-
-/'* \brief Get the libopenmpt version number
-
-  Returns the libopenmpt version number.
-  \return The value represents (major Shl 24 + minor Shl 16 + patch Shl 0).
-  \remarks libopenmpt < 0.3.0-pre used the following scheme: (major Shl 24 + minor Shl 16 + revision).
-  \remarks Check the HiWord of the return value against OPENMPT_API_VERSION to ensure that the correct library version is loaded.
-'/
-Declare Function openmpt_get_library_version() As ULong
-
-/'* \brief Get the core version number
-
-  Return the OpenMPT core version number.
-  \return The value represents (majormajor << 24 + major << 16 + minor << 8 + minorminor).
-'/
-Declare Function openmpt_get_core_version() As ULong
-
-'* Return a verbose library version string from openmpt_get_string(). \deprecated Please use \code "library_version" \endcode directly.
-#Define OPENMPT_STRING_LIBRARY_VERSION "library_version"
-'* Return a verbose library features string from openmpt_get_string(). \deprecated Please use \code "library_features" \endcode directly.
-#Define OPENMPT_STRING_LIBRARY_FEATURES "library_features"
-'* Return a verbose OpenMPT core version string from openmpt_get_string(). \deprecated Please use \code "core_version" \endcode directly.
-#Define OPENMPT_STRING_CORE_VERSION "core_version"
-'* Return information about the current build (e.g. the build date or compiler used) from openmpt_get_string(). \deprecated Please use \code "build" \endcode directly.
-#Define OPENMPT_STRING_BUILD "build"
-'* Return all contributors from openmpt_get_string(). \deprecated Please use \code "credits" \endcode directly.
-#Define OPENMPT_STRING_CREDITS "credits"
-'* Return contact information about libopenmpt from openmpt_get_string(). \deprecated Please use \code "contact" \endcode directly.
-#Define OPENMPT_STRING_CONTACT "contact"
-'* Return the libopenmpt license from openmpt_get_string(). \deprecated Please use \code "license" \endcode directly.
-#Define OPENMPT_STRING_LICENSE "license"
-
-/'* \brief Free a string returned by libopenmpt
-
-  Frees any string that got returned by libopenmpt.
-'/
-Declare Sub openmpt_free_string(ByVal Str As Const ZString Ptr)
-
-/'* \brief Get library related metadata.
-
-  \param key Key to query.
-        Possible keys are:
-         -  "library_version": verbose library version string
-         -  "library_version_is_release": "1" if the version is an officially released version                              
-         -  "library_features": verbose library features string
-         -  "core_version": verbose OpenMPT core version string
-         -  "source_url": original source code URL
-         -  "source_date": original source code date
-         -  "source_revision": original source code revision
-         -  "source_is_modified": "1" if the original source has been modified
-         -  "source_has_mixed_revisions": "1" if the original source has been compiled from different various revision
-         -  "source_is_package": "1" if the original source has been obtained from a source pacakge instead of source code version control
-         -  "build": information about the current build (e.g. the build date or compiler used)
-         -  "build_compiler": information about the compiler used to build libopenmpt
-         -  "credits": all contributors
-         -  "contact": contact information about libopenmpt
-         -  "license": the libopenmpt license
-         -  "url": libopenmpt website URL
-         -  "support_forum_url": libopenmpt support and discussions forum URL
-         -  "bugtracker_url": libopenmpt bug and issue tracker URL
-  \return A (possibly multi-line) string containing the queried information. If no information is available, the string is empty.
-  \remarks Use openmpt_get_string to automatically handle the lifetime of the returned pointer.
-'/
-Declare Function openmpt_get_string_ Alias "openmpt_get_string" (ByVal key As Const ZString Ptr) As Const ZString Ptr
-
-/'* \brief Get a list of supported file extensions
-
-  \return The semicolon-separated list of extensions supported by this libopenmpt build. The extensions are returned lower-case without a leading dot.
-  \remarks Use openmpt_get_supported_extensions to automatically handle the lifetime of the returned pointer.
-'/
-Declare Function openmpt_get_supported_extensions() As Const ZString Ptr
-
-/'* \brief Query whether a file extension is supported
-
-  \param extension file extension to query without a leading dot. The case is ignored.
-  \return 1 if the extension is supported by libopenmpt, 0 otherwise.
-'/
-Declare Function openmpt_is_extension_supported(ByVal extension As Const ZString Ptr) As Long
-
-'* Seek to the given offset relative to the beginning of the file.
-Const OPENMPT_STREAM_SEEK_SET = 0
-'* Seek to the given offset relative to the current position in the file.
-Const OPENMPT_STREAM_SEEK_CUR = 1
-'* Seek to the given offset relative to the end of the file.
-Const OPENMPT_STREAM_SEEK_END = 2
-
-/'* \brief Read bytes from stream
-
-  Read bytes data from stream to dst.
-  \param stream Stream to read data from
-  \param dst Target where to copy data.
-  \param bytes Number of bytes to read.
-  \return Number of bytes actually read and written to dst.
-  \retval 0 End of stream or error.
-  \remarks Short reads are allowed as long as they return at least 1 byte if EOF is not reached.
-'/
-Type openmpt_stream_read_func As Function(ByVal stream As Any Ptr, ByVal dst As Any Ptr, ByVal bytes As UInteger) As UInteger
-
-/'* \brief Seek stream position
-
-  Seek to stream position offset at whence.
-  \param stream Stream to operate on.
-  \param offset Offset to seek to.
-  \param whence OPENMPT_STREAM_SEEK_SET, OPENMPT_STREAM_SEEK_CUR, OPENMPT_STREAM_SEEK_END. See C89 documentation.
-  \return Returns 0 on success.
-  \retval 0 Success.
-  \retval -1 Failure. Position does not get updated.
-  \remarks libopenmpt will not try to seek beyond the file size, thus it is not important whether you allow for virtual positioning after the file end, or return an error in that case. The position equal to the file size needs to be seekable to.
-'/
-Type openmpt_stream_seek_func As Function(ByVal stream As Any Ptr, ByVal offset As LongInt, ByVal whence As Long) As Long
-
-/'* \brief Tell stream position
-
-  Tell position of stream.
-  \param stream Stream to operate on.
-  \return Current position in stream.
-  \retval -1 Failure.
-'/
-Type openmpt_stream_tell_func As Function(ByVal stream As Any Ptr) As LongInt
-
-/'* \brief Stream callbacks
-
-  Stream callbacks used by libopenmpt for stream operations.
-'/
-Type openmpt_stream_callbacks
-	/'* \brief Read callback.
-
-	  \sa openmpt_stream_read_func
-	'/
-	read_func As openmpt_stream_read_func
-
-	/'* \brief Seek callback.
-	  Seek callback can be NULL if seeking is not supported.
-	  \sa openmpt_stream_seek_func
-	'/
-	seek_func As openmpt_stream_seek_func
-
-	/'* \brief Tell callback.
-	  Tell callback can be NULL if seeking is not supported.
-	  \sa openmpt_stream_tell_func
-	'/
-	tell_func As openmpt_stream_tell_func
-End Type
-
-/'* \brief Logging function
-
-  \param message UTF-8 encoded log message.
-  \param user User context that was passed to openmpt_module_create2(), openmpt_module_create_from_memory2() or openmpt_could_open_probability2().
-'/
-Type openmpt_log_func As Sub(ByVal message As Const ZString Ptr, ByVal user As Any Ptr)
-
-/'* \brief Default logging function
-
-  Default logging function that logs anything to stderr.
-'/
-Declare Sub openmpt_log_func_default(ByVal message As Const ZString Ptr, ByVal user As Any Ptr)
-
-/'* \brief Silent logging function
-
-  Silent logging function that throws any log message away.
-'/
-Declare Sub openmpt_log_func_silent(ByVal message As Const ZString Ptr, ByVal user As Any Ptr)
-
-'* No error. \since 0.3.0
-Const OPENMPT_ERROR_OK = 0
-
-'* Lowest value libopenmpt will use for any of its own error codes. \since 0.3.0
-Const OPENMPT_ERROR_BASE = 256
-
-'* Unknown internal error. \since 0.3.0
-Const OPENMPT_ERROR_UNKNOWN = OPENMPT_ERROR_BASE + 1
-
-'* Unknown internal C++ exception. \since 0.3.0
-Const OPENMPT_ERROR_EXCEPTION = OPENMPT_ERROR_BASE + 11
-
-'* Out of memory. \since 0.3.0
-Const OPENMPT_ERROR_OUT_OF_MEMORY = OPENMPT_ERROR_BASE + 21
-
-'* Runtime error. \since 0.3.0
-Const OPENMPT_ERROR_RUNTIME = OPENMPT_ERROR_BASE + 30
-'* Range error. \since 0.3.0
-Const OPENMPT_ERROR_RANGE = OPENMPT_ERROR_BASE + 31
-'* Arithmetic overflow. \since 0.3.0
-Const OPENMPT_ERROR_OVERFLOW = OPENMPT_ERROR_BASE + 32
-'* Arithmetic underflow. \since 0.3.0
-Const OPENMPT_ERROR_UNDERFLOW = OPENMPT_ERROR_BASE + 33
-
-'* Logic error. \since 0.3.0
-Const OPENMPT_ERROR_LOGIC = OPENMPT_ERROR_BASE + 40
-'* Value domain error. \since 0.3.0
-Const OPENMPT_ERROR_DOMAIN = OPENMPT_ERROR_BASE + 41
-'* Maximum supported size exceeded. \since 0.3.0
-Const OPENMPT_ERROR_LENGTH = OPENMPT_ERROR_BASE + 42
-'* Argument out of range. \since 0.3.0
-Const OPENMPT_ERROR_OUT_OF_RANGE = OPENMPT_ERROR_BASE + 43
-'* Invalid argument. \since 0.3.0
-Const OPENMPT_ERROR_INVALID_ARGUMENT = OPENMPT_ERROR_BASE + 44
-
-'* General libopenmpt error. \since 0.3.0
-Const OPENMPT_ERROR_GENERAL = OPENMPT_ERROR_BASE + 101
-'* openmpt_module Ptr is invalid. \since 0.3.0
-Const OPENMPT_ERROR_INVALID_MODULE_POINTER = OPENMPT_ERROR_BASE + 102
-'* NULL pointer argument. \since 0.3.0
-Const OPENMPT_ERROR_ARGUMENT_NULL_POINTER = OPENMPT_ERROR_BASE + 103
-
-/'* \brief Check whether the error is transient
-
-  Checks whether an error code represents a transient error which may not occur again in a later try if for example memory has been freed up after an out-of-memory error.
-  \param errorcode Error code.
-  \retval 0 Error is not transient.
-  \retval 1 Error is transient.
-  \sa OPENMPT_ERROR_OUT_OF_MEMORY
-  \since 0.3.0
-'/
-Declare Function openmpt_error_is_transient(ByVal errorcode As Long) As Long
-
-/'* \brief Convert error code to text
-
-  Converts an error code into a text string describing the error.
-  \param errorcode Error code.
-  \return Allocated string describing the error.
-  \retval NULL Not enough memory to allocate the string.
-  \since 0.3.0
-  \remarks Use openmpt_error_string to automatically handle the lifetime of the returned pointer.
-'/
-Declare Function openmpt_error_string_ Alias "openmpt_error_string" (ByVal errorcode As Long) As Const ZString Ptr
-
-'* Do not log or store the error. \since 0.3.0
-Const OPENMPT_ERROR_FUNC_RESULT_NONE = 0
-'* Log the error. \since 0.3.0
-Const OPENMPT_ERROR_FUNC_RESULT_LOG = 1
-'* Store the error. \since 0.3.0
-Const OPENMPT_ERROR_FUNC_RESULT_STORE = 2
-'* Log and store the error. \since 0.3.0
-Const OPENMPT_ERROR_FUNC_RESULT_DEFAULT = OPENMPT_ERROR_FUNC_RESULT_LOG Or OPENMPT_ERROR_FUNC_RESULT_STORE
-
-/'* \brief Error function
-
-  \param errorcode Error code.
-  \param user User context that was passed to openmpt_module_create2(), openmpt_module_create_from_memory2() or openmpt_could_open_probability2().
-  \return Mask of OPENMPT_ERROR_FUNC_RESULT_LOG and OPENMPT_ERROR_FUNC_RESULT_STORE.
-  \retval OPENMPT_ERROR_FUNC_RESULT_NONE Do not log or store the error.
-  \retval OPENMPT_ERROR_FUNC_RESULT_LOG Log the error.
-  \retval OPENMPT_ERROR_FUNC_RESULT_STORE Store the error.
-  \retval OPENMPT_ERROR_FUNC_RESULT_DEFAULT Log and store the error.
-  \sa OPENMPT_ERROR_FUNC_RESULT_NONE
-  \sa OPENMPT_ERROR_FUNC_RESULT_LOG
-  \sa OPENMPT_ERROR_FUNC_RESULT_STORE
-  \sa OPENMPT_ERROR_FUNC_RESULT_DEFAULT
-  \sa openmpt_error_func_default
-  \sa openmpt_error_func_log
-  \sa openmpt_error_func_store
-  \sa openmpt_error_func_ignore
-  \sa openmpt_error_func_errno
-  \since 0.3.0
-'/
-Type openmpt_error_func As Function(ByVal errorcode As Long, ByVal user As Any Ptr) As Long
-
-/'* \brief Default error function
-
-  Causes all errors to be logged and stored.
-  \param errorcode Error code.
-  \param user Ignored.
-  \retval OPENMPT_ERROR_FUNC_RESULT_DEFAULT Always.
-  \since 0.3.0
-'/
-Declare Function openmpt_error_func_default(ByVal errorcode As Long, ByVal User As Any Ptr) As Long
-
-/'* \brief Log error function
-
-  Causes all errors to be logged.
-  \param errorcode Error code.
-  \param user Ignored.
-  \retval OPENMPT_ERROR_FUNC_RESULT_LOG Always.
-  \since 0.3.0
-'/
-Declare Function openmpt_error_func_log(ByVal errorcode As Long, ByVal user As Any Ptr) As Long
-
-/'* \brief Store error function
-
-  Causes all errors to be stored.
-  \param errorcode Error code.
-  \param user Ignored.
-  \retval OPENMPT_ERROR_FUNC_RESULT_STORE Always.
-  \since 0.3.0
-'/
-Declare Function openmpt_error_func_store(ByVal errorcode As Long, ByVal user As Any Ptr) As Long
-
-/'* \brief Ignore error function
-
-  Causes all errors to be neither logged nor stored.
-  \param errorcode Error code.
-  \param user Ignored.
-  \retval OPENMPT_ERROR_FUNC_RESULT_NONE Always.
-  \since 0.3.0
-'/
-Declare Function openmpt_error_func_ignore(ByVal errorcode As Long, ByVal user As Any Ptr) As Long
-
-/'* \brief Errno error function
-
-  Causes all errors to be stored in the pointer passed in as user.
-  \param errorcode Error code.
-  \param user Pointer to an int as generated by openmpt_error_func_errno_userdata.
-  \retval OPENMPT_ERROR_FUNC_RESULT_NONE user is not NULL.
-  \retval OPENMPT_ERROR_FUNC_RESULT_DEFAULT user is NULL.
-  \since 0.3.0
-'/
-Declare Function openmpt_error_func_errno(ByVal errorcode As Long, ByVal user As Any Ptr) As Long
-
-/'* \brief User pointer for openmpt_error_func_errno
-
-  Provides a suitable user pointer argument for openmpt_error_func_errno.
-  \param errorcode Pointer to an integer value to be used as output by openmpt_error_func_errno.
-  \retval Cast(Any Ptr, errorcode).
-  \since 0.3.0
-'/
-Declare Function openmpt_error_func_errno_userdata(ByVal errorcode As Long Ptr) As Any Ptr
-
-/'* \brief Roughly scan the input stream to find out whether libopenmpt might be able to open it
-
-  \param stream_callbacks Input stream callback operations.
-  \param stream Input stream to scan.
-  \param effort Effort to make when validating stream. Effort 0.0 does not even look at stream at all and effort 1.0 completely loads the file from stream. A lower effort requires less data to be loaded but only gives a rough estimate answer. Use an effort of 0.25 to only verify the header data of the module file.
-  \param logfunc Logging function where warning and errors are written. May be NULL.
-  \param user Logging function user context.
-  \return Probability between 0.0 and 1.0.
-  \remarks openmpt_could_open_probability() can return any value between 0.0 and 1.0. Only 0.0 and 1.0 are definitive answers, all values in between are just estimates. In general, any return value >0.0 means that you should try loading the file, and any value below 1.0 means that loading may fail. If you want a threshold above which you can be reasonably sure that libopenmpt will be able to load the file, use >=0.5. If you see the need for a threshold below which you could reasonably outright reject a file, use <0.25 (Note: Such a threshold for rejecting on the lower end is not recommended, but may be required for better integration into some other framework's probe scoring.).
-  \remarks openmpt_could_open_probability() expects the complete file data to be eventually available to it, even if it is asked to just parse the header. Verification will be unreliable (both false positives and false negatives), if you pretend that the file is just some few bytes of initial data threshold in size. In order to really just access the first bytes of a file, check in your callback functions whether data or seeking is requested beyond your initial data threshold, and in that case, return an error. openmpt_could_open_probability() will treat this as any other I/O error and return 0.0. You must not expect the correct result in this case. You instead must remember that it asked for more data than you currently want to provide to it and treat this situation as if openmpt_could_open_probability() returned 0.5.
-  \sa openmpt_stream_callbacks
-  \deprecated Please use openmpt_module_could_open_probability2().
-  \since 0.3.0
-'/
-Declare Function openmpt_could_open_probability(ByVal stream_callbacks As openmpt_stream_callbacks, ByVal stream As Any Ptr, ByVal effort As Double, ByVal logfunc As openmpt_log_func, ByVal user As Any Ptr) As Double
-
-/'* \brief Roughly scan the input stream to find out whether libopenmpt might be able to open it
-
-  \param stream_callbacks Input stream callback operations.
-  \param stream Input stream to scan.
-  \param effort Effort to make when validating stream. Effort 0.0 does not even look at stream at all and effort 1.0 completely loads the file from stream. A lower effort requires less data to be loaded but only gives a rough estimate answer. Use an effort of 0.25 to only verify the header data of the module file.
-  \param logfunc Logging function where warning and errors are written. May be NULL.
-  \param loguser Logging function user context.
-  \param errfunc Error function to define error behaviour. May be NULL.
-  \param erruser Error function user context.
-  \param errorcode Pointer to an integer where an error may get stored. May be NULL.
-  \param error_message Pointer to a string pointer where an error message may get stored. May be NULL.
-  \return Probability between 0.0 and 1.0.
-  \remarks openmpt_probe_file_header() or openmpt_probe_file_header_without_filesize() provide a simpler and faster interface that fits almost all use cases better. It is recommended to use openmpt_probe_file_header() or openmpt_probe_file_header_without_filesize() instead of openmpt_could_open_probability().
-  \remarks openmpt_could_open_probability2() can return any value between 0.0 and 1.0. Only 0.0 and 1.0 are definitive answers, all values in between are just estimates. In general, any return value >0.0 means that you should try loading the file, and any value below 1.0 means that loading may fail. If you want a threshold above which you can be reasonably sure that libopenmpt will be able to load the file, use >=0.5. If you see the need for a threshold below which you could reasonably outright reject a file, use <0.25 (Note: Such a threshold for rejecting on the lower end is not recommended, but may be required for better integration into some other framework's probe scoring.).
-  \remarks openmpt_could_open_probability2() expects the complete file data to be eventually available to it, even if it is asked to just parse the header. Verification will be unreliable (both false positives and false negatives), if you pretend that the file is just some few bytes of initial data threshold in size. In order to really just access the first bytes of a file, check in your callback functions whether data or seeking is requested beyond your initial data threshold, and in that case, return an error. openmpt_could_open_probability() will treat this as any other I/O error and return 0.0. You must not expect the correct result in this case. You instead must remember that it asked for more data than you currently want to provide to it and treat this situation as if openmpt_could_open_probability() returned 0.5.
-  \sa openmpt_stream_callbacks
-  \sa openmpt_probe_file_header
-  \sa openmpt_probe_file_header_without_filesize
-  \since 0.3.0
-'/
-Declare Function openmpt_could_open_probability2(ByVal stream_callbacks As openmpt_stream_callbacks, ByVal stream As Any Ptr, ByVal effort As Double, ByVal logfunc As openmpt_log_func, ByVal loguser As Any Ptr, ByVal errfunc As openmpt_error_func, ByVal erruser As Any Ptr, ByVal errorcode As Long Ptr, ByVal error_message As Const ZString Ptr Ptr) As Double
-
-/'* \brief Get recommended header size for successfull format probing
-
-  \sa openmpt_probe_file_header()
-  \sa openmpt_probe_file_header_without_filesize()
-  \since 0.3.0
-'/
-Declare Function openmpt_probe_file_header_get_recommended_size() As UInteger
-
-'* Probe for module formats in openmpt_probe_file_header() or openmpt_probe_file_header_without_filesize(). \since 0.3.0
-Const OPENMPT_PROBE_FILE_HEADER_FLAGS_MODULES = 1
-'* Probe for module-specific container formats in openmpt_probe_file_header() or openmpt_probe_file_header_without_filesize(). \since 0.3.0
-Const OPENMPT_PROBE_FILE_HEADER_FLAGS_CONTAINERS = 2
-
-'* Probe for the default set of formats in openmpt_probe_file_header() or openmpt_probe_file_header_without_filesize(). \since 0.3.0
-Const OPENMPT_PROBE_FILE_HEADER_FLAGS_DEFAULT = OPENMPT_PROBE_FILE_HEADER_FLAGS_MODULES or OPENMPT_PROBE_FILE_HEADER_FLAGS_CONTAINERS
-'* Probe for no formats in openmpt_probe_file_header() or openmpt_probe_file_header_without_filesize(). \since 0.3.0
-Const OPENMPT_PROBE_FILE_HEADER_FLAGS_NONE = 0
-
-'* Possible return values fo openmpt_probe_file_header() and openmpt_probe_file_header_without_filesize(). \since 0.3.0
-Const OPENMPT_PROBE_FILE_HEADER_RESULT_SUCCESS = 1
-'* Possible return values fo openmpt_probe_file_header() and openmpt_probe_file_header_without_filesize(). \since 0.3.0
-Const OPENMPT_PROBE_FILE_HEADER_RESULT_FAILURE = 0
-'* Possible return values fo openmpt_probe_file_header() and openmpt_probe_file_header_without_filesize(). \since 0.3.0
-Const OPENMPT_PROBE_FILE_HEADER_RESULT_WANTMOREDATA = -1
-'* Possible return values fo openmpt_probe_file_header() and openmpt_probe_file_header_without_filesize(). \since 0.3.0
-Const OPENMPT_PROBE_FILE_HEADER_RESULT_ERROR = -255
-
-/'* \brief Probe the provided bytes from the beginning of a file for supported file format headers to find out whether libopenmpt might be able to open it
-
-  \param flags Bit mask of OPENMPT_PROBE_FILE_HEADER_FLAGS_MODULES and OPENMPT_PROBE_FILE_HEADER_FLAGS_CONTAINERS, or OPENMPT_PROBE_FILE_HEADER_FLAGS_DEFAULT.
-  \param data Beginning of the file data.
-  \param size Size of the beginning of the file data.
-  \param filesize Full size of the file data on disk.
-  \param logfunc Logging function where warning and errors are written. May be NULL.
-  \param loguser Logging function user context. Used to pass any user-defined data associated with this module to the logging function.
-  \param errfunc Error function to define error behaviour. May be NULL.
-  \param erruser Error function user context. Used to pass any user-defined data associated with this module to the logging function.
-  \param error Pointer to an integer where an error may get stored. May be NULL.
-  \param error_message Pointer to a string pointer where an error message may get stored. May be NULL.
-  \remarks It is recommended to provide openmpt_probe_file_header_get_recommended_size() bytes of data for data and size. If the file is smaller, only provide the filesize amount and set size and filesize to the file's size. 
-  \remarks openmpt_could_open_probability2() provides a more elaborate interface that might be required for special use cases. It is recommended to use openmpt_probe_file_header() though, if possible.
-  \retval OPENMPT_PROBE_FILE_HEADER_RESULT_SUCCESS The file will most likely be supported by libopenmpt.
-  \retval OPENMPT_PROBE_FILE_HEADER_RESULT_FAILURE The file is not supported by libopenmpt.
-  \retval OPENMPT_PROBE_FILE_HEADER_RESULT_WANTMOREDATA An answer could not be determined with the amount of data provided.
-  \retval OPENMPT_PROBE_FILE_HEADER_RESULT_ERROR An internal error occurred.
-  \sa openmpt_probe_file_header_get_recommended_size()
-  \sa openmpt_probe_file_header_without_filesize()
-  \sa openmpt_probe_file_header_from_stream()
-  \sa openmpt_could_open_probability2()
-  \since 0.3.0
-'/
-Declare Function openmpt_probe_file_header(ByVal flags As ULongInt, ByVal Data As Const Any Ptr, ByVal size As UInteger, ByVal filesize As ULongInt, ByVal logfunc As openmpt_log_func, ByVal loguser As Any Ptr, ByVal errfunc As openmpt_error_func, ByVal erruser As Any Ptr, ByVal Error As Long Ptr, ByVal error_message As Const ZString Ptr Ptr) As Long
-
-/'* \brief Probe the provided bytes from the beginning of a file for supported file format headers to find out whether libopenmpt might be able to open it
-
-  \param flags Bit mask of OPENMPT_PROBE_FILE_HEADER_FLAGS_MODULES and OPENMPT_PROBE_FILE_HEADER_FLAGS_CONTAINERS, or OPENMPT_PROBE_FILE_HEADER_FLAGS_DEFAULT.
-  \param data Beginning of the file data.
-  \param size Size of the beginning of the file data.
-  \param logfunc Logging function where warning and errors are written. May be NULL.
-  \param loguser Logging function user context. Used to pass any user-defined data associated with this module to the logging function.
-  \param errfunc Error function to define error behaviour. May be NULL.
-  \param erruser Error function user context. Used to pass any user-defined data associated with this module to the logging function.
-  \param error Pointer to an integer where an error may get stored. May be NULL.
-  \param error_message Pointer to a string pointer where an error message may get stored. May be NULL.
-  \remarks It is recommended to use openmpt_probe_file_header() and provide the acutal file's size as a parameter if at all possible. libopenmpt can provide more accurate answers if the filesize is known.
-  \remarks It is recommended to provide openmpt_probe_file_header_get_recommended_size() bytes of data for data and size. If the file is smaller, only provide the filesize amount and set size to the file's size. 
-  \remarks openmpt_could_open_probability2() provides a more elaborate interface that might be required for special use cases. It is recommended to use openmpt_probe_file_header() though, if possible.
-  \retval OPENMPT_PROBE_FILE_HEADER_RESULT_SUCCESS The file will most likely be supported by libopenmpt.
-  \retval OPENMPT_PROBE_FILE_HEADER_RESULT_FAILURE The file is not supported by libopenmpt.
-  \retval OPENMPT_PROBE_FILE_HEADER_RESULT_WANTMOREDATA An answer could not be determined with the amount of data provided.
-  \retval OPENMPT_PROBE_FILE_HEADER_RESULT_ERROR An internal error occurred.
-  \sa openmpt_probe_file_header_get_recommended_size()
-  \sa openmpt_probe_file_header()
-  \sa openmpt_probe_file_header_from_stream()
-  \sa openmpt_could_open_probability2()
-  \since 0.3.0
-'/
-Declare Function openmpt_probe_file_header_without_filesize(ByVal flags As ULongInt, ByVal Data As Const Any Ptr, ByVal size As UInteger, ByVal logfunc As openmpt_log_func, ByVal loguser As Any Ptr, ByVal errfunc As openmpt_error_func, ByVal erruser As Any Ptr, ByVal Error As Long Ptr, ByVal error_message As Const ZString Ptr Ptr) As Long
-
-/'* \brief Probe the provided bytes from the beginning of a file for supported file format headers to find out whether libopenmpt might be able to open it
-
-  \param flags Bit mask of OPENMPT_PROBE_FILE_HEADER_FLAGS_MODULES and OPENMPT_PROBE_FILE_HEADER_FLAGS_CONTAINERS, or OPENMPT_PROBE_FILE_HEADER_FLAGS_DEFAULT.
-  \param stream_callbacks Input stream callback operations.
-  \param stream Input stream to scan.
-  \param logfunc Logging function where warning and errors are written. May be NULL.
-  \param loguser Logging function user context. Used to pass any user-defined data associated with this module to the logging function.
-  \param errfunc Error function to define error behaviour. May be NULL.
-  \param erruser Error function user context. Used to pass any user-defined data associated with this module to the logging function.
-  \param error Pointer to an integer where an error may get stored. May be NULL.
-  \param error_message Pointer to a string pointer where an error message may get stored. May be NULL.
-  \remarks The stream is left in an unspecified state when this function returns.
-  \remarks It is recommended to provide openmpt_probe_file_header_get_recommended_size() bytes of data for data and size. If the file is smaller, only provide the filesize amount and set size and filesize to the file's size. 
-  \remarks openmpt_could_open_probability2() provides a more elaborate interface that might be required for special use cases. It is recommended to use openmpt_probe_file_header() though, if possible.
-  \retval OPENMPT_PROBE_FILE_HEADER_RESULT_SUCCESS The file will most likely be supported by libopenmpt.
-  \retval OPENMPT_PROBE_FILE_HEADER_RESULT_FAILURE The file is not supported by libopenmpt.
-  \retval OPENMPT_PROBE_FILE_HEADER_RESULT_WANTMOREDATA An answer could not be determined with the amount of data provided.
-  \retval OPENMPT_PROBE_FILE_HEADER_RESULT_ERROR An internal error occurred.
-  \sa openmpt_probe_file_header_get_recommended_size()
-  \sa openmpt_probe_file_header()
-  \sa openmpt_probe_file_header_without_filesize()
-  \sa openmpt_could_open_probability2()
-  \since 0.3.0
-'/
-Declare Function openmpt_probe_file_header_from_stream(ByVal flags As ULongInt, ByVal stream_callbacks As openmpt_stream_callbacks, ByVal stream As Any Ptr, ByVal logfunc As openmpt_log_func, ByVal loguser As Any Ptr, ByVal errfunc As openmpt_error_func, ByVal erruser As Any Ptr, ByVal Error As Long Ptr, ByVal error_message As Const ZString Ptr Ptr) As Long
-
-
-'* \brief Opaque type representing a libopenmpt module
-Type openmpt_module
-	opaque As Any Ptr
-End Type
-
-Type openmpt_module_initial_ctl
-	ctl As Const ZString Ptr
-	value As Const ZString Ptr
-End Type
-
-/'* \brief Construct an openmpt_module
-
-  \param stream_callbacks Input stream callback operations.
-  \param stream Input stream to load the module from.
-  \param logfunc Logging function where warning and errors are written. The logging function may be called throughout the lifetime of openmpt_module.
-  \param user User-defined data associated with this module. This value will be passed to the logging callback function (logfunc)
-  \param ctls A map of initial ctl values. See openmpt_module_get_ctls().
-  \return A pointer to the constructed openmpt_module, or NULL on failure.
-  \remarks The input data can be discarded after an openmpt_module has been constructed successfully.
-  \sa openmpt_stream_callbacks
-'/
-Declare Function openmpt_module_create(ByVal stream_callbacks As openmpt_stream_callbacks, ByVal stream As Any Ptr, ByVal logfunc As openmpt_log_func = 0, ByVal user As Any Ptr = 0, ByVal ctls As Const openmpt_module_initial_ctl Ptr = 0) As openmpt_module Ptr
-
-/'* \brief Construct an openmpt_module
-
-  \param stream_callbacks Input stream callback operations.
-  \param stream Input stream to load the module from.
-  \param logfunc Logging function where warning and errors are written. The logging function may be called throughout the lifetime of openmpt_module. May be NULL.
-  \param loguser User-defined data associated with this module. This value will be passed to the logging callback function (logfunc)
-  \param errfunc Error function to define error behaviour. May be NULL.
-  \param erruser Error function user context.
-  \param errorcode Pointer to an integer where an error may get stored. May be NULL.
-  \param error_message Pointer to a string pointer where an error message may get stored. May be NULL.
-  \param ctls A map of initial ctl values. See openmpt_module_get_ctls().
-  \return A pointer to the constructed openmpt_module, or NULL on failure.
-  \remarks The input data can be discarded after an openmpt_module has been constructed successfully.
-  \sa openmpt_stream_callbacks
-  \since 0.3.0
-'/
-Declare Function openmpt_module_create2(ByVal stream_callbacks As openmpt_stream_callbacks, ByVal stream As Any Ptr, ByVal logfunc As openmpt_log_func = 0, ByVal loguser As Any Ptr = 0, ByVal errfunc As openmpt_error_func = 0, ByVal erruser As Any Ptr = 0, ByVal errorcode As Long Ptr = 0, ByVal error_message As Const ZString Ptr Ptr = 0, ByVal ctls As Const openmpt_module_initial_ctl Ptr = 0) As openmpt_module Ptr
-
-/'* \brief Construct an openmpt_module
-
-  \param filedata Data to load the module from.
-  \param filesize Amount of data available.
-  \param logfunc Logging function where warning and errors are written. The logging function may be called throughout the lifetime of openmpt_module.
-  \param user User-defined data associated with this module. This value will be passed to the logging callback function (logfunc)
-  \param ctls A map of initial ctl values. See openmpt_module_get_ctls().
-  \return A pointer to the constructed openmpt_module, or NULL on failure.
-  \remarks The input data can be discarded after an openmpt_module has been constructed successfully.
-'/
-Declare Function openmpt_module_create_from_memory(ByVal filedata As Const Any Ptr, ByVal filesize As UInteger, ByVal logfunc As openmpt_log_func = 0, ByVal user As Any Ptr = 0, ByVal ctls As Const openmpt_module_initial_ctl Ptr = 0) As openmpt_module Ptr
-
-/'* \brief Construct an openmpt_module
-
-  \param filedata Data to load the module from.
-  \param filesize Amount of data available.
-  \param logfunc Logging function where warning and errors are written. The logging function may be called throughout the lifetime of openmpt_module.
-  \param loguser User-defined data associated with this module. This value will be passed to the logging callback function (logfunc)
-  \param errfunc Error function to define error behaviour. May be NULL.
-  \param erruser Error function user context.
-  \param errorcode Pointer to an integer where an error may get stored. May be NULL.
-  \param error_message Pointer to a string pointer where an error message may get stored. May be NULL.
-  \param ctls A map of initial ctl values. See openmpt_module_get_ctls().
-  \return A pointer to the constructed openmpt_module, or NULL on failure.
-  \remarks The input data can be discarded after an openmpt_module has been constructed successfully.
-  \since 0.3.0
-'/
-Declare Function openmpt_module_create_from_memory2(ByVal filedata As Const Any Ptr, ByVal filesize As UInteger, ByVal logfunc As openmpt_log_func, ByVal loguser As Any Ptr, ByVal errfunc As openmpt_error_func, ByVal erruser As Any Ptr, ByVal errorcode As Long Ptr, ByVal error_message As Const ZString Ptr Ptr, ByVal ctls As Const openmpt_module_initial_ctl Ptr) As openmpt_module Ptr
-
-/'* \brief Unload a previously created openmpt_module from memory.
-
-  \param module The module to unload.
-'/
-Declare Sub openmpt_module_destroy(ByVal module As openmpt_module Ptr)
-
-/'* \brief Set logging function.
-
-  Set the logging function of an already constructed openmpt_module.
-  \param module The module handle to work on.
-  \param logfunc Logging function where warning and errors are written. The logging function may be called throughout the lifetime of openmpt_module.
-  \param loguser User-defined data associated with this module. This value will be passed to the logging callback function (logfunc)
-  \since 0.3.0
-'/
-Declare Sub openmpt_module_set_log_func(ByVal module As openmpt_module Ptr, ByVal logfunc As openmpt_log_func, ByVal loguser As Any Ptr)
-
-/'* \brief Set error function.
-
-  Set the error function of an already constructed openmpt_module.
-  \param module The module handle to work on.
-  \param errfunc Error function to define error behaviour. May be NULL.
-  \param erruser Error function user context.
-  \since 0.3.0
-'/
-Declare Sub openmpt_module_set_error_func(ByVal module As openmpt_module Ptr, ByVal errfunc As openmpt_error_func, ByVal erruser As Any Ptr)
-
-/'* \brief Get last error.
-
-  Return the error currently stored in an openmpt_module. The stored error is not cleared.
-  \param module The module handle to work on.
-  \return The error currently stored.
-  \sa openmpt_module_error_get_last_message
-  \sa openmpt_module_error_set_last
-  \sa openmpt_module_error_clear
-  \since 0.3.0
-'/
-Declare Function openmpt_module_error_get_last(ByVal module As openmpt_module Ptr) As Long
-
-/'* \brief Get last error message.
-
-  Return the error message currently stored in an openmpt_module. The stored error is not cleared.
-  \param module The module handle to work on.
-  \return The error message currently stored.
-  \sa openmpt_module_error_set_last
-  \sa openmpt_module_error_clear
-  \since 0.3.0
-  \remarks Use openmpt_module_error_get_last_message to automatically handle the lifetime of the returned pointer.
-'/
-Declare Function openmpt_module_error_get_last_message_ Alias "openmpt_module_error_get_last_message" (ByVal module As openmpt_module Ptr) As Const ZString Ptr
-
-/'* \brief Set last error.
-
-  Set the error currently stored in an openmpt_module.
-  \param module The module handle to work on.
-  \param errorcode Error to be stored.
-  \sa openmpt_module_error_get_last
-  \sa openmpt_module_error_clear
-  \since 0.3.0
-'/
-Declare Sub openmpt_module_error_set_last(ByVal module As openmpt_module Ptr, ByVal errorcode As Long)
-
-/'* \brief Clear last error.
-
-  Set the error currently stored in an openmpt_module to OPPENMPT_ERROR_OK.
-  \param module The module handle to work on.
-  \sa openmpt_module_error_get_last
-  \sa openmpt_module_error_set_last
-  \since 0.3.0
-'/
-Declare Sub openmpt_module_error_clear(ByVal module As openmpt_module Ptr)
-
-/'*
-  \defgroup openmpt_module_render_param Render param indices
- 
-  \brief Parameter index to use with openmpt_module_get_render_param() and openmpt_module_set_render_param()
-  @{
-'/
-/'* \brief Master Gain
-
-  The related value represents a relative gain in milliBel.\n
-  The default value is 0.\n
-  The supported value range is unlimited.\n
-'/
-Const OPENMPT_MODULE_RENDER_MASTERGAIN_MILLIBEL = 1
-/'* \brief Stereo Separation
-
-  The related value represents the stereo separation generated by the libopenmpt mixer in percent.\n
-  The default value is 100.\n
-  The supported value range is [0,200].\n
-'/
-Const OPENMPT_MODULE_RENDER_STEREOSEPARATION_PERCENT = 2
-/'* \brief Interpolation Filter
-
-  The related value represents the interpolation filter length used by the libopenmpt mixer.\n
-  The default value is 0, which indicates a recommended default value.\n
-  The supported value range is [0,inf). Values greater than the implementation limit are clamped to the maximum supported value.\n
-  Currently supported values:
-   - 0: internal default
-   - 1: no interpolation (zero order hold)
-   - 2: linear interpolation
-   - 4: cubic interpolation
-   - 8: windowed sinc with 8 taps
-'/
-Const OPENMPT_MODULE_RENDER_INTERPOLATIONFILTER_LENGTH = 3
-/'* \brief Volume Ramping Strength
-
-  The related value represents the amount of volume ramping done by the libopenmpt mixer.\n
-  The default value is -1, which indicates a recommended default value.\n
-  The meaningful value range is [-1..10].\n
-  A value of 0 completely disables volume ramping. This might cause clicks in sound output.\n
-  Higher values imply slower/softer volume ramps.
-'/
-Const OPENMPT_MODULE_RENDER_VOLUMERAMPING_STRENGTH = 4
-'* @}
-
-/'*
-  \defgroup openmpt_module_command_index Pattern cell indices
-
-  \brief Parameter index to use with openmpt_module_get_pattern_row_channel_command(), openmpt_module_format_pattern_row_channel_command() and openmpt_module_highlight_pattern_row_channel_command()
-  @{
-'/
-Const OPENMPT_MODULE_COMMAND_NOTE = 0
-Const OPENMPT_MODULE_COMMAND_INSTRUMENT = 1
-Const OPENMPT_MODULE_COMMAND_VOLUMEEFFECT = 2
-Const OPENMPT_MODULE_COMMAND_EFFECT = 3
-Const OPENMPT_MODULE_COMMAND_VOLUME = 4
-Const OPENMPT_MODULE_COMMAND_PARAMETER = 5
-'* @}
-
-/'* \brief Select a sub-song from a multi-song module
-
-  \param module The module handle to work on.
-  \param subsong Index of the sub-song. -1 plays all sub-songs consecutively.
-  \return 1 on success, 0 on failure.
-  \sa openmpt_module_get_num_subsongs, openmpt_module_get_selected_subsong, openmpt_module_get_subsong_name
-  \remarks Whether subsong -1 (all subsongs consecutively), subsong 0 or some other subsong is selected by default, is an implementation detail and subject to change. If you do not want to care about subsongs, it is recommended to just not call openmpt_module_select_subsong() at all.
-'/
-Declare Function openmpt_module_select_subsong(ByVal module As openmpt_module Ptr, ByVal subsong As Long) As Long
-
-/'* \brief Get currently selected sub-song from a multi-song module
-
-  \param module The module handle to work on.
-  \return Currently selected sub-song. -1 for all subsongs consecutively, 0 or greater for the current sub-song index.
-  \sa openmpt_module_get_num_subsongs, openmpt_module_select_subsong, openmpt_module_get_subsong_name
-  \since 0.3.0
-'/
-Declare Function openmpt_module_get_selected_subsong(ByVal module As openmpt_module Ptr) As Long
-
-/'* \brief Set Repeat Count
-
-  \param module The module handle to work on.
-  \param repeat_count Repeat Count
-    - -1: repeat forever
-    - 0: play once, repeat zero times (the default)
-    - n>0: play once and repeat n times after that
-  \return 1 on success, 0 on failure.
-  \sa openmpt_module_get_repeat_count
-'/
-Declare Function openmpt_module_set_repeat_count(ByVal module As openmpt_module Ptr, ByVal repeat_count As Long) As Long
-
-/'* \brief Get Repeat Count
-
-  \param module The module handle to work on.
-  \return Repeat Count
-    - -1: repeat forever
-    - 0: play once, repeat zero times (the default)
-    - n>0: play once and repeat n times after that
-  \sa openmpt_module_set_repeat_count
-'/
-Declare Function openmpt_module_get_repeat_count(ByVal module As openmpt_module Ptr) As Long
-
-/'* \brief approximate song duration
-
-  \param module The module handle to work on.
-  \return Approximate duration of current sub-song in seconds.
-'/
-Declare Function openmpt_module_get_duration_seconds(ByVal module As openmpt_module Ptr) As Double
-
-/'* \brief Set approximate current song position
-
-  \param module The module handle to work on.
-  \param seconds Seconds to seek to. If seconds is out of range, the position gets set to song start or end respectively.
-  \return Approximate new song position in seconds.
-  \sa openmpt_module_get_position_seconds
-'/
-Declare Function openmpt_module_set_position_seconds(ByVal module As openmpt_module Ptr, ByVal seconds As Double) As Double
-
-/'* \brief Get current song position
-
-  \param module The module handle to work on.
-  \return Current song position in seconds.
-  \sa openmpt_module_set_position_seconds
-'/
-Declare Function openmpt_module_get_position_seconds(ByVal module As openmpt_module Ptr) As Double
-
-/'* \brief Set approximate current song position
-
-  If order or row are out of range, to position is not modified and the current position is returned.
-  \param module The module handle to work on.
-  \param order Pattern order number to seek to.
-  \param row Pattern row number to seek to.
-  \return Approximate new song position in seconds.
-  \sa openmpt_module_set_position_seconds
-  \sa openmpt_module_get_position_seconds
-'/
-Declare Function openmpt_module_set_position_order_row(ByVal module As openmpt_module Ptr, ByVal order As Long, ByVal row As Long) As Double
-
-/'* \brief Get render parameter
-
-  \param module The module handle to work on.
-  \param param Parameter to query. See \ref openmpt_module_render_param
-  \param value Pointer to the variable that receives the current value of the parameter.
-  \return 1 on success, 0 on failure (invalid param or value is NULL).
-  \sa OPENMPT_MODULE_RENDER_MASTERGAIN_MILLIBEL
-  \sa OPENMPT_MODULE_RENDER_STEREOSEPARATION_PERCENT
-  \sa OPENMPT_MODULE_RENDER_INTERPOLATIONFILTER_LENGTH
-  \sa OPENMPT_MODULE_RENDER_VOLUMERAMPING_STRENGTH
-  \sa openmpt_module_set_render_param
-'/
-Declare Function openmpt_module_get_render_param(ByVal module As openmpt_module Ptr, ByVal param As Long, ByVal value As Long Ptr) As Long
-
-/'* \brief Set render parameter
-
-  \param module The module handle to work on.
-  \param param Parameter to set. See \ref openmpt_module_render_param
-  \param value The value to set param to.
-  \return 1 on success, 0 on failure (invalid param).
-  \sa OPENMPT_MODULE_RENDER_MASTERGAIN_MILLIBEL
-  \sa OPENMPT_MODULE_RENDER_STEREOSEPARATION_PERCENT
-  \sa OPENMPT_MODULE_RENDER_INTERPOLATIONFILTER_LENGTH
-  \sa OPENMPT_MODULE_RENDER_VOLUMERAMPING_STRENGTH
-  \sa openmpt_module_get_render_param
-'/
-Declare Function openmpt_module_set_render_param(ByVal module As openmpt_module Ptr, ByVal param As Long, ByVal value As Long) As Long
-
-'*@{
-/'* \brief Render audio data
-
-  \param module The module handle to work on.
-  \param samplerate Sample rate to render output. Should be in [8000,192000], but this is not enforced.
-  \param count Number of audio frames to render per channel.
-  \param mono Pointer to a buffer of at least count elements that receives the mono/center output.
-  \return The number of frames actually rendered.
-  \retval 0 The end of song has been reached.
-  \remarks The output buffers are only written to up to the returned number of elements.
-  \remarks You can freely switch between any of the "openmpt_module_read*" variants if you see a need to do so. libopenmpt tries to introduce as little switching annoyances as possible. Normally, you would only use a single one of these functions for rendering a particular module.
-  \remarks It is recommended to use the floating point API because of the greater dynamic range and no implied clipping.
-  \sa \ref libopenmpt_freebasic_outputformat
-'/
-Declare Function openmpt_module_read_mono(ByVal module As openmpt_module Ptr, ByVal samplerate As Long, ByVal count As UInteger, ByVal mono As Short Ptr) As UInteger
-
-/'* \brief Render audio data
-
-  \param module The module handle to work on.
-  \param samplerate Sample rate to render output. Should be in [8000,192000], but this is not enforced.
-  \param count Number of audio frames to render per channel.
-  \param left Pointer to a buffer of at least count elements that receives the left output.
-  \param right Pointer to a buffer of at least count elements that receives the right output.
-  \return The number of frames actually rendered.
-  \retval 0 The end of song has been reached.
-  \remarks The output buffers are only written to up to the returned number of elements.
-  \remarks You can freely switch between any of the "openmpt_module_read*" variants if you see a need to do so. libopenmpt tries to introduce as little switching annoyances as possible. Normally, you would only use a single one of these functions for rendering a particular module.
-  \remarks It is recommended to use the floating point API because of the greater dynamic range and no implied clipping.
-  \sa \ref libopenmpt_freebasic_outputformat
-'/
-Declare Function openmpt_module_read_stereo(ByVal module As openmpt_module Ptr, ByVal samplerate As Long, ByVal count As UInteger, ByVal Left As Short Ptr, ByVal Right As Short Ptr) As UInteger
-
-/'* \brief Render audio data
-
-  \param module The module handle to work on.
-  \param samplerate Sample rate to render output. Should be in [8000,192000], but this is not enforced.
-  \param count Number of audio frames to render per channel.
-  \param left Pointer to a buffer of at least count elements that receives the left output.
-  \param right Pointer to a buffer of at least count elements that receives the right output.
-  \param rear_left Pointer to a buffer of at least count elements that receives the rear left output.
-  \param rear_right Pointer to a buffer of at least count elements that receives the rear right output.
-  \return The number of frames actually rendered.
-  \retval 0 The end of song has been reached.
-  \remarks The output buffers are only written to up to the returned number of elements.
-  \remarks You can freely switch between any of the "openmpt_module_read*" variants if you see a need to do so. libopenmpt tries to introduce as little switching annoyances as possible. Normally, you would only use a single one of these functions for rendering a particular module.
-  \remarks It is recommended to use the floating point API because of the greater dynamic range and no implied clipping.
-  \sa \ref libopenmpt_freebasic_outputformat
-'/
-Declare Function openmpt_module_read_quad(ByVal module As openmpt_module Ptr, ByVal samplerate As Long, ByVal count As UInteger, ByVal Left As Short Ptr, ByVal Right As Short Ptr, ByVal rear_left As Short Ptr, ByVal rear_right As Short Ptr) As UInteger
-
-/'* \brief Render audio data
-
-  \param module The module handle to work on.
-  \param samplerate Sample rate to render output. Should be in [8000,192000], but this is not enforced.
-  \param count Number of audio frames to render per channel.
-  \param mono Pointer to a buffer of at least count elements that receives the mono/center output.
-  \return The number of frames actually rendered.
-  \retval 0 The end of song has been reached.
-  \remarks The output buffers are only written to up to the returned number of elements.
-  \remarks You can freely switch between any of the "openmpt_module_read*" variants if you see a need to do so. libopenmpt tries to introduce as little switching annoyances as possible. Normally, you would only use a single one of these functions for rendering a particular module.
-  \remarks Floating point samples are in the [-1.0..1.0] nominal range. They are not clipped to that range though and thus might overshoot.
-  \sa \ref libopenmpt_freebasic_outputformat
-'/
-Declare Function openmpt_module_read_float_mono(ByVal module As openmpt_module Ptr, ByVal samplerate As Long, ByVal count As UInteger, ByVal mono As Single Ptr) As UInteger
-
-/'* \brief Render audio data
-
-  \param module The module handle to work on.
-  \param samplerate Sample rate to render output. Should be in [8000,192000], but this is not enforced.
-  \param count Number of audio frames to render per channel.
-  \param left Pointer to a buffer of at least count elements that receives the left output.
-  \param right Pointer to a buffer of at least count elements that receives the right output.
-  \return The number of frames actually rendered.
-  \retval 0 The end of song has been reached.
-  \remarks The output buffers are only written to up to the returned number of elements.
-  \remarks You can freely switch between any of the "openmpt_module_read*" variants if you see a need to do so. libopenmpt tries to introduce as little switching annoyances as possible. Normally, you would only use a single one of these functions for rendering a particular module.
-  \remarks Floating point samples are in the [-1.0..1.0] nominal range. They are not clipped to that range though and thus might overshoot.
-  \sa \ref libopenmpt_freebasic_outputformat
-'/
-Declare Function openmpt_module_read_float_stereo(ByVal module As openmpt_module Ptr, ByVal samplerate As Long, ByVal count As UInteger, ByVal Left As Single Ptr, ByVal Right As Single Ptr) As UInteger
-
-/'* \brief Render audio data
-
-  \param module The module handle to work on.
-  \param samplerate Sample rate to render output. Should be in [8000,192000], but this is not enforced.
-  \param count Number of audio frames to render per channel.
-  \param left Pointer to a buffer of at least count elements that receives the left output.
-  \param right Pointer to a buffer of at least count elements that receives the right output.
-  \param rear_left Pointer to a buffer of at least count elements that receives the rear left output.
-  \param rear_right Pointer to a buffer of at least count elements that receives the rear right output.
-  \return The number of frames actually rendered.
-  \retval 0 The end of song has been reached.
-  \remarks The output buffers are only written to up to the returned number of elements.
-  \remarks You can freely switch between any of the "openmpt_module_read*" variants if you see a need to do so. libopenmpt tries to introduce as little switching annoyances as possible. Normally, you would only use a single one of these functions for rendering a particular module.
-  \remarks Floating point samples are in the [-1.0..1.0] nominal range. They are not clipped to that range though and thus might overshoot.
-  \sa \ref libopenmpt_freebasic_outputformat
-'/
-Declare Function openmpt_module_read_float_quad(ByVal module As openmpt_module Ptr, ByVal samplerate As Long, ByVal count As UInteger, ByVal Left As Single Ptr, ByVal Right As Single Ptr, ByVal rear_left As Single Ptr, ByVal rear_right As Single Ptr) As UInteger
-
-/'* \brief Render audio data
-
-  \param module The module handle to work on.
-  \param samplerate Sample rate to render output. Should be in [8000,192000], but this is not enforced.
-  \param count Number of audio frames to render per channel.
-  \param interleaved_stereo Pointer to a buffer of at least count*2 elements that receives the interleaved stereo output in the order (L,R).
-  \return The number of frames actually rendered.
-  \retval 0 The end of song has been reached.
-  \remarks The output buffers are only written to up to the returned number of elements.
-  \remarks You can freely switch between any of the "openmpt_module_read*" variants if you see a need to do so. libopenmpt tries to introduce as little switching annoyances as possible. Normally, you would only use a single one of these functions for rendering a particular module.
-  \remarks It is recommended to use the floating point API because of the greater dynamic range and no implied clipping.
-  \sa \ref libopenmpt_freebasic_outputformat
-'/
-Declare Function openmpt_module_read_interleaved_stereo(ByVal module As openmpt_module Ptr, ByVal samplerate As Long, ByVal count As UInteger, ByVal interleaved_stereo As Short Ptr) As UInteger
-
-/'* \brief Render audio data
-
-  \param module The module handle to work on.
-  \param samplerate Sample rate to render output. Should be in [8000,192000], but this is not enforced.
-  \param count Number of audio frames to render per channel.
-  \param interleaved_quad Pointer to a buffer of at least count*4 elements that receives the interleaved suad surround output in the order (L,R,RL,RR).
-  \return The number of frames actually rendered.
-  \retval 0 The end of song has been reached.
-  \remarks The output buffers are only written to up to the returned number of elements.
-  \remarks You can freely switch between any of the "openmpt_module_read*" variants if you see a need to do so. libopenmpt tries to introduce as little switching annoyances as possible. Normally, you would only use a single one of these functions for rendering a particular module.
-  \remarks It is recommended to use the floating point API because of the greater dynamic range and no implied clipping.
-  \sa \ref libopenmpt_freebasic_outputformat
-'/
-Declare Function openmpt_module_read_interleaved_quad(ByVal module As openmpt_module Ptr, ByVal samplerate As Long, ByVal count As UInteger, ByVal interleaved_quad As Short Ptr) As UInteger
-
-/'* \brief Render audio data
-
-  \param module The module handle to work on.
-  \param samplerate Sample rate to render output. Should be in [8000,192000], but this is not enforced.
-  \param count Number of audio frames to render per channel.
-  \param interleaved_stereo Pointer to a buffer of at least count*2 elements that receives the interleaved stereo output in the order (L,R).
-  \return The number of frames actually rendered.
-  \retval 0 The end of song has been reached.
-  \remarks The output buffers are only written to up to the returned number of elements.
-  \remarks You can freely switch between any of the "openmpt_module_read*" variants if you see a need to do so. libopenmpt tries to introduce as little switching annoyances as possible. Normally, you would only use a single one of these functions for rendering a particular module.
-  \remarks Floating point samples are in the [-1.0..1.0] nominal range. They are not clipped to that range though and thus might overshoot.
-  \sa \ref libopenmpt_freebasic_outputformat
-'/
-Declare Function openmpt_module_read_interleaved_float_stereo(ByVal module As openmpt_module Ptr, ByVal samplerate As Long, ByVal count As UInteger, ByVal interleaved_stereo As Single Ptr) As UInteger
-
-/'* \brief Render audio data
-
-  \param module The module handle to work on.
-  \param samplerate Sample rate to render output. Should be in [8000,192000], but this is not enforced.
-  \param count Number of audio frames to render per channel.
-  \param interleaved_quad Pointer to a buffer of at least count*4 elements that receives the interleaved suad surround output in the order (L,R,RL,RR).
-  \return The number of frames actually rendered.
-  \retval 0 The end of song has been reached.
-  \remarks The output buffers are only written to up to the returned number of elements.
-  \remarks You can freely switch between any of the "openmpt_module_read*" variants if you see a need to do so. libopenmpt tries to introduce as little switching annoyances as possible. Normally, you would only use a single one of these functions for rendering a particular module.
-  \remarks Floating point samples are in the [-1.0..1.0] nominal range. They are not clipped to that range though and thus might overshoot.
-  \sa \ref libopenmpt_freebasic_outputformat
-'/
-Declare Function openmpt_module_read_interleaved_float_quad(ByVal module As openmpt_module Ptr, ByVal samplerate As Long, ByVal count As UInteger, ByVal interleaved_quad As Single Ptr) As UInteger
-'*@}
-
-/'* \brief Get the list of supported metadata item keys
-
-  \param module The module handle to work on.
-  \return Metadata item keys supported by openmpt_module_get_metadata, as a semicolon-separated list.
-  \sa openmpt_module_get_metadata
-  \remarks Use openmpt_module_get_metadata_keys to automatically handle the lifetime of the returned pointer.
-'/
-Declare Function openmpt_module_get_metadata_keys_ Alias "openmpt_module_get_metadata_keys" (ByVal module As openmpt_module Ptr) As Const ZString Ptr
-
-/'* \brief Get a metadata item value
-
-  \param module The module handle to work on.
-  \param key Metadata item key to query. Use openmpt_module_get_metadata_keys to check for available keys.
-           Possible keys are:
-           - type: Module format extension (e.g. it)
-           - type_long: Format name associated with the module format (e.g. Impulse Tracker)
-           - originaltype: Module format extension (e.g. it) of the original module in case the actual type is a converted format (e.g. mo3 or gdm)
-           - originaltype_long: Format name associated with the module format (e.g. Impulse Tracker) of the original module in case the actual type is a converted format (e.g. mo3 or gdm)
-           - container: Container format the module file is embedded in, if any (e.g. umx)
-           - container_long: Full container name if the module is embedded in a container (e.g. Unreal Music)
-           - tracker: Tracker that was (most likely) used to save the module file, if known
-           - artist: Author of the module
-           - title: Module title
-           - date: Date the module was last saved, in ISO-8601 format.
-           - message: Song message. If the song message is empty or the module format does not support song messages, a list of instrument and sample names is returned instead.
-           - message_raw: Song message. If the song message is empty or the module format does not support song messages, an empty string is returned.
-           - warnings: A list of warnings that were generated while loading the module.
-  \return The associated value for key.
-  \sa openmpt_module_get_metadata_keys
-  \remarks Use openmpt_module_get_metadata to automatically handle the lifetime of the returned pointer.
-'/
-Declare Function openmpt_module_get_metadata_ Alias "openmpt_module_get_metadata" (ByVal module As openmpt_module Ptr, ByVal key As Const ZString Ptr) As Const ZString Ptr
-
-/'* \brief Get the current speed
-
-  \param module The module handle to work on.
-  \return The current speed in ticks per row.
-'/
-Declare Function openmpt_module_get_current_speed(ByVal module As openmpt_module Ptr) As Long
-
-/'* \brief Get the current tempo
-
-  \param module The module handle to work on.
-  \return The current tempo in tracker units. The exact meaning of this value depends on the tempo mode being used.
-'/
-Declare Function openmpt_module_get_current_tempo(ByVal module As openmpt_module Ptr) As Long
-
-/'* \brief Get the current order
-
-  \param module The module handle to work on.
-  \return The current order at which the module is being played back.
-'/
-Declare Function openmpt_module_get_current_order(ByVal module As openmpt_module Ptr) As Long
-
-/'* \brief Get the current pattern
-
-  \param module The module handle to work on.
-  \return The current pattern that is being played.
-'/
-Declare Function openmpt_module_get_current_pattern(ByVal module As openmpt_module Ptr) As Long
-
-/'* \brief Get the current row
-
-  \param module The module handle to work on.
-  \return The current row at which the current pattern is being played.
-'/
-Declare Function openmpt_module_get_current_row(ByVal module As openmpt_module Ptr) As Long
-
-/'* \brief Get the current amount of playing channels.
-
-  \param module The module handle to work on.
-  \return The amount of sample channels that are currently being rendered.
-'/
-Declare Function openmpt_module_get_current_playing_channels(ByVal module As openmpt_module Ptr) As Long
-
-/'* \brief Get an approximate indication of the channel volume.
-
-  \param module The module handle to work on.
-  \param channel The channel whose volume should be retrieved.
-  \return The approximate channel volume.
-  \remarks The returned value is solely based on the note velocity and does not take the actual waveform of the playing sample into account.
-'/
-Declare Function openmpt_module_get_current_channel_vu_mono(ByVal module As openmpt_module Ptr, ByVal channel As Long) As Single
-
-/'* \brief Get an approximate indication of the channel volume on the front-left speaker.
-
-  \param module The module handle to work on.
-  \param channel The channel whose volume should be retrieved.
-  \return The approximate channel volume.
-  \remarks The returned value is solely based on the note velocity and does not take the actual waveform of the playing sample into account.
-'/
-Declare Function openmpt_module_get_current_channel_vu_left(ByVal module As openmpt_module Ptr, ByVal channel As Long) As Single
-
-/'* \brief Get an approximate indication of the channel volume on the front-right speaker.
-
-  \param module The module handle to work on.
-  \param channel The channel whose volume should be retrieved.
-  \return The approximate channel volume.
-  \remarks The returned value is solely based on the note velocity and does not take the actual waveform of the playing sample into account.
-'/
-Declare Function openmpt_module_get_current_channel_vu_right(ByVal module As openmpt_module Ptr, ByVal channel As Long) As Single
-
-/'* \brief Get an approximate indication of the channel volume on the rear-left speaker.
-
-  \param module The module handle to work on.
-  \param channel The channel whose volume should be retrieved.
-  \return The approximate channel volume.
-  \remarks The returned value is solely based on the note velocity and does not take the actual waveform of the playing sample into account.
-'/
-Declare Function openmpt_module_get_current_channel_vu_rear_left(ByVal module As openmpt_module Ptr, ByVal channel As Long) As Single
-
-/'* \brief Get an approximate indication of the channel volume on the rear-right speaker.
-
-  \param module The module handle to work on.
-  \param channel The channel whose volume should be retrieved.
-  \return The approximate channel volume.
-  \remarks The returned value is solely based on the note velocity and does not take the actual waveform of the playing sample into account.
-'/
-Declare Function openmpt_module_get_current_channel_vu_rear_right(ByVal module As openmpt_module Ptr, ByVal channel As Long) As Single
-
-/'* \brief Get the number of sub-songs
-
-  \param module The module handle to work on.
-  \return The number of sub-songs in the module. This includes any "hidden" songs (songs that share the same sequence, but start at different order indices) and "normal" sub-songs or "sequences" (if the format supports them).
-  \sa openmpt_module_get_subsong_name, openmpt_module_select_subsong, openmpt_module_get_selected_subsong
-'/
-Declare Function openmpt_module_get_num_subsongs(ByVal module As openmpt_module Ptr) As Long
-
-/'* \brief Get the number of pattern channels
-
-  \param module The module handle to work on.
-  \return The number of pattern channels in the module. Not all channels do necessarily contain data.
-  \remarks The number of pattern channels is completely independent of the number of output channels. libopenmpt can render modules in mono, stereo or quad surround, but the choice of which of the three modes to use must not be made based on the return value of this function, which may be any positive integer amount. Only use this function for informational purposes.
-'/
-Declare Function openmpt_module_get_num_channels(ByVal module As openmpt_module Ptr) As Long
-
-/'* \brief Get the number of orders
-
-  \param module The module handle to work on.
-  \return The number of orders in the current sequence of the module.
-'/
-Declare Function openmpt_module_get_num_orders(ByVal module As openmpt_module Ptr) As Long
-
-/'* \brief Get the number of patterns
-
-  \param module The module handle to work on.
-  \return The number of distinct patterns in the module.
-'/
-Declare Function openmpt_module_get_num_patterns(ByVal module As openmpt_module Ptr) As Long
-
-/'* \brief Get the number of instruments
-
-  \param module The module handle to work on.
-  \return The number of instrument slots in the module. Instruments are a layer on top of samples, and are not supported by all module formats.
-'/
-Declare Function openmpt_module_get_num_instruments(ByVal module As openmpt_module Ptr) As Long
-
-/'* \brief Get the number of samples
-
-  \param module The module handle to work on.
-  \return The number of sample slots in the module.
-'/
-Declare Function openmpt_module_get_num_samples(ByVal module As openmpt_module Ptr) As Long
-
-/'* \brief Get a sub-song name
-
-  \param module The module handle to work on.
-  \param index The sub-song whose name should be retrieved
-  \return The sub-song name.
-  \sa openmpt_module_get_num_subsongs, openmpt_module_select_subsong, openmpt_module_get_selected_subsong
-  \remarks Use openmpt_module_get_subsong_name to automatically handle the lifetime of the returned pointer.
-'/
-Declare Function openmpt_module_get_subsong_name_ Alias "openmpt_module_get_subsong_name" (ByVal module As openmpt_module Ptr, ByVal index As Long) As Const ZString Ptr
-
-/'* \brief Get a channel name
-
-  \param module The module handle to work on.
-  \param index The channel whose name should be retrieved
-  \return The channel name.
-  \sa openmpt_module_get_num_channels
-  \remarks Use openmpt_module_get_channel_name to automatically handle the lifetime of the returned pointer.
-'/
-Declare Function openmpt_module_get_channel_name_ Alias "openmpt_module_get_channel_name" (ByVal module As openmpt_module Ptr, ByVal index As Long) As Const ZString Ptr
-
-/'* \brief Get an order name
-
-  \param module The module handle to work on.
-  \param index The order whose name should be retrieved
-  \return The order name.
-  \sa openmpt_module_get_num_orders
-  \remarks Use openmpt_module_get_order_name to automatically handle the lifetime of the returned pointer.
-'/
-Declare Function openmpt_module_get_order_name_ Alias "openmpt_module_get_order_name" (ByVal module As openmpt_module Ptr, ByVal index As Long) As Const ZString Ptr
-
-/'* \brief Get a pattern name
-
-  \param module The module handle to work on.
-  \param index The pattern whose name should be retrieved
-  \return The pattern name.
-  \sa openmpt_module_get_num_patterns
-  \remarks Use openmpt_module_get_pattern_name to automatically handle the lifetime of the returned pointer.
-'/
-Declare Function openmpt_module_get_pattern_name_ Alias "openmpt_module_get_pattern_name" (ByVal module As openmpt_module Ptr, ByVal index As Long) As Const ZString Ptr
-
-/'* \brief Get an instrument name
-
-  \param module The module handle to work on.
-  \param index The instrument whose name should be retrieved
-  \return The instrument name.
-  \sa openmpt_module_get_num_instruments
-  \remarks Use openmpt_module_get_instrument_name to automatically handle the lifetime of the returned pointer.
-'/
-Declare Function openmpt_module_get_instrument_name_ Alias "openmpt_module_get_instrument_name" (ByVal module As openmpt_module Ptr, ByVal index As Long) As Const ZString Ptr
-
-/'* \brief Get a sample name
-
-  \param module The module handle to work on.
-  \param index The sample whose name should be retrieved
-  \return The sample name.
-  \sa openmpt_module_get_num_samples
-  \remarks Use openmpt_module_get_sample_name to automatically handle the lifetime of the returned pointer.
-'/
-Declare Function openmpt_module_get_sample_name_ Alias "openmpt_module_get_sample_name" (ByVal module As openmpt_module Ptr, ByVal index As Long) As Const ZString Ptr
-
-/'* \brief Get pattern at order position
-
-  \param module The module handle to work on.
-  \param order The order item whose pattern index should be retrieved.
-  \return The pattern index found at the given order position of the current sequence.
-'/
-Declare Function openmpt_module_get_order_pattern(ByVal module As openmpt_module Ptr, ByVal order As Long) As Long
-
-/'* \brief Get the number of rows in a pattern
-
-  \param module The module handle to work on.
-  \param pattern The pattern whose row count should be retrieved.
-  \return The number of rows in the given pattern. If the pattern does not exist, 0 is returned.
-'/
-Declare Function openmpt_module_get_pattern_num_rows(ByVal module As openmpt_module Ptr, ByVal pattern As Long) As Long
-
-/'* \brief Get raw pattern content
-
-  \param module The module handle to work on.
-  \param pattern The pattern whose data should be retrieved.
-  \param row The row from which the data should be retrieved.
-  \param channel The channel from which the data should be retrieved.
-  \param command The cell index at which the data should be retrieved. See \ref openmpt_module_command_index
-  \return The internal, raw pattern data at the given pattern position.
-'/
-Declare Function openmpt_module_get_pattern_row_channel_command_(ByVal module As openmpt_module Ptr, ByVal pattern As Long, ByVal row As Long, ByVal channel As Long, ByVal command_ As Long) As UByte
-
-/'* \brief Get formatted (human-readable) pattern content
-
-  \param module The module handle to work on.
-  \param pattern The pattern whose data should be retrieved.
-  \param row The row from which the data should be retrieved.
-  \param channel The channel from which the data should be retrieved.
-  \param command The cell index at which the data should be retrieved.
-  \return The formatted pattern data at the given pattern position. See \ref openmpt_module_command_index
-  \sa openmpt_module_highlight_pattern_row_channel_command
-  \remarks Use openmpt_module_format_pattern_row_channel_command to automatically handle the lifetime of the returned pointer.
-'/
-Declare Function openmpt_module_format_pattern_row_channel_command_ Alias "openmpt_module_format_pattern_row_channel_command" (ByVal module As openmpt_module Ptr, ByVal pattern As Long, ByVal row As Long, ByVal channel As Long, ByVal command_ As Long) As Const ZString Ptr
-
-/'* \brief Get highlighting information for formatted pattern content
-
-  \param module The module handle to work on.
-  \param pattern The pattern whose data should be retrieved.
-  \param row The row from which the data should be retrieved.
-  \param channel The channel from which the data should be retrieved.
-  \param command The cell index at which the data should be retrieved. See \ref openmpt_module_command_index
-  \return The highlighting string for the formatted pattern data as retrieved by openmpt_module_get_pattern_row_channel_command at the given pattern position.
-  \remarks The returned string will map each character position of the string returned by openmpt_module_get_pattern_row_channel_command to a highlighting instruction.
-           Possible highlighting characters are:
-           - " " : empty/space
-           - "." : empty/dot
-           - "n" : generic note
-           - "m" : special note
-           - "i" : generic instrument
-           - "u" : generic volume column effect
-           - "v" : generic volume column parameter
-           - "e" : generic effect column effect
-           - "f" : generic effect column parameter
-  \sa openmpt_module_get_pattern_row_channel_command
-  \remarks Use openmpt_module_highlight_pattern_row_channel_command to automatically handle the lifetime of the returned pointer.
-'/
-Declare Function openmpt_module_highlight_pattern_row_channel_command_ Alias "openmpt_module_highlight_pattern_row_channel_command" (ByVal module As openmpt_module Ptr, ByVal pattern As Long, ByVal row As Long, ByVal channel As Long, ByVal command_ As Long) As Const ZString Ptr
-
-/'* \brief Get formatted (human-readable) pattern content
-
-  \param module The module handle to work on.
-  \param pattern The pattern whose data should be retrieved.
-  \param row The row from which the data should be retrieved.
-  \param channel The channel from which the data should be retrieved.
-  \param width The maximum number of characters the string should contain. 0 means no limit.
-  \param pad If true, the string will be resized to the exact length provided in the width parameter.
-  \return The formatted pattern data at the given pattern position.
-  \sa openmpt_module_highlight_pattern_row_channel
-  \remarks Use openmpt_module_format_pattern_row_channel to automatically handle the lifetime of the returned pointer.
-'/
-Declare Function openmpt_module_format_pattern_row_channel_ Alias "openmpt_module_format_pattern_row_channel" (ByVal module As openmpt_module Ptr, ByVal pattern As Long, ByVal row As Long, ByVal channel As Long, ByVal width_ As UInteger, ByVal pad As Long) As Const ZString Ptr
-
-/'* \brief Get highlighting information for formatted pattern content
-
-  \param module The module handle to work on.
-  \param pattern The pattern whose data should be retrieved.
-  \param row The row from which the data should be retrieved.
-  \param channel The channel from which the data should be retrieved.
-  \param width The maximum number of characters the string should contain. 0 means no limit.
-  \param pad If true, the string will be resized to the exact length provided in the width parameter.
-  \return The highlighting string for the formatted pattern data as retrieved by openmpt_module_format_pattern_row_channel at the given pattern position.
-  \sa openmpt_module_format_pattern_row_channel
-  \remarks Use openmpt_module_highlight_pattern_row_channel to automatically handle the lifetime of the returned pointer.
-'/
-Declare Function openmpt_module_highlight_pattern_row_channel_ Alias "openmpt_module_highlight_pattern_row_channel" (ByVal module As openmpt_module Ptr, ByVal pattern As Long, ByVal row As Long, ByVal channel As Long, ByVal width_ As UInteger, ByVal pad As Long) As Const ZString Ptr
-
-/'* \brief Retrieve supported ctl keys
-
-  \param module The module handle to work on.
-  \return A semicolon-separated list containing all supported ctl keys.
-  \remarks Currently supported ctl values are:
-           - load.skip_samples: Set to "1" to avoid loading samples into memory
-           - load.skip_patterns: Set to "1" to avoid loading patterns into memory
-           - load.skip_plugins: Set to "1" to avoid loading plugins
-           - load.skip_subsongs_init: Set to "1" to avoid pre-initializing sub-songs. Skipping results in faster module loading but slower seeking.
-           - seek.sync_samples: Set to "1" to sync sample playback when using openmpt_module_set_position_seconds or openmpt_module_set_position_order_row.
-           - subsong: The current subsong. Setting it has identical semantics as openmpt_module_select_subsong(), getting it returns the currently selected subsong.
-           - play.at_end: Chooses the behaviour when the end of song is reached:
-                          - "fadeout": Fades the module out for a short while. Subsequent reads after the fadeout will return 0 rendered frames.
-                          - "continue": Returns 0 rendered frames when the song end is reached. Subsequent reads will continue playing from the song start or loop start.
-                          - "stop": Returns 0 rendered frames when the song end is reached. Subsequent reads will return 0 rendered frames.
-           - play.tempo_factor: Set a floating point tempo factor. "1.0" is the default tempo.
-           - play.pitch_factor: Set a floating point pitch factor. "1.0" is the default pitch.
-           - render.resampler.emulate_amiga: Set to "1" to enable the Amiga resampler for Amiga modules. This emulates the sound characteristics of the Paula chip and overrides the selected interpolation filter. Non-Amiga module formats are not affected by this setting.
-           - render.opl.volume_factor: Set volume factor applied to synthesized OPL sounds, relative to the default OPL volume.
-           - dither: Set the dither algorithm that is used for the 16 bit versions of openmpt_module_read. Supported values are:
-                     - 0: No dithering.
-                     - 1: Default mode. Chosen by OpenMPT code, might change.
-                     - 2: Rectangular, 0.5 bit depth, no noise shaping (original ModPlug Tracker).
-                     - 3: Rectangular, 1 bit depth, simple 1st order noise shaping
-  \remarks Use openmpt_module_get_ctls to automatically handle the lifetime of the returned pointer.
-'/
-Declare Function openmpt_module_get_ctls_ Alias "openmpt_module_get_ctls" (ByVal module As openmpt_module Ptr) As Const ZString Ptr
-
-/'* \brief Get current ctl value
-
-  \param module The module handle to work on.
-  \param ctl The ctl key whose value should be retrieved.
-  \return The associated ctl value, or NULL on failure.
-  \sa openmpt_module_get_ctls
-  \remarks Use openmpt_module_ctl_get to automatically handle the lifetime of the returned pointer.
-'/
-Declare Function openmpt_module_ctl_get_ Alias "openmpt_module_ctl_get" (ByVal module As openmpt_module Ptr, ByVal ctl As Const ZString Ptr) As Const ZString Ptr
-
-/'* \brief Set ctl value
-
-  \param module The module handle to work on.
-  \param ctl The ctl key whose value should be set.
-  \param value The value that should be set.
-  \return 1 if successful, 0 in case the value is not sensible (e.g. negative tempo factor) or the ctl is not recognized.
-  \sa openmpt_module_get_ctls
-'/
-Declare Function openmpt_module_ctl_set(ByVal module As openmpt_module Ptr, ByVal ctl As Const ZString Ptr, ByVal value As Const ZString Ptr) As Long
-
-'* Callbacks for CRT FILE* handling
-Function openmpt_stream_read_func(ByVal stream As Any Ptr, ByVal dst As Any Ptr, ByVal bytes As UInteger) As UInteger
-	Dim retval As UInteger = 0
-	Var f = Cast( FILE Ptr, stream )
-	If ( f = 0 ) Then Return 0
-	retval = fread( dst, 1, bytes, f )
-	If ( retval <= 0 ) Then Return 0
-	Return retval
-End Function
-
-'* Callbacks for CRT FILE* handling
-Function openmpt_stream_seek_func(ByVal stream As Any Ptr, ByVal offset As LongInt, ByVal whence As Long) As Long
-	Var f = Cast( FILE Ptr, stream )
-	If ( f = 0 ) Then Return -1
-	Dim fwhence As Long
-	Select Case whence
-	Case OPENMPT_STREAM_SEEK_SET
-		fwhence = SEEK_SET
-	Case OPENMPT_STREAM_SEEK_CUR
-		fwhence = SEEK_CUR
-	Case OPENMPT_STREAM_SEEK_END
-		fwhence = SEEK_END
-	Case Else
-		Return -1
-	End Select
-	Return IIf(fseek( f, offset, fwhence ) <> 0, -1, 0)
-End Function
-
-'* Callbacks for CRT FILE* handling
-Function openmpt_stream_tell_func(ByVal stream As Any Ptr) As LongInt
-	Dim retval As LongInt = 0
-	Var f = Cast( FILE Ptr, stream )
-	If ( f = 0 ) Then
-		Return -1
-	EndIf
-	retval = ftell( f )
-	If ( retval < 0 ) Then Return -1
-	Return retval
-End Function
-
-End Extern
-
-'* Retrieve the set of stream callbacks for CRT FILE*
-Function openmpt_stream_get_file_callbacks() As openmpt_stream_callbacks
-	Static callbacks As openmpt_stream_callbacks = (@openmpt_stream_read_func, @openmpt_stream_seek_func, @openmpt_stream_tell_func)
-	Return callbacks
-End Function
-
-/'* \brief Construct an openmpt_module
-
-  \param file The FreeBASIC file handle to load from.
-  \param logfunc Logging function where warning and errors are written. May be NULL.
-  \param loguser Logging function user context. Used to pass any user-defined data associated with this module to the logging function.
-  \param errfunc Error function to define error behaviour. May be NULL.
-  \param erruser Error function user context. Used to pass any user-defined data associated with this module to the error function.
-  \param errorcode Pointer to an integer where an error may get stored. May be NULL.
-  \param error_message Pointer to a string pointer where an error message may get stored. May be NULL.
-  \param ctls A map of initial ctl values. See openmpt_module_get_ctls().
-  \return A pointer to the constructed openmpt_module, or NULL on failure.
-  \remarks The file handle can be closed after an openmpt_module has been constructed successfully.
-  \sa openmpt_module_create2
-'/
-Function openmpt_module_create_from_fbhandle2(_
-		ByVal file As Integer,_
-		ByVal logfunc As openmpt_log_func = 0,_
-		ByVal loguser As Any Ptr = 0,_
-		ByVal errfunc As openmpt_error_func = 0,_
-		ByVal erruser As Any Ptr = 0,_
-		ByVal errorcode As Long Ptr = 0,_
-		ByVal error_message As Const ZString Ptr Ptr = 0,_
-		ByVal ctls As Const openmpt_module_initial_ctl Ptr = 0) As openmpt_module Ptr
-	Return openmpt_module_create2(openmpt_stream_get_file_callbacks(), Cast(FILE Ptr, FileAttr(file, fbFileAttrHandle)), logfunc, loguser, errfunc, erruser, errorcode, error_message, ctls)
-End Function
-
-/'* \brief Construct an openmpt_module
-
-  \param file The FreeBASIC file handle to load from.
-  \param logfunc Logging function where warning and errors are written. May be NULL.
-  \param loguser Logging function user context. Used to pass any user-defined data associated with this module to the logging function.
-  \param ctls A map of initial ctl values. See openmpt_module_get_ctls().
-  \return A pointer to the constructed openmpt_module, or NULL on failure.
-  \remarks The file handle can be closed after an openmpt_module has been constructed successfully.
-  \deprecated Please use openmpt_module_create_from_fbhandle2().
-  \sa openmpt_module_create2
-'/
-Function openmpt_module_create_from_fbhandle(_
-		ByVal file As Integer,_
-		ByVal logfunc As openmpt_log_func = 0,_
-		ByVal loguser As Any Ptr = 0,_
-		ByVal ctls As Const openmpt_module_initial_ctl Ptr = 0) As openmpt_module Ptr
-	Return openmpt_module_create_from_fbhandle2(file, logfunc, loguser, 0, 0, 0, 0, ctls)
-End Function
-
-/'* \brief Construct an openmpt_module
-
-  \param filename The file to load from.
-  \param logfunc Logging function where warning and errors are written. May be NULL.
-  \param loguser Logging function user context. Used to pass any user-defined data associated with this module to the logging function.
-  \param errfunc Error function to define error behaviour. May be NULL.
-  \param erruser Error function user context. Used to pass any user-defined data associated with this module to the error function.
-  \param errorcode Pointer to an integer where an error may get stored. May be NULL.
-  \param error_message Pointer to a string pointer where an error message may get stored. May be NULL.
-  \param ctls A map of initial ctl values. See openmpt_module_get_ctls().
-  \return A pointer to the constructed openmpt_module, or NULL on failure.
-  \sa openmpt_module_create2
-'/
-Function openmpt_module_create_from_filename2(_
-		ByRef filename As String,_
-		ByVal logfunc As openmpt_log_func = 0,_
-		ByVal loguser As Any Ptr = 0,_
-		ByVal errfunc As openmpt_error_func = 0,_
-		ByVal erruser As Any Ptr = 0,_
-		ByVal errorcode As Long Ptr = 0,_
-		ByVal error_message As Const ZString Ptr Ptr = 0,_
-		ByVal ctls As Const openmpt_module_initial_ctl Ptr = 0) As openmpt_module Ptr
-	Var file = fopen(filename, "rb")
-	Var retval = CPtr(openmpt_module Ptr, 0)
-	If(file <> 0) Then
-		retval = openmpt_module_create2(openmpt_stream_get_file_callbacks(), file, logfunc, loguser, errfunc, erruser, errorcode, error_message, ctls)
-		fclose(file)
-	EndIf
-	Return retval
-End Function
-
-/'* \brief Construct an openmpt_module
-
-  \param filename The file to load from.
-  \param logfunc Logging function where warning and errors are written. May be NULL.
-  \param loguser Logging function user context. Used to pass any user-defined data associated with this module to the logging function.
-  \param ctls A map of initial ctl values. See openmpt_module_get_ctls().
-  \return A pointer to the constructed openmpt_module, or NULL on failure.
-  \deprecated Please use openmpt_module_create_from_filename2().
-  \sa openmpt_module_create2
-'/
-Function openmpt_module_create_from_filename(_
-		ByRef filename As String,_
-		ByVal logfunc As openmpt_log_func = 0,_
-		ByVal loguser As Any Ptr = 0,_
-		ByVal ctls As Const openmpt_module_initial_ctl Ptr = 0) As openmpt_module Ptr
-	Return openmpt_module_create_from_filename2(filename, logfunc, loguser, 0, 0, 0, 0, ctls)
-End Function
-
-'* String handling for wrapping and freeing ZStrings returned by libopenmpt
-Function openmpt_get_zstring(sz As Const ZString Ptr) As String
-	If(sz = 0) Then Return ""
-	Dim As String s = *sz
-	openmpt_free_string(sz)
-	Return s
-End Function
-
-'* \sa openmpt_get_string_
-Function openmpt_get_string(ByVal key As Const ZString Ptr) As String
-	Return openmpt_get_zstring(openmpt_get_string_(key))
-End Function
-
-'* \sa openmpt_error_string_
-Function openmpt_error_string (ByVal errorcode As Long) As String
-	Return openmpt_get_zstring(openmpt_error_string_(errorcode))
-End Function
-
-'* \sa openmpt_module_error_get_last_message_
-Function openmpt_module_error_get_last_message (ByVal module As openmpt_module Ptr) As String
-	Return openmpt_get_zstring(openmpt_module_error_get_last_message_(module))
-End Function
-
-'* \sa openmpt_module_get_metadata_keys_
-Function openmpt_module_get_metadata_keys(ByVal module As openmpt_module Ptr) As String
-	Return openmpt_get_zstring(openmpt_module_get_metadata_keys_(module))
-End Function
-
-'* \sa openmpt_module_get_metadata_
-Function openmpt_module_get_metadata(ByVal module As openmpt_module Ptr, ByVal key As Const ZString Ptr) As String
-	Return openmpt_get_zstring(openmpt_module_get_metadata_(module, key))
-End Function
-
-'* \sa openmpt_module_get_subsong_name_
-Function openmpt_module_get_subsong_name(ByVal module As openmpt_module Ptr, ByVal index As Long) As String
-	Return openmpt_get_zstring(openmpt_module_get_subsong_name_(module, index))
-End Function
-
-'* \sa openmpt_module_get_channel_name_
-Function openmpt_module_get_channel_name(ByVal module As openmpt_module Ptr, ByVal index As Long) As String
-	Return openmpt_get_zstring(openmpt_module_get_channel_name_(module, index))
-End Function
-
-'* \sa openmpt_module_get_order_name_
-Function openmpt_module_get_order_name(ByVal module As openmpt_module Ptr, ByVal index As Long) As String
-	Return openmpt_get_zstring(openmpt_module_get_order_name_(module, index))
-End Function
-
-'* \sa openmpt_module_get_pattern_name_
-Function openmpt_module_get_pattern_name(ByVal module As openmpt_module Ptr, ByVal index As Long) As String
-	Return openmpt_get_zstring(openmpt_module_get_pattern_name_(module, index))
-End Function
-
-'* \sa openmpt_module_get_instrument_name_
-Function openmpt_module_get_instrument_name(ByVal module As openmpt_module Ptr, ByVal index As Long) As String
-	Return openmpt_get_zstring(openmpt_module_get_instrument_name_(module, index))
-End Function
-
-'* \sa openmpt_module_get_sample_name_
-Function openmpt_module_get_sample_name(ByVal module As openmpt_module Ptr, ByVal index As Long) As String
-	Return openmpt_get_zstring(openmpt_module_get_sample_name_(module, index))
-End Function
-
-'* \sa openmpt_module_format_pattern_row_channel_command_
-Function openmpt_module_format_pattern_row_channel_command(ByVal module As openmpt_module Ptr, ByVal pattern As Long, ByVal row As Long, ByVal channel As Long, ByVal command_ As Long) As String
-	Return openmpt_get_zstring(openmpt_module_format_pattern_row_channel_command_(module, pattern, row, channel, command_))
-End Function
-
-'* \sa openmpt_module_highlight_pattern_row_channel_command_
-Function openmpt_module_highlight_pattern_row_channel_command(ByVal module As openmpt_module Ptr, ByVal pattern As Long, ByVal row As Long, ByVal channel As Long, ByVal command_ As Long) As String
-	Return openmpt_get_zstring(openmpt_module_highlight_pattern_row_channel_command_(module, pattern, row, channel, command_))
-End Function
-
-'* \sa openmpt_module_format_pattern_row_channel_
-Function openmpt_module_format_pattern_row_channel(ByVal module As openmpt_module Ptr, ByVal pattern As Long, ByVal row As Long, ByVal channel As Long, ByVal width_ As UInteger, ByVal pad As Long) As String
-	Return openmpt_get_zstring(openmpt_module_format_pattern_row_channel_(module, pattern, row, channel, width_, pad))
-End Function
-
-'* \sa openmpt_module_highlight_pattern_row_channel_
-Function openmpt_module_highlight_pattern_row_channel(ByVal module As openmpt_module Ptr, ByVal pattern As Long, ByVal row As Long, ByVal channel As Long, ByVal width_ As UInteger, ByVal pad As Long) As String
-	Return openmpt_get_zstring(openmpt_module_highlight_pattern_row_channel_(module, pattern, row, channel, width_, pad))
-End Function
-
-'* \sa openmpt_module_get_ctls_
-Function openmpt_module_get_ctls(ByVal module As openmpt_module Ptr) As String
-	Return openmpt_get_zstring(openmpt_module_get_ctls_(module))
-End Function
-
-'* \sa openmpt_module_ctl_get_
-Function openmpt_module_ctl_get(ByVal module As openmpt_module Ptr, ByVal ctl As Const ZString Ptr) As String
-	Return openmpt_get_zstring(openmpt_module_ctl_get_(module, ctl))
-End Function

+ 0 - 332
libopenmpt.mod/openmpt/libopenmpt/bindings/freebasic/libopenmpt_ext.bi

@@ -1,332 +0,0 @@
-/'
- ' libopenmpt_ext.bi
- ' -----------------
- ' Purpose: libopenmpt public FreeBASIC interface for libopenmpt extensions
- ' Notes  : (currently none)
- ' Authors: Johannes Schultz
- '          OpenMPT Devs
- ' The OpenMPT source code is released under the BSD license. Read LICENSE for more details.
- '/
-
-#Pragma Once
-
-#Include Once "libopenmpt.bi"
-
-Extern "C"
-
-'* \brief Opaque type representing a libopenmpt extension module
-Type openmpt_module_ext
-	opaque As Any Ptr
-End Type
-
-/'* \brief Construct an openmpt_module_ext
-
-  \param stream_callbacks Input stream callback operations.
-  \param stream Input stream to load the module from.
-  \param logfunc Logging function where warning and errors are written. The logging function may be called throughout the lifetime of openmpt_module_ext. May be NULL.
-  \param loguser User-defined data associated with this module. This value will be passed to the logging callback function (logfunc)
-  \param errfunc Error function to define error behaviour. May be NULL.
-  \param erruser Error function user context.
-  \param errorcode Pointer to an integer where an error may get stored. May be NULL.
-  \param error_message Pointer to a string pointer where an error message may get stored. May be NULL.
-  \param ctls A map of initial ctl values, see openmpt_module_get_ctls.
-  \return A pointer to the constructed openmpt_module_ext, or NULL on failure.
-  \remarks The input data can be discarded after an openmpt_module_ext has been constructed successfully.
-  \sa openmpt_stream_callbacks
-  \since 0.3.0
-'/
-Declare Function openmpt_module_ext_create(ByVal stream_callbacks As openmpt_stream_callbacks, ByVal stream As Any Ptr, ByVal logfunc As openmpt_log_func, ByVal loguser As Any Ptr, ByVal errfunc As openmpt_error_func, ByVal erruser As Any Ptr, ByVal Error As Long Ptr, ByVal error_message As Const ZString Ptr Ptr, ByVal ctls As Const openmpt_module_initial_ctl Ptr) As openmpt_module_ext Ptr
-
-/'* \brief Construct an openmpt_module_ext
-
-  \param filedata Data to load the module from.
-  \param filesize Amount of data available.
-  \param logfunc Logging function where warning and errors are written. The logging function may be called throughout the lifetime of openmpt_module_ext.
-  \param loguser User-defined data associated with this module. This value will be passed to the logging callback function (logfunc)
-  \param errfunc Error function to define error behaviour. May be NULL.
-  \param erruser Error function user context.
-  \param errorcode Pointer to an integer where an error may get stored. May be NULL.
-  \param error_message Pointer to a string pointer where an error message may get stored. May be NULL.
-  \param ctls A map of initial ctl values, see openmpt_module_get_ctls.
-  \return A pointer to the constructed openmpt_module_ext, or NULL on failure.
-  \remarks The input data can be discarded after an openmpt_module_ext has been constructed successfully.
-  \since 0.3.0
-'/
-Declare Function openmpt_module_ext_create_from_memory(ByVal filedata As Const Any Ptr, ByVal filesize As UInteger, ByVal logfunc As openmpt_log_func, ByVal loguser As Any Ptr, ByVal errfunc As openmpt_error_func, ByVal erruser As Any Ptr, ByVal Error As Long Ptr, ByVal error_message As Const ZString Ptr Ptr, ByVal ctls As Const openmpt_module_initial_ctl Ptr) As openmpt_module_ext Ptr
-
-/'* \brief Unload a previously created openmpt_module_ext from memory.
-
-  \param mod_ext The module to unload.
-  \since 0.3.0
-'/
-Declare Sub openmpt_module_ext_destroy(ByVal mod_ext As openmpt_module_ext Ptr)
-
-/'* \brief Retrieve the openmpt_module handle from an openmpt_module_ext handle.
-
-  \param mod_ext The extension module handle to convert
-  \return An equivalent openmpt_module handle to pass to standard libopenmpt functions 
-  \since 0.3.0
-'/
-Declare Function openmpt_module_ext_get_module(ByVal mod_ext As openmpt_module_ext Ptr) As openmpt_module Ptr
-
-/'* Retrieve a libopenmpt extension.
-
-  \param mod_ext The module handle to work on.
-  \param interface_id The name of the extension interface to retrieve (e.g. LIBOPENMPT_EXT_C_INTERFACE_PATTERN_VIS).
-  \param interface Appropriate structure of interface function pointers which is to be filled by this function (e.g. a pointer to a openmpt_module_ext_interface_pattern_vis structure).
-  \param interface_size Size of the interface's structure of function pointers (e.g. sizeof(openmpt_module_ext_interface_pattern_vis)).
-  \return 1 on success, 0 if the interface was not found.
-  \since 0.3.0
-'/
-Declare Function openmpt_module_ext_get_interface(ByVal mod_ext As openmpt_module_ext Ptr, ByVal interface_id As Const ZString Ptr, ByVal interface As Any Ptr, ByVal interface_size As UInteger) As Long
-
-#define LIBOPENMPT_EXT_C_INTERFACE_PATTERN_VIS "pattern_vis"
-
-'* Pattern command type
-Const OPENMPT_MODULE_EXT_INTERFACE_PATTERN_VIS_EFFECT_TYPE_UNKNOWN = 0
-Const OPENMPT_MODULE_EXT_INTERFACE_PATTERN_VIS_EFFECT_TYPE_GENERAL = 1
-Const OPENMPT_MODULE_EXT_INTERFACE_PATTERN_VIS_EFFECT_TYPE_GLOBAL = 2
-Const OPENMPT_MODULE_EXT_INTERFACE_PATTERN_VIS_EFFECT_TYPE_VOLUME = 3
-Const OPENMPT_MODULE_EXT_INTERFACE_PATTERN_VIS_EFFECT_TYPE_PANNING = 4
-Const OPENMPT_MODULE_EXT_INTERFACE_PATTERN_VIS_EFFECT_TYPE_PITCH = 5
-
-Type openmpt_module_ext_interface_pattern_vis
-	/'* Get pattern command type for pattern highlighting
-
-	  \param mod_ext The module handle to work on.
-	  \param pattern The pattern whose data should be retrieved.
-	  \param row The row from which the data should be retrieved.
-	  \param channel The channel from which the data should be retrieved.
-	  \return The command type in the effect column at the given pattern position (see OPENMPT_MODULE_EXT_INTERFACE_PATTERN_VIS_EFFECT_TYPE_*)
-	  \sa get_pattern_row_channel_effect_type
-	'/
-	get_pattern_row_channel_volume_effect_type As Function(ByVal mod_ext As openmpt_module_ext Ptr, ByVal pattern As Long, ByVal row As Long, ByVal channel As Long) As Long
-
-	/'* Get pattern command type for pattern highlighting
-
-	  \param mod_ext The module handle to work on.
-	  \param pattern The pattern whose data should be retrieved.
-	  \param row The row from which the data should be retrieved.
-	  \param channel The channel from which the data should be retrieved.
-	  \return The command type in the effect column at the given pattern position (see OPENMPT_MODULE_EXT_INTERFACE_PATTERN_VIS_EFFECT_TYPE_*)
-	  \sa get_pattern_row_channel_volume_effect_type
-	'/
-	get_pattern_row_channel_effect_type As Function(ByVal mod_ext As openmpt_module_ext Ptr, ByVal pattern As Long, ByVal row As Long, ByVal channel As Long) As Long
-End Type
-
-#define LIBOPENMPT_EXT_C_INTERFACE_INTERACTIVE "interactive"
-
-Type openmpt_module_ext_interface_interactive
-	/'* Set the current ticks per row (speed)
-
-	  \param mod_ext The module handle to work on.
-	  \param speed The new tick count in range [1, 65535].
-	  \throws openmpt::exception Throws an exception derived from openmpt::exception if the speed is outside the specified range.
-	  \return 1 on success, 0 on failure.
-	  \sa openmpt_module_get_current_speed
-	'/
-	set_current_speed As Function(ByVal mod_ext As openmpt_module_ext Ptr, ByVal speed As Long) As Long
-
-	/'* Set the current module tempo
-
-	  \param mod_ext The module handle to work on.
-	  \param tempo The new tempo in range [32, 512]. The exact meaning of the value depends on the tempo mode used by the module.
-	  \return 1 on success, 0 on failure.
-	  \remarks The tempo may be reset by pattern commands at any time. Use set_tempo_factor to apply a tempo factor that is independent of pattern commands.
-	  \sa openmpt_module_get_current_tempo
-	'/
-	set_current_tempo As Function(ByVal mod_ext As openmpt_module_ext Ptr, ByVal tempo As Long) As Long
-
-	/'* Set the current module tempo factor without affecting playback pitch
-
-	  \param mod_ext The module handle to work on.
-	  \param factor The new tempo factor in range ]0.0, 4.0] - 1.0 means unmodified tempo.
-	  \return 1 on success, 0 on failure.
-	  \remarks Modifying the tempo without applying the same pitch factor using set_pitch_factor may cause rhythmic samples (e.g. drum loops) to go out of sync.
-	  \sa get_tempo_factor
-	'/
-	set_tempo_factor As Function(ByVal mod_ext As openmpt_module_ext Ptr, ByVal factor As Double) As Long
-
-	/'* Gets the current module tempo factor
-
-	  \param mod_ext The module handle to work on.
-	  \return The current tempo factor.
-	  \sa set_tempo_factor
-	'/
-	get_tempo_factor As Function(ByVal mod_ext As openmpt_module_ext Ptr) As Double
-
-	/'* Set the current module pitch factor without affecting playback speed
-
-	  \param mod_ext The module handle to work on.
-	  \param factor The new pitch factor in range ]0.0, 4.0] - 1.0 means unmodified pitch.
-	  \return 1 on success, 0 on failure.
-	  \remarks Modifying the pitch without applying the the same tempo factor using set_tempo_factor may cause rhythmic samples (e.g. drum loops) to go out of sync.
-	  \remarks To shift the pich by `n` semitones, the parameter can be calculated as follows: `2.0 ^ ( n / 12.0 )`
-	  \sa get_pitch_factor
-	'/
-	set_pitch_factor As Function(ByVal mod_ext As openmpt_module_ext Ptr, ByVal factor As Double) As Long
-
-	/'* Gets the current module pitch factor
-
-	  \param mod_ext The module handle to work on.
-	  \return The current pitch factor.
-	  \sa set_pitch_factor
-	'/
-	get_pitch_factor As Function(ByVal mod_ext As openmpt_module_ext Ptr) As Double
-
-	/'* Set the current global volume
-
-	  \param mod_ext The module handle to work on.
-	  \param volume The new global volume in range [0.0, 1.0]
-	  \return 1 on success, 0 on failure.
-	  \remarks The global volume may be reset by pattern commands at any time. Use openmpt_module_set_render_param to apply a global overall volume factor that is independent of pattern commands.
-	  \sa get_global_volume
-	'/
-	set_global_volume As Function(ByVal mod_ext As openmpt_module_ext Ptr, ByVal volume As Double) As Long
-
-	/'* Get the current global volume
-
-	  \param mod_ext The module handle to work on.
-	  \return The current global volume in range [0.0, 1.0]
-	  \sa set_global_volume
-	'/
-	get_global_volume As Function(ByVal mod_ext As openmpt_module_ext Ptr) As Double
-
-	/'* Set the current channel volume for a channel
-
-	  \param mod_ext The module handle to work on.
-	  \param channel The channel whose volume should be set, in range [0, openmpt_module_get_num_channels()[
-	  \param volume The new channel volume in range [0.0, 1.0]
-	  \return 1 on success, 0 on failure (channel out of range).
-	  \remarks The channel volume may be reset by pattern commands at any time.
-	  \sa get_channel_volume
-	'/
-	set_channel_volume As Function(ByVal mod_ext As openmpt_module_ext Ptr, ByVal channel As Long, ByVal volume As Double) As Long
-
-	/'* Get the current channel volume for a channel
-
-	  \param mod_ext The module handle to work on.
-	  \param channel The channel whose volume should be retrieved, in range [0, openmpt_module_get_num_channels()[
-	  \return The current channel volume in range [0.0, 1.0]
-	  \sa set_channel_volume
-	'/
-	get_channel_volume As Function(ByVal mod_ext As openmpt_module_ext Ptr, ByVal channel As Long) As Double
-
-	/'* Set the current mute status for a channel
-
-	  \param mod_ext The module handle to work on.
-	  \param channel The channel whose mute status should be set, in range [0, openmpt_module_get_num_channels()[
-	  \param mute The new mute status. true is muted, false is unmuted.
-	  \return 1 on success, 0 on failure (channel out of range).
-	  \sa get_channel_mute_status
-	'/
-	set_channel_mute_status As Function(ByVal mod_ext As openmpt_module_ext Ptr, ByVal channel As Long, ByVal mute As Long) As Long
-
-	/'* Get the current mute status for a channel
-
-	  \param mod_ext The module handle to work on.
-	  \param channel The channel whose mute status should be retrieved, in range [0, openmpt_module_get_num_channels()[
-	  \return The current channel mute status. true is muted, false is unmuted.
-	  \sa set_channel_mute_status
-	'/
-	get_channel_mute_status As Function(ByVal mod_ext As openmpt_module_ext Ptr, ByVal channel As Long) As Long
-
-	/'* Set the current mute status for an instrument
-
-	  \param mod_ext The module handle to work on.
-	  \param instrument The instrument whose mute status should be set, in range [0, openmpt_module_get_num_instruments()[ if openmpt_module_get_num_instruments is not 0, otherwise in [0, openmpt_module_get_num_samples()[
-	  \param mute The new mute status. true is muted, false is unmuted.
-	  \return 1 on success, 0 on failure (instrument out of range).
-	  \sa get_instrument_mute_status
-	'/
-	set_instrument_mute_status As Function(ByVal mod_ext As openmpt_module_ext Ptr, ByVal instrument As Long, ByVal mute As Long) As Long
-
-	/'* Get the current mute status for an instrument
-
-	  \param mod_ext The module handle to work on.
-	  \param instrument The instrument whose mute status should be retrieved, in range [0, openmpt_module_get_num_instruments()[ if openmpt_module_get_num_instruments is not 0, otherwise in [0, openmpt_module_get_num_samples()[
-	  \return The current instrument mute status. 1 is muted, 0 is unmuted, -1 means the instrument was out of range.
-	  \sa set_instrument_mute_status
-	'/
-	get_instrument_mute_status As Function(ByVal mod_ext As openmpt_module_ext Ptr, ByVal instrument As Long) As Long
-
-	/'* Play a note using the specified instrument
-
-	  \param mod_ext The module handle to work on.
-	  \param instrument The instrument that should be played, in range [0, openmpt_module_get_num_instruments()[ if openmpt_module_get_num_instruments is not 0, otherwise in [0, openmpt_module_get_num_samples()[
-	  \param note The note to play, in rage [0, 119]. 60 is the middle C.
-	  \param volume The volume at which the note should be triggered, in range [0.0, 1.0]
-	  \param panning The panning position at which the note should be triggered, in range [-1.0, 1.0], 0.0 is center.
-	  \return The channel on which the note is played. This can pe be passed to stop_note to stop the note. -1 means that no channel could be allocated and the note is not played.
-	  \sa stop_note
-	'/
-	play_note As Function(ByVal mod_ext As openmpt_module_ext Ptr, ByVal instrument As Long, ByVal note As Long, ByVal volume As Double, ByVal panning As Double) As Long
-
-	/'* Stop the note playing on the specified channel
-
-	  \param mod_ext The module handle to work on.
-	  \param channel The channel on which the note should be stopped.
-	  \return 1 on success, 0 on failure (channel out of range).
-	  \sa play_note
-	'/
-	stop_note As Function(ByVal mod_ext As openmpt_module_ext Ptr, ByVal channel As Long) As Long
-End Type
-
-End Extern
-
-/'* \brief Construct an openmpt_module_ext
-
-  \param file The FreeBASIC file handle to load from.
-  \param logfunc Logging function where warning and errors are written. May be NULL.
-  \param loguser Logging function user context. Used to pass any user-defined data associated with this module to the logging function.
-  \param errfunc Error function to define error behaviour. May be NULL.
-  \param erruser Error function user context. Used to pass any user-defined data associated with this module to the error function.
-  \param errorcode Pointer to an integer where an error may get stored. May be NULL.
-  \param error_message Pointer to a string pointer where an error message may get stored. May be NULL.
-  \param ctls A map of initial ctl values, see openmpt_module_get_ctls.
-  \return A pointer to the constructed openmpt_module, or NULL on failure.
-  \remarks The file handle can be closed after an openmpt_module has been constructed successfully.
-  \sa openmpt_module_ext_create
-'/
-Function openmpt_module_ext_create_from_fbhandle(_
-		ByVal file As Integer,_
-		ByVal logfunc As openmpt_log_func = 0,_
-		ByVal loguser As Any Ptr = 0,_
-		ByVal errfunc As openmpt_error_func = 0,_
-		ByVal erruser As Any Ptr = 0,_
-		ByVal errorcode As Long Ptr = 0,_
-		ByVal error_message As Const ZString Ptr Ptr = 0,_
-		ByVal ctls As Const openmpt_module_initial_ctl Ptr = 0) As openmpt_module_ext Ptr
-	Return openmpt_module_ext_create(openmpt_stream_get_file_callbacks(), Cast(FILE Ptr, FileAttr(file, fbFileAttrHandle)), logfunc, loguser, errfunc, erruser, errorcode, error_message, ctls)
-End Function
-
-/'* \brief Construct an openmpt_module_ext
-
-  \param filename The file to load from.
-  \param logfunc Logging function where warning and errors are written. May be NULL.
-  \param loguser Logging function user context. Used to pass any user-defined data associated with this module to the logging function.
-  \param errfunc Error function to define error behaviour. May be NULL.
-  \param erruser Error function user context. Used to pass any user-defined data associated with this module to the error function.
-  \param errorcode Pointer to an integer where an error may get stored. May be NULL.
-  \param error_message Pointer to a string pointer where an error message may get stored. May be NULL.
-  \param ctls A map of initial ctl values, see openmpt_module_get_ctls.
-  \return A pointer to the constructed openmpt_module, or NULL on failure.
-  \sa openmpt_module_ext_create
-'/
-Function openmpt_module_ext_create_from_filename(_
-		ByRef filename As String,_
-		ByVal logfunc As openmpt_log_func = 0,_
-		ByVal loguser As Any Ptr = 0,_
-		ByVal errfunc As openmpt_error_func = 0,_
-		ByVal erruser As Any Ptr = 0,_
-		ByVal errorcode As Long Ptr = 0,_
-		ByVal error_message As Const ZString Ptr Ptr = 0,_
-		ByVal ctls As Const openmpt_module_initial_ctl Ptr = 0) As openmpt_module_ext Ptr
-	Var file = fopen(filename, "rb")
-	Var retval = CPtr(openmpt_module Ptr, 0)
-	If(file <> 0) Then
-		retval = openmpt_module_ext_create(openmpt_stream_get_file_callbacks(), file, logfunc, loguser, errfunc, erruser, errorcode, error_message, ctls)
-		fclose(file)
-	EndIf
-	Return retval
-End Function

+ 0 - 17
libopenmpt.mod/openmpt/libopenmpt/doc/in_openmpt.txt

@@ -1,17 +0,0 @@
-
-in_openmpt
-==========
-
-in_openmpt is a module file (https://en.wikipedia.org/wiki/Module_file) input
-plugin for Winamp >= 2.0 (or compatible players). in_openmpt is based on
-libopenmpt.
-
-
-Installation
-------------
-
-"in_openmpt.dll" must be placed into the Winamp "Plugins" directory, and
-"openmpt-mpg123.dll" must be placed into the Winamp directory.
-
-
-See https://lib.openmpt.org/ for documentation, FAQ and other details.

+ 0 - 16
libopenmpt.mod/openmpt/libopenmpt/doc/xmp-openmpt.txt

@@ -1,16 +0,0 @@
-
-xmp-openmpt
-===========
-
-xmp-openmpt is a module file (https://en.wikipedia.org/wiki/Module_file) input
-plugin for XMPlay >= 3.8.0.0. xmp-openmpt is based on libopenmpt.
-
-
-Installation
-------------
-
-"xmp-openmpt.dll" and "openmpt-mpg123.dll" must both be placed into the XMPlay
-plugins directory.
-
-
-See https://lib.openmpt.org/ for documentation, FAQ and other details.

+ 0 - 780
libopenmpt.mod/openmpt/libopenmpt/dox/changelog.md

@@ -1,780 +0,0 @@
-
-Changelog {#changelog}
-=========
-
-For fully detailed change log, please see the source repository directly. This
-is just a high-level summary.
-
-### libopenmpt 0.5.0-pre
-
- *  [**New**] OggMod compressed FastTracker 2 XM (OXM) modules are now
-    supported.
- *  [**New**] libopenmpt C++: New API
-    `openmpt::module::module(std::vector<std::byte> data)`,
-    `openmpt::module::module(const std::byte * data, std::size_t size)`,
-    `openmpt::module::module(const std::byte * beg, const std::byte * end)`.
- *  [**New**] libopenmpt C++: New API
-    `openmpt::probe_file_header(flags, const std::byte * data, std::size_t size, filesize)`,
-    `openmpt::probe_file_header(flags, const std::byte * data, std::size_t size)`.
- *  [**New**] libopenmpt_ext C++: New API
-    `openmpt::module_ext::module_ext(std::vector<std::byte> data)`,
-    `openmpt::module_ext::module_ext(const std::byte * data, std::size_t size)`,
-    `openmpt::module_ext::module_ext(std::vector<std::uint8_t> data)`,
-    `openmpt::module_ext::module_ext(const std::uint8_t * data, std::size_t size)`.
-
- *  [**Change**] std::istream based file I/O has been speed up.
- *  [**Change**] Dependency on iconv on Linux has been removed.
-
- *  [**Regression**] foo_openmpt: foo_openmpt is discontinued. Please use
-    Kode54's fork foo_openmpt54:
-    <https://www.foobar2000.org/components/view/foo_openmpt54>.
- *  [**Regression**] Support for client code using C++11 or C++ 14 has been
-    removed. C++17 is now required to build libopenmpt client applications.
- *  [**Regression**] Support for building with C++11 or C++14 has been removed.
-    C++17 is now required to build libopenmpt.
- *  [**Regression**] Support for Visual Studio 2015 has been removed.
- *  [**Regression**] Support for GCC 4.8, 4.9, 5, 6 has been removed.
- *  [**Regression**] Support for Clang 3.6, 3.7, 3.8, 3.9, 4 has been removed.
- *  [**Regression**] Building with Android NDK older than NDK r18b is not
-    supported any more.
- *  [**Regression**] Windows XP and Windows Vista are no longer supported.
- *  [**Regression**] It is no longer possible to optionally use iconv for
-    character set conversions.
-
- *  [**Bug**] openmpt123: openmpt123 now honors the current locale and outputs
-    text appropriately.
- *  [**Bug**] openmpt123: Piping text output to other than console window
-    targets on Windows has been fixed.
-
-### libopenmpt 0.4.0
-
- *  [**New**] libopenmpt now includes emulation of the OPL chip and thus plays
-    OPL instruments in S3M, C67 and MPTM files. OPL chip emulation volume can be
-    changed with the new ctl `render.opl.volume_factor`.
- *  [**New**] libopenmpt now supports CDFM / Composer 670 module files.
- *  [**New**] Autotools `configure` and plain `Makefile` now honor the variable
-    `CXXSTDLIB_PCLIBSPRIVATE` which serves the sole purpose of listing the
-    standard library (or libraries) required for static linking. The contents of
-    this variable will be put in `libopenmpt.pc` `Libs.private` and used for
-    nothing else. See \ref libopenmpt_c_staticlinking .
- *  [**New**] foo_openmpt: foo_openmpt now also works on Windows XP.
- *  [**New**] libopenmpt Emscripten builds now ship with MP3 support by
-    default, based on minimp3 by Lion (github.com/lieff).
- *  [**New**] libopenmpt: New ctl `play.at_end` can be used to change what
-    happens when the song end is reached:
-     *  "fadeout": Fades the module out for a short while. Subsequent reads
-        after the fadeout will return 0 rendered frames. This is the default and
-        identical to the behaviour in previous libopenmpt versions. 
-     *  "continue": Returns 0 rendered frames when the song end is reached.
-        Subsequent reads will continue playing from the song start or loop
-        start. This can be used for custom loop logic, such as loop
-        auto-detection and longer fadeouts.
-     *  "stop": Returns 0 rendered frames when the song end is reached.
-        Subsequent reads will return 0 rendered frames.
- *  [**New**] Add new metadata fields `"originaltype"` and `"originaltype_long"`
-    which allow more clearly reflecting what is going on with converted formats
-    like MO3 and GDM.
- *  [**New**] `Makefile` `CONFIG=emscripten` now can generate WebAssembly via
-    the additional option `EMSCRIPTEN_TARGET=wasm`.
- *  [**New**] Compiling for DOS is now experimentally supported via DJGPP GCC
-    7.2 or later.
-
- *  [**Change**] minimp3: Instead of the LGPL-2.1-licensed minimp3 by KeyJ,
-    libopenmpt now uses the CC0-1.0-licensed minimp3 by Lion (github.com/lieff)
-    as a fallback if libmpg123 is unavailable. The `USE_MINIMP3` `Makefile`
-    option is gone and minimp3 will be used automatically in the `Makefile`
-    build system if libmpg123 is not available.
- *  [**Change**] openmpt123: openmpt123 now rejects `--output-type` in `--ui`
-    and `--batch` modes and also rejects `--output` in `--render` mode. These
-    combinations of options really made no sense and were rather confusing.
- *  [**Change**] Android NDK build system now uses libc++ (`c++_shared`) instead
-    of GNU libstdc++ (`gnustl_shared`), as recommended by Android NDK r16b.
- *  [**Change**] xmp-openmpt: `openmpt-mpg123.dll` is no longer optional and
-    must be placed into the same directory as `xmp-openmpt.dll`.
- *  [**Change**] in_openmpt: `openmpt-mpg123.dll` is no longer optional and must
-    be placed either into the directory of the player itself or into the same
-    directory as `in_openmpt.dll`. This is dependent on how the player loads its
-    plugins. For WinAMP 5, `openmpt-mpg123.dll` needs to be in the directory
-    which contains `winamp.exe`. `in_openmpt.dll` needs to be in the `Plugins`
-    directory.
- *  [**Change**] foo_openmpt: foo_openmpt is now packaged as a fb2k-component
-    package for easier installation.
- *  [**Change**] When building libopenmpt with MinGW-w64, it is now recommended
-    to use the posix thread model (as opposed to the win32 threading model),
-    because the former does support std::mutex while the latter does not. When
-    building with win32 threading model with the Autotools build system, it is
-    recommended to provide the `mingw-std-threads` package. Building libopenmpt
-    with MinGW-w64 without any `std::thread`/`std::mutex` support is deprecated
-    and support for such configurations will be removed in libopenmpt 0.5.
- *  [**Change**] `Makefile` `CONFIG=emscripten` now has 4 `EMSCRIPTEN_TARGET=`
-    settings: `wasm` generates WebAssembly, `asmjs128m` generates asm.js with a
-    fixed size 128MB heap, `asmjs` generates asm.js with a fixed default size
-    heap (as of Emscripten 1.38.11, this amounts to 16MB), `js` generates
-    JavaScript with dynamic heap growth and with compatibility for older VMs.
- *  [**Change**] libmodplug: Update public headers to libmodplug 0.8.8.5. This
-    adds support for kind-of automatic MODPLUG_EXPORT decoration on Windows.
-
- *  [**Regression**] Support for Clang 3.4, 3.5 has been removed.
- *  [**Regression**] Building with Android NDK older than NDK r16b is not
-    supported any more.
- *  [**Regression**] Support for Emscripten versions older than 1.38.5 has been
-    removed.
- *  [**Regression**] Support for libmpg123 older than 1.14.0 has been removed.
- *  [**Regression**] Using MediaFoundation to decode MP3 samples is no longer
-    supported. Use libmpg123 or minimp3 instead.
- *  [**Regression**] libmodplug: Support for emulating libmodplug 0.8.7 API/ABI
-    has been removed.
-
- *  [**Bug**] xmp-openmpt: Sample rate and number of output channels were not
-    applied correctly when using per-file settings.
- *  [**Bug**] Internal mixer state was not initialized properly when initially
-    rendering in 44100kHz stereo format.
- *  [**Bug**] openmpt123: Prevent libsdl2 and libsdl from being enabled at the
-    same time because they conflict with each other.
- *  [**Bug**] libmodplug: Setting `SNDMIX_NORESAMPLING` in the C++ API always
-    resulted in linear interpolation instead of nearest neighbour
-
- *  IT: In Compatible Gxx mode, allow sample changes next to a tone portamento
-    effect if a previous sample has already stopped playing.
- *  IT: Fix broken volume envelopes with negative values as found in breakdwn.it
-    by Elysis.
- *  MOD: Slides and delayed notes are executed on every repetition of a row with
-    row delay (fixes "ode to protracker").
- *  XM: If the sustain point of the panning envelope is reached before key-off,
-    it is never released.
- *  XM: Do not default recall volume / panning for delayed instrument-less notes
- *  XM :E60 loop bug was not considered in song length calucation.
- *  S3M: Notes without instrument number use previous note's sample offset.
- *  Tighten M15 and MOD file rejection heuristics.
- *  J2B: Ignore frequency limits from file header. Fixes Medivo.j2b, broken
-    since libopenmpt-0.2.6401-beta17.
- *  STM: More accurate tempo calculation.
- *  STM: Better support for early format revisions (no such files have been
-    found in the wild, though).
- *  STM: Last character of sample name was missing.
- *  SFX: Work around bad conversions of the "Operation Stealth" soundtrack by
-    turning pattern breaks into note stops.
- *  IMF: Filter cutoff was upside down and the cutoff range was too small.
- *  ParamEq plugin center frequency was not limited correctly.
- *  Keep track of active SFx macro during seeking.
- *  The "note cut" duplicate note action did not volume-ramp the previously
-    playing sample.
- *  A song starting with non-existing patterns could not be played.
- *  DSM: Support restart position and 16-bit samples.
- *  DTM: Import global volume.
- *  MOD: Support notes in octave 2, like in FastTracker 2 (fixes DOPE.MOD).
- *  Do not apply Amiga playback heuristics to MOD files that have clearly been
-    written with a PC tracker.
- *  MPTM: More logical release node behaviour.
- *  Subsong search is now less thorough. It could previously find many subsongs
-    that are technically correct (unplayed rows at the beginning of patterns
-    that have been jumped over due to pattern breaks), but so far no real-world
-    module that would require such a thorough subsong detection was found. The
-    old mechanism caused way more false positives than intended with real-world
-    modules, though.
- *  Restrict the unpacked size of compressed DMF, IT, MDL and MO3 samples to
-    avoid huge allocations with malformed small files.
-
-### libopenmpt 0.3 (2017-09-27)
-
- *  [**New**] New error handling functionality in the C API, which in particular
-    allows distinguishing potentially transient out-of-memory errors from parse
-    errors during module loading. 
- *  [**New**] New API `openmpt::module::get_selected_subsong()` (C++) and
-    `openmpt_module_get_selected_subsong()` (C).
- *  [**New**] Faster file header probing API `openmpt::probe_file_header()` and
-    `openmpt::probe_file_header_get_recommended_size` (C++), and
-    `openmpt_probe_file_header()`,
-    `openmpt_probe_file_header_without_filesize()`,
-    `openmpt_probe_file_header_from_stream()` and
-    `openmpt_probe_file_header_get_recommended_size()` (C).
- *  [**New**] New API `openmpt::could_open_probability()` (C++) and
-    `openmpt_could_open_probability()` (C). This fixes a spelling error in the
-    old 0.2 API.
- *  [**New**] openmpt123: openmpt123 can now open M3U, M3U8, M3UEXT, M3U8EXT and
-    PLSv2 playlists via the `--playlist` option.
- *  [**New**] openmpt123: openmpt123 now supports very fast file header probing
-    via the `--probe` option.
- *  [**New**] Libopenmpt now supports building for Windows 10 Universal (Windows
-    Store 8.2) APIs with MSVC, and also for the older Windows Runtime APIs with
-    MinGW-w64.
- *  [**New**] New API header `libopenmpt_ext.h` which implements the libopenmpt
-    extension APIs also for the C interface.
- *  [**New**] The Reverb effect (S99 in S3M/IT/MPTM, and X99 in XM) is now
-    implemented in libopenmpt.
- *  [**New**] For Amiga modules, a new resampler based on the Amiga's sound
-    characteristics has been added. It can be activated by passing the
-    `render.resampler.emulate_amiga` ctl with a value of `1`. Non-Amiga modules
-    are not affected by this, and setting the ctl overrides the resampler choice
-    specified by `OPENMPT_MODULE_RENDER_INTERPOLATIONFILTER_LENGTH` or
-    `openmpt::module::RENDER_INTERPOLATIONFILTER_LENGTH`. Support for the MOD
-    command E0x (Set LED Filter) is also available when the Amiga resampler is
-    enabled. 
-
- *  [**Change**] libopenmpt versioning changed and follows the more conventional
-    major.minor.patch as well as the recommendations of the
-    [SemVer](http://semver.org/) scheme now. In addition to the SemVer
-    requirements, pre-1.0.0 versions will also honor API and ABI stability in
-    libopenmpt (i.e. libopenmpt ignores SemVer Clause 4). 
- *  [**Change**] The output directories of the MSVC build system were changed to
-    `bin/vs2015-shared/x86-64-win7/` (and similar) layout which allows building
-    in the same tree with different compiler versions without overwriting other
-    outputs.
- *  [**Change**] The emscripten build now exports libopenmpt as 'libopenmpt'
-    instead of the default 'Module'.
- *  [**Change**] Android: The build system changed. The various Android.mk files
-    have been merged into a single one which can be controlled using command
-    line options.
- *  [**Change**] The `Makefile` build system now passes `std=c++11` to the
-    compiler by default. Older compilers may still work if you pass
-    `STDCXX=c++0x` to the `make` invocation.
- *  [**Change**] The `Makefile` option `ANCIENT=1` is gone.
- *  [**Change**] The optional dependencies on `libltdl` or `libdl` are gone.
-    They are no longer needed for any functionality.
-
- *  [**Regression**] Compiling client code using the C++ API now requires a
-    compiler running in C++11 mode.
- *  [**Regression**] Support for GCC 4.1, 4.2, 4.3, 4.4, 4.5, 4.6, 4.7 has been
-    removed.
- *  [**Regression**] Support for Clang 3.0, 3.1, 3.2, 3.3 has been removed.
- *  [**Regression**] Support for Emscripten versions older than 1.31.0 has been
-    removed.
- *  [**Regression**] Support for Android NDK versions older than 11 has been
-    removed.
- *  [**Regression**] Visual Studio 2008, 2010, 2012, 2013 support has been
-    removed.
- *  [**Regression**] Dynamic run-time loading of libmpg123 is no longer
-    supported. Libmpg123 must be linked at link-time now.
- *  [**Regression**] xmp-openmpt: xmp-openmpt now requires XMPlay 3.8 or later
-    and compiling xmp-openmpt requires an appropriate XMPlay SDK with
-    `XMPIN_FACE` >= `4`.
- *  [**Regression**] Support for libmpg123 older than 1.13.0 has been removed.
- *  [**Regression**] Un4seen unmo3 support has been removed.
-
- *  [**Bug**] C++ API: `openmpt::exception` did not define copy and move
-    constructors or copy and move assignment operators in libopenmpt 0.2. The
-    compiler-generated ones were not adequate though. libopenmpt 0.3 adds the
-    appropriate special member functions. This adds the respective symbol names
-    to the exported ABI, which, depending on the compiler, might or might not
-    have been there in libopenmpt 0.2. The possibly resulting possible ODR
-    violation only affects cases that did crash in the libopenmpt 0.2 API anyway
-    due to memory double-free, and does not cause any further problems in
-    practice for all known platforms and compilers.
- *  [**Bug**] The C API could crash instead of failing gracefully in
-    out-of-memory situations.
- *  [**Bug**] The test suite could fail on MacOSX or FreeBSD in non-fatal ways
-    when no locale was active.
- *  [**Bug**] `libopenmpt_stream_callbacks_fd.h` and
-    `libopenmpt_stream_callbacks_file.h` were missing in Windows development
-    packages.
- *  [**Bug**] libopenmpt on Windows did not properly guard against current
-    working directory DLL injection attacks.
- *  [**Bug**] localtime() was used to determine the version of Schism Tracker
-    used to save IT and S3M files. This function is not guaranteed to be
-    thread-safe by the standard and is now no longer used.
- *  [**Bug**] Possible crashes with malformed IT, ITP, AMS, MDL, MED, MPTM, PSM
-    and Startrekker files.
- *  [**Bug**] Possible hangs with malformed DBM, MPTM and PSM files.
- *  [**Bug**] Possible hangs with malformed files containing cyclic plugin
-    routings.
- *  [**Bug**] Excessive loading times with malformed ITP / truncated AMS files.
- *  [**Bug**] Plugins did not work correctly when changing the sample rate
-    between two render calls.
- *  [**Bug**] Possible NULL-pointer dereference read during obscure
-    out-of-memory situations while handling exceptions in the C API.
- *  [**Bug**] libmodplug: `libmodplug.pc` was wrong.
- *  [**Bug**] Cross-compiling libopenmpt with autotools for Windows now properly
-    sets `-municode` and `-mconsole` as well as all required Windows system
-    libraries.
- *  [**Bug**] foo_openmpt: Interpolation filter and volume ramping settings were
-    confused in previous versions. This version resets both to the defaults.
- *  [**Bug**] libmodplug: The CSoundFile::Read function in the emulated
-    libmodplug C++ API returned the wrong value, causing qmmp (and possibly
-    other software) to crash.
-
- *  Support for SoundTracker Pro II (STP) and Digital Tracker (DTM) modules.
- *  Increased accuracy of the sample position and sample rate to drift less when
-    playing very long samples.
- *  Various playback improvements for IT and XM files.
- *  Channel frequency could wrap around after some excessive portamento / down
-    in some formats since libopenmpt 0.2-beta17.
- *  Playback improvements for S3M files made with Impulse Tracker and
-    Schism Tracker.
- *  ParamEq plugin emulation didn't do anything at full gain (+15dB).
- *  All standard DMO effects are now also emulated on non-Windows and non-MSVC
-    systems.
- *  Added `libopenmpt_stream_callbacks_buffer.h` which adds
-    `openmpt_stream_callbacks` support for in-memory buffers, possibly even only
-    using a truncated prefix view into a bigger file which is useful for
-    probing.
- *  Avoid enabling some ProTracker-specific quirks for MOD files most likely
-    created with ScreamTracker 3.
- *  Tremolo effect only had half the intended strength in MOD files.
- *  Pattern loops ending on the last row a pattern were not executed correctly
-    in S3M files.
- *  Work-around for reading MIDI macros and plugin settings in some malformed IT
-    files written by old UNMO3 versions.
- *  Improve tracker detection in IT format.
- *  Playback fixes for 8-channel MED files
- *  Do not set note volume to 0 on out-of-range offset in XM files.
- *  Better import of some slide commands in SFX files.
- *  Sample 15 in "Crew Generation" by Necros requires short loops at the
-    beginning of the sample to not be ignored. Since we need to ignore them in
-    some (non-ProTracker) modules, we heuristically disable the old loop
-    sanitization behaviour based on the module channel count.
- *  Both normal and percentage offset in PLM files were handled as percentage
-    offset.
- *  MT2 files with instruments that had both sample and plugin assignments were
-    not read correctly.
- *  Some valid FAR files were rejected erroneously.
- *  Support for VBlank timing flag and comment field in PT36 files.
- *  Improved accuracy of vibrato command in DIGI / DBM files.
- *  STM: Add support for "WUZAMOD!" magic bytes and allow some slightly
-    malformed STM files to load which were previously rejected.
- *  Detect whether "hidden" patterns in the order list of SoundTracker modules
-    should be taken into account or not.
- *  Tighten heuristics for rejecting invalid 669, M15, MOD and ICE files and
-    loosen them in other places to allow some valid MOD files to load.
- *  Improvements to seeking: Channel panning was not always updated from
-    instruments / samples when seeking, and out-of-range global volume was not
-    applied correctly in some formats.
- *  seek.sync_samples=1 did not apply PTM reverse offset effect and the volume
-    slide part of combined volume slide + vibrato commands.
- *  If the order list was longer than 256 items and there was a pattern break
-    effect without a position jump on the last pattern of the sequence, it did
-    not jump to the correct restart order.
- *  `Makefile` has now explicit support for FreeBSD with no special option or
-    configuration required.
- *  openmpt123: Improved section layout in man page.
- *  libmodplug: Added all missing C++ API symbols that are accessible via the
-    public libmodplug header file.
- *  Autotools build system now has options `--disable-openmpt123`,
-    `--disable-tests` and `--disable-examples` which may be desireable when
-    cross-compiling.
- *  Windows binary packages now ship with libmpg123 included.
-
-### libopenmpt 0.2-beta20 (2016-08-07)
-
- *  [**Bug**] PSM loader was broken on big-endian platforms since forever.
- *  [**Bug**] `load.skip_samples` ctl did not work for PSM16 modules.
-
- *  There is a new `subsong` ctl, which can return the currently selected
-    subsong.
- *  More accurate ProTracker arpeggio wrap-around emulation.
- *  More accurate sample tuning in PSM16 files.
- *  Samples in DSM files were sometimes detuned and some pattern commands were
-    not imported correctly.
- *  More accurate import of MDL 7-bit panning command.
- *  Only import pattern commands supported by the UltraTracker version that was
-    used to save ULT files. Add support for command 5-C (end loop).
- *  DMF sample loop lengths were off by one.
- *  Unis 669 pan slide effect was too deep.
- *  Several valid (but slightly corrupted possibly due to disk failures or data
-    transfer errors) SoundTracker files were no longer loading since libopenmpt
-    0.2-beta18.
-
-### libopenmpt 0.2-beta19 (2016-07-23)
-
- *  [**Change**] libopenmpt now uses C++14 `[[deprecated]]` attribute instead
-    of compiler-specific solutions when appropriate.
- *  [**Change**] libopenmpt C++ header now uses C++11 `noexcept` instead of
-    C++98 `throw()` exception specification when supported. `throw()` is
-    deprecated since C++11. This does not change API or ABI as they are
-    equivalent. Use `LIBOPENMPT_ASSUME_CPLUSPLUS_NOEXCEPT` to override the
-    default.
- *  [**Change**] The preprocessor macro `LIBOPENMPT_ANCIENT_COMPILER_STDINT` is
-    gone. Please use `LIBOPENMPT_ASSUME_CPLUSPLUS_CSTDINT instead`.
-    Additionally, the typedefs moved from illegal namespace ::std into somewhat
-    less dangerous namespace ::openmpt::std. You can test
-    `#ifdef LIBOPENMPT_QUIRK_NO_CSTDINT` client-side to check whether
-    `libopenmpt.hpp` used the non-standard types. (Note: Of all supported
-    compilers, this change only affects the 3 compilers with only limited
-    support: MSVC 2008, GCC 4.1, GCC 4.2.)
-
- *  [**Bug**] xmp-openmpt: Crash when viewing sample texts.
-
- *  The public libopenmpt C++ header has auto-detection logic for the used C++
-    standard now. In case your client code compiler misreports the standard
-    version or you want to override it for other reasons,
-    `#define LIBOPENMPT_ASSUME_CPLUSPLUS` to the value of the standard version
-    you desire to be used. There is also a macro for each individual aspect,
-    like `LIBOPENMPT_ASSUME_CPLUSPLUS_CSTDINT`,
-    `LIBOPENMPT_ASSUME_CPLUSPLUS_DEPRECATED`,
-    `LIBOPENMPT_ASSUME_CPLUSPLUS_NOEXCEPT` which take precedence over the
-    general macro.
- *  Portamento with sample swap behaviour was wrong for ProTracker MODs.
- *  Rewritten loader and various playback fixes for MDL files.
- *  libopenmpt 0.2-beta18 broke import of many pattern commands in DBM, DMF and
-    ULT files.
- *  ADPCM samples in MOD files were broken since libopenmpt 0.2-beta17.
-
-### libopenmpt 0.2-beta18 (2016-07-11)
-
- *  [**Change**] openmpt123: Add PulseAudio output support. Autotools and
-    `Makefile` build systems now depend on `libpulse` and `libpulse-simple` by
-    default. Disable with `--without-pulseaudio` or `NO_PULSEAUDIO=1`
-    respectively. When enabled, PulseAudio will be the default output driver,
- *  [**Change**] xmp-openmpt: Settings are now stored in xmplay.ini like with
-    every other plugin.
-
- *  [**Regression**] openmpt123: Support for FLAC < 1.3.0 has been removed. FLAC
-    before 1.3.0 is broken beyond repair as it provides `assert.h` in the
-    include path.
-
- *  [**Bug**] Generated pkg-config file libopenmpt.pc by both `Makefile` and
-    Autotools build systems was totally broken.
- *  [**Bug**] libopenmpt no longer uses the non-thread-safe global std::rand()
-    function.
- *  [**Bug**] Sample loops in GDM modules did not work when using Emscripten.
- *  [**Bug**] XM and MO3 loaders could crash due to unaligned memory accesses.
- *  [**Bug**] Fixed incorrect handling of custom MPTM tunings on big endian
-    platforms.
- *  [**Bug**] Fixed various problems found with clang 3.8 static analyzer,
-    address sanitizer and undefined behaviour sanitizer.
- *  [**Bug**] File header probing functionality was broken for most formats.
- *  [**Bug**] With non-seekable streams, the entire file was almost always
-    cached even if it was not of any supported module type.
-
- *  Seeking in allsubsongs-mode now works correctly.
- *  openmpt123: Added subsong support.
- *  Various playback fixes for 669, IT, MT2 and MTM files.
- *  Some MOD files with more than 128 patterns (e.g. NIETNU.MOD) were not loaded
-    correctly.
- *  A new example `libopenmpt_example_c_probe` has been added which demonstrates
-    the usage and flexibility of openmpt_could_open_propability() in the C API
-    under various constraints.
-
-### libopenmpt 0.2-beta17 (2016-05-21)
-
- *  [**Change**] The Makefile and Autotools build systems now require to
-    explicitly specify `NO_LTDL=1` or `--without-ltdl` respectively if no
-    support for dynamic loading of third party libraries via libtool libltdl is
-    desired.
- *  [**Change**] In the Makefile build system option `USE_MO3` and the Autotools
-    build system option `--enable-mo3` are gone. Dynamic loading of un4seen
-    unmo3 is now always enabled when dynamic loading is possible and built-in
-    MO3 support is not possible because either a MP3 or a Vorbis decoder is
-    missing.
- *  [**Change**] The MSVC build system changed. The `libopenmptDLL` project is
-    gone. Use the new `ReleaseShared` configuration of the `libopenmpt` project
-    instead. libopenmpt now links against zlib by default. A separate project
-    with smaller footprint linking against miniz is still available as
-    `libopenmpt-small`.
- *  [**Change**] The constants used to query library information from
-    `openmpt_get_string()` and `openmpt::string::get()` (i.e. OPENMPT_STRING_FOO
-    and openmpt::string::FOO) have been deprecated because having syntactic
-    constants for theses keys makes extending the API in a backwards and
-    forwards compatible way harder than it should be. Please just use the string
-    literals directly.
- *  [**Change**] Deprecated API identifiers will now cause deprecation warnings
-    with MSVC, GCC and clang. `#define LIBOPENMPT_NO_DEPRECATE` to disable the
-    warnings.
- *  [**Change**] openmpt123: `--[no-]shuffle` option has been renamed to
-    `--[no-]randomize`. A new `--[no-]shuffle` option has been added which
-    shuffles randomly through the playlist as opposed to randomizing the
-    playlist upfront.
- *  [**Change**] Support for Un4seen unmo3 has generally been deprecated in
-    favour of the new internal mo3 decoder. Un4seen unmo3 support will be
-    removed on 2018-01-01.
-
- *  [**Bug**] Memory consumption during loading has been reduced by about 1/3 in
-    case a seekable input stream is provided (either via C API callback open
-    functions or via C++ API iostream constructors).
- *  [**Bug**] Some samples in AMS modules were detuned when using Emscripten.
- *  [**Bug**] Possible crash with excessive portamento down in some formats.
- *  [**Bug**] Possible crashes with malformed AMF, AMS, DBM, IT, MDL, MED, MPTM,
-    MT2, PSM and MMCMP-, XPK- and PP20-compressed files.
- *  [**Bug**] `openmpt::module::format_pattern_row_channel` with `width == 0`
-    was returning an empty string instead of an string with unconstrained
-    length.
-
- *  Support for ProTracker 3.6 IFF-style modules and SoundFX / MultiMedia Sound
-    (SFX / MMS) modules.
- *  libopenmpt now has support for DMO plugins on Windows when built with MSVC.
-    Additionally, the DMO Compression, Distortion, Echo, Gargle, ParamEQ and
-    WavesReverb DSPs are emulated on on all other platforms.
- *  libopenmpt now supports the DigiBooster Echo DSP.
- *  To avoid any of the aforementioned plugins to be used, the load.skip_plugins
-    ctl can be passed when loading a module.
- *  libopenmpt got native MO3 support with MP3 decoding either via libmpg123 or
-    MediaFoundation (on Windows 7 and up) and Vorbis decoding via libogg,
-    libvorbis, libvorbisfile or stb_vorbis.
- *  libopenmpt MSVC builds with Visual Studio 2010 or later on Windows 7 or
-    later now use an internal MO3 decoder with libogg, libvorbis, libvorbisfile,
-    and libmpg123 or minimp3 or MediaFoundation suppport by default. Visual
-    Studio 2008 builds still use unmo3.dll by default but also support the
-    built-in decoder in which case libmpg123 is required.
- *  libopenmpt with Makefile or Autotools build system can now also use
-    glibc/libdl instead of libtool/libltdl for dynamic loading of third-party
-    libraries. Options `NO_DL=1` and `--without-dl` have been added
-    respectively.
- *  The `Makefile` build system got 4 new options NO_MPG123, NO_OGG, NO_VORBIS,
-    NO_VORBISFILE. The default is to use the new dependencies automatically.
- *  The `Autotools` build system got 4 new options --without-mpg123,
-    --without-ogg, --without-vorbis, --without-vorbisfile. The default is to use
-    the new dependencies automatically.
- *  Makefile and Android builds got support for using minimp3 instead of
-    libmpg123. For Android, use `Android-minimp3-stbvorbis.mk`, for Makefile use
-    `USE_MINIMP3=1`. You have to download
-    [minimp3](http://keyj.emphy.de/minimp3/) yourself and put its contents into
-    `include/minimp3/`.
- *  `"source_url"`, `"source_date"` and `"build_compiler"` keys have been added
-    to `openmpt_string_get()` and `openmpt::string::get()`.
- *  openmpt123: Add new `--[no-]restart]` option which restarts the playlist
-    when finished.
- *  Improved Ultimate SoundTracker version detection heuristics.
- *  Playing a sample at a sample rate close to the mix rate could lead to small
-    clicks when using vibrato.
- *  More fine-grained internal legacy module compatibility settings to correctly
-    play back modules made with older versions of OpenMPT and a few other
-    trackers.
- *  The tail of compressed MDL samples was slightly off.
- *  Some probably hex-edited XM files (e.g. cybernostra weekend.xm) were not
-    loaded correctly.
- *  Countless other playback fixes for MOD, XM, S3M, IT and MT2 files.
-
-### libopenmpt 0.2-beta16 (2015-11-22)
-
- *  [**Change**] The Autotools build system does strict checking of all
-    dependencies now. Instead of best effort auto-magic detection of all
-    potentially optional dependencies, the default set of dependencies is now
-    enforced unless each individual dependency gets explicitely disabled via
-    `--without-foo` or `--disable-foo` `./configure` switches. Run
-    `./configure --help` for the full list of options.
-
- *  [**Bug**] Some MOD files were erroneously detected as 669 files.
- *  [**Bug**] Some malformed AMF files could result in very long loading times.
- *  [**Bug**] Fixed crashes in IMF and MT2 loaders.
- *  [**Bug**] MTM files generated by UNMO3 were not loaded properly.
- 
- *  Improved MTM playback.
- *  `make CONFIG=haiku` for Haiku has been added.
- *  Language bindings for FreeBASIC have been added (see
-    `libopenmpt/bindings/`).
-
-### libopenmpt 0.2-beta15 (2015-10-31)
-
- *  [**Change**] openmpt123: SDL2 is now supported and preferred to SDL1 if
-    available with the `Makefile` build system.
-
- *  [**Bug**] Emscripten support for older emscripten versions broke in -beta14.
-    These are now supported again when using `make CONFIG=emscripten-old`.
- *  [**Bug**] Fixed crashes in MED loader.
-
- *  Playback improvements and loader fixes for MOD, MT2 and MED.
-
-### libopenmpt 0.2-beta14 (2015-09-13)
-
- *  [**Change**] The C++ API example now uses the PortAudio C++ bindings
-    instead of the C API.
- *  [**Change**] Default compiler options for Emscripten have been changed to
-    more closely match the Emscripten recommendations.
-
- *  [**Bug**] Client code compilation with C89 compilers was broken in beta13.
- *  [**Bug**] Test suite failed on certain Emscripten/node.js combinations.
- *  [**Bug**] Fixed various crashes or hangs in DMF, OKT, PLM, IT and MPTM
-    loaders.
-
- *  Implemented error handling in the libopenmpt API examples.
- *  Various playback improvements and fixes for OKT, IT and MOD.
-
-### libopenmpt 0.2-beta13 (2015-08-16)
-
- *  [**Change**] The MSVC build system has been redone. Solutions are now
-    located in `build/vsVERSION/`.
-
- *  [**Bug**] get_current_channel_vu_left and get_current_channel_vu_right only
-    return the volume of the front left and right channels now.
-    get_current_channel_vu_rear_left and get_current_channel_vu_rear_right
-    do now actually work and return non-zero values.
- *  [**Bug**] Fix crashes and hangs in MED and MDL loaders and with some
-    truncated compressed IT samples.
- *  [**Bug**] Fix crash when playing extremely high-pitched samples.
-
- *  Completed C and C++ documentation
- *  Added new key for openmpt::module::get_metadata, "message_raw", which
-    returns an empty string if there is no song message rather than a list of
-    instrument names.
- *  in_openmpt: Support for compiling with VS2008.
- *  xmp-openmpt: Support for compiling with VS2008.
- *  in_openmpt: Add a more readable file information window.
-
-### libopenmpt 0.2-beta12 (2015-04-19)
-
- *  Playback fix when row delay effect is used together with offset command.
- *  A couple of fixes for the seek.sync_samples=1 case.
- *  IT compatibility fix for IT note delay.
- *  ProTracker MOD playback compatibility improvement.
-
-### libopenmpt 0.2-beta11 (2015-04-18)
-
- *  [**Change**] openmpt_stream_seek_func() now gets called with
-    OPENMPT_STREAM_SEEK_SET, OPENMPT_STREAM_SEEK_CUR and
-    OPENMPT_STREAM_SEEK_END whence parameter instead of SEEK_SET, SEEK_CUR and
-    SEEK_END. These are defined to 0, 1 and 2 respectively which corresponds to
-    the definition in all common C libraries. If your C library uses different
-    constants, this theoretically breaks binary compatibility. The old
-    libopenmpt code, however, never actually called the seek function, thus,
-    there will be no problem in practice.
- *  [**Change**] openmpt123: When both SDL1.2 and PortAudio are available,
-    SDL is now the preferred backend because SDL is more widespread and better
-    tested on all kinds of different platforms, and in general, SDL is just
-    more reliable.
-
- *  [**Bug**] libopenmpt now also compiles with GCC 4.3.
-
- *  libopenmpt now supports PLM (Disorder Tracker 2) files.
- *  Various playback improvements and fixes for IT, S3M, XM, MOD, PTM and 669
-    files.
-
-### libopenmpt 0.2-beta10 (2015-02-17)
-
- *  [**Change**] Makefile configuration filenames changed from
-    `build/make/Makefile.config.*` to `build/make/config-*.mk`.
- *  [**Change**] libopenmpt for Android now supports unmo3 from un4seen. See
-    `build/android_ndk/README.AndroidNDK.txt` for details.
-
- *  [**Bug**] Fix out-of-bounds read in mixer code for ProTracker-compatible
-    MOD files which was introduced back in r4223 / beta6.
-
- *  Vibrato effect was too weak in beta8 and beta9 in IT linear slide mode.
- *  Very small fine portamento was wrong in beta8 and beta9 in IT linear slide
-    mode.
- *  Tiny IT playback compatibility improvements.
- *  STM playback improvements.
-
-### libopenmpt 0.2-beta9 (2014-12-21)
-
- *  [**Bug**] libopenmpt_ext.hpp was missing from the Windows binary zip files.
-
-### libopenmpt 0.2-beta8 (2014-12-21)
-
- *  [**Change**] foo_openmpt: Settings are now accessible via foobar2000
-    advanced settings.
- *  [**Change**] Autotools based build now supports libunmo3. Specify
-    --enable-unmo3.
- *  [**Change**] Support for dynamic loading of libunmo3 on MacOS X.
- *  [**Change**] libopenmpt now uses libltld (from libtool) for dynamic loading
-    of libunmo3 on all non-Windows platforms.
- *  [**Change**] Support for older compilers:
-     *  GCC 4.1.x to 4.3.x (use `make ANCIENT=1`)
-     *  Microsoft Visual Studio 2008 (with latest Service Pack)
-        (see `build/vs2008`)
- *  [**Change**] libopenmpt_ext.hpp is now distributed by default. The API is
-    still considered experimental and not guaranteed to stay API or ABI
-    compatible.
- *  [**Change**] xmp-openmpt / in_openmpt: No more libopenmpt_settings.dll.
-    The settings dialog now uses a statically linked copy of MFC.
-
- *  [**Bug**] The -autotools tarballs were not working at all.
-
- *  Vastly improved MT2 loader.
- *  Improved S3M playback compatibility.
- *  Added openmpt::ext::interactive, an extension which adds a whole bunch of
-    new functionality to change playback in some way or another.
- *  Added possibility to sync sample playback when using
-    openmpt::module::set_position_* by setting the ctl value
-    seek.sync_samples=1  
- *  Support for "hidden" subsongs has been added.
-    They are accessible through the same interface as ordinary subsongs, i.e.
-    use openmpt::module::select_subsong to switch between any kind of subsongs.
- *  All subsongs can now be played consecutively by passing -1 as the subsong
-    index in openmpt::module::select_subsong.
- *  Added documentation for a couple of more functions.
-
-### libopenmpt 0.2-beta7 (2014-09-07)
-
- *  [**Change**] libopenmpt now has an GNU Autotools based build system (in
-    addition to all previously supported ways of building libopenmpt).
-    Autotools support is packaged separately as tarballs ending in
-    `-autotools.tar.gz`.
-
- *  [**Bug**] The distributed windows .zip file did not include pugixml.
-
- *  [**Regression**] openmpt123: Support for writing WavPack (.wv) files has
-    been removed.
-    
-    Reasoning:
-     1. WavPack support was incomplete and did not include support for writing
-        WavPack metadata at all.
-     2. openmpt123 already supports libSndFile which can be used to write
-        uncompressed lossless WAV files which can then be encoded to whatever
-        format the user desires with other tools.
-
-### libopenmpt 0.2-beta6 (2014-09-06)
-
- *  [**Change**] openmpt123: SDL is now also used by default if availble, in
-    addition to PortAudio.
- *  [**Change**] Support for emscripten is no longer experimental.
- *  [**Change**] libopenmpt itself can now also be compiled with VS2008.
-
- *  [**Bug**] Fix all known crashes on platforms that do not support unaligned
-    memory access.
- *  [**Bug**] openmpt123: Effect column was always missing in pattern display.
-
-### libopenmpt 0.2-beta5 (2014-06-15)
-
- *  [**Change**] Add unmo3 support for non-Windows builds.
- *  [**Change**] Namespace all internal functions in order to allow statically
-    linking against libopenmpt without risking duplicate symbols.
- *  [**Change**] Iconv is now completely optional and only used on Linux
-    systems by default.
- *  [**Change**] Added libopenmpt_example_c_stdout.c, an example without
-    requiring PortAudio.
- *  [**Change**] Add experimental support for building libopenmpt with
-    emscripten.
-
- *  [**Bug**] Fix ping-pong loop behaviour which broke in 0.2-beta3.
- *  [**Bug**] Fix crashes when accessing invalid patterns through libopenmpt
-    API.
- *  [**Bug**] Makefile: Support building with missing optional dependencies
-    without them being stated explicitely.
- *  [**Bug**] openmpt123: Crash when quitting while playback is stopped.
- *  [**Bug**] openmpt123: Crash when writing output to a file in interactive UI
-    mode.
- *  [**Bug**] openmpt123: Wrong FLAC output filename in --render mode.
-
- *  Various smaller playback accuracy improvements.
-
-### libopenmpt 0.2-beta4 (2014-02-25)
-
- *  [**Bug**] Makefile: Dependency tracking for the test suite did not work.
-
-### libopenmpt 0.2-beta3 (2014-02-21)
-
- *  [**Change**] The test suite is now built by default with Makefile based
-    builds. Use `TEST=0` to skip building the tests. `make check` runs the test
-    suite.
-
- *  [**Bug**] Crash in MOD and XM loaders on architectures not supporting
-    unaligned memory access.
- *  [**Bug**] MMCMP, PP20 and XPK unpackers should now work on non-x86 hardware
-    and implement proper bounds checking.
- *  [**Bug**] openmpt_module_get_num_samples() returned the wrong value.
- *  [**Bug**] in_openmpt: DSP plugins did not work properly.
- *  [**Bug**] in_openmpt/xmp-openmpt: Setting name for stereo separation was
-    misspelled. This version will revert your stereo separation settings to
-    default.
- *  [**Bug**] Crash when loading some corrupted modules with stereo samples.
-
- *  Support building on Android NDK.
- *  Avoid clicks in sample loops when using interpolation.
- *  IT filters are now done in integer instead of floating point. This improves
-    performance, especially on architectures with no or a slow FPU.
- *  MOD pattern break handling fixes.
- *  Various XM playback improvements.
- *  Improved and switchable dithering when using 16bit integer API.
-
-### libopenmpt 0.2-beta2 (2014-01-12)
-
- *  [**Bug**] MT2 loader crash.
- *  [**Bug**] Saving settings in in_openmpt and xmp-openmpt did not work.
- *  [**Bug**] Load libopenmpt_settings.dll also from below Plugins directory in
-    Winamp.
-
- *  DBM playback improvements.
-
-### libopenmpt 0.2-beta1 (2013-12-31)
-
- *  First release.
-

+ 0 - 122
libopenmpt.mod/openmpt/libopenmpt/dox/dependencies.md

@@ -1,122 +0,0 @@
-
-Dependencies {#dependencies}
-============
-
-
-Dependencies
-------------
-
-### libopenmpt
-
- *  Supported compilers for building libopenmpt:
-     *  **Microsoft Visual Studio 2017** or higher, running on a x86-64 build
-        system (other target systems are supported)
-     *  **GCC 7.1** or higher
-     *  **Clang 5** or higher
-     *  **MinGW-W64 7.1** or higher (it is recommended to preferably use
-        posix threading model as opposed to win32 threading model, or at least
-        have mingw-std-threads available otherwise)
-     *  **emscripten 1.38.5** or higher
-     *  **DJGPP GCC 7.2** or higher
-     *  any other **C++17 compliant** compiler (full standard compliant mode is
-        known to work with GCC >= 5.1 and Clang >= 3.8)
-        
-        libopenmpt makes the following assumptions about the C++ implementation
-        used for building:
-         *  `std::numeric_limits<unsigned char>::digits == 8` (enforced by
-            static_assert)
-         *  `sizeof(char) == 1` (enforced by static_assert)
-         *  existence of `std::uintptr_t` (enforced by static_assert)
-         *  in C++20 mode, `std::endian::little != std::endian::big` (enforced
-            by static_assert)
-         *  `wchar_t` encoding is either UTF-16 or UTF-32 (implicitly assumed)
-         *  representation of basic source character set is ASCII (implicitly
-            assumed)
-         *  representation of basic source character set is identical in char
-            and `wchar_t` (implicitly assumed)
-         *  libopenmpt also has experimental support for platforms without
-            `wchar_t` support like DJGPP
-        
-        libopenmpt does not rely on any specific implementation defined or
-        undefined behaviour (if it does, that's a bug in libopenmpt). In
-        particular:
-         *  `char` can be `signed` or `unsigned`
-         *  shifting signed values is implementation defined
-         *  `signed` integer overflow is undefined
-         *  `float` and `double` can be non-IEEE754
-
- *  Required compilers to use libopenmpt:
-     *  Any **C89** / **C99** / **C11** compatible compiler should work with
-        the C API as long as a **C99** compatible **stdint.h** is available.
-     *  Any **C++17** compatible compiler should work with the C++ API.
- *  **J2B** support requires an inflate (deflate decompression) implementation:
-     *  **zlib**
-     *  **miniz** can be used internally if no zlib is available.
- *  Built-in **MO3** support requires:
-     *  **libmpg123 >= 1.14.0**
-     *  **libogg**
-     *  **libvorbis**
-     *  **libvorbisfile**
-     *  Instead of libmpg123, **minimp3 by Lion (github.com/lieff)** can be used
-        internally to decode MP3 samples.
-     *  Instead of libogg, libvorbis and libvorbisfile, **stb_vorbis** can be
-        used internally to decode Vorbis samples.
- *  Building on Unix-like systems requires:
-     *  **GNU make**
-     *  **pkg-config**
- *  The Autotools-based build system requires:
-     *  **pkg-config 0.24** or higher
-     *  **zlib**
-     *  **doxygen**
-
-### openmpt123
-
- *  Supported compilers for building openmpt123:
-     *  **Microsoft Visual Studio 2017** or higher, running on a x86-64 build
-        system (other target systems are supported)
-     *  **GCC 7.1** or higher
-     *  **Clang 5** or higher
-     *  **MinGW-W64 7.1** or higher
-     *  **DJGPP GCC 7.2** or higher
-     *  any **C++17 compliant** compiler
- *  Live sound output requires one of:
-     *  **PulseAudio**
-     *  **SDL 2**
-     *  **SDL 1.2**
-     *  **PortAudio v19**
-     *  **Win32**
-     *  **liballegro 4.2** on DJGPP/DOS
-
-
-Optional dependencies
----------------------
-
-### libopenmpt
-
- *  **doxygen 1.8** or higher is required to build the documentation.
-
-### openmpt123
-
- *  Rendering to PCM files can use:
-     *  **FLAC 1.2** or higher
-     *  **libsndfile**
-     *  **Win32** for WAVE
-     *  raw PCM has no external dependencies
- *  **help2man** is required to build the documentation.
-
-
-Source packages
----------------
- 
-Building the source packages additionally requires:
- *  7z (7-zip)
- *  autoconf
- *  autoconf-archive
- *  automake
- *  gzip
- *  help2man
- *  libtool
- *  subversion
- *  tar
- *  xpath (libxml-xpath-perl)
- *  zip

+ 0 - 42
libopenmpt.mod/openmpt/libopenmpt/dox/index.dox

@@ -1,42 +0,0 @@
-
-/*!
- * \mainpage Contents
- *
- * libopenmpt is a cross-platform C++ and C library to decode <a href="https://en.wikipedia.org/wiki/Module_file">tracked music files (modules)</a> into a raw PCM audio stream.
- *
- * libopenmpt is based on the player code of the Open ModPlug Tracker project (OpenMPT, <a href="https://openmpt.org/">https://openmpt.org/</a>)
- *
- * \section toc Contents
- * - \ref quickstart "Quick Start"
- * - \ref md_README "README"
- * - \ref dependencies "Dependencies"
- * - \ref packaging "Packaging"
- * - \ref md_doc_contributing "Contributing"
- * - \ref md_doc_libopenmpt_styleguide "Style Guide"
- * - \ref tests "Tests"
- * - \ref changelog "Changelog"
- * - \ref md_doc_module_formats "Implementing new Module Formats"
- * - \ref todo "TODO"
- * \subsection toc_apis APIs
- * - libopenmpt
- *   - \ref libopenmpt "Common Details"
- * - libopenmpt C++
- *   - \ref libopenmpt_cpp_overview "Overview"
- *   - \ref libopenmpt_cpp "Details"
- * - libopenmpt C
- *   - \ref libopenmpt_c_overview "Overview"
- *   - \ref libopenmpt_c "Details"
- * - libopenmpt_ext C++
- *   - \ref libopenmpt_ext_cpp_overview "Overview"
- *   - \ref libopenmpt_ext_cpp "Details"
- * - libopenmpt_ext C
- *   - \ref libopenmpt_ext_c_overview "Overview"
- *   - \ref libopenmpt_ext_c "Details"
- *
- * \section toc_website Website
- * https://lib.openmpt.org/
- *
- * \section toc_license License
- * \include LICENSE
- *
- */

+ 0 - 38
libopenmpt.mod/openmpt/libopenmpt/dox/packaging.md

@@ -1,38 +0,0 @@
-Packaging {#packaging}
-=========
-
-
-Packaging
----------
-
-
-### Packaging recommendations for distribution package maintainers
-
- *  libopenmpt (since 0.3) uses SemVer 2.0.0 versioning. See
-    [semver.org](https://semver.org/spec/v2.0.0.html). Clause 4 is ignored for
-    libopenmpt, which means that libopenmpt will also provide API/ABI
-    compatbility semantics for pre-1.0.0 versions as required by SemVer 2.0.0
-    only for post-1.0.0 versions. The SemVer versioning scheme is incompatible
-    with Debian/Ubuntu package versions, however it can easily be processed to
-    be compatible by replacing '-' (hyphen) with '~' (tilde). It is recommended
-    that you use this exact transformation if required.
- *  Use the autotools source package.
- *  Use the default set of dependencies required by the autotools package.
- *  Read \ref libopenmpt_c_staticlinking and thus possibly pass
-    `CXXSTDLIB_PCLIBSPRIVATE` variable to `configure` if appropriate and/or
-    desired.
- *  Run the test suite in your build process.
- *  Send any build system improvement patches upstream.
- *  Do not include the libmodplug emulation layer in the default libopenmpt
-    binary package. Either do not package it at all, or provide a separate
-    package named libopenmpt-modplug or libmodplug-openmpt (or similar), which
-    depends on libopenmpt, provides libmodplug, and conflicts with original
-    libmodplug.
- *  Split openmpt123 into its own binary package because it has more
-    dependencies than libopenmpt itself.
- *  Consider providing an additional openmpt123 package (in addition to the
-    default openmpt123 package with all audio output drivers), built with fewer
-    audio output drivers so it does not transitively depend on X11. Name that
-    package and its executable openmpt123-nox (or whatever else may be common
-    practice in your distribution).
-

+ 0 - 70
libopenmpt.mod/openmpt/libopenmpt/dox/quickstart.md

@@ -1,70 +0,0 @@
-
-Quick Start {#quickstart}
-===========
-
-
-### Autotools-based
-
- 1. Grab a `libopenmpt-VERSION.autotools.tar.gz` tarball.
- 2. Get dependencies:
-     -  **gcc >= 7.1** or **clang >= 5**
-     -  **pkg-config >= 0.24**
-     -  **zlib**
-     -  **libogg**, **libvorbis**, **libvorbisfile**
-     -  **libmpg123 >= 1.14.0**
-     -  **doxygen >= 1.8**
-     -  **libpulse**, **libpulse-simple** (required only by openmpt123)
-     -  **portaudio-v19** (required only by openmpt123)
-     -  **libFLAC** (required only by openmpt123)
-     -  **libsndfile** (required only by openmpt123)
- 3. *Optional*:
-     -  **libSDL >= 1.2.x** (required only by openmpt123)
- 4. Run:
-    
-        ./configure
-        make
-        make check
-        sudo make install
-
-### Windows
-
- 1. Get dependencies:
-     -  **Microsoft Visual Studio >= 2017**
- 2. *Optionally* get dependencies:
-     -  **Winamp SDK**
-     -  **XMPlay SDK**
- 3. Checkout `https://source.openmpt.org/svn/openmpt/trunk/OpenMPT/` .
- 4. Open `build\vs2015\openmpt123.sln` or `build\vs2015\libopenmpt.sln` or `build\vs2015\xmp-openmpt.sln` or `build\vs2015\in_openmpt.sln` in *Microsoft Visual Studio 2015*.
- 5. Select appropriate configuration and build. Binaries are generated in `bin\`
- 6. Drag a module onto `openmpt123.exe` or copy the player plugin DLLs (`in_openmpt.dll` or `xmp-openmpt.dll`) into the respective player directory.
-
-### Unix-like
-
- 1. Get dependencies:
-     -  **GNU make**
-     -  **gcc >= 5.1** or **clang >= 3.8**
-     -  **pkg-config**
-     -  **zlib**
-     -  **libogg**, **libvorbis**, **libvorbisfile**
-     -  **libmpg123 >= 1.14.0**
-     -  **libpulse**, **libpulse-simple** (required only by openmpt123)
-     -  **portaudio-v19** (required only by openmpt123)
-     -  **libFLAC** (required only by openmpt123)
-     -  **libsndfile** (required only by openmpt123)
- 2. *Optional*:
-     -  **libSDL >= 1.2.x** (required only by openmpt123)
-     -  **doxygen >= 1.8**
-     -  **help2man**
- 3. Run:
-    
-        svn checkout https://source.openmpt.org/svn/openmpt/trunk/OpenMPT/ openmpt-trunk
-        cd openmpt-trunk
-        make clean
-        make
-        make doc
-        make check
-        sudo make install         # installs into /usr/local by default
-        sudo make install-doc     # installs into /usr/local by default
-        sudo ldconfig             # required on some systems (i.e. Linux)
-        openmpt123 $SOMEMODULE
-

+ 0 - 44
libopenmpt.mod/openmpt/libopenmpt/dox/tests.md

@@ -1,44 +0,0 @@
-
-Tests {#tests}
-=====
-
-
-libopenmpt provides some basic unit tests that check the platform for general
-sanity and do some basic internal functionality testing. The test suite
-requires a special libopenmpt build that includes file saving functionality
-which is not included in normal builds. This is handled by all provided build
-systems automatically.
-
-### Running Tests
-
-#### On Unix-like systems
-
-Compile with
-
-    make $YOURMAKEOPTIONS clean
-    make $YOURMAKEOPTIONS
-
-and run
-
-    make $YOURMAKEOPTIONS check
-
-As the build system retains no state between make invocations, you have to
-provide your make options on every make invocation.
-
-#### Autotools-based build system
-
-    ./configure
-    make check
-
-#### On Windows
-
-Using Visual Studio 20??, compile
-
-    build\vs20??\libopenmpt_test.sln
-
-and run
-
-    bin\$ARCH\libopenmpt_test.exe
-
-from the root of the source tree.
-

+ 0 - 8
libopenmpt.mod/openmpt/libopenmpt/dox/todo.md

@@ -1,8 +0,0 @@
-
-TODO {#todo}
-====
-
-
-See the roadmap in the bug tracker at
-[https://bugs.openmpt.org/roadmap_page.php](https://bugs.openmpt.org/roadmap_page.php).
-

+ 0 - 500
libopenmpt.mod/openmpt/libopenmpt/in_openmpt.cpp

@@ -1,500 +0,0 @@
-/*
- * in_openmpt.cpp
- * --------------
- * Purpose: libopenmpt winamp input plugin implementation
- * Notes  : (currently none)
- * Authors: OpenMPT Devs
- * The OpenMPT source code is released under the BSD license. Read LICENSE for more details.
- */
-
-#ifndef NO_WINAMP
-
-#if defined(_MFC_VER) || 1
-#ifndef _CRT_SECURE_NO_WARNINGS
-#define _CRT_SECURE_NO_WARNINGS
-#endif
-#ifndef _WIN32_WINNT
-#define _WIN32_WINNT 0x0501 // _WIN32_WINNT_WINXP
-#endif
-#define _AFX_NO_MFC_CONTROLS_IN_DIALOGS // Avoid binary bloat from linking unused MFC controls
-#define NOMINMAX
-#include <afxwin.h>
-#include <afxcmn.h>
-#include <windows.h>
-#endif // _MFC_VER
-
-#ifdef LIBOPENMPT_BUILD_DLL
-#undef LIBOPENMPT_BUILD_DLL
-#endif
-
-#ifdef _MSC_VER
-#ifndef _CRT_SECURE_NO_WARNINGS
-#define _CRT_SECURE_NO_WARNINGS
-#endif
-#ifndef _SCL_SECURE_NO_WARNINGS
-#define _SCL_SECURE_NO_WARNINGS
-#endif
-#endif // _MSC_VER
-
-#include "libopenmpt.hpp"
-
-#include "libopenmpt_plugin_gui.hpp"
-
-#include "svn_version.h"
-#if defined(OPENMPT_VERSION_REVISION)
-static const char * in_openmpt_string = "in_openmpt " OPENMPT_API_VERSION_STRING "." OPENMPT_API_VERSION_STRINGIZE(OPENMPT_VERSION_REVISION);
-#else
-static const char * in_openmpt_string = "in_openmpt " OPENMPT_API_VERSION_STRING;
-#endif
-
-#ifndef NOMINMAX
-#define NOMINMAX
-#endif
-#include <windows.h>
-
-#define UNICODE_INPUT_PLUGIN
-#include "winamp/Winamp/IN2.H"
-#include "winamp/Winamp/wa_ipc.h"
-
-#include <algorithm>
-#include <fstream>
-#include <iostream>
-#include <iterator>
-#include <sstream>
-
-#define BPS 16
-
-#define WINAMP_DSP_HEADROOM_FACTOR 2
-#define WINAMP_BUFFER_SIZE_FRAMES  576
-
-#define WM_OPENMPT_SEEK (WM_USER+3)
-
-#define SHORT_TITLE "in_openmpt"
-
-static void apply_options();
-
-static std::string StringEncode( const std::wstring &src, UINT codepage )
-{
-	int required_size = WideCharToMultiByte( codepage, 0, src.c_str(), -1, NULL, 0, NULL, NULL );
-	if(required_size <= 0)
-	{
-		return std::string();
-	}
-	std::vector<CHAR> encoded_string( required_size );
-	WideCharToMultiByte( codepage, 0, src.c_str(), -1, &encoded_string[0], encoded_string.size(), NULL, NULL );
-	return &encoded_string[0];
-}
-
-static std::wstring StringDecode( const std::string & src, UINT codepage )
-{
-	int required_size = MultiByteToWideChar( codepage, 0, src.c_str(), -1, NULL, 0 );
-	if(required_size <= 0)
-	{
-		return std::wstring();
-	}
-	std::vector<WCHAR> decoded_string( required_size );
-	MultiByteToWideChar( codepage, 0, src.c_str(), -1, &decoded_string[0], decoded_string.size() );
-	return &decoded_string[0];
-}
-
-template <typename Tstring, typename Tstring2, typename Tstring3>
-static inline Tstring StringReplace( Tstring str, const Tstring2 & oldStr_, const Tstring3 & newStr_ ) {
-	std::size_t pos = 0;
-	const Tstring oldStr = oldStr_;
-	const Tstring newStr = newStr_;
-	while ( ( pos = str.find( oldStr, pos ) ) != Tstring::npos ) {
-		str.replace( pos, oldStr.length(), newStr );
-		pos += newStr.length();
-	}
-	return str;
-}
-
-struct self_winamp_t {
-	std::vector<char> filetypes_string;
-	libopenmpt::plugin::settings settings;
-	int samplerate;
-	int channels;
-	std::wstring cached_filename;
-	std::wstring cached_title;
-	int cached_length;
-	std::wstring cached_infotext;
-	std::int64_t decode_position_frames;
-	openmpt::module * mod;
-	HANDLE PlayThread;
-	DWORD PlayThreadID;
-	bool paused;
-	std::vector<std::int16_t> buffer;
-	std::vector<std::int16_t> interleaved_buffer;
-	self_winamp_t() : settings(TEXT(SHORT_TITLE), true) {
-		filetypes_string.clear();
-		settings.changed = apply_options;
-		settings.load();
-		std::vector<std::string> extensions = openmpt::get_supported_extensions();
-		for ( std::vector<std::string>::iterator ext = extensions.begin(); ext != extensions.end(); ++ext ) {
-			std::copy( (*ext).begin(), (*ext).end(), std::back_inserter( filetypes_string ) );
-			filetypes_string.push_back('\0');
-			std::copy( SHORT_TITLE, SHORT_TITLE + std::strlen(SHORT_TITLE), std::back_inserter( filetypes_string ) );
-			filetypes_string.push_back('\0');
-		}
-		filetypes_string.push_back('\0');
-		samplerate = settings.samplerate;
-		channels = settings.channels;
-		cached_filename = std::wstring();
-		cached_title = std::wstring();
-		cached_length = 0;
-		cached_infotext = std::wstring();
-		decode_position_frames = 0;
-		mod = 0;
-		PlayThread = 0;
-		PlayThreadID = 0;
-		paused = false;
-		buffer.resize( WINAMP_BUFFER_SIZE_FRAMES * channels );
-		interleaved_buffer.resize( WINAMP_BUFFER_SIZE_FRAMES * channels * WINAMP_DSP_HEADROOM_FACTOR );
-	}
-	~self_winamp_t() {
-		return;
-	}
-};
-
-static self_winamp_t * self = 0;
-
-static void apply_options() {
-	if ( self->mod ) {
-		self->mod->set_repeat_count( self->settings.repeatcount );
-		self->mod->set_render_param( openmpt::module::RENDER_MASTERGAIN_MILLIBEL, self->settings.mastergain_millibel );
-		self->mod->set_render_param( openmpt::module::RENDER_STEREOSEPARATION_PERCENT, self->settings.stereoseparation );
-		self->mod->set_render_param( openmpt::module::RENDER_INTERPOLATIONFILTER_LENGTH, self->settings.interpolationfilterlength );
-		self->mod->set_render_param( openmpt::module::RENDER_VOLUMERAMPING_STRENGTH, self->settings.ramping );
-		self->mod->ctl_set( "render.resampler.emulate_amiga", self->settings.use_amiga_resampler ? "1" : "0" );
-	}
-	self->settings.save();
-}
-
-extern In_Module inmod;
-
-static DWORD WINAPI DecodeThread( LPVOID );
-
-static std::wstring generate_infotext( const std::wstring & filename, const openmpt::module & mod ) {
-	std::wostringstream str;
-	str << L"filename: " << filename << std::endl;
-	str << L"duration: " << mod.get_duration_seconds() << L"seconds" << std::endl;
-	std::vector<std::string> metadatakeys = mod.get_metadata_keys();
-	for ( std::vector<std::string>::iterator key = metadatakeys.begin(); key != metadatakeys.end(); ++key ) {
-		if ( *key == "message_raw" ) {
-			continue;
-		}
-		str << StringDecode( *key, CP_UTF8 ) << L": " << StringDecode( mod.get_metadata(*key), CP_UTF8 ) << std::endl;
-	}
-	return str.str();
-}
-
-static void config( HWND hwndParent ) {
-	libopenmpt::plugin::gui_edit_settings( &self->settings, hwndParent, TEXT(SHORT_TITLE) );
-	apply_options();
-}
-
-static void about( HWND hwndParent ) {
-	std::ostringstream about;
-	about << SHORT_TITLE << " version " << openmpt::string::get( "library_version" ) << " " << "(built " << openmpt::string::get( "build" ) << ")" << std::endl;
-	about << " Copyright (c) 2013-2019 OpenMPT developers (https://lib.openmpt.org/)" << std::endl;
-	about << " OpenMPT version " << openmpt::string::get( "core_version" ) << std::endl;
-	about << std::endl;
-	about << openmpt::string::get( "contact" ) << std::endl;
-	about << std::endl;
-	about << "Show full credits?" << std::endl;
-	if ( MessageBox( hwndParent, StringDecode( about.str(), CP_UTF8 ).c_str(), TEXT(SHORT_TITLE), MB_ICONINFORMATION | MB_YESNOCANCEL | MB_DEFBUTTON1 ) != IDYES ) {
-		return;
-	}
-	std::ostringstream credits;
-	credits << openmpt::string::get( "credits" );
-	libopenmpt::plugin::gui_show_file_info( hwndParent, TEXT(SHORT_TITLE), StringReplace( StringDecode( credits.str(), CP_UTF8 ), L"\n", L"\r\n" ) );
-}
-
-static void init() {
-	if ( !self ) {
-		self = new self_winamp_t();
-		inmod.FileExtensions = &(self->filetypes_string[0]);
-	}
-}
-
-static void quit() {
-	if ( self ) {
-		inmod.FileExtensions = NULL;
-		delete self;
-		self = 0;
-	}
-}
-
-static int isourfile( const in_char * fn ) {
-	return 0;
-}
-
-static int play( const in_char * fn ) {
-	if ( !fn ) {
-		return -1;
-	}
-	try {
-		std::ifstream s( fn, std::ios::binary );
-		std::map< std::string, std::string > ctls;
-		ctls["seek.sync_samples"] = "1";
-		self->mod = new openmpt::module( s, std::clog, ctls );
-		self->cached_filename = fn;
-		self->cached_title = StringDecode( self->mod->get_metadata( "title" ), CP_UTF8 );
-		self->cached_length = static_cast<int>( self->mod->get_duration_seconds() * 1000.0 );
-		self->cached_infotext = generate_infotext( self->cached_filename, *self->mod );
-		apply_options();
-		self->samplerate = self->settings.samplerate;
-		self->channels = self->settings.channels;
-		int maxlatency = inmod.outMod->Open( self->samplerate, self->channels, BPS, -1, -1 );
-		std::ostringstream str;
-		str << maxlatency;
-		inmod.SetInfo( self->mod->get_num_channels(), self->samplerate/1000, self->channels, 1 );
-		inmod.SAVSAInit( maxlatency, self->samplerate );
-		inmod.VSASetInfo( self->channels, self->samplerate );
-		inmod.outMod->SetVolume( -666 );
-		inmod.outMod->SetPan( 0 );
-		self->paused = false;
-		self->decode_position_frames = 0;
-		self->PlayThread = CreateThread( NULL, 0, DecodeThread, NULL, 0, &self->PlayThreadID );
-		return 0;
-	} catch ( ... ) {
-		if ( self->mod ) {
-			delete self->mod;
-			self->mod = 0;
-		}
-		return -1;
-	}
-}
-
-static void pause() {
-	self->paused = true;
-	inmod.outMod->Pause( 1 );
-}
-
-static void unpause() {
-	self->paused = false;
-	inmod.outMod->Pause( 0 );
-}
-
-static int ispaused() {
-	return self->paused ? 1 : 0;
-}
-
-static void stop() {
-	PostThreadMessage( self->PlayThreadID, WM_QUIT, 0, 0 );
-	WaitForSingleObject( self->PlayThread, INFINITE );
-	CloseHandle( self->PlayThread );
-	self->PlayThread = 0;
-	self->PlayThreadID = 0;
-	delete self->mod;
-	self->mod = 0;
-	inmod.outMod->Close();
-	inmod.SAVSADeInit();
-}
-
-static int getlength() {
-	return self->cached_length;
-}
-
-static int getoutputtime() {
-	//return (int)( self->decode_position_frames * 1000 / self->mod->get_render_param( openmpt::module::RENDER_SAMPLERATE_HZ ) /* + ( inmod.outMod->GetOutputTime() - inmod.outMod->GetWrittenTime() ) */ );
-	return inmod.outMod->GetOutputTime();
-}
-
-static void setoutputtime( int time_in_ms ) {
-	PostThreadMessage( self->PlayThreadID, WM_OPENMPT_SEEK, 0, time_in_ms );
-}
-
-static void setvolume( int volume ) {
-	inmod.outMod->SetVolume( volume );
-}
-
-static void setpan( int pan ) { 
-	inmod.outMod->SetPan( pan );
-}
-
-static int infobox( const in_char * fn, HWND hWndParent ) {
-	if ( fn && fn[0] != '\0' && self->cached_filename != std::wstring(fn) ) {
-		try {
-			std::ifstream s( fn, std::ios::binary );
-			openmpt::module mod( s );
-			libopenmpt::plugin::gui_show_file_info( hWndParent, TEXT(SHORT_TITLE), StringReplace( generate_infotext( fn, mod ), L"\n", L"\r\n" ) );
-		} catch ( ... ) {
-		}
-	} else {
-		libopenmpt::plugin::gui_show_file_info( hWndParent, TEXT(SHORT_TITLE), StringReplace( self->cached_infotext, L"\n", L"\r\n" ) );
-	}
-	return 0;
-}
-
-static void getfileinfo( const in_char * filename, in_char * title, int * length_in_ms ) {
-	if ( !filename || *filename == '\0' ) {
-		if ( length_in_ms ) {
-			*length_in_ms = self->cached_length;
-		}
-		if ( title ) {
-			std::wstring truncated_title = self->cached_title;
-			if ( truncated_title.length() >= GETFILEINFO_TITLE_LENGTH ) {
-				truncated_title.resize( GETFILEINFO_TITLE_LENGTH - 1 );
-			}
-			wcscpy( title, truncated_title.c_str() );
-		}
-	} else {
-		try {
-			std::ifstream s( filename, std::ios::binary );
-			openmpt::module mod( s );
-			if ( length_in_ms ) {
-				*length_in_ms = static_cast<int>( mod.get_duration_seconds() * 1000.0 );
-			}
-			if ( title ) {
-				std::wstring truncated_title = StringDecode( mod.get_metadata("title"), CP_UTF8 );
-				if ( truncated_title.length() >= GETFILEINFO_TITLE_LENGTH ) {
-					truncated_title.resize( GETFILEINFO_TITLE_LENGTH - 1 );
-				}
-				wcscpy( title, truncated_title.c_str() );
-			}
-		} catch ( ... ) {
-		}
-	}
-}
-
-static void eq_set( int on, char data[10], int preamp ) {
-	return;
-}
-
-static DWORD WINAPI DecodeThread( LPVOID ) {
-	MSG msg;
-	PeekMessage( &msg, NULL, 0, 0, PM_NOREMOVE );
-	bool eof = false;
-	while ( true ) {
-		bool quit = false;
-		while ( PeekMessage( &msg, NULL, 0, 0, PM_REMOVE ) ) {
-			if ( msg.message == WM_QUIT ) {
-				quit = true;
-			} else if ( msg.message == WM_OPENMPT_SEEK ) {
-				double pos_seconds = self->mod->set_position_seconds( msg.lParam * 0.001 );
-				self->decode_position_frames = (std::int64_t)( pos_seconds * (double)self->samplerate);
-				eof = false;
-				inmod.outMod->Flush( (int)( pos_seconds * 1000.0 ) );
-			}
-		}
-		if ( quit ) {
-			break;
-		}
-		if ( eof ) {
-			inmod.outMod->CanWrite(); // update output plugin state
-			if ( !inmod.outMod->IsPlaying() ) {
-				PostMessage( inmod.hMainWindow, WM_WA_MPEG_EOF, 0, 0 );
-				return 0;
-			}
-			Sleep( 10 );
-		} else {
-			bool dsp_active = inmod.dsp_isactive() ? true : false;
-			if ( inmod.outMod->CanWrite() >= (int)( WINAMP_BUFFER_SIZE_FRAMES * self->channels * sizeof( signed short ) ) * ( dsp_active ? WINAMP_DSP_HEADROOM_FACTOR : 1 ) ) {
-				int frames = 0;
-				switch ( self->channels ) {
-				case 1:
-					frames = self->mod->read( self->samplerate, WINAMP_BUFFER_SIZE_FRAMES, (&(self->buffer[0]))+0*WINAMP_BUFFER_SIZE_FRAMES );
-					for ( int frame = 0; frame < frames; frame++ ) {
-						self->interleaved_buffer[frame*1+0] = self->buffer[0*WINAMP_BUFFER_SIZE_FRAMES+frame];
-					}
-					break;
-				case 2:
-					frames = self->mod->read( self->samplerate, WINAMP_BUFFER_SIZE_FRAMES, (&(self->buffer[0]))+0*WINAMP_BUFFER_SIZE_FRAMES, (&(self->buffer[0]))+1*WINAMP_BUFFER_SIZE_FRAMES );
-					for ( int frame = 0; frame < frames; frame++ ) {
-						self->interleaved_buffer[frame*2+0] = self->buffer[0*WINAMP_BUFFER_SIZE_FRAMES+frame];
-						self->interleaved_buffer[frame*2+1] = self->buffer[1*WINAMP_BUFFER_SIZE_FRAMES+frame];
-					}
-					break;
-				case 4:
-					frames = self->mod->read( self->samplerate, WINAMP_BUFFER_SIZE_FRAMES, (&(self->buffer[0]))+0*WINAMP_BUFFER_SIZE_FRAMES, (&(self->buffer[0]))+1*WINAMP_BUFFER_SIZE_FRAMES, (&(self->buffer[0]))+2*WINAMP_BUFFER_SIZE_FRAMES, (&(self->buffer[0]))+3*WINAMP_BUFFER_SIZE_FRAMES );
-					for ( int frame = 0; frame < frames; frame++ ) {
-						self->interleaved_buffer[frame*4+0] = self->buffer[0*WINAMP_BUFFER_SIZE_FRAMES+frame];
-						self->interleaved_buffer[frame*4+1] = self->buffer[1*WINAMP_BUFFER_SIZE_FRAMES+frame];
-						self->interleaved_buffer[frame*4+2] = self->buffer[2*WINAMP_BUFFER_SIZE_FRAMES+frame];
-						self->interleaved_buffer[frame*4+3] = self->buffer[3*WINAMP_BUFFER_SIZE_FRAMES+frame];
-					}
-					break;
-				}
-				if ( frames == 0 ) {
-					eof = true;
-				} else {
-					self->decode_position_frames += frames;
-					std::int64_t decode_pos_ms = (self->decode_position_frames * 1000 / self->samplerate );
-					inmod.SAAddPCMData( &( self->interleaved_buffer[0] ), self->channels, BPS, (int)decode_pos_ms );
-					inmod.VSAAddPCMData( &( self->interleaved_buffer[0] ), self->channels, BPS, (int)decode_pos_ms );
-					if ( dsp_active ) {
-						frames = inmod.dsp_dosamples( &( self->interleaved_buffer[0] ), frames, BPS, self->channels, self->samplerate );
-					}
-					int bytes = frames * self->channels * sizeof( signed short );
-					inmod.outMod->Write( (char*)&( self->interleaved_buffer[0] ), bytes );
-				}
-			} else {
-				Sleep( 10 );
-			}
-		}
-	}
-	return 0;
-}
-
-In_Module inmod = {
-	IN_VER,
-	const_cast< char * >( in_openmpt_string ), // SHORT_TITLE,
-	0, // hMainWindow
-	0, // hDllInstance
-	NULL, // filled later in Init() "mptm\0ModPlug Tracker Module (*.mptm)\0",
-	1, // is_seekable
-	1, // uses output
-	config,
-	about,
-	init,
-	quit,
-	getfileinfo,
-	infobox,
-	isourfile,
-	play,
-	pause,
-	unpause,
-	ispaused,
-	stop,
-	getlength,
-	getoutputtime,
-	setoutputtime,
-	setvolume,
-	setpan,
-	0,0,0,0,0,0,0,0,0, // vis
-	0,0, // dsp
-	eq_set,
-	NULL, // setinfo
-	0 // out_mod
-};
-
-extern "C" __declspec(dllexport) In_Module * winampGetInModule2() {
-	return &inmod;
-}
-
-
-#ifdef _MFC_VER
-
-namespace libopenmpt {
-namespace plugin {
-
-void DllMainAttach() {
-	// nothing
-}
-
-void DllMainDetach() {
-	// nothing
-}
-
-} // namespace plugin
-} // namespace libopenmpt
-
-#else
-
-// nothing
-
-#endif
-
-
-#endif // NO_WINAMP

Unele fișiere nu au fost afișate deoarece prea multe fișiere au fost modificate în acest diff