Updated libOpenMPT to version 0.7

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
This commit is contained in:
Christopher Snowhill 2023-05-04 18:20:54 -07:00
parent 49bfd5053f
commit dfa5f41984
No known key found for this signature in database
397 changed files with 34547 additions and 17251 deletions

File diff suppressed because it is too large Load diff

View file

@ -35,12 +35,11 @@ How to compile
- Supported Visual Studio versions:
- Visual Studio 2017, 2019, and 2022 Community/Professional/Enterprise
- Visual Studio 2019, and 2022 Community/Professional/Enterprise
To compile the project, open `build/vsVERSIONwin7/OpenMPT.sln` (VERSION
being 2017, 2019, or 2022) and hit the compile button. Other target
systems can be found in the `vs2017*`, `vs2019*`, and `vs2022*` sibling
folders.
being 2019, or 2022) and hit the compile button. Other target systems
can be found in the `vs2019*`, and `vs2022*` sibling folders.
Note that you have to build the `PluginBridge` and `PluginBridgeLegacy`
projects manually for architectures other than the one you are building
@ -55,11 +54,13 @@ How to compile
headers and implementation, which significantly increases the matrix of
possible configurations to test.
- Visual Studio 2017 XP targeting toolset
- OpenMPT requires the compile host system to be Windows 8.1 (or later) amd64,
or Windows 11 (or later) ARM64.
- In order to build OpenMPT for Windows XP, the Visual Studio 2017 XP
targetting toolset as well as the Windows 8.1 SDK need to be installed. The
targeting toolset as well as the Windows 8.1 SDK need to be installed. The
SDK is optionally included with Visual Studio 2017, but must be separately
installed with later Visual Studio versions.
@ -74,8 +75,8 @@ How to compile
### libopenmpt and openmpt123
See [Dependencies](libopenmpt/dox/dependencies.md) and
[Getting Started](libopenmpt/dox/gettingstarted.md).
See [Dependencies](doc/libopenmpt/dependencies.md) and
[Getting Started](doc/libopenmpt/gettingstarted.md).
Contributing to OpenMPT/libopenmpt

View file

@ -6,12 +6,12 @@ include $(CLEAR_VARS)
LOCAL_MODULE := openmpt
LOCAL_CFLAGS +=#-std=c99
LOCAL_CFLAGS += -std=c17
LOCAL_CPPFLAGS += -std=c++17 -fexceptions -frtti
LOCAL_CPP_FEATURES += exceptions rtti
LOCAL_C_INCLUDES += $(LOCAL_PATH) $(LOCAL_PATH)/src $(LOCAL_PATH)/common $(LOCAL_PATH)/build/svn_version
LOCAL_C_INCLUDES += $(LOCAL_PATH) $(LOCAL_PATH)/src $(LOCAL_PATH)/common
LOCAL_CFLAGS += -fvisibility=hidden -Wall -DLIBOPENMPT_BUILD -DMPT_WITH_ZLIB
LOCAL_CPPFLAGS +=#-fvisibility=hidden -Wall -DLIBOPENMPT_BUILD -DMPT_WITH_ZLIB
@ -88,12 +88,11 @@ LOCAL_SRC_FILES += \
common/ComponentManager.cpp \
common/Logging.cpp \
common/mptFileIO.cpp \
common/mptFileTemporary.cpp \
common/mptFileType.cpp \
common/mptPathString.cpp \
common/mptRandom.cpp \
common/mptString.cpp \
common/mptStringBuffer.cpp \
common/mptStringFormat.cpp \
common/mptStringParse.cpp \
common/mptTime.cpp \
common/Profiler.cpp \
common/serialization_utils.cpp \
@ -112,6 +111,7 @@ LOCAL_SRC_FILES += \
soundlib/InstrumentExtensions.cpp \
soundlib/ITCompression.cpp \
soundlib/ITTools.cpp \
soundlib/Load_667.cpp \
soundlib/Load_669.cpp \
soundlib/Load_amf.cpp \
soundlib/Load_ams.cpp \
@ -125,6 +125,7 @@ LOCAL_SRC_FILES += \
soundlib/Load_far.cpp \
soundlib/Load_fmt.cpp \
soundlib/Load_gdm.cpp \
soundlib/Load_gt2.cpp \
soundlib/Load_imf.cpp \
soundlib/Load_it.cpp \
soundlib/Load_itp.cpp \
@ -150,6 +151,7 @@ LOCAL_SRC_FILES += \
soundlib/Load_uax.cpp \
soundlib/Load_wav.cpp \
soundlib/Load_xm.cpp \
soundlib/Load_xmf.cpp \
soundlib/Message.cpp \
soundlib/MIDIEvents.cpp \
soundlib/MIDIMacros.cpp \

View file

@ -1,5 +1,5 @@
APP_CFLAGS :=#-std=c99
APP_CFLAGS := -std=c17
APP_CPPFLAGS := -std=c++17 -fexceptions -frtti
APP_LDFLAGS :=
APP_STL := c++_shared

View file

@ -1,4 +1,4 @@
MPT_SVNVERSION=18680
MPT_SVNURL=https://source.openmpt.org/svn/openmpt/tags/libopenmpt-0.6.8
MPT_SVNDATE=2023-01-29T12:13:49.877060Z
MPT_SVNVERSION=19147
MPT_SVNURL=https://source.openmpt.org/svn/openmpt/tags/libopenmpt-0.7.0
MPT_SVNDATE=2023-04-30T12:58:58.547157Z

View file

@ -0,0 +1,120 @@
#!/usr/bin/env bash
# stop on error
set -e
# normalize current directory to project root
cd build 2>&1 > /dev/null || true
cd ..
function download_and_unpack_tar () {
set -e
MPT_GET_DESTDIR="$1"
MPT_GET_URL="$2"
MPT_GET_FILE="$3"
MPT_GET_SUBDIR="$4"
if [ ! -f "$3" ]; then
wget "$2" -O "$3"
fi
cd include
if [ -d "$1" ]; then
rm -rf "$1"
fi
if [ "$4" = "." ]; then
mkdir "$1"
cd "$1"
tar xvaf "../../$3"
cd ..
else
tar xvaf "../$3"
if [ ! "$4" = "$1" ]; then
mv "$4" "$1"
fi
fi
cd ..
return 0
}
function download_and_unpack_zip () {
set -e
MPT_GET_DESTDIR="$1"
MPT_GET_URL="$2"
MPT_GET_FILE="$3"
MPT_GET_SUBDIR="$4"
if [ ! -f "$3" ]; then
wget "$2" -O "$3"
fi
cd include
if [ -d "$1" ]; then
rm -rf "$1"
fi
if [ "$4" = "." ]; then
mkdir "$1"
cd "$1"
unzip "../../$3"
cd ..
else
unzip "../$3"
if [ ! "$4" = "$1" ]; then
mv "$4" "$1"
fi
fi
cd ..
return 0
}
function download_and_unpack_7z () {
set -e
MPT_GET_DESTDIR="$1"
MPT_GET_URL="$2"
MPT_GET_FILE="$3"
MPT_GET_SUBDIR="$4"
if [ ! -f "$3" ]; then
wget "$2" -O "$3"
fi
cd include
if [ -d "$1" ]; then
rm -rf "$1"
fi
if [ "$4" = "." ]; then
mkdir "$1"
cd "$1"
7z x "../../$3"
cd ..
else
7z x "../$3"
if [ ! "$4" = "$1" ]; then
mv "$4" "$1"
fi
fi
cd ..
return 0
}
function download () {
set -e
MPT_GET_URL="$1"
MPT_GET_FILE="$2"
if [ ! -f "$2" ]; then
wget "$1" -O "$2"
fi
return 0
}
if [ ! -d "build/externals" ]; then
mkdir build/externals
fi
if [ ! -d "build/tools" ]; then
mkdir build/tools
fi
download_and_unpack_zip "allegro42" "https://lib.openmpt.org/files/libopenmpt/contrib/allegro/allegro-4.2.3.1-hg.8+r8500.zip" "build/externals/allegro-4.2.3.1-hg.8+r8500.zip" "."
download_and_unpack_zip "cwsdpmi" "https://lib.openmpt.org/files/libopenmpt/contrib/djgpp/cwsdpmi/csdpmi7b.zip" "build/externals/csdpmi7b.zip" "."
download "https://lib.openmpt.org/files/libopenmpt/contrib/djgpp/cwsdpmi/csdpmi7s.zip" "build/externals/csdpmi7s.zip"
#download_and_unpack_zip "cwsdpmi" "https://djgpp.mirror.garr.it/current/v2misc/csdpmi7b.zip" "build/externals/csdpmi7b.zip" "."
#download "https://djgpp.mirror.garr.it/current/v2misc/csdpmi7s.zip" "build/externals/csdpmi7s.zip"
download_and_unpack_7z "winamp" "https://web.archive.org/web/20131217072017if_/http://download.nullsoft.com/winamp/plugin-dev/WA5.55_SDK.exe" "build/externals/WA5.55_SDK.exe" "."
ln -s OUT.H include/winamp/Winamp/out.h
download_and_unpack_zip "xmplay" "https://www.un4seen.com/files/xmp-sdk.zip" "build/externals/xmp-sdk.zip" "."

View file

@ -13,15 +13,25 @@ AR = ar
endif
ifneq ($(STDCXX),)
CXXFLAGS_STDCXX = -std=$(STDCXX)
CXXFLAGS_STDCXX = -std=$(STDCXX) -fexceptions -frtti -pthread
# We do not enable C++20 for fuzzer builds, because it prevents detecting
# shifting of signed values which changed from undefined to defined behaviour
# in C++20. As we still support C+ü+17, we need to catch these problem cases.
#else ifeq ($(shell printf '\n' > bin/empty.cpp ; if $(CXX) -std=c++20 -c bin/empty.cpp -o bin/empty.out > /dev/null 2>&1 ; then echo 'c++20' ; fi ), c++20)
#CXXFLAGS_STDCXX = -std=c++20 -fexceptions -frtti -pthread
else
ifeq ($(shell printf '\n' > bin/empty.cpp ; if $(CXX) -std=c++17 -c bin/empty.cpp -o bin/empty.out > /dev/null 2>&1 ; then echo 'c++17' ; fi ), c++17)
CXXFLAGS_STDCXX = -std=c++17
CXXFLAGS_STDCXX = -std=c++17 -fexceptions -frtti -pthread
endif
ifneq ($(STDC),)
CFLAGS_STDC = -std=$(STDC) -pthread
else ifeq ($(shell printf '\n' > bin/empty.c ; if $(CC) -std=c17 -c bin/empty.c -o bin/empty.out > /dev/null 2>&1 ; then echo 'c17' ; fi ), c17)
CFLAGS_STDC = -std=c17 -pthread
else
CFLAGS_STDC = -std=c11 -pthread
endif
CFLAGS_STDC = -std=c99
CXXFLAGS += $(CXXFLAGS_STDCXX)
CFLAGS += $(CFLAGS_STDC)
LDFLAGS += -pthread
DYNLINK=0
SHARED_LIB=0

View file

@ -0,0 +1,68 @@
ifeq ($(origin CC),default)
CC = $(TOOLCHAIN_PREFIX)clang$(TOOLCHAIN_SUFFIX)
endif
ifeq ($(origin CXX),default)
CXX = $(TOOLCHAIN_PREFIX)clang++$(TOOLCHAIN_SUFFIX)
endif
ifeq ($(origin LD),default)
LD = $(CXX)
endif
ifeq ($(origin AR),default)
AR = $(TOOLCHAIN_PREFIX)ar$(TOOLCHAIN_SUFFIX)
endif
ifneq ($(STDCXX),)
CXXFLAGS_STDCXX = -std=$(STDCXX) -fexceptions -frtti -pthread
else ifeq ($(shell printf '\n' > bin/empty.cpp ; if $(CXX) -std=c++20 -c bin/empty.cpp -o bin/empty.out > /dev/null 2>&1 ; then echo 'c++20' ; fi ), c++20)
CXXFLAGS_STDCXX = -std=c++20 -fexceptions -frtti -pthread
else
CXXFLAGS_STDCXX = -std=c++17 -fexceptions -frtti -pthread
endif
ifneq ($(STDC),)
CFLAGS_STDC = -std=$(STDC) -pthread
else ifeq ($(shell printf '\n' > bin/empty.c ; if $(CC) -std=c17 -c bin/empty.c -o bin/empty.out > /dev/null 2>&1 ; then echo 'c17' ; fi ), c17)
CFLAGS_STDC = -std=c17 -pthread
else
CFLAGS_STDC = -std=c11 -pthread
endif
CXXFLAGS += $(CXXFLAGS_STDCXX)
CFLAGS += $(CFLAGS_STDC)
LDFLAGS += -pthread
CPPFLAGS +=
CXXFLAGS += -fPIC
CFLAGS += -fPIC
LDFLAGS +=
LDLIBS += -lm
ARFLAGS := rcs
MODERN=1
NATIVE=1
OPTIMIZE=vectorize
OPTIMIZE_LTO=1
ifeq ($(NATIVE),1)
CXXFLAGS += -march=native
CFLAGS += -march=native
endif
ifeq ($(OPTIMIZE_LTO),1)
CXXFLAGS += -flto
CFLAGS += -flto
LDFLAGS += -flto
endif
ifeq ($(CHECKED_ADDRESS),1)
CXXFLAGS += -fsanitize=address
CFLAGS += -fsanitize=address
endif
ifeq ($(CHECKED_UNDEFINED),1)
CXXFLAGS += -fsanitize=undefined
CFLAGS += -fsanitize=undefined
endif
include build/make/warnings-clang.mk
EXESUFFIX=

View file

@ -13,15 +13,22 @@ AR = $(TOOLCHAIN_PREFIX)ar$(TOOLCHAIN_SUFFIX)
endif
ifneq ($(STDCXX),)
CXXFLAGS_STDCXX = -std=$(STDCXX)
CXXFLAGS_STDCXX = -std=$(STDCXX) -fexceptions -frtti -pthread
else ifeq ($(shell printf '\n' > bin/empty.cpp ; if $(CXX) -std=c++20 -c bin/empty.cpp -o bin/empty.out > /dev/null 2>&1 ; then echo 'c++20' ; fi ), c++20)
CXXFLAGS_STDCXX = -std=c++20 -fexceptions -frtti -pthread
else
ifeq ($(shell printf '\n' > bin/empty.cpp ; if $(CXX) -std=c++17 -c bin/empty.cpp -o bin/empty.out > /dev/null 2>&1 ; then echo 'c++17' ; fi ), c++17)
CXXFLAGS_STDCXX = -std=c++17
CXXFLAGS_STDCXX = -std=c++17 -fexceptions -frtti -pthread
endif
ifneq ($(STDC),)
CFLAGS_STDC = -std=$(STDC) -pthread
else ifeq ($(shell printf '\n' > bin/empty.c ; if $(CC) -std=c17 -c bin/empty.c -o bin/empty.out > /dev/null 2>&1 ; then echo 'c17' ; fi ), c17)
CFLAGS_STDC = -std=c17 -pthread
else
CFLAGS_STDC = -std=c11 -pthread
endif
CFLAGS_STDC = -std=c99
CXXFLAGS += $(CXXFLAGS_STDCXX)
CFLAGS += $(CFLAGS_STDC)
LDFLAGS += -pthread
CPPFLAGS +=
CXXFLAGS += -fPIC
@ -30,9 +37,19 @@ LDFLAGS +=
LDLIBS += -lm
ARFLAGS := rcs
ifeq ($(NATIVE),1)
CXXFLAGS += -march=native
CFLAGS += -march=native
endif
ifeq ($(MODERN),1)
LDFLAGS += -fuse-ld=lld
endif
ifeq ($(OPTIMIZE_LTO),1)
CXXFLAGS += -flto=thin
CFLAGS += -flto=thin
LDFLAGS += -Wl,--thinlto-jobs=all
endif
ifeq ($(CHECKED_ADDRESS),1)

View file

@ -8,6 +8,8 @@ include build/make/config-clang.mk
# Mac OS X overrides
DYNLINK=0
SHARED_SONAME=0
MPT_COMPILER_NOSECTIONS=1
MPT_COMPILER_NOGCSECTIONS=1
else ifeq ($(HOST_FLAVOUR),MSYS2)
@ -33,6 +35,11 @@ else ifeq ($(HOST_FLAVOUR),LINUX)
include build/make/config-gcc.mk
else ifeq ($(HOST_FLAVOUR),NETBSD)
include build/make/config-gcc.mk
NO_PORTAUDIOCPP?=1
else ifeq ($(HOST_FLAVOUR),FREEBSD)
include build/make/config-clang.mk
@ -56,13 +63,13 @@ include build/make/config-gcc.mk
else
include build/make/config-generic.mk
include build/make/config-unknown.mk
endif
else
include build/make/config-generic.mk
include build/make/config-unknown.mk
endif

View file

@ -14,21 +14,369 @@ endif
# Note that we are using GNU extensions instead of 100% standards-compliant
# mode, because otherwise DJGPP-specific headers/functions are unavailable.
CXXFLAGS_STDCXX = -std=gnu++17
CFLAGS_STDC = -std=gnu99
CXXFLAGS += $(CXXFLAGS_STDCXX)
CFLAGS += $(CFLAGS_STDC)
ifneq ($(STDCXX),)
CXXFLAGS_STDCXX = -std=$(STDCXX) -fexceptions -frtti -fpermissive
else ifeq ($(shell printf '\n' > bin/empty.cpp ; if $(CXX) -std=gnu++20 -c bin/empty.cpp -o bin/empty.out > /dev/null 2>&1 ; then echo 'c++20' ; fi ), c++20)
CXXFLAGS_STDCXX = -std=gnu++20 -fexceptions -frtti -fpermissive
else
CXXFLAGS_STDCXX = -std=gnu++17 -fexceptions -frtti -fpermissive
endif
ifneq ($(STDC),)
CFLAGS_STDC = -std=$(STDC)
else ifeq ($(shell printf '\n' > bin/empty.c ; if $(CC) -std=gnu17 -c bin/empty.c -o bin/empty.out > /dev/null 2>&1 ; then echo 'c17' ; fi ), c17)
CFLAGS_STDC = -std=gnu17
else
CFLAGS_STDC = -std=gnu11
endif
CXXFLAGS += $(CXXFLAGS_STDCXX) -fallow-store-data-races -fno-threadsafe-statics
CFLAGS += $(CFLAGS_STDC) -fallow-store-data-races
CPPFLAGS +=
CXXFLAGS += -march=i386 -m80387 -mtune=pentium -ffast-math
CFLAGS += -march=i386 -m80387 -mtune=pentium -ffast-math
LDFLAGS +=
LDLIBS += -lm
ARFLAGS := rcs
CPU?=generic/common
include build/make/warnings-gcc.mk
# Enable 128bit SSE registers.
# This requires pure DOS with only CWSDPMI as DOS extender.
# It will not work in a Win9x DOS window, or in WinNT NTVDM.
# It will also not work with almost all other VCPI or DPMI hosts (e.g. EMM386.EXE).
SSE?=0
ifneq ($(SSE),0)
FPU_NONE := -mno-80387
FPU_287 := -m80387 -mfpmath=387 -mno-fancy-math-387
FPU_387 := -m80387 -mfpmath=387
FPU_MMX := -m80387 -mmmx -mfpmath=387
FPU_3DNOW := -m80387 -mmmx -m3dnow -mfpmath=387
FPU_3DNOWA := -m80387 -mmmx -m3dnow -m3dnowa -mfpmath=387
FPU_3DASSE := -m80387 -mmmx -m3dnow -m3dnowa -mfxsr -msse -mfpmath=sse,387
FPU_SSE := -m80387 -mmmx -mfxsr -msse -mfpmath=sse,387
FPU_SSE2 := -m80387 -mmmx -mfxsr -msse -msse2 -mfpmath=sse
FPU_SSE3 := -m80387 -mmmx -mfxsr -msse -msse2 -msse3 -mfpmath=sse
FPU_SSSE3 := -m80387 -mmmx -mfxsr -msse -msse2 -msse3 -mssse3 -mfpmath=sse
FPU_SSE4_1 := -m80387 -mmmx -mfxsr -msse -msse2 -msse3 -mssse3 -msse4.1 -mfpmath=sse
FPU_SSE4_2 := -m80387 -mmmx -mfxsr -msse -msse2 -msse3 -mssse3 -msse4.1 -msse4.2 -mfpmath=sse
FPU_SSE4A := -m80387 -mmmx -mfxsr -msse -msse2 -msse3 -mssse3 -msse4a -mfpmath=sse
else
FPU_NONE := -mno-80387
FPU_287 := -m80387 -mfpmath=387 -mno-fancy-math-387
FPU_387 := -m80387 -mfpmath=387
FPU_MMX := -m80387 -mmmx -mfpmath=387
FPU_3DNOW := -m80387 -mmmx -m3dnow -mfpmath=387
FPU_3DNOWA := -m80387 -mmmx -m3dnow -m3dnowa -mfpmath=387
FPU_3DASSE := -mno-sse -mno-fxsr -m80387 -mmmx -m3dnow -m3dnowa -mfpmath=387
FPU_SSE := -mno-sse -mno-fxsr -m80387 -mmmx -mfpmath=387
FPU_SSE2 := -mno-sse2 -mno-sse -mno-fxsr -m80387 -mmmx -mfpmath=387
FPU_SSE3 := -mno-sse3 -mno-sse2 -mno-sse -mno-fxsr -m80387 -mmmx -mfpmath=387
FPU_SSSE3 := -mno-ssse3 -mno-sse3 -mno-sse2 -mno-sse -mno-fxsr -m80387 -mmmx -mfpmath=387
FPU_SSE4_1 := -mno-sse4.1 -mno-ssse3 -mno-sse3 -mno-sse2 -mno-sse -mno-fxsr -m80387 -mmmx -mfpmath=387
FPU_SSE4_2 := -mno-sse4.2 -mno-sse4.1 -mno-ssse3 -mno-sse3 -mno-sse2 -mno-sse -mno-fxsr -m80387 -mmmx -mfpmath=387
FPU_SSE4A := -mno-sse4a -mno-ssse3 -mno-sse3 -mno-sse2 -mno-sse -mno-fxsr -m80387 -mmmx -mfpmath=387
endif
OPT_DEF := -Os
OPT_SIMD := -O3
CACHE_386 :=64 # 0/64/128
CACHE_486 :=128 # 0/64/128/256
CACHE_S7 :=256 # 128/256/512
CACHE_SS7 :=512 # 256/512/1024
CACHE_PENTIUMPRO :=512 # 256/512/1024
CACHE_PENTIUM2 :=512 # 256/512
CACHE_PENTIUM3 :=256 # 256/512
CACHE_PENTIUM4 :=256 # 256/512
CACHE_PENTIUM41 :=512 # 512/1024
CACHE_CORE :=2048 # 512/1024/2048
CACHE_CORE2 :=2048 # 1024/2048/3072/4096/6144
CACHE_CELERON :=0 # 0/128/256
CACHE_PENTIUMM :=1024 # 1024/2048
CACHE_ATOM :=512 # 512
CACHE_K63 :=256 # 128/256
CACHE_ATHLON :=512 # 512
CACHE_ATHLONXP :=256 # 256/512
CACHE_ATHLON64 :=512 # 256/512/1024
CACHE_DURON :=64 # 64
CACHE_DURONXP :=64 # 64
CACHE_SEMPRON64 :=128 # 128/256/512
TUNE_586 :=-mtune=pentium
TUNE_586MMX :=-mtune=pentium-mmx
TUNE_686 :=-mtune=pentiumpro
TUNE_686MMX :=-mtune=pentium2
TUNE_686SSE :=-mtune=pentium3
TUNE_686SSE2:=-mtune=pentium-m
TUNE_686SSE3:=-mtune=pentium-m
generic/early := $(XXX) -march=i386 $(FPU_NONE) -mtune=i386 $(OPT_DEF)
generic/common := $(XXX) -march=i386 $(FPU_387) -mtune=pentium $(OPT_DEF)
generic/late := $(XXX) -march=i686 $(FPU_SSSE3) -mtune=generic $(OPT_SIMD)
generic/nofpu := $(X__) -march=i386 $(FPU_NONE) -mtune=i386 $(OPT_DEF) # 386SX, 386DX, 486SX, Cyrix Cx486SLC..Cx486S, NexGen Nx586
generic/386 := $(X__) -march=i386 $(FPU_387) -mtune=i386 $(OPT_DEF) # 386+387
generic/486 := $(XX_) -march=i486 $(FPU_387) -mtune=i486 $(OPT_DEF) # 486DX, AMD Am5x86, Cyrix Cx4x86DX..6x86L, NexGen Nx586-PF
generic/486-mmx := $(___) -march=i486 $(FPU_MMX) -mtune=winchip-c6 $(OPT_SIMD) # IDT WinChip-C6, Rise mP6
generic/486-3dnow := $(___) -march=i486 $(FPU_3DNOW) -mtune=winchip2 $(OPT_SIMD) # IDT WinChip-2
generic/586 := $(XX_) -march=i586 $(FPU_387) -mtune=pentium $(OPT_DEF) # Intel Pentium, AMD K5
generic/586-mmx := $(XX_) -march=pentium-mmx $(FPU_MMX) -mtune=pentium-mmx $(OPT_SIMD) # Intel Pentium-MMX, AMD K6
generic/586-3dnow := $(XX_) -march=k6-2 $(FPU_3DNOW) -mtune=k6-2 $(OPT_SIMD) # AMD K6-2..K6-3
generic/686 := $(___) -march=pentiumpro $(FPU_387) -mtune=pentiumpro $(OPT_DEF) # Intel Pentium-Pro
generic/686-mmx := $(XXX) -march=i686 $(FPU_MMX) -mtune=pentium2 $(OPT_SIMD) # Intel Pentium-2.., AMD Bulldozer.., VIA C3-Nehemiah.., Cyrix 6x86MX.., Transmeta Crusoe.., NSC Geode-GX1..
generic/686-3dnow := $(___) -march=i686 $(FPU_3DNOW) -mtune=c3 $(OPT_SIMD) # VIA Cyrix-3..C3-Ezra
generic/686-3dnowa:= $(XX_) -march=athlon $(FPU_3DNOWA) -mtune=athlon $(OPT_SIMD) # AMD Athlon..K10
generic/sse := $(X__) -march=i686 $(FPU_SSE) -mtune=pentium3 $(OPT_SIMD) # Intel Pentium-3.., AMD Athlon-XP.., VIA C3-Nehemiah.., Transmeta Efficeon.., DM&P Vortex86DX3..
generic/sse2 := $(XX_) -march=i686 $(FPU_SSE2) -mtune=generic $(OPT_SIMD) # Intel Pentium-4.., AMD Athlon-64.., VIA C7-Esther.., Transmeta Efficeon..
generic/sse3 := $(___) -march=i686 $(FPU_SSE3) -mtune=generic $(OPT_SIMD) # Intel Core.., AMD Athlon-64-X2.., VIA C7-Esther.., Transmeta Efficeon-88xx..
generic/ssse3 := $(___) -march=i686 $(FPU_SSSE3) -mtune=generic $(OPT_SIMD) # Intel Core-2.., AMD Bobcat.., Via Nano-1000..
generic/sse4_1 := $(___) -march=i686 $(FPU_SSE4_1) -mtune=generic $(OPT_SIMD) # Intel Core-1st, AMD Bulldozer.., Via Nano-3000..
generic/sse4_2 := $(___) -march=i686 $(FPU_SSE4_2) -mtune=generic $(OPT_SIMD) # Intel Core-1st, AMD Bulldozer.., Via Nano-C..
intel/i386 := $(XX_) -march=i386 $(FPU_NONE) -mtune=i386 $(OPT_DEF) --param l1-cache-size=0 --param l2-cache-size=$(CACHE_386)
intel/i486sx := $(___) -march=i486 $(FPU_NONE) -mtune=i486 $(OPT_DEF) --param l1-cache-size=6 --param l2-cache-size=$(CACHE_486)
intel/i386+80287 := $(___) -march=i386 $(FPU_287) -mtune=i386 $(OPT_DEF) --param l1-cache-size=0 --param l2-cache-size=$(CACHE_386)
intel/i386+80387 := $(XX_) -march=i386 $(FPU_387) -mtune=i386 $(OPT_DEF) --param l1-cache-size=0 --param l2-cache-size=$(CACHE_386)
intel/i486dx := $(XXX) -march=i486 $(FPU_387) -mtune=i486 $(OPT_DEF) --param l1-cache-size=6 --param l2-cache-size=$(CACHE_486)
intel/pentium := $(XXX) -march=pentium $(FPU_387) -mtune=pentium $(OPT_DEF) --param l1-cache-size=8 --param l2-cache-size=$(CACHE_S7)
intel/pentium-mmx := $(XXX) -march=pentium-mmx $(FPU_MMX) -mtune=pentium-mmx $(OPT_SIMD) --param l1-cache-size=16 --param l2-cache-size=$(CACHE_S7)
intel/pentium-pro := $(___) -march=pentiumpro $(FPU_387) -mtune=pentiumpro $(OPT_DEF) --param l1-cache-size=8 --param l2-cache-size=$(CACHE_PENTIUMPRO)
intel/pentium2 := $(___) -march=pentium2 $(FPU_MMX) -mtune=pentium2 $(OPT_SIMD) --param l1-cache-size=16 --param l2-cache-size=$(CACHE_PENTIUM2)
intel/pentium3 := $(___) -march=pentium3 $(FPU_SSE) -mtune=pentium3 $(OPT_SIMD) --param l1-cache-size=16 --param l2-cache-size=$(CACHE_PENTIUM3)
intel/pentium4 := $(___) -march=pentium4 $(FPU_SSE2) -mtune=pentium4 $(OPT_SIMD) --param l1-cache-size=8 --param l2-cache-size=$(CACHE_PENTIUM4)
intel/pentium4.1 := $(___) -march=prescott $(FPU_SSE3) -mtune=prescott $(OPT_SIMD) --param l1-cache-size=8 --param l2-cache-size=$(CACHE_PENTIUM41)
intel/core2 := $(___) -march=core2 $(FPU_SSSE3) -mtune=core2 $(OPT_SIMD) --param l1-cache-size=32 --param l2-cache-size=$(CACHE_CORE2)
intel/celeron := $(___) -march=pentium2 $(FPU_MMX) -mtune=pentium2 $(OPT_SIMD) --param l1-cache-size=16 --param l2-cache-size=$(CACHE_CELERON)
intel/pentium-m := $(___) -march=pentium-m $(FPU_SSE2) -mtune=pentium-m $(OPT_SIMD) --param l1-cache-size=16 --param l2-cache-size=$(CACHE_PENTIUMM)
intel/core := $(___) -march=pentium-m $(FPU_SSE3) -mtune=core2 $(OPT_SIMD) --param l1-cache-size=32 --param l2-cache-size=$(CACHE_CORE)
intel/atom := $(___) -march=bonnell $(FPU_SSSE3) -mtune=bonnell $(OPT_SIMD) --param l1-cache-size=24 --param l2-cache-size=$(CACHE_ATOM)
intel/late := $(XX_) -march=i686 $(FPU_SSSE3) -mtune=intel $(OPT_SIMD)
amd/am386 := $(___) -march=i386 $(FPU_NONE) -mtune=i386 $(OPT_DEF) --param l1-cache-size=0 --param l2-cache-size=$(CACHE_386)
amd/am486sx := $(___) -march=i486 $(FPU_NONE) -mtune=i486 $(OPT_DEF) --param l1-cache-size=6 --param l2-cache-size=$(CACHE_486)
amd/am386+80387 := $(___) -march=i386 $(FPU_387) -mtune=i386 $(OPT_DEF) --param l1-cache-size=0 --param l2-cache-size=$(CACHE_386)
amd/am486dx := $(___) -march=i486 $(FPU_387) -mtune=i486 $(OPT_DEF) --param l1-cache-size=6 --param l2-cache-size=$(CACHE_486)
amd/am486dxe := $(___) -march=i486 $(FPU_387) -mtune=i486 $(OPT_DEF) --param l1-cache-size=12 --param l2-cache-size=$(CACHE_486)
amd/am5x86 := $(___) -march=i486 $(FPU_387) -mtune=i486 $(OPT_DEF) --param l1-cache-size=12 --param l2-cache-size=$(CACHE_486)
amd/k5 := $(XXX) -march=i586 $(FPU_387) -mtune=i586 $(OPT_DEF) --param l1-cache-size=8 --param l2-cache-size=$(CACHE_S7)
amd/k5-pentium := $(XXX) -march=i586 $(FPU_387) -mtune=pentium $(OPT_DEF) --param l1-cache-size=8 --param l2-cache-size=$(CACHE_S7)
amd/k5-pentiumpro := $(XXX) -march=i586 $(FPU_387) -mtune=pentiumpro $(OPT_DEF) --param l1-cache-size=8 --param l2-cache-size=$(CACHE_S7)
amd/k5-pentium2 := $(XXX) -march=i586 $(FPU_387) -mtune=pentium2 $(OPT_DEF) --param l1-cache-size=8 --param l2-cache-size=$(CACHE_S7)
amd/k5-k6 := $(XXX) -march=i586 $(FPU_387) -mtune=k6 $(OPT_DEF) --param l1-cache-size=8 --param l2-cache-size=$(CACHE_S7)
amd/k6 := $(XXX) -march=k6 $(FPU_MMX) -mtune=k6 $(OPT_SIMD) --param l1-cache-size=32 --param l2-cache-size=$(CACHE_S7)
amd/k6-2 := $(XXX) -march=k6-2 $(FPU_3DNOW) -mtune=k6-2 $(OPT_SIMD) --param l1-cache-size=32 --param l2-cache-size=$(CACHE_SS7)
amd/k6-3 := $(___) -march=k6-3 $(FPU_3DNOW) -mtune=k6-3 $(OPT_SIMD) --param l1-cache-size=32 --param l2-cache-size=$(CACHE_K63)
amd/athlon := $(XX_) -march=athlon $(FPU_3DNOWA) -mtune=athlon $(OPT_SIMD) --param l1-cache-size=64 --param l2-cache-size=$(CACHE_ATHLON)
amd/athlon-xp := $(XX_) -march=athlon-xp $(FPU_3DASSE) -mtune=athlon-xp $(OPT_SIMD) --param l1-cache-size=64 --param l2-cache-size=$(CACHE_ATHLONXP)
amd/athlon64 := $(X__) -march=k8 $(FPU_SSE2) -mtune=k8 $(OPT_SIMD) --param l1-cache-size=64 --param l2-cache-size=$(CACHE_ATHLON64)
amd/athlon64-sse3 := $(___) -march=k8-sse3 $(FPU_SSE3) -mtune=k8-sse3 $(OPT_SIMD) --param l1-cache-size=64 --param l2-cache-size=$(CACHE_ATHLON64)
amd/k10 := $(___) -march=amdfam10 $(FPU_SSE4A) -mtune=amdfam10 $(OPT_SIMD) --param l1-cache-size=64 --param l2-cache-size=512
amd/duron := $(XX_) -march=athlon $(FPU_3DNOWA) -mtune=athlon $(OPT_SIMD) --param l1-cache-size=64 --param l2-cache-size=$(CACHE_DURON)
amd/duron-xp := $(___) -march=athlon-xp $(FPU_3DASSE) -mtune=athlon-xp $(OPT_SIMD) --param l1-cache-size=64 --param l2-cache-size=$(CACHE_DURONXP)
amd/sempron64 := $(___) -march=k8 $(FPU_SSE2) -mtune=k8 $(OPT_SIMD) --param l1-cache-size=64 --param l2-cache-size=$(CACHE_SEMPRON64)
amd/geode-gx := $(___) -march=geode $(FPU_3DNOW) -mtune=geode $(OPT_SIMD) --param l1-cache-size=16 --param l2-cache-size=0
amd/geode-lx := $(___) -march=geode $(FPU_3DNOW) -mtune=geode $(OPT_SIMD) --param l1-cache-size=64 --param l2-cache-size=128
amd/geode-nx := $(___) -march=athlon-xp $(FPU_3DASSE) -mtune=athlon-xp $(OPT_SIMD) --param l1-cache-size=64 --param l2-cache-size=256
amd/bobcat := $(___) -march=btver1 $(FPU_SSE4A) -mtune=btver1 $(OPT_SIMD) --param l1-cache-size=32 --param l2-cache-size=512
amd/jaguar := $(___) -march=btver2 $(FPU_SSE4A) -mtune=btver2 $(OPT_SIMD) --param l1-cache-size=32 --param l2-cache-size=1024
amd/late-3dnow := $(XX_) -march=athlon-xp $(FPU_3DASSE) -mtune=athlon-xp $(OPT_SIMD) --param l1-cache-size=64 --param l2-cache-size=512
amd/late := $(XX_) -march=i686 $(FPU_SSE4A) -mtune=generic $(OPT_SIMD)
nexgen/nx586 := $(___) -march=i486 $(FPU_NONE) $(TUNE_586) $(OPT_DEF) --param l1-cache-size=16 --param l2-cache-size=$(CACHE_486)
nexgen/nx586pf := $(___) -march=i486 $(FPU_387) $(TUNE_586) $(OPT_DEF) --param l1-cache-size=16 --param l2-cache-size=$(CACHE_486)
ibm/386slc := $(___) -march=i386 $(FPU_NONE) -mtune=i386 $(OPT_DEF) --param l1-cache-size=6 --param l2-cache-size=$(CACHE_386)
ibm/486slc := $(___) -march=i486 $(FPU_NONE) -mtune=i386 $(OPT_DEF) --param l1-cache-size=12 --param l2-cache-size=$(CACHE_386)
ibm/486bl := $(___) -march=i486 $(FPU_NONE) -mtune=i386 $(OPT_DEF) --param l1-cache-size=12 --param l2-cache-size=$(CACHE_486)
cyrix/cx486slc := $(___) -march=i386 $(FPU_NONE) -mtune=i486 $(OPT_DEF) --param l1-cache-size=1 --param l2-cache-size=$(CACHE_386)
cyrix/cx486dlc := $(___) -march=i386 $(FPU_NONE) -mtune=i486 $(OPT_DEF) --param l1-cache-size=1 --param l2-cache-size=$(CACHE_386)
cyrix/cx4x86s := $(___) -march=i486 $(FPU_NONE) -mtune=i486 $(OPT_DEF) --param l1-cache-size=2 --param l2-cache-size=$(CACHE_486)
cyrix/cx4x86dx := $(___) -march=i486 $(FPU_387) -mtune=i486 $(OPT_DEF) --param l1-cache-size=6 --param l2-cache-size=$(CACHE_486)
cyrix/cx5x86 := $(___) -march=i486 $(FPU_387) -mtune=i486 $(OPT_DEF) --param l1-cache-size=12 --param l2-cache-size=$(CACHE_486)
cyrix/6x86 := $(XXX) -march=i486 $(FPU_387) $(TUNE_586) $(OPT_DEF) --param l1-cache-size=12 --param l2-cache-size=$(CACHE_S7)
cyrix/6x86l := $(___) -march=i486 $(FPU_387) $(TUNE_586) $(OPT_DEF) --param l1-cache-size=12 --param l2-cache-size=$(CACHE_S7)
cyrix/6x86mx := $(___) -march=i686 $(FPU_MMX) $(TUNE_686MMX) $(OPT_SIMD) --param l1-cache-size=48 --param l2-cache-size=$(CACHE_SS7)
cyrix/mediagx-gx := $(___) -march=i486 $(FPU_387) -mtune=i486 $(OPT_DEF) --param l1-cache-size=9 --param l2-cache-size=0
cyrix/mediagx-gxm := $(___) -march=i686 $(FPU_MMX) $(TUNE_686MMX) $(OPT_SIMD) --param l1-cache-size=9 --param l2-cache-size=0
nsc/geode-gx1 := $(___) -march=i686 $(FPU_MMX) $(TUNE_686MMX) $(OPT_SIMD) --param l1-cache-size=9 --param l2-cache-size=0
nsc/geode-gx2 := $(___) -march=geode $(FPU_3DNOW) -mtune=geode $(OPT_SIMD) --param l1-cache-size=16 --param l2-cache-size=0
idt/winchip-c6 := $(XX_) -march=winchip-c6 $(FPU_MMX) -mtune=winchip-c6 $(OPT_SIMD) --param l1-cache-size=32 --param l2-cache-size=$(CACHE_S7)
idt/winchip2 := $(XX_) -march=winchip2 $(FPU_3DNOW) -mtune=winchip2 $(OPT_SIMD) --param l1-cache-size=32 --param l2-cache-size=$(CACHE_SS7)
via/cyrix3-joshua := $(XX_) -march=i686 $(FPU_3DNOW) $(TUNE_686MMX) $(OPT_SIMD) --param l1-cache-size=48 --param l2-cache-size=256
via/cyrix3-samuel := $(___) -march=c3 $(FPU_3DNOW) -mtune=c3 $(OPT_SIMD) --param l1-cache-size=64 --param l2-cache-size=0
via/c3-samuel2 := $(___) -march=samuel-2 $(FPU_3DNOW) -mtune=samuel-2 $(OPT_SIMD) --param l1-cache-size=64 --param l2-cache-size=64
via/c3-ezra := $(___) -march=samuel-2 $(FPU_3DNOW) -mtune=samuel-2 $(OPT_SIMD) --param l1-cache-size=64 --param l2-cache-size=64
via/c3-nehemiah := $(XX_) -march=nehemiah $(FPU_SSE) -mtune=nehemiah $(OPT_SIMD) --param l1-cache-size=64 --param l2-cache-size=64
via/c7-esther := $(XX_) -march=esther $(FPU_SSE3) -mtune=esther $(OPT_SIMD) --param l1-cache-size=64 --param l2-cache-size=128
via/late := $(XX_) -march=i686 $(FPU_SSE3) -mtune=esther $(OPT_SIMD)
umc/u5s := $(___) -march=i486 $(FPU_NONE) -mtune=i486 $(OPT_DEF) --param l1-cache-size=6 --param l2-cache-size=$(CACHE_486)
umc/u5d := $(___) -march=i486 $(FPU_387) -mtune=i486 $(OPT_DEF) --param l1-cache-size=6 --param l2-cache-size=$(CACHE_486)
transmeta/crusoe := $(___) -march=i686 $(FPU_MMX) $(TUNE_686MMX) $(OPT_SIMD) --param l1-cache-size=64 --param l2-cache-size=256
transmeta/efficeon:= $(___) -march=i686 $(FPU_SSE2) $(TUNE_686SSE2) $(OPT_SIMD) --param l1-cache-size=64 --param l2-cache-size=1024
transmeta/tm8800 := $(___) -march=i686 $(FPU_SSE3) $(TUNE_686SSE3) $(OPT_SIMD) --param l1-cache-size=64 --param l2-cache-size=1024
uli/m6117c := $(___) -march=i386 $(FPU_NONE) -mtune=i386 $(OPT_DEF) --param l1-cache-size=0 --param l2-cache-size=$(CACHE_386)
rise/mp6 := $(XX_) -march=i586 $(FPU_MMX) $(TUNE_586MMX) $(OPT_SIMD) --param l1-cache-size=8 --param l2-cache-size=$(CACHE_SS7)
sis/55x := $(___) -march=i586 $(FPU_MMX) $(TUNE_586MMX) $(OPT_SIMD) --param l1-cache-size=8 --param l2-cache-size=0
dmnp/m6117d := $(___) -march=i386 $(FPU_NONE) -mtune=i386 $(OPT_DEF) --param l1-cache-size=0 --param l2-cache-size=$(CACHE_386)
dmnp/vortex86sx := $(___) -march=i386 $(FPU_NONE) -mtune=i386 $(OPT_DEF) --param l1-cache-size=16 --param l2-cache-size=0
dmnp/vortex86dx := $(___) -march=i486 $(FPU_387) -mtune=i486 $(OPT_DEF) --param l1-cache-size=16 --param l2-cache-size=256
dmnp/vortex86mx := $(___) -march=i486 $(FPU_387) -mtune=i486 $(OPT_DEF) --param l1-cache-size=16 --param l2-cache-size=256
dmnp/vortex86 := $(___) -march=i586 $(FPU_MMX) $(TUNE_586MMX) $(OPT_SIMD) --param l1-cache-size=8 --param l2-cache-size=0
dmnp/vortex86dx2 := $(___) -march=i586 $(FPU_MMX) $(TUNE_586MMX) $(OPT_SIMD) --param l1-cache-size=16 --param l2-cache-size=256
dmnp/vortex86dx3 := $(___) -march=i686 $(FPU_SSE) $(TUNE_686SSE) $(OPT_SIMD) --param l1-cache-size=32 --param l2-cache-size=512
ifeq ($($(CPU)),)
$(error unknown CPU)
endif
CPUFLAGS := $($(CPU))
# parse CPU optimization options
ifeq ($(findstring -O3,$(CPUFLAGS)),-O3)
OPTIMIZE=vectorize
CPUFLAGS := $(filter-out -O3,$(CPUFLAGS))
endif
ifeq ($(findstring -Os,$(CPUFLAGS)),-Os)
OPTIMIZE=size
CPUFLAGS := $(filter-out -Os,$(CPUFLAGS))
endif
# Handle the no-FPU case by linking DJGPP's own emulator.
# DJGPP does not provide a suitable soft-float library for -mno-80397.
ifeq ($(findstring -mno-80387,$(CPUFLAGS)),-mno-80387)
CPU_CFLAGS := $(filter-out -mno-80387,$(CPUFLAGS)) -m80387
CPU_LDFLAGS :=
CPU_LDLIBS := -lemu
else ifeq ($(findstring -mno-fancy-math-387,$(CPUFLAGS)),-mno-fancy-math-387)
CPU_CFLAGS := $(filter-out -mno-fancy-math-387,$(CPUFLAGS))
CPU_LDFLAGS :=
CPU_LDLIBS := -lemu
else
CPU_CFLAGS := $(CPUFLAGS)
CPU_LDFLAGS :=
CPU_LDLIBS :=
endif
ifeq ($(FLAVOURED_DIR),1)
EXESUFFIX=.exe
ifeq ($(findstring -msse,$(CPUFLAGS)),-msse)
FLAVOUR_DIR=$(CPU)-sse/
FLAVOUR_O=.$(subst /,-,$(CPU)-sse)
else
FLAVOUR_DIR=$(CPU)/
FLAVOUR_O=.$(subst /,-,$(CPU))
endif
FLAVOUR_DIR_MADE:=$(shell $(MKDIR_P) bin/$(FLAVOUR_DIR))
else ifeq ($(FLAVOURED_EXE),1)
ifeq ($(CPU),generic/common)
EXESUFFIX=.exe
else
EXESUFFIX:=.exe
ifeq ($(findstring -msse,$(CPUFLAGS)),-msse)
EXESUFFIX:=-SSE$(EXESUFFIX)
endif
ifeq ($(OPTIMIZE),size)
EXESUFFIX:=-Os$(EXESUFFIX)
else ifeq ($(OPTIMIZE),speed)
EXESUFFIX:=-O2$(EXESUFFIX)
else ifeq ($(OPTIMIZE),vectorize)
EXESUFFIX:=-O3$(EXESUFFIX)
endif
EXESUFFIX:=-$(subst /,-,$(CPU))$(EXESUFFIX)
endif
ifeq ($(findstring -msse,$(CPUFLAGS)),-msse)
FLAVOUR_O=.$(subst /,-,$(CPU)-sse)
else
FLAVOUR_O=.$(subst /,-,$(CPU))
endif
else
EXESUFFIX=.exe
FLAVOUR_DIR=
FLAVOUR_O=
endif
CPPFLAGS +=
CXXFLAGS += $(CPU_CFLAGS)
CFLAGS += $(CPU_CFLAGS)
LDFLAGS += $(CPU_LDFLAGS)
LDLIBS += -lm $(CPU_LDLIBS)
ARFLAGS := rcs
OPTIMIZE_FASTMATH=1
include build/make/warnings-gcc.mk
DYNLINK=0
SHARED_LIB=0
@ -36,18 +384,24 @@ STATIC_LIB=1
SHARED_SONAME=0
DEBUG=0
OPTIMIZE=0
OPTIMIZE_SIZE=1
IS_CROSS=1
# generates warnings
MPT_COMPILER_NOVISIBILITY=1
# causes crashes on process shutdown,
# makes memory locking difficult
# causes crashes on process shutdown with liballegro
MPT_COMPILER_NOGCSECTIONS=1
ifeq ($(OPTIMIZE_LTO),1)
CXXFLAGS += -flto=auto -Wno-attributes
CFLAGS += -flto=auto -Wno-attributes
endif
ifneq ($(DEBUG),1)
LDFLAGS += -s
endif
ifeq ($(ALLOW_LGPL),1)
LOCAL_ZLIB=1
LOCAL_MPG123=1
@ -68,18 +422,4 @@ NO_SDL2=1
NO_SNDFILE=1
NO_FLAC=1
ifeq ($(BUNDLED_ALLEGRO42),1)
CPPFLAGS_ALLEGRO42 := -Iinclude/allegro42/include -DALLEGRO_HAVE_STDINT_H -DLONG_LONG="long long"
LDFLAGS_ALLEGRO42 :=
LDLIBS_ALLEGRO42 := include/allegro42/lib/djgpp/liballeg.a
include/allegro42/lib/djgpp/liballeg.a:
+cd include/allegro42 && ./xmake.sh clean
+cd include/allegro42 && ./xmake.sh lib
bin/openmpt123$(EXESUFFIX): include/allegro42/lib/djgpp/liballeg.a
MISC_OUTPUTS += include/allegro42/lib/djgpp/liballeg.a
endif
USE_ALLEGRO42=1

View file

@ -19,12 +19,18 @@ EMSCRIPTEN_PORTS?=0
ifneq ($(STDCXX),)
CXXFLAGS_STDCXX = -std=$(STDCXX)
else ifeq ($(shell printf '\n' > bin/empty.cpp ; if $(CXX) -std=c++20 -c bin/empty.cpp -o bin/empty.out > /dev/null 2>&1 ; then echo 'c++20' ; fi ), c++20)
CXXFLAGS_STDCXX = -std=c++20
else
ifeq ($(shell printf '\n' > bin/empty.cpp ; if $(CXX) -std=c++17 -c bin/empty.cpp -o bin/empty.out > /dev/null 2>&1 ; then echo 'c++17' ; fi ), c++17)
CXXFLAGS_STDCXX = -std=c++17
endif
ifneq ($(STDC),)
CFLAGS_STDC = -std=$(STDC)
else ifeq ($(shell printf '\n' > bin/empty.c ; if $(CC) -std=c17 -c bin/empty.c -o bin/empty.out > /dev/null 2>&1 ; then echo 'c17' ; fi ), c17)
CFLAGS_STDC = -std=c17
else
CFLAGS_STDC = -std=c11
endif
CFLAGS_STDC = -std=c99
CXXFLAGS += $(CXXFLAGS_STDCXX)
CFLAGS += $(CFLAGS_STDC)
@ -149,8 +155,7 @@ NO_SHARED_LINKER_FLAG=1
# Disable the generic compiler optimization flags as emscripten is sufficiently different.
# Optimization flags are hard-coded for emscripten in this file.
DEBUG=0
OPTIMIZE=0
OPTIMIZE_SIZE=0
OPTIMIZE=none
IS_CROSS=1

View file

@ -13,28 +13,49 @@ AR = $(TOOLCHAIN_PREFIX)ar$(TOOLCHAIN_SUFFIX)
endif
ifneq ($(STDCXX),)
CXXFLAGS_STDCXX = -std=$(STDCXX)
CXXFLAGS_STDCXX = -std=$(STDCXX) -fexceptions -frtti -pthread
else ifeq ($(shell printf '\n' > bin/empty.cpp ; if $(CXX) -std=c++20 -c bin/empty.cpp -o bin/empty.out > /dev/null 2>&1 ; then echo 'c++20' ; fi ), c++20)
CXXFLAGS_STDCXX = -std=c++20 -fexceptions -frtti -pthread
else
ifeq ($(shell printf '\n' > bin/empty.cpp ; if $(CXX) -std=c++17 -c bin/empty.cpp -o bin/empty.out > /dev/null 2>&1 ; then echo 'c++17' ; fi ), c++17)
CXXFLAGS_STDCXX = -std=c++17
CXXFLAGS_STDCXX = -std=c++17 -fexceptions -frtti -pthread
endif
ifneq ($(STDC),)
CFLAGS_STDC = -std=$(STDC) -pthread
else ifeq ($(shell printf '\n' > bin/empty.c ; if $(CC) -std=c17 -c bin/empty.c -o bin/empty.out > /dev/null 2>&1 ; then echo 'c17' ; fi ), c17)
CFLAGS_STDC = -std=c17 -pthread
else
CFLAGS_STDC = -std=c11 -pthread
endif
CFLAGS_STDC = -std=c99
CXXFLAGS += $(CXXFLAGS_STDCXX)
CFLAGS += $(CFLAGS_STDC)
LDFLAGS += -pthread
CPPFLAGS +=
CXXFLAGS += -fPIC
CFLAGS += -fPIC
CXXFLAGS += -fPIC
CFLAGS += -fPIC
LDFLAGS +=
LDLIBS += -lm
ARFLAGS := rcs
ifeq ($(NATIVE),1)
CXXFLAGS += -march=native
CFLAGS += -march=native
endif
ifeq ($(MODERN),1)
LDFLAGS += -fuse-ld=gold
endif
ifeq ($(OPTIMIZE_LTO),1)
CXXFLAGS += -flto
CFLAGS += -flto
endif
ifeq ($(ANALYZE),1)
CXXFLAGS += -fanalyzer -Wno-analyzer-malloc-leak -Wno-analyzer-null-dereference -Wno-analyzer-possible-null-argument -Wno-analyzer-possible-null-dereference
CFLAGS += -fanalyzer -Wno-analyzer-malloc-leak -Wno-analyzer-null-dereference -Wno-analyzer-possible-null-argument -Wno-analyzer-possible-null-dereference
endif
ifeq ($(CHECKED_ADDRESS),1)
CXXFLAGS += -fsanitize=address
CFLAGS += -fsanitize=address

View file

@ -1,34 +0,0 @@
$(warning warning: CONFIG=generic is deprecated. Use CONFIG=standard instead.)
ifeq ($(origin CC),default)
CC = cc
endif
ifeq ($(origin CXX),default)
CXX = c++
endif
ifeq ($(origin LD),default)
LD = $(CXX)
endif
ifeq ($(origin AR),default)
AR = ar
endif
CXXFLAGS_STDCXX = -std=c++17
CFLAGS_STDC = -std=c99
CXXFLAGS += $(CXXFLAGS_STDCXX)
CFLAGS += $(CFLAGS_STDC)
CPPFLAGS +=
CXXFLAGS +=
CFLAGS +=
LDFLAGS +=
LDLIBS +=
ARFLAGS := rcs
MPT_COMPILER_GENERIC=1
SHARED_LIB=0
DYNLINK=0
EXESUFFIX=

View file

@ -1,4 +0,0 @@
$(warning warning: CONFIG=haiku is deprecated. The OS is auto-detected.)
include config-defaults.mk

View file

@ -0,0 +1,69 @@
ifeq ($(origin CC),default)
CC = $(TOOLCHAIN_PREFIX)icx$(TOOLCHAIN_SUFFIX)
endif
ifeq ($(origin CXX),default)
CXX = $(TOOLCHAIN_PREFIX)icpx$(TOOLCHAIN_SUFFIX)
endif
ifeq ($(origin LD),default)
LD = $(CXX)
endif
ifeq ($(origin AR),default)
AR = $(TOOLCHAIN_PREFIX)ar$(TOOLCHAIN_SUFFIX)
endif
ifneq ($(STDCXX),)
CXXFLAGS_STDCXX = -std=$(STDCXX) -fexceptions -frtti -pthread
else ifeq ($(shell printf '\n' > bin/empty.cpp ; if $(CXX) -std=c++20 -c bin/empty.cpp -o bin/empty.out > /dev/null 2>&1 ; then echo 'c++20' ; fi ), c++20)
CXXFLAGS_STDCXX = -std=c++20 -fexceptions -frtti -pthread
else
CXXFLAGS_STDCXX = -std=c++17 -fexceptions -frtti -pthread
endif
ifneq ($(STDC),)
CFLAGS_STDC = -std=$(STDC) -pthread
else ifeq ($(shell printf '\n' > bin/empty.c ; if $(CC) -std=c17 -c bin/empty.c -o bin/empty.out > /dev/null 2>&1 ; then echo 'c17' ; fi ), c17)
CFLAGS_STDC = -std=c17 -pthread
else
CFLAGS_STDC = -std=c11 -pthread
endif
CXXFLAGS += $(CXXFLAGS_STDCXX)
CFLAGS += $(CFLAGS_STDC)
LDFLAGS += -pthread
CPPFLAGS +=
CXXFLAGS += -fPIC
CFLAGS += -fPIC
LDFLAGS +=
LDLIBS +=
ARFLAGS := rcs
MODERN=0
NATIVE=0
OPTIMIZE=vectorize
OPTIMIZE_FASTMATH=0
OPTIMIZE_LTO=1
FASTMATH_STYLE=
CXXFLAGS += -fp-model=precise
CFLAGS += -fp-model=precise
ifeq ($(OPTIMIZE_LTO),1)
CXXFLAGS += -ipo
CFLAGS += -ipo
LDFLAGS += -ipo
endif
ifeq ($(CHECKED_ADDRESS),1)
CXXFLAGS += -fsanitize=address
CFLAGS += -fsanitize=address
endif
ifeq ($(CHECKED_UNDEFINED),1)
CXXFLAGS += -fsanitize=undefined
CFLAGS += -fsanitize=undefined
endif
include build/make/warnings-clang.mk
EXESUFFIX=

View file

@ -1,4 +0,0 @@
$(warning warning: CONFIG=macosx is deprecated. The OS is auto-detected.)
include config-defaults.mk

View file

@ -26,12 +26,24 @@ ifeq ($(origin AR),default)
AR = $(MINGW_ARCH)-w64-mingw32-ar$(MINGW_FLAVOUR)
endif
ifneq ($(STDCXX),)
CXXFLAGS_STDCXX = -std=$(STDCXX) -fexceptions -frtti
else ifeq ($(shell printf '\n' > bin/empty.cpp ; if $(CXX) -std=c++20 -c bin/empty.cpp -o bin/empty.out > /dev/null 2>&1 ; then echo 'c++20' ; fi ), c++20)
CXXFLAGS_STDCXX = -std=c++20 -fexceptions -frtti
else
CXXFLAGS_STDCXX = -std=c++17 -fexceptions -frtti
CFLAGS_STDC = -std=c99
endif
ifneq ($(STDC),)
CFLAGS_STDC = -std=$(STDC)
else ifeq ($(shell printf '\n' > bin/empty.c ; if $(CC) -std=c17 -c bin/empty.c -o bin/empty.out > /dev/null 2>&1 ; then echo 'c17' ; fi ), c17)
CFLAGS_STDC = -std=c17
else
CFLAGS_STDC = -std=c11
endif
CXXFLAGS += $(CXXFLAGS_STDCXX)
CFLAGS += $(CFLAGS_STDC)
CPPFLAGS +=
CPPFLAGS += -DNOMINMAX
ifeq ($(MINGW_COMPILER),clang)
CXXFLAGS += -municode
CFLAGS += -municode
@ -41,9 +53,12 @@ CXXFLAGS += -municode -mthreads
CFLAGS += -municode -mthreads
LDFLAGS += -mconsole
endif
LDLIBS += -lm -lole32 -lrpcrt4 -lwinmm
LDLIBS += -lm
ARFLAGS := rcs
LDLIBS_LIBOPENMPTTEST += -lole32 -lrpcrt4
LDLIBS_OPENMPT123 += -lwinmm
PC_LIBS_PRIVATE += -lole32 -lrpcrt4
ifeq ($(WINDOWS_FAMILY),)
@ -52,13 +67,10 @@ else ifeq ($(WINDOWS_FAMILY),desktop-app)
# nothing
else ifeq ($(WINDOWS_FAMILY),app)
CPPFLAGS += -DWINAPI_FAMILY=2
OPENMPT123=0
else ifeq ($(WINDOWS_FAMILY),phone-app)
CPPFLAGS += -DWINAPI_FAMILY=3
OPENMPT123=0
else ifeq ($(WINDOWS_FAMILY),pc-app)
CPPFLAGS += -DWINAPI_FAMILY=2
OPENMPT123=0
else
$(error unknown WINDOWS_FAMILY)
endif
@ -74,11 +86,11 @@ CPPFLAGS += -D_WIN32_WINDOWS=0x0490
else ifeq ($(WINDOWS_VERSION),winnt4)
CPPFLAGS += -D_WIN32_WINNT=0x0400
else ifeq ($(WINDOWS_VERSION),win2000)
CPPFLAGS += -D_WIN32_WINNT=0x0500
CPPFLAGS += -DNTDDI_VERSION=0x05000000 -D_WIN32_WINNT=0x0500
else ifeq ($(WINDOWS_VERSION),winxp)
CPPFLAGS += -D_WIN32_WINNT=0x0501
CPPFLAGS += -DNTDDI_VERSION=0x05010000 -D_WIN32_WINNT=0x0501
else ifeq ($(WINDOWS_VERSION),winxp64)
CPPFLAGS += -D_WIN32_WINNT=0x0502
CPPFLAGS += -DNTDDI_VERSION=0x05020100 -D_WIN32_WINNT=0x0502
else ifeq ($(WINDOWS_VERSION),winvista)
CPPFLAGS += -DNTDDI_VERSION=0x06000000 -D_WIN32_WINNT=0x0600
else ifeq ($(WINDOWS_VERSION),win7)
@ -89,6 +101,8 @@ else ifeq ($(WINDOWS_VERSION),win8.1)
CPPFLAGS += -DNTDDI_VERSION=0x06030000 -D_WIN32_WINNT=0x0603
else ifeq ($(WINDOWS_VERSION),win10)
CPPFLAGS += -DNTDDI_VERSION=0x0A000000 -D_WIN32_WINNT=0x0A00
else ifeq ($(WINDOWS_VERSION),win11)
CPPFLAGS += -DNTDDI_VERSION=0x0A00000B -D_WIN32_WINNT=0x0A00
else
$(error unknown WINDOWS_VERSION)
endif

View file

@ -1,66 +0,0 @@
ifeq ($(origin CC),default)
CC = mingw32-gcc$(MINGW_FLAVOUR)
endif
ifeq ($(origin CXX),default)
CXX = mingw32-g++$(MINGW_FLAVOUR)
endif
ifeq ($(origin LD),default)
LD = $(CXX)
endif
ifeq ($(origin AR),default)
AR = mingw32-gcc-ar$(MINGW_FLAVOUR)
endif
CXXFLAGS_STDCXX = -std=gnu++17
CFLAGS_STDC = -std=gnu99
CXXFLAGS += $(CXXFLAGS_STDCXX)
CFLAGS += $(CFLAGS_STDC)
CPPFLAGS += -DWIN32 -D_WIN32 -DWINVER=0x0410 -D_WIN32_WINDOWS=0x0410 -DMPT_BUILD_RETRO
CXXFLAGS += -mconsole -mthreads
CFLAGS += -mconsole -mthreads
LDFLAGS +=
LDLIBS += -lm -lole32 -lrpcrt4 -lwinmm
ARFLAGS := rcs
LDFLAGS += -static -static-libgcc -static-libstdc++
#CXXFLAGS += -ffunction-sections -fdata-sections
#CFLAGS += -ffunction-sections -fdata-sections
#LDFLAGS += -Wl,--gc-sections
CXXFLAGS += -march=i486 -m80387 -mtune=pentium
CFLAGS += -march=i486 -m80387 -mtune=pentium
PC_LIBS_PRIVATE += -lole32 -lrpcrt4
include build/make/warnings-gcc.mk
EXESUFFIX=.exe
SOSUFFIX=.dll
SOSUFFIXWINDOWS=1
DYNLINK=0
SHARED_LIB=1
STATIC_LIB=0
SHARED_SONAME=0
FORCE_UNIX_STYLE_COMMANDS=1
IN_OPENMPT=1
XMP_OPENMPT=1
IS_CROSS=1
NO_ZLIB=1
NO_MPG123=1
NO_OGG=1
NO_VORBIS=1
NO_VORBISFILE=1
NO_PORTAUDIO=1
NO_PORTAUDIOCPP=1
NO_PULSEAUDIO=1
NO_SDL2=1
NO_SNDFILE=1
NO_FLAC=1

View file

@ -0,0 +1,106 @@
ifeq ($(origin CC),default)
CC = mingw32-gcc$(MINGW_FLAVOUR)
endif
ifeq ($(origin CXX),default)
CXX = mingw32-g++$(MINGW_FLAVOUR)
endif
ifeq ($(origin LD),default)
LD = $(CXX)
endif
ifeq ($(origin AR),default)
AR = mingw32-gcc-ar$(MINGW_FLAVOUR)
endif
ifneq ($(STDCXX),)
CXXFLAGS_STDCXX = -std=$(STDCXX) -fexceptions -frtti
else ifeq ($(shell printf '\n' > bin/empty.cpp ; if $(CXX) -std=gnu++20 -c bin/empty.cpp -o bin/empty.out > /dev/null 2>&1 ; then echo 'c++20' ; fi ), c++20)
CXXFLAGS_STDCXX = -std=gnu++20 -fexceptions -frtti
else
CXXFLAGS_STDCXX = -std=gnu++17 -fexceptions -frtti
endif
ifneq ($(STDC),)
CFLAGS_STDC = -std=$(STDC)
else ifeq ($(shell printf '\n' > bin/empty.c ; if $(CC) -std=gnu17 -c bin/empty.c -o bin/empty.out > /dev/null 2>&1 ; then echo 'c17' ; fi ), c17)
CFLAGS_STDC = -std=gnu17
else
CFLAGS_STDC = -std=gnu11
endif
CXXFLAGS += $(CXXFLAGS_STDCXX)
CFLAGS += $(CFLAGS_STDC)
CPPFLAGS += -DNOMINMAX
CPPFLAGS += -DMPT_BUILD_RETRO
CXXFLAGS += -mconsole -mthreads
CFLAGS += -mconsole -mthreads
LDFLAGS +=
LDLIBS += -lm
ARFLAGS := rcs
ifeq ($(WINDOWS_VERSION),)
# nothing
else ifeq ($(WINDOWS_VERSION),win95)
CPPFLAGS += -DWINVER=0x0400 -D_WIN32_WINDOWS=0x0400
else ifeq ($(WINDOWS_VERSION),win98)
CPPFLAGS += -DWINVER=0x0410 -D_WIN32_WINDOWS=0x0410
else ifeq ($(WINDOWS_VERSION),winme)
CPPFLAGS += -DWINVER=0x0490 -D_WIN32_WINDOWS=0x0490
else ifeq ($(WINDOWS_VERSION),winnt4)
CPPFLAGS += -D_WIN32_WINNT=0x0400
else ifeq ($(WINDOWS_VERSION),win2000)
CPPFLAGS += -D_WIN32_WINNT=0x0500
else ifeq ($(WINDOWS_VERSION),winxp)
CPPFLAGS += -D_WIN32_WINNT=0x0501
else
$(error unknown WINDOWS_VERSION)
endif
LDLIBS_LIBOPENMPTTEST += -lole32 -lrpcrt4
LDLIBS_OPENMPT123 += -lwinmm
LDFLAGS += -static -static-libgcc -static-libstdc++
# enable gc-sections for all configurations in order to remove as much of the
# stdlib as possible
MPT_COMPILER_NOSECTIONS=1
MPT_COMPILER_NOGCSECTIONS=1
CXXFLAGS += -ffunction-sections -fdata-sections
CFLAGS += -ffunction-sections -fdata-sections
LDFLAGS += -Wl,--gc-sections
CXXFLAGS += -march=i586 -m80387 -mtune=pentium
CFLAGS += -march=i586 -m80387 -mtune=pentium
PC_LIBS_PRIVATE += -lole32 -lrpcrt4
include build/make/warnings-gcc.mk
EXESUFFIX=.exe
SOSUFFIX=.dll
SOSUFFIXWINDOWS=1
DYNLINK=0
SHARED_LIB=1
STATIC_LIB=0
SHARED_SONAME=0
OPTIMIZE=size
FORCE_UNIX_STYLE_COMMANDS=1
IN_OPENMPT=1
XMP_OPENMPT=1
IS_CROSS=1
NO_ZLIB=1
NO_MPG123=1
NO_OGG=1
NO_VORBIS=1
NO_VORBISFILE=1
NO_PORTAUDIO=1
NO_PORTAUDIOCPP=1
NO_PULSEAUDIO=1
NO_SDL2=1
NO_SNDFILE=1
NO_FLAC=1

View file

@ -0,0 +1,107 @@
ifeq ($(origin CC),default)
CC = i386-mingw32crt-gcc$(MINGW_FLAVOUR)
endif
ifeq ($(origin CXX),default)
CXX = i386-mingw32crt-g++$(MINGW_FLAVOUR)
endif
ifeq ($(origin LD),default)
LD = $(CXX)
endif
ifeq ($(origin AR),default)
AR = i386-mingw32crt-gcc-ar$(MINGW_FLAVOUR)
endif
ifneq ($(STDCXX),)
CXXFLAGS_STDCXX = -std=$(STDCXX) -fexceptions -frtti
else ifeq ($(shell printf '\n' > bin/empty.cpp ; if $(CXX) -std=gnu++20 -c bin/empty.cpp -o bin/empty.out > /dev/null 2>&1 ; then echo 'c++20' ; fi ), c++20)
CXXFLAGS_STDCXX = -std=gnu++20 -fexceptions -frtti
else
CXXFLAGS_STDCXX = -std=gnu++17 -fexceptions -frtti
endif
ifneq ($(STDC),)
CFLAGS_STDC = -std=$(STDC)
else ifeq ($(shell printf '\n' > bin/empty.c ; if $(CC) -std=gnu17 -c bin/empty.c -o bin/empty.out > /dev/null 2>&1 ; then echo 'c17' ; fi ), c17)
CFLAGS_STDC = -std=gnu17
else
CFLAGS_STDC = -std=gnu11
endif
CXXFLAGS += $(CXXFLAGS_STDCXX)
CFLAGS += $(CFLAGS_STDC)
CPPFLAGS += -DNOMINMAX
CPPFLAGS += -DMPT_BUILD_RETRO
CXXFLAGS += -mconsole -mthreads
CFLAGS += -mconsole -mthreads
LDFLAGS +=
LDLIBS += -lm
ARFLAGS := rcs
ifeq ($(WINDOWS_VERSION),)
# nothing
else ifeq ($(WINDOWS_VERSION),win95)
CPPFLAGS += -DWINVER=0x0400 -D_WIN32_WINDOWS=0x0400
else ifeq ($(WINDOWS_VERSION),win98)
CPPFLAGS += -DWINVER=0x0410 -D_WIN32_WINDOWS=0x0410
else ifeq ($(WINDOWS_VERSION),winme)
CPPFLAGS += -DWINVER=0x0490 -D_WIN32_WINDOWS=0x0490
else ifeq ($(WINDOWS_VERSION),winnt4)
CPPFLAGS += -D_WIN32_WINNT=0x0400
else ifeq ($(WINDOWS_VERSION),win2000)
CPPFLAGS += -D_WIN32_WINNT=0x0500
else ifeq ($(WINDOWS_VERSION),winxp)
CPPFLAGS += -D_WIN32_WINNT=0x0501
else
$(error unknown WINDOWS_VERSION)
endif
LDLIBS_LIBOPENMPTTEST += -lole32 -lrpcrt4
LDLIBS_OPENMPT123 += -lwinmm
LDFLAGS += -static -static-libgcc -static-libstdc++
# enable gc-sections for all configurations in order to remove as much of the
# stdlib as possible
MPT_COMPILER_NOSECTIONS=1
MPT_COMPILER_NOGCSECTIONS=1
CXXFLAGS += -ffunction-sections -fdata-sections
CFLAGS += -ffunction-sections -fdata-sections
LDFLAGS += -Wl,--gc-sections
CXXFLAGS += -march=i386 -m80387 -mtune=i486
CFLAGS += -march=i386 -m80387 -mtune=i486
PC_LIBS_PRIVATE += -lole32 -lrpcrt4
include build/make/warnings-gcc.mk
EXESUFFIX=.exe
SOSUFFIX=.dll
SOSUFFIXWINDOWS=1
DYNLINK=0
SHARED_LIB=1
STATIC_LIB=0
SHARED_SONAME=0
OPTIMIZE=size
FORCE_UNIX_STYLE_COMMANDS=1
EXAMPLES=0
IN_OPENMPT=0
XMP_OPENMPT=0
IS_CROSS=1
NO_ZLIB=1
NO_MPG123=1
NO_OGG=1
NO_VORBIS=1
NO_VORBISFILE=1
NO_PORTAUDIO=1
NO_PORTAUDIOCPP=1
NO_PULSEAUDIO=1
NO_SDL2=1
NO_SNDFILE=1
NO_FLAC=1

View file

@ -1,65 +0,0 @@
ifeq ($(origin CC),default)
CC = i686-w64-mingw32-gcc$(MINGW_FLAVOUR)
endif
ifeq ($(origin CXX),default)
CXX = i686-w64-mingw32-g++$(MINGW_FLAVOUR)
endif
ifeq ($(origin LD),default)
LD = $(CXX)
endif
ifeq ($(origin AR),default)
AR = i686-w64-mingw32-ar$(MINGW_FLAVOUR)
endif
CXXFLAGS_STDCXX = -std=c++17
CFLAGS_STDC = -std=c99
CXXFLAGS += $(CXXFLAGS_STDCXX)
CFLAGS += $(CFLAGS_STDC)
CPPFLAGS += -DWIN32 -D_WIN32
ifeq ($(MINGW_COMPILER),clang)
CXXFLAGS += -municode
CFLAGS += -municode
LDFLAGS += -mconsole -mthreads
else
CXXFLAGS += -municode -mthreads
CFLAGS += -municode -mthreads
LDFLAGS += -mconsole
endif
LDLIBS += -lm -lole32 -lrpcrt4 -lwinmm
ARFLAGS := rcs
PC_LIBS_PRIVATE += -lole32 -lrpcrt4
ifeq ($(MINGW_COMPILER),clang)
include build/make/warnings-clang.mk
else
include build/make/warnings-gcc.mk
endif
EXESUFFIX=.exe
SOSUFFIX=.dll
SOSUFFIXWINDOWS=1
DYNLINK=0
SHARED_LIB=1
STATIC_LIB=0
SHARED_SONAME=0
IS_CROSS=1
NO_ZLIB=1
NO_LTDL=1
NO_DL=1
NO_MPG123=1
NO_OGG=1
NO_VORBIS=1
NO_VORBISFILE=1
NO_PORTAUDIO=1
NO_PORTAUDIOCPP=1
NO_PULSEAUDIO=1
NO_SDL=1
NO_SDL2=1
NO_SNDFILE=1
NO_FLAC=1

View file

@ -1,65 +0,0 @@
ifeq ($(origin CC),default)
CC = x86_64-w64-mingw32-gcc$(MINGW_FLAVOUR)
endif
ifeq ($(origin CXX),default)
CXX = x86_64-w64-mingw32-g++$(MINGW_FLAVOUR)
endif
ifeq ($(origin LD),default)
LD = $(CXX)
endif
ifeq ($(origin AR),default)
AR = x86_64-w64-mingw32-ar$(MINGW_FLAVOUR)
endif
CXXFLAGS_STDCXX = -std=c++17
CFLAGS_STDC = -std=c99
CXXFLAGS += $(CXXFLAGS_STDCXX)
CFLAGS += $(CFLAGS_STDC)
CPPFLAGS += -DWIN32 -D_WIN32 -DWIN64 -D_WIN64
ifeq ($(MINGW_COMPILER),clang)
CXXFLAGS += -municode
CFLAGS += -municode
LDFLAGS += -mconsole -mthreads
else
CXXFLAGS += -municode -mthreads
CFLAGS += -municode -mthreads
LDFLAGS += -mconsole
endif
LDLIBS += -lm -lole32 -lrpcrt4 -lwinmm
ARFLAGS := rcs
PC_LIBS_PRIVATE += -lole32 -lrpcrt4
ifeq ($(MINGW_COMPILER),clang)
include build/make/warnings-clang.mk
else
include build/make/warnings-gcc.mk
endif
EXESUFFIX=.exe
SOSUFFIX=.dll
SOSUFFIXWINDOWS=1
DYNLINK=0
SHARED_LIB=1
STATIC_LIB=0
SHARED_SONAME=0
IS_CROSS=1
NO_ZLIB=1
NO_LTDL=1
NO_DL=1
NO_MPG123=1
NO_OGG=1
NO_VORBIS=1
NO_VORBISFILE=1
NO_PORTAUDIO=1
NO_PORTAUDIOCPP=1
NO_PULSEAUDIO=1
NO_SDL=1
NO_SDL2=1
NO_SNDFILE=1
NO_FLAC=1

View file

@ -1,67 +0,0 @@
ifeq ($(origin CC),default)
CC = x86_64-w64-mingw32-gcc$(MINGW_FLAVOUR)
endif
ifeq ($(origin CXX),default)
CXX = x86_64-w64-mingw32-g++$(MINGW_FLAVOUR)
endif
ifeq ($(origin LD),default)
LD = $(CXX)
endif
ifeq ($(origin AR),default)
AR = x86_64-w64-mingw32-ar$(MINGW_FLAVOUR)
endif
CXXFLAGS_STDCXX = -std=c++17
CFLAGS_STDC = -std=c99
CXXFLAGS += $(CXXFLAGS_STDCXX)
CFLAGS += $(CFLAGS_STDC)
CPPFLAGS += -DWIN32 -D_WIN32 -DWIN64 -D_WIN64 -DWINAPI_FAMILY=0x2 -D_WIN32_WINNT=0x0602
ifeq ($(MINGW_COMPILER),clang)
CXXFLAGS += -municode
CFLAGS += -municode
LDFLAGS += -mconsole -mthreads
else
CXXFLAGS += -municode -mthreads
CFLAGS += -municode -mthreads
LDFLAGS += -mconsole
endif
LDLIBS += -lm -lole32 -lwinmm
ARFLAGS := rcs
PC_LIBS_PRIVATE += -lole32 -lrpcrt4
ifeq ($(MINGW_COMPILER),clang)
include build/make/warnings-clang.mk
else
include build/make/warnings-gcc.mk
endif
EXESUFFIX=.exe
SOSUFFIX=.dll
SOSUFFIXWINDOWS=1
DYNLINK=0
SHARED_LIB=1
STATIC_LIB=0
SHARED_SONAME=0
IS_CROSS=1
OPENMPT123=0
NO_ZLIB=1
NO_LTDL=1
NO_DL=1
NO_MPG123=1
NO_OGG=1
NO_VORBIS=1
NO_VORBISFILE=1
NO_PORTAUDIO=1
NO_PORTAUDIOCPP=1
NO_PULSEAUDIO=1
NO_SDL=1
NO_SDL2=1
NO_SNDFILE=1
NO_FLAC=1

View file

@ -1,67 +0,0 @@
ifeq ($(origin CC),default)
CC = i686-w64-mingw32-gcc$(MINGW_FLAVOUR)
endif
ifeq ($(origin CXX),default)
CXX = i686-w64-mingw32-g++$(MINGW_FLAVOUR)
endif
ifeq ($(origin LD),default)
LD = $(CXX)
endif
ifeq ($(origin AR),default)
AR = i686-w64-mingw32-ar$(MINGW_FLAVOUR)
endif
CXXFLAGS_STDCXX = -std=c++17
CFLAGS_STDC = -std=c99
CXXFLAGS += $(CXXFLAGS_STDCXX)
CFLAGS += $(CFLAGS_STDC)
CPPFLAGS += -DWIN32 -D_WIN32 -DWINAPI_FAMILY=0x2 -D_WIN32_WINNT=0x0602
ifeq ($(MINGW_COMPILER),clang)
CXXFLAGS += -municode
CFLAGS += -municode
LDFLAGS += -mconsole -mthreads
else
CXXFLAGS += -municode -mthreads
CFLAGS += -municode -mthreads
LDFLAGS += -mconsole
endif
LDLIBS += -lm -lole32 -lrpcrt4 -lwinmm
ARFLAGS := rcs
PC_LIBS_PRIVATE += -lole32 -lrpcrt4
ifeq ($(MINGW_COMPILER),clang)
include build/make/warnings-clang.mk
else
include build/make/warnings-gcc.mk
endif
EXESUFFIX=.exe
SOSUFFIX=.dll
SOSUFFIXWINDOWS=1
DYNLINK=0
SHARED_LIB=1
STATIC_LIB=0
SHARED_SONAME=0
IS_CROSS=1
OPENMPT123=0
NO_ZLIB=1
NO_LTDL=1
NO_DL=1
NO_MPG123=1
NO_OGG=1
NO_VORBIS=1
NO_VORBISFILE=1
NO_PORTAUDIO=1
NO_PORTAUDIOCPP=1
NO_PULSEAUDIO=1
NO_SDL=1
NO_SDL2=1
NO_SNDFILE=1
NO_FLAC=1

View file

@ -13,7 +13,7 @@ AR = ar
endif
CXXFLAGS_STDCXX = -std=c++17
CFLAGS_STDC = -std=c99
CFLAGS_STDC = -std=c17
CXXFLAGS += $(CXXFLAGS_STDCXX)
CFLAGS += $(CFLAGS_STDC)

View file

@ -0,0 +1,32 @@
ifeq ($(origin CC),default)
CC = cc
endif
ifeq ($(origin CXX),default)
CXX = c++
endif
ifeq ($(origin LD),default)
LD = $(CXX)
endif
ifeq ($(origin AR),default)
AR = ar
endif
CXXFLAGS_STDCXX = -std=c++17
CFLAGS_STDC = -std=c11
CXXFLAGS += $(CXXFLAGS_STDCXX)
CFLAGS += $(CFLAGS_STDC)
CPPFLAGS +=
CXXFLAGS +=
CFLAGS +=
LDFLAGS +=
LDLIBS +=
ARFLAGS := rcs
MPT_COMPILER_GENERIC=1
SHARED_LIB=0
DYNLINK=0
EXESUFFIX=

View file

@ -1,8 +1,9 @@
CXXFLAGS_WARNINGS += -Wcast-align -Wcast-qual -Wmissing-prototypes -Wshift-count-negative -Wshift-count-overflow -Wshift-op-parentheses -Wshift-overflow -Wshift-sign-overflow -Wundef
CFLAGS_WARNINGS += -Wcast-align -Wcast-qual -Wmissing-prototypes -Wshift-count-negative -Wshift-count-overflow -Wshift-op-parentheses -Wshift-overflow -Wshift-sign-overflow -Wundef
CXXFLAGS_WARNINGS += -Wcast-align -Wcast-qual -Wdouble-promotion -Wfloat-conversion -Wmissing-prototypes -Wshift-count-negative -Wshift-count-overflow -Wshift-op-parentheses -Wshift-overflow -Wshift-sign-overflow -Wundef
CFLAGS_WARNINGS += -Wcast-align -Wcast-qual -Wdouble-promotion -Wfloat-conversion -Wmissing-prototypes -Wshift-count-negative -Wshift-count-overflow -Wshift-op-parentheses -Wshift-overflow -Wshift-sign-overflow -Wundef
CXXFLAGS_WARNINGS += -Wdeprecated -Wextra-semi -Wframe-larger-than=16000 -Wglobal-constructors -Wimplicit-fallthrough -Wmissing-declarations -Wnon-virtual-dtor -Wreserved-id-macro
CFLAGS_WARNINGS += -Wframe-larger-than=4000
#CXXFLAGS_WARNINGS += -Wfloat-equal
#CXXFLAGS_WARNINGS += -Wdocumentation
@ -10,23 +11,21 @@ CXXFLAGS_WARNINGS += -Wdeprecated -Wextra-semi -Wframe-larger-than=16000 -Wgloba
#CXXFLAGS_WARNINGS += -Weverything -Wno-c++98-compat -Wno-c++98-compat-pedantic -Wno-c++98-c++11-c++14-compat -Wno-padded -Wno-weak-vtables -Wno-sign-conversion -Wno-shadow-field-in-constructor -Wno-conversion -Wno-switch-enum -Wno-old-style-cast
ifeq ($(MODERN),1)
LDFLAGS += -fuse-ld=lld
ifeq ($(OPTIMIZE_LTO),1)
LDFLAGS += -Wl,--thinlto-jobs=all
endif
CXXFLAGS_WARNINGS +=
CFLAGS_WARNINGS += -Wframe-larger-than=4000
CFLAGS_WARNINGS +=
LDFLAGS_WARNINGS += -Wl,-no-undefined -Wl,--detect-odr-violations
# re-renable after 1.29 branch
#CXXFLAGS_WARNINGS += -Wdouble-promotion
#CFLAGS_WARNINGS += -Wdouble-promotion
endif
CFLAGS_SILENT += -Wno-\#warnings
CFLAGS_SILENT += -Wno-cast-align
CFLAGS_SILENT += -Wno-cast-qual
CFLAGS_SILENT += -Wno-double-promotion
CFLAGS_SILENT += -Wno-float-conversion
CFLAGS_SILENT += -Wno-frame-larger-than
CFLAGS_SILENT += -Wno-missing-prototypes
CFLAGS_SILENT += -Wno-sign-compare
CFLAGS_SILENT += -Wno-unused-function
CFLAGS_SILENT += -Wno-unused-parameter
CFLAGS_SILENT += -Wno-unused-variable
FASTMATH_STYLE=clang

View file

@ -1,21 +1,21 @@
CXXFLAGS_WARNINGS += -Wcast-align -Wcast-qual -Wfloat-conversion -Wframe-larger-than=16000 -Winit-self -Wlogical-op -Wmissing-declarations -Wpointer-arith -Wstrict-aliasing -Wsuggest-override -Wundef
CFLAGS_WARNINGS += -Wcast-align -Wcast-qual -Wfloat-conversion -Wlogical-op -Wundef
CXXFLAGS_WARNINGS += -Wcast-align -Wcast-qual -Wdouble-promotion -Wfloat-conversion -Wframe-larger-than=16000 -Winit-self -Wlogical-op -Wmissing-declarations -Wpointer-arith -Wstrict-aliasing -Wsuggest-override -Wundef
CFLAGS_WARNINGS += -Wcast-align -Wcast-qual -Wdouble-promotion -Wfloat-conversion -Wlogical-op -Wstrict-prototypes -Wundef
CXXFLAGS_WARNINGS += -Wno-psabi
ifeq ($(MODERN),1)
LDFLAGS += -fuse-ld=gold
CXXFLAGS_WARNINGS +=
CFLAGS_WARNINGS += -Wframe-larger-than=4000
#CXXFLAGS_WARNINGS += -Wstrict-aliasing -Wpointer-arith -Winit-self -Wshadow -Wswitch-enum -Wstrict-prototypes
CFLAGS_WARNINGS += -Wframe-larger-than=4000
#CXXFLAGS_WARNINGS += -Wshadow -Wswitch-enum
# gold
LDFLAGS_WARNINGS += -Wl,-no-undefined -Wl,--detect-odr-violations
# re-renable after 1.29 branch
#CXXFLAGS_WARNINGS += -Wdouble-promotion
#CFLAGS_WARNINGS += -Wdouble-promotion
# GCC 8
CXXFLAGS_WARNINGS += -Wcast-align=strict
CFLAGS_WARNINGS += -Wcast-align=strict
endif
CFLAGS_SILENT += -Wno-cast-qual
CFLAGS_SILENT += -Wno-double-promotion
CFLAGS_SILENT += -Wno-empty-body
CFLAGS_SILENT += -Wno-float-conversion
CFLAGS_SILENT += -Wno-implicit-fallthrough
@ -26,3 +26,5 @@ CFLAGS_SILENT += -Wno-type-limits
CFLAGS_SILENT += -Wno-unused-but-set-variable
CFLAGS_SILENT += -Wno-unused-function
CFLAGS_SILENT += -Wno-unused-parameter
FASTMATH_STYLE=gcc

View file

@ -1,10 +1,10 @@
#pragma once
#define OPENMPT_VERSION_SVNVERSION "18680"
#define OPENMPT_VERSION_REVISION 18680
#define OPENMPT_VERSION_SVNVERSION "19147"
#define OPENMPT_VERSION_REVISION 19147
#define OPENMPT_VERSION_DIRTY 0
#define OPENMPT_VERSION_MIXEDREVISIONS 0
#define OPENMPT_VERSION_URL "https://source.openmpt.org/svn/openmpt/tags/libopenmpt-0.6.8"
#define OPENMPT_VERSION_DATE "2023-01-29T12:13:49.877060Z"
#define OPENMPT_VERSION_URL "https://source.openmpt.org/svn/openmpt/tags/libopenmpt-0.7.0"
#define OPENMPT_VERSION_DATE "2023-04-30T12:58:58.547157Z"
#define OPENMPT_VERSION_IS_PACKAGE 1

View file

@ -0,0 +1,341 @@
// !$*UTF8*$!
{
archiveVersion = 1;
classes = {
};
objectVersion = 46;
objects = {
/* Begin PBXBuildFile section */
022CF042734F913429163E82 /* layer3.c in Sources */ = {isa = PBXBuildFile; fileRef = BAACDA4AE2E792FCCA83208A /* layer3.c */; };
022FC83459953B260BA35674 /* synth_real.c in Sources */ = {isa = PBXBuildFile; fileRef = C3CD341CF5C67ECE6FA5BA5C /* synth_real.c */; };
0DDEA7A4A06C7196094515E4 /* optimize.c in Sources */ = {isa = PBXBuildFile; fileRef = 1B61528CDECD143E1D70B8CC /* optimize.c */; };
142B46E0854DE7D23B149520 /* layer2.c in Sources */ = {isa = PBXBuildFile; fileRef = 9796B208BFD16ABAA76CF848 /* layer2.c */; };
21B328E68EDB3758906E2726 /* equalizer.c in Sources */ = {isa = PBXBuildFile; fileRef = 0F54AFAE5CB7A5E0D2D6A5EE /* equalizer.c */; };
242DF798687C9D0AAAA3D5D8 /* tabinit.c in Sources */ = {isa = PBXBuildFile; fileRef = 6B2790408CF33D72C9A86680 /* tabinit.c */; };
26299D7E974C3E704D12EBBE /* layer1.c in Sources */ = {isa = PBXBuildFile; fileRef = 748089C69CBB42788456D006 /* layer1.c */; };
2CE230149E04D10653CB7E54 /* format.c in Sources */ = {isa = PBXBuildFile; fileRef = AD3049FCD56B02AEBD06903C /* format.c */; };
2F06D05D7C69C68FF288C69D /* compat.c in Sources */ = {isa = PBXBuildFile; fileRef = A7ABBCE59297E2D7DA7DAB25 /* compat.c */; };
5BC0EB1CC8E8F98ECA7BE95C /* synth_s32.c in Sources */ = {isa = PBXBuildFile; fileRef = 739C6384C0FF59B6371E59C4 /* synth_s32.c */; };
64A7B16E5E696DE098686FAE /* synth.c in Sources */ = {isa = PBXBuildFile; fileRef = 907B4FB6D8EC33E81D8B05F6 /* synth.c */; };
6C03B21AB052578CF279905A /* feature.c in Sources */ = {isa = PBXBuildFile; fileRef = A60D55A2C7D902D4048E2BE2 /* feature.c */; };
82DB3C387C9CF8AAB69BFA78 /* parse.c in Sources */ = {isa = PBXBuildFile; fileRef = 440E80E08C7F6512D11E3720 /* parse.c */; };
8ADD039E1D6ACD90864371DE /* icy2utf8.c in Sources */ = {isa = PBXBuildFile; fileRef = C3752BE686E0ED98C5849226 /* icy2utf8.c */; };
9CA288B296644524D06346F2 /* index.c in Sources */ = {isa = PBXBuildFile; fileRef = 754AC0BABDBBA4EC025A76FA /* index.c */; };
BCB343AA29DB521C2B6E41EA /* stringbuf.c in Sources */ = {isa = PBXBuildFile; fileRef = 0BDCDC32593FD264CF5ED272 /* stringbuf.c */; };
C2065F0E06550480487C3D4E /* readers.c in Sources */ = {isa = PBXBuildFile; fileRef = 489101566A5CAE88A711D796 /* readers.c */; };
C39C716430C47FD632576FA4 /* libmpg123.c in Sources */ = {isa = PBXBuildFile; fileRef = 54E0A14CA243977E1862978C /* libmpg123.c */; };
C3D66B021F17BE74F2720942 /* id3.c in Sources */ = {isa = PBXBuildFile; fileRef = F56A100A0C7CAB3CFC98A64A /* id3.c */; };
D1E3070CCBA4C37E05A3C54C /* dct64.c in Sources */ = {isa = PBXBuildFile; fileRef = F4F6A4743D6788A682065AB4 /* dct64.c */; };
D618207A2D7D936CDF8BAEBA /* synth_8bit.c in Sources */ = {isa = PBXBuildFile; fileRef = A1E03F02D3D989B44DB8C542 /* synth_8bit.c */; };
E236244C3D7777BE10D1C28C /* icy.c in Sources */ = {isa = PBXBuildFile; fileRef = E598BBB4FCAB56E6ECC751F4 /* icy.c */; };
EAB0691E1B9461102EAC975E /* ntom.c in Sources */ = {isa = PBXBuildFile; fileRef = 5B10DD6681370D18E83E03A6 /* ntom.c */; };
EE6448D8E826054A22250718 /* frame.c in Sources */ = {isa = PBXBuildFile; fileRef = 78DBF380C14CD7B205EBA9C0 /* frame.c */; };
F155B58DD59CBDBF5989EBCD /* compat_str.c in Sources */ = {isa = PBXBuildFile; fileRef = CDD5DB15FEB9D30711D20955 /* compat_str.c */; };
/* End PBXBuildFile section */
/* Begin PBXFileReference section */
0BDCDC32593FD264CF5ED272 /* stringbuf.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; name = stringbuf.c; path = ../../../include/mpg123/src/libmpg123/stringbuf.c; sourceTree = "<group>"; };
0F54AFAE5CB7A5E0D2D6A5EE /* equalizer.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; name = equalizer.c; path = ../../../include/mpg123/src/libmpg123/equalizer.c; sourceTree = "<group>"; };
1B61528CDECD143E1D70B8CC /* optimize.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; name = optimize.c; path = ../../../include/mpg123/src/libmpg123/optimize.c; sourceTree = "<group>"; };
440E80E08C7F6512D11E3720 /* parse.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; name = parse.c; path = ../../../include/mpg123/src/libmpg123/parse.c; sourceTree = "<group>"; };
489101566A5CAE88A711D796 /* readers.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; name = readers.c; path = ../../../include/mpg123/src/libmpg123/readers.c; sourceTree = "<group>"; };
54E0A14CA243977E1862978C /* libmpg123.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; name = libmpg123.c; path = ../../../include/mpg123/src/libmpg123/libmpg123.c; sourceTree = "<group>"; };
5B10DD6681370D18E83E03A6 /* ntom.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; name = ntom.c; path = ../../../include/mpg123/src/libmpg123/ntom.c; sourceTree = "<group>"; };
6B2790408CF33D72C9A86680 /* tabinit.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; name = tabinit.c; path = ../../../include/mpg123/src/libmpg123/tabinit.c; sourceTree = "<group>"; };
739C6384C0FF59B6371E59C4 /* synth_s32.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; name = synth_s32.c; path = ../../../include/mpg123/src/libmpg123/synth_s32.c; sourceTree = "<group>"; };
748089C69CBB42788456D006 /* layer1.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; name = layer1.c; path = ../../../include/mpg123/src/libmpg123/layer1.c; sourceTree = "<group>"; };
754AC0BABDBBA4EC025A76FA /* index.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; name = index.c; path = ../../../include/mpg123/src/libmpg123/index.c; sourceTree = "<group>"; };
78DBF380C14CD7B205EBA9C0 /* frame.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; name = frame.c; path = ../../../include/mpg123/src/libmpg123/frame.c; sourceTree = "<group>"; };
907B4FB6D8EC33E81D8B05F6 /* synth.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; name = synth.c; path = ../../../include/mpg123/src/libmpg123/synth.c; sourceTree = "<group>"; };
9796B208BFD16ABAA76CF848 /* layer2.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; name = layer2.c; path = ../../../include/mpg123/src/libmpg123/layer2.c; sourceTree = "<group>"; };
A1E03F02D3D989B44DB8C542 /* synth_8bit.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; name = synth_8bit.c; path = ../../../include/mpg123/src/libmpg123/synth_8bit.c; sourceTree = "<group>"; };
A60D55A2C7D902D4048E2BE2 /* feature.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; name = feature.c; path = ../../../include/mpg123/src/libmpg123/feature.c; sourceTree = "<group>"; };
A7ABBCE59297E2D7DA7DAB25 /* compat.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; name = compat.c; path = ../../../include/mpg123/src/compat/compat.c; sourceTree = "<group>"; };
AD3049FCD56B02AEBD06903C /* format.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; name = format.c; path = ../../../include/mpg123/src/libmpg123/format.c; sourceTree = "<group>"; };
BAACDA4AE2E792FCCA83208A /* layer3.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; name = layer3.c; path = ../../../include/mpg123/src/libmpg123/layer3.c; sourceTree = "<group>"; };
C3752BE686E0ED98C5849226 /* icy2utf8.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; name = icy2utf8.c; path = ../../../include/mpg123/src/libmpg123/icy2utf8.c; sourceTree = "<group>"; };
C3CD341CF5C67ECE6FA5BA5C /* synth_real.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; name = synth_real.c; path = ../../../include/mpg123/src/libmpg123/synth_real.c; sourceTree = "<group>"; };
C6BCBF7D1D4A29EFF5C33DBD /* openmpt-mpg123.dll */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.dylib"; includeInIndex = 0; name = "openmpt-mpg123.dll"; path = "openmpt-mpg123.dll"; sourceTree = BUILT_PRODUCTS_DIR; };
CDD5DB15FEB9D30711D20955 /* compat_str.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; name = compat_str.c; path = ../../../include/mpg123/src/compat/compat_str.c; sourceTree = "<group>"; };
E598BBB4FCAB56E6ECC751F4 /* icy.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; name = icy.c; path = ../../../include/mpg123/src/libmpg123/icy.c; sourceTree = "<group>"; };
F4F6A4743D6788A682065AB4 /* dct64.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; name = dct64.c; path = ../../../include/mpg123/src/libmpg123/dct64.c; sourceTree = "<group>"; };
F56A100A0C7CAB3CFC98A64A /* id3.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; name = id3.c; path = ../../../include/mpg123/src/libmpg123/id3.c; sourceTree = "<group>"; };
/* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */
A9087E6DA26E7FDF9609DCAD /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXFrameworksBuildPhase section */
/* Begin PBXCopyFilesBuildPhase section */
E2ED1E19CDD9440B15BF0C59 /* Embed Libraries */ = {
isa = PBXCopyFilesBuildPhase;
buildActionMask = 2147483647;
dstPath = "";
dstSubfolderSpec = 10;
files = (
);
name = "Embed Libraries";
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXCopyFilesBuildPhase section */
/* Begin PBXGroup section */
0F03317AECAE342CC052B7BA /* mpg123 */ = {
isa = PBXGroup;
children = (
3E657050E1B0F982FC81C690 /* compat */,
2C61E28ACF50093C5E75E8CA /* libmpg123 */,
A6C936B49B3FADE6EA134CF4 /* Products */,
);
name = mpg123;
sourceTree = "<group>";
};
2C61E28ACF50093C5E75E8CA /* libmpg123 */ = {
isa = PBXGroup;
children = (
F4F6A4743D6788A682065AB4 /* dct64.c */,
0F54AFAE5CB7A5E0D2D6A5EE /* equalizer.c */,
A60D55A2C7D902D4048E2BE2 /* feature.c */,
AD3049FCD56B02AEBD06903C /* format.c */,
78DBF380C14CD7B205EBA9C0 /* frame.c */,
E598BBB4FCAB56E6ECC751F4 /* icy.c */,
C3752BE686E0ED98C5849226 /* icy2utf8.c */,
F56A100A0C7CAB3CFC98A64A /* id3.c */,
754AC0BABDBBA4EC025A76FA /* index.c */,
748089C69CBB42788456D006 /* layer1.c */,
9796B208BFD16ABAA76CF848 /* layer2.c */,
BAACDA4AE2E792FCCA83208A /* layer3.c */,
54E0A14CA243977E1862978C /* libmpg123.c */,
5B10DD6681370D18E83E03A6 /* ntom.c */,
1B61528CDECD143E1D70B8CC /* optimize.c */,
440E80E08C7F6512D11E3720 /* parse.c */,
489101566A5CAE88A711D796 /* readers.c */,
0BDCDC32593FD264CF5ED272 /* stringbuf.c */,
907B4FB6D8EC33E81D8B05F6 /* synth.c */,
A1E03F02D3D989B44DB8C542 /* synth_8bit.c */,
C3CD341CF5C67ECE6FA5BA5C /* synth_real.c */,
739C6384C0FF59B6371E59C4 /* synth_s32.c */,
6B2790408CF33D72C9A86680 /* tabinit.c */,
);
name = libmpg123;
sourceTree = "<group>";
};
3E657050E1B0F982FC81C690 /* compat */ = {
isa = PBXGroup;
children = (
A7ABBCE59297E2D7DA7DAB25 /* compat.c */,
CDD5DB15FEB9D30711D20955 /* compat_str.c */,
);
name = compat;
sourceTree = "<group>";
};
A6C936B49B3FADE6EA134CF4 /* Products */ = {
isa = PBXGroup;
children = (
C6BCBF7D1D4A29EFF5C33DBD /* openmpt-mpg123.dll */,
);
name = Products;
sourceTree = "<group>";
};
/* End PBXGroup section */
/* Begin PBXNativeTarget section */
6CFC1BC3B56CFFF5FA0BD203 /* mpg123 */ = {
isa = PBXNativeTarget;
buildConfigurationList = 9743C6CC90A9C83E8445250C /* Build configuration list for PBXNativeTarget "mpg123" */;
buildPhases = (
18EFFF0D1256007F05F15D4D /* Resources */,
829D18647C0319D66F9E76A4 /* Sources */,
A9087E6DA26E7FDF9609DCAD /* Frameworks */,
E2ED1E19CDD9440B15BF0C59 /* Embed Libraries */,
);
buildRules = (
);
dependencies = (
);
name = mpg123;
productName = mpg123;
productReference = C6BCBF7D1D4A29EFF5C33DBD /* openmpt-mpg123.dll */;
productType = "com.apple.product-type.library.dynamic";
};
/* End PBXNativeTarget section */
/* Begin PBXProject section */
08FB7793FE84155DC02AAC07 /* Project object */ = {
isa = PBXProject;
buildConfigurationList = 1DEB928908733DD80010E9CD /* Build configuration list for PBXProject "mpg123" */;
compatibilityVersion = "Xcode 3.2";
hasScannedForEncodings = 1;
mainGroup = 0F03317AECAE342CC052B7BA /* mpg123 */;
projectDirPath = "";
projectRoot = "";
targets = (
6CFC1BC3B56CFFF5FA0BD203 /* openmpt-mpg123.dll */,
);
};
/* End PBXProject section */
/* Begin PBXResourcesBuildPhase section */
18EFFF0D1256007F05F15D4D /* Resources */ = {
isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647;
files = (
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXResourcesBuildPhase section */
/* Begin PBXSourcesBuildPhase section */
829D18647C0319D66F9E76A4 /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
2F06D05D7C69C68FF288C69D /* compat.c in Sources */,
F155B58DD59CBDBF5989EBCD /* compat_str.c in Sources */,
D1E3070CCBA4C37E05A3C54C /* dct64.c in Sources */,
21B328E68EDB3758906E2726 /* equalizer.c in Sources */,
6C03B21AB052578CF279905A /* feature.c in Sources */,
2CE230149E04D10653CB7E54 /* format.c in Sources */,
EE6448D8E826054A22250718 /* frame.c in Sources */,
E236244C3D7777BE10D1C28C /* icy.c in Sources */,
8ADD039E1D6ACD90864371DE /* icy2utf8.c in Sources */,
C3D66B021F17BE74F2720942 /* id3.c in Sources */,
9CA288B296644524D06346F2 /* index.c in Sources */,
26299D7E974C3E704D12EBBE /* layer1.c in Sources */,
142B46E0854DE7D23B149520 /* layer2.c in Sources */,
022CF042734F913429163E82 /* layer3.c in Sources */,
C39C716430C47FD632576FA4 /* libmpg123.c in Sources */,
EAB0691E1B9461102EAC975E /* ntom.c in Sources */,
0DDEA7A4A06C7196094515E4 /* optimize.c in Sources */,
82DB3C387C9CF8AAB69BFA78 /* parse.c in Sources */,
C2065F0E06550480487C3D4E /* readers.c in Sources */,
BCB343AA29DB521C2B6E41EA /* stringbuf.c in Sources */,
64A7B16E5E696DE098686FAE /* synth.c in Sources */,
D618207A2D7D936CDF8BAEBA /* synth_8bit.c in Sources */,
022FC83459953B260BA35674 /* synth_real.c in Sources */,
5BC0EB1CC8E8F98ECA7BE95C /* synth_s32.c in Sources */,
242DF798687C9D0AAAA3D5D8 /* tabinit.c in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXSourcesBuildPhase section */
/* Begin PBXVariantGroup section */
/* End PBXVariantGroup section */
/* Begin XCBuildConfiguration section */
4C50EB499ED7163B711B7989 /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
ARCHS = "$(NATIVE_ARCH_ACTUAL)";
CLANG_CXX_LANGUAGE_STANDARD = "c++1z";
CONFIGURATION_BUILD_DIR = "$(SYMROOT)";
CONFIGURATION_TEMP_DIR = "$(OBJROOT)";
COPY_PHASE_STRIP = NO;
GCC_ENABLE_FIX_AND_CONTINUE = YES;
GCC_OPTIMIZATION_LEVEL = 0;
GCC_PREPROCESSOR_DEFINITIONS = (
DEBUG,
MPT_BUILD_DEBUG,
OPT_GENERIC,
);
GCC_SYMBOLS_PRIVATE_EXTERN = NO;
GCC_WARN_ABOUT_RETURN_TYPE = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
OBJROOT = obj/Debug/mpg123;
ONLY_ACTIVE_ARCH = YES;
SYMROOT = "../../../bin/debug/xcode4-ios/all";
USER_HEADER_SEARCH_PATHS = (
../../../include/mpg123/ports/Xcode,
../../../include/mpg123/src/libmpg123,
../../../include/mpg123/src/compat,
../../../include/mpg123/src,
);
};
name = Debug;
};
7C31350CED53D5FEA31A834C /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
CONFIGURATION_BUILD_DIR = "../../../bin/release/xcode4-ios/all";
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
EXECUTABLE_EXTENSION = dll;
GCC_DYNAMIC_NO_PIC = NO;
INSTALL_PATH = /usr/local/lib;
PRODUCT_NAME = "openmpt-mpg123";
};
name = Release;
};
98A0BBC3A55D6B351A47DA03 /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
ARCHS = "$(NATIVE_ARCH_ACTUAL)";
CLANG_CXX_LANGUAGE_STANDARD = "c++1z";
CONFIGURATION_BUILD_DIR = "$(SYMROOT)";
CONFIGURATION_TEMP_DIR = "$(OBJROOT)";
GCC_OPTIMIZATION_LEVEL = 3;
GCC_PREPROCESSOR_DEFINITIONS = (
NDEBUG,
OPT_GENERIC,
);
GCC_SYMBOLS_PRIVATE_EXTERN = NO;
GCC_WARN_ABOUT_RETURN_TYPE = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
OBJROOT = obj/Release/mpg123;
ONLY_ACTIVE_ARCH = NO;
SYMROOT = "../../../bin/release/xcode4-ios/all";
USER_HEADER_SEARCH_PATHS = (
../../../include/mpg123/ports/Xcode,
../../../include/mpg123/src/libmpg123,
../../../include/mpg123/src/compat,
../../../include/mpg123/src,
);
};
name = Release;
};
9C9C6D92965E2A04D05D2BD2 /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
CONFIGURATION_BUILD_DIR = "../../../bin/debug/xcode4-ios/all";
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
EXECUTABLE_EXTENSION = dll;
GCC_DYNAMIC_NO_PIC = NO;
INSTALL_PATH = /usr/local/lib;
PRODUCT_NAME = "openmpt-mpg123";
};
name = Debug;
};
/* End XCBuildConfiguration section */
/* Begin XCConfigurationList section */
1DEB928908733DD80010E9CD /* Build configuration list for PBXProject "mpg123" */ = {
isa = XCConfigurationList;
buildConfigurations = (
4C50EB499ED7163B711B7989 /* Debug */,
98A0BBC3A55D6B351A47DA03 /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Debug;
};
9743C6CC90A9C83E8445250C /* Build configuration list for PBXNativeTarget "openmpt-mpg123.dll" */ = {
isa = XCConfigurationList;
buildConfigurations = (
9C9C6D92965E2A04D05D2BD2 /* Debug */,
7C31350CED53D5FEA31A834C /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Debug;
};
/* End XCConfigurationList section */
};
rootObject = 08FB7793FE84155DC02AAC07 /* Project object */;
}

View file

@ -0,0 +1,255 @@
// !$*UTF8*$!
{
archiveVersion = 1;
classes = {
};
objectVersion = 46;
objects = {
/* Begin PBXBuildFile section */
9C9F8407CD837BF9E09BB247 /* bitwise.c in Sources */ = {isa = PBXBuildFile; fileRef = 1891292F3EB758E1A5BE4F6F /* bitwise.c */; };
FF0BAB212FEFA3134307D961 /* framing.c in Sources */ = {isa = PBXBuildFile; fileRef = B766F1A9DD8D215B449417E9 /* framing.c */; };
/* End PBXBuildFile section */
/* Begin PBXFileReference section */
1891292F3EB758E1A5BE4F6F /* bitwise.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; name = bitwise.c; path = ../../../include/ogg/src/bitwise.c; sourceTree = "<group>"; };
1E47F32D446E22DFAB75196D /* ogg.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = ogg.h; path = ../../../include/ogg/include/ogg/ogg.h; sourceTree = "<group>"; };
5036DE60765D0E12DD6404A0 /* openmpt-ogg.dll */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.dylib"; includeInIndex = 0; name = "openmpt-ogg.dll"; path = "openmpt-ogg.dll"; sourceTree = BUILT_PRODUCTS_DIR; };
93F6FCDFE159F3115778F31F /* os_types.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = os_types.h; path = ../../../include/ogg/include/ogg/os_types.h; sourceTree = "<group>"; };
B766F1A9DD8D215B449417E9 /* framing.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; name = framing.c; path = ../../../include/ogg/src/framing.c; sourceTree = "<group>"; };
/* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */
95F8A3D038E6CA82C80CAA10 /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXFrameworksBuildPhase section */
/* Begin PBXCopyFilesBuildPhase section */
CC7C283CE38EC36ED3AABE7C /* Embed Libraries */ = {
isa = PBXCopyFilesBuildPhase;
buildActionMask = 2147483647;
dstPath = "";
dstSubfolderSpec = 10;
files = (
);
name = "Embed Libraries";
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXCopyFilesBuildPhase section */
/* Begin PBXGroup section */
5775D4184366DFCA959E7A58 /* src */ = {
isa = PBXGroup;
children = (
1891292F3EB758E1A5BE4F6F /* bitwise.c */,
B766F1A9DD8D215B449417E9 /* framing.c */,
);
name = src;
sourceTree = "<group>";
};
5E8C725002DF100215175890 /* include */ = {
isa = PBXGroup;
children = (
BE79831562CC20C775046955 /* ogg */,
);
name = include;
sourceTree = "<group>";
};
A078B4BDABA964AF054BE2FD /* ogg */ = {
isa = PBXGroup;
children = (
5E8C725002DF100215175890 /* include */,
5775D4184366DFCA959E7A58 /* src */,
A6C936B49B3FADE6EA134CF4 /* Products */,
);
name = ogg;
sourceTree = "<group>";
};
A6C936B49B3FADE6EA134CF4 /* Products */ = {
isa = PBXGroup;
children = (
5036DE60765D0E12DD6404A0 /* openmpt-ogg.dll */,
);
name = Products;
sourceTree = "<group>";
};
BE79831562CC20C775046955 /* ogg */ = {
isa = PBXGroup;
children = (
1E47F32D446E22DFAB75196D /* ogg.h */,
93F6FCDFE159F3115778F31F /* os_types.h */,
);
name = ogg;
sourceTree = "<group>";
};
/* End PBXGroup section */
/* Begin PBXNativeTarget section */
886C6A4681D26BB8756DC886 /* ogg */ = {
isa = PBXNativeTarget;
buildConfigurationList = 8433EC2F272212E1B647F26F /* Build configuration list for PBXNativeTarget "ogg" */;
buildPhases = (
05E02470A8CE4B2237F42AB0 /* Resources */,
6F8D3DC7127B6479A1A14407 /* Sources */,
95F8A3D038E6CA82C80CAA10 /* Frameworks */,
CC7C283CE38EC36ED3AABE7C /* Embed Libraries */,
);
buildRules = (
);
dependencies = (
);
name = ogg;
productName = ogg;
productReference = 5036DE60765D0E12DD6404A0 /* openmpt-ogg.dll */;
productType = "com.apple.product-type.library.dynamic";
};
/* End PBXNativeTarget section */
/* Begin PBXProject section */
08FB7793FE84155DC02AAC07 /* Project object */ = {
isa = PBXProject;
buildConfigurationList = 1DEB928908733DD80010E9CD /* Build configuration list for PBXProject "ogg" */;
compatibilityVersion = "Xcode 3.2";
hasScannedForEncodings = 1;
mainGroup = A078B4BDABA964AF054BE2FD /* ogg */;
projectDirPath = "";
projectRoot = "";
targets = (
886C6A4681D26BB8756DC886 /* openmpt-ogg.dll */,
);
};
/* End PBXProject section */
/* Begin PBXResourcesBuildPhase section */
05E02470A8CE4B2237F42AB0 /* Resources */ = {
isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647;
files = (
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXResourcesBuildPhase section */
/* Begin PBXSourcesBuildPhase section */
6F8D3DC7127B6479A1A14407 /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
9C9F8407CD837BF9E09BB247 /* bitwise.c in Sources */,
FF0BAB212FEFA3134307D961 /* framing.c in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXSourcesBuildPhase section */
/* Begin PBXVariantGroup section */
/* End PBXVariantGroup section */
/* Begin XCBuildConfiguration section */
8F6FCF26DF8363D862019566 /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
ARCHS = "$(NATIVE_ARCH_ACTUAL)";
CLANG_CXX_LANGUAGE_STANDARD = "c++1z";
CONFIGURATION_BUILD_DIR = "$(SYMROOT)";
CONFIGURATION_TEMP_DIR = "$(OBJROOT)";
GCC_OPTIMIZATION_LEVEL = 3;
GCC_PREPROCESSOR_DEFINITIONS = (
NDEBUG,
);
GCC_SYMBOLS_PRIVATE_EXTERN = NO;
GCC_WARN_ABOUT_RETURN_TYPE = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
OBJROOT = obj/Release/ogg;
ONLY_ACTIVE_ARCH = NO;
SYMROOT = "../../../bin/release/xcode4-ios/all";
SYSTEM_HEADER_SEARCH_PATHS = (
../../../include/ogg/include,
"$(inherited)",
);
};
name = Release;
};
C49D8BAF120081E1881F81EF /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
CONFIGURATION_BUILD_DIR = "../../../bin/release/xcode4-ios/all";
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
EXECUTABLE_EXTENSION = dll;
GCC_DYNAMIC_NO_PIC = NO;
INSTALL_PATH = /usr/local/lib;
PRODUCT_NAME = "openmpt-ogg";
};
name = Release;
};
C86DC9EC74D08A1E3359002C /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
ARCHS = "$(NATIVE_ARCH_ACTUAL)";
CLANG_CXX_LANGUAGE_STANDARD = "c++1z";
CONFIGURATION_BUILD_DIR = "$(SYMROOT)";
CONFIGURATION_TEMP_DIR = "$(OBJROOT)";
COPY_PHASE_STRIP = NO;
GCC_ENABLE_FIX_AND_CONTINUE = YES;
GCC_OPTIMIZATION_LEVEL = 0;
GCC_PREPROCESSOR_DEFINITIONS = (
DEBUG,
MPT_BUILD_DEBUG,
);
GCC_SYMBOLS_PRIVATE_EXTERN = NO;
GCC_WARN_ABOUT_RETURN_TYPE = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
OBJROOT = obj/Debug/ogg;
ONLY_ACTIVE_ARCH = YES;
SYMROOT = "../../../bin/debug/xcode4-ios/all";
SYSTEM_HEADER_SEARCH_PATHS = (
../../../include/ogg/include,
"$(inherited)",
);
};
name = Debug;
};
DFACBF75A3188127E1BC25B5 /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
CONFIGURATION_BUILD_DIR = "../../../bin/debug/xcode4-ios/all";
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
EXECUTABLE_EXTENSION = dll;
GCC_DYNAMIC_NO_PIC = NO;
INSTALL_PATH = /usr/local/lib;
PRODUCT_NAME = "openmpt-ogg";
};
name = Debug;
};
/* End XCBuildConfiguration section */
/* Begin XCConfigurationList section */
1DEB928908733DD80010E9CD /* Build configuration list for PBXProject "ogg" */ = {
isa = XCConfigurationList;
buildConfigurations = (
C86DC9EC74D08A1E3359002C /* Debug */,
8F6FCF26DF8363D862019566 /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Debug;
};
8433EC2F272212E1B647F26F /* Build configuration list for PBXNativeTarget "openmpt-ogg.dll" */ = {
isa = XCConfigurationList;
buildConfigurations = (
DFACBF75A3188127E1BC25B5 /* Debug */,
C49D8BAF120081E1881F81EF /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Debug;
};
/* End XCConfigurationList section */
};
rootObject = 08FB7793FE84155DC02AAC07 /* Project object */;
}

View file

@ -0,0 +1,531 @@
// !$*UTF8*$!
{
archiveVersion = 1;
classes = {
};
objectVersion = 46;
objects = {
/* Begin PBXBuildFile section */
16716A7E46033970211078BE /* block.c in Sources */ = {isa = PBXBuildFile; fileRef = 777077261A5E9DD8A9847D66 /* block.c */; };
16B25260019E7852498440A0 /* psy.c in Sources */ = {isa = PBXBuildFile; fileRef = EDFFC5E89252639AA48AAC28 /* psy.c */; };
3EA9B7E0953722526DB03620 /* info.c in Sources */ = {isa = PBXBuildFile; fileRef = E03CFA68E3ADCC9A651A70A8 /* info.c */; };
412482943AE63F0674E540D4 /* codebook.c in Sources */ = {isa = PBXBuildFile; fileRef = 2A6247DC72D32C0EB771FE1C /* codebook.c */; };
42BABA9A3C7C770C767B78DA /* registry.c in Sources */ = {isa = PBXBuildFile; fileRef = D1E246821A532AB45EF1FCC2 /* registry.c */; };
55E0C63CC703672E7CCA147C /* synthesis.c in Sources */ = {isa = PBXBuildFile; fileRef = 3A6CA00462A758B64A42E644 /* synthesis.c */; };
571301CEB254554085AEA00E /* floor1.c in Sources */ = {isa = PBXBuildFile; fileRef = 501CFA76672F95A8574B90B6 /* floor1.c */; };
63BC07FCBEFD5B6E9257A63C /* lookup.c in Sources */ = {isa = PBXBuildFile; fileRef = 35F064C44D02FFF63D1EFB04 /* lookup.c */; };
650BD9CE95EFD1C0A908080E /* smallft.c in Sources */ = {isa = PBXBuildFile; fileRef = CEB55B76F4DB8B285BE281B6 /* smallft.c */; };
665EF2C06020AF329A1FB100 /* mapping0.c in Sources */ = {isa = PBXBuildFile; fileRef = 379713488007F77AC4A6C988 /* mapping0.c */; };
66F0DF98BD7E4A0A95F75DD8 /* mdct.c in Sources */ = {isa = PBXBuildFile; fileRef = C67232A0C9E304D24B4FA8E0 /* mdct.c */; };
7C34482667206E18AF063666 /* lpc.c in Sources */ = {isa = PBXBuildFile; fileRef = 7091344E14E3D200271C1A8E /* lpc.c */; };
A4B9FD2CFFFB509ED3559B6C /* floor0.c in Sources */ = {isa = PBXBuildFile; fileRef = 3AED1EF451FFBA26421BB534 /* floor0.c */; };
A7912A52EBDFCFC42E070892 /* vorbisfile.c in Sources */ = {isa = PBXBuildFile; fileRef = C39AD0BAE5667DEC221BA6FA /* vorbisfile.c */; };
B1D3BC04AB957876E5947A44 /* envelope.c in Sources */ = {isa = PBXBuildFile; fileRef = 14D8424C5D49267EA1E7F88C /* envelope.c */; };
BC748D10B6364982F0354B50 /* analysis.c in Sources */ = {isa = PBXBuildFile; fileRef = 4AAD1098931DF4CAD7BCC6D8 /* analysis.c */; };
BDB5A0B818F6F42AEC513EF8 /* window.c in Sources */ = {isa = PBXBuildFile; fileRef = 72232FC08935CAF27951C600 /* window.c */; };
D5E5E506C0D20AF808B7D346 /* lsp.c in Sources */ = {isa = PBXBuildFile; fileRef = 6F30132E1382B0E025BAF96E /* lsp.c */; };
D85CD4BE497F75B0FF4622FE /* vorbisenc.c in Sources */ = {isa = PBXBuildFile; fileRef = 92BA4166BAF4FA18A29087A6 /* vorbisenc.c */; };
E344DF0C2793847E69BABD4C /* sharedbook.c in Sources */ = {isa = PBXBuildFile; fileRef = 72897ED494552C06D10A5514 /* sharedbook.c */; };
E77EFABE1862F2B02B7B28FE /* bitrate.c in Sources */ = {isa = PBXBuildFile; fileRef = 0944F5662F6B251896721BA6 /* bitrate.c */; };
FC4D923C52DAFCAE2B54107C /* res0.c in Sources */ = {isa = PBXBuildFile; fileRef = 16DFB5041A5087369BBD2B44 /* res0.c */; };
FC66A059C11BF6CB758A9E99 /* openmpt-ogg.lib in Frameworks */ = {isa = PBXBuildFile; fileRef = 322B76417ACAB4739DF66C81 /* openmpt-ogg.lib */; };
/* End PBXBuildFile section */
/* Begin PBXContainerItemProxy section */
3D2DCDF83693CF6A2A2F2C38 /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = 386FE2DA60AA9B8C4846291A /* ogg.xcodeproj */;
proxyType = 1;
remoteGlobalIDString = 886C6A4681D26BB8756DC886;
remoteInfo = "openmpt-ogg.dll";
};
EAF35B5FE4595CD1D7F4B99F /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = 386FE2DA60AA9B8C4846291A /* ogg.xcodeproj */;
proxyType = 2;
remoteGlobalIDString = 5036DE60765D0E12DD6404A0;
remoteInfo = "openmpt-ogg.dll";
};
/* End PBXContainerItemProxy section */
/* Begin PBXFileReference section */
058BB8B85C19232A349236F8 /* openmpt-vorbis.dll */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.dylib"; includeInIndex = 0; name = "openmpt-vorbis.dll"; path = "openmpt-vorbis.dll"; sourceTree = BUILT_PRODUCTS_DIR; };
07BE8ECA1ED129FC0EED250A /* window.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = window.h; path = ../../../include/vorbis/lib/window.h; sourceTree = "<group>"; };
0944F5662F6B251896721BA6 /* bitrate.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; name = bitrate.c; path = ../../../include/vorbis/lib/bitrate.c; sourceTree = "<group>"; };
0C6D4B2032937AD2999A7160 /* smallft.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = smallft.h; path = ../../../include/vorbis/lib/smallft.h; sourceTree = "<group>"; };
0D82D8FD2F4E862F6C03AF3D /* psych_8.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = psych_8.h; path = ../../../include/vorbis/lib/modes/psych_8.h; sourceTree = "<group>"; };
13C8DC265C39C058A0D89266 /* codebook.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = codebook.h; path = ../../../include/vorbis/lib/codebook.h; sourceTree = "<group>"; };
14D8424C5D49267EA1E7F88C /* envelope.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; name = envelope.c; path = ../../../include/vorbis/lib/envelope.c; sourceTree = "<group>"; };
15F93858BA4BD60ACC841E98 /* lsp.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = lsp.h; path = ../../../include/vorbis/lib/lsp.h; sourceTree = "<group>"; };
16DFB5041A5087369BBD2B44 /* res0.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; name = res0.c; path = ../../../include/vorbis/lib/res0.c; sourceTree = "<group>"; };
16F680C77237D43945921F07 /* codec.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = codec.h; path = ../../../include/vorbis/include/vorbis/codec.h; sourceTree = "<group>"; };
175A5978BBACF72ACDE53FB8 /* lpc.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = lpc.h; path = ../../../include/vorbis/lib/lpc.h; sourceTree = "<group>"; };
1F836091517CAB43CB5BE6D1 /* residue_44.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = residue_44.h; path = ../../../include/vorbis/lib/modes/residue_44.h; sourceTree = "<group>"; };
2740402E4D666FE0B46D666E /* masking.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = masking.h; path = ../../../include/vorbis/lib/masking.h; sourceTree = "<group>"; };
285CE11ECBA86A50E679375E /* os.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = os.h; path = ../../../include/vorbis/lib/os.h; sourceTree = "<group>"; };
2A6247DC72D32C0EB771FE1C /* codebook.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; name = codebook.c; path = ../../../include/vorbis/lib/codebook.c; sourceTree = "<group>"; };
2AAE7645EE1A37F72CBDDC85 /* setup_11.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = setup_11.h; path = ../../../include/vorbis/lib/modes/setup_11.h; sourceTree = "<group>"; };
35CF7AFDF93B3CAF37DEE13D /* psych_44.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = psych_44.h; path = ../../../include/vorbis/lib/modes/psych_44.h; sourceTree = "<group>"; };
35F064C44D02FFF63D1EFB04 /* lookup.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; name = lookup.c; path = ../../../include/vorbis/lib/lookup.c; sourceTree = "<group>"; };
374A6BCA5F85247C4720B20A /* highlevel.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = highlevel.h; path = ../../../include/vorbis/lib/highlevel.h; sourceTree = "<group>"; };
379713488007F77AC4A6C988 /* mapping0.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; name = mapping0.c; path = ../../../include/vorbis/lib/mapping0.c; sourceTree = "<group>"; };
386FE2DA60AA9B8C4846291A /* openmpt-ogg.lib */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = "ogg.xcodeproj"; path = ogg.xcodeproj; sourceTree = SOURCE_ROOT; };
3A6CA00462A758B64A42E644 /* synthesis.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; name = synthesis.c; path = ../../../include/vorbis/lib/synthesis.c; sourceTree = "<group>"; };
3AED1EF451FFBA26421BB534 /* floor0.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; name = floor0.c; path = ../../../include/vorbis/lib/floor0.c; sourceTree = "<group>"; };
3B10AC6A3E817E9CBFEE22AA /* mdct.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = mdct.h; path = ../../../include/vorbis/lib/mdct.h; sourceTree = "<group>"; };
3BA7A5A17FF64B13C21D83E1 /* vorbisenc.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = vorbisenc.h; path = ../../../include/vorbis/include/vorbis/vorbisenc.h; sourceTree = "<group>"; };
450CC03BDA837F6D491FD67B /* residue_44u.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = residue_44u.h; path = ../../../include/vorbis/lib/modes/residue_44u.h; sourceTree = "<group>"; };
46FCE5106D2314C2D42A0B50 /* bitrate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = bitrate.h; path = ../../../include/vorbis/lib/bitrate.h; sourceTree = "<group>"; };
4AAD1098931DF4CAD7BCC6D8 /* analysis.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; name = analysis.c; path = ../../../include/vorbis/lib/analysis.c; sourceTree = "<group>"; };
501CFA76672F95A8574B90B6 /* floor1.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; name = floor1.c; path = ../../../include/vorbis/lib/floor1.c; sourceTree = "<group>"; };
5BED095DF163C88F60001F9D /* setup_44p51.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = setup_44p51.h; path = ../../../include/vorbis/lib/modes/setup_44p51.h; sourceTree = "<group>"; };
63614891852CF5C3C1E21ED1 /* setup_X.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = setup_X.h; path = ../../../include/vorbis/lib/modes/setup_X.h; sourceTree = "<group>"; };
6B3067A02E9C29526D3FCDE0 /* lookup_data.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = lookup_data.h; path = ../../../include/vorbis/lib/lookup_data.h; sourceTree = "<group>"; };
6B6795D0827A310272962C10 /* scales.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = scales.h; path = ../../../include/vorbis/lib/scales.h; sourceTree = "<group>"; };
6CCD7211303933C36EDCD851 /* setup_44.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = setup_44.h; path = ../../../include/vorbis/lib/modes/setup_44.h; sourceTree = "<group>"; };
6E91170FA08A61C11A699D4F /* residue_16.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = residue_16.h; path = ../../../include/vorbis/lib/modes/residue_16.h; sourceTree = "<group>"; };
6F30132E1382B0E025BAF96E /* lsp.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; name = lsp.c; path = ../../../include/vorbis/lib/lsp.c; sourceTree = "<group>"; };
7091344E14E3D200271C1A8E /* lpc.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; name = lpc.c; path = ../../../include/vorbis/lib/lpc.c; sourceTree = "<group>"; };
72232FC08935CAF27951C600 /* window.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; name = window.c; path = ../../../include/vorbis/lib/window.c; sourceTree = "<group>"; };
72897ED494552C06D10A5514 /* sharedbook.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; name = sharedbook.c; path = ../../../include/vorbis/lib/sharedbook.c; sourceTree = "<group>"; };
746BBDBB37D77F6D767B23FB /* psych_16.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = psych_16.h; path = ../../../include/vorbis/lib/modes/psych_16.h; sourceTree = "<group>"; };
777077261A5E9DD8A9847D66 /* block.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; name = block.c; path = ../../../include/vorbis/lib/block.c; sourceTree = "<group>"; };
7EC1E432F2AA5BE414F80A72 /* res_books_stereo.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = res_books_stereo.h; path = ../../../include/vorbis/lib/books/coupled/res_books_stereo.h; sourceTree = "<group>"; };
90EE3C51B2B9E983EF6F1291 /* setup_8.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = setup_8.h; path = ../../../include/vorbis/lib/modes/setup_8.h; sourceTree = "<group>"; };
92BA4166BAF4FA18A29087A6 /* vorbisenc.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; name = vorbisenc.c; path = ../../../include/vorbis/lib/vorbisenc.c; sourceTree = "<group>"; };
94C8EB12391B88C44B53D152 /* psy.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = psy.h; path = ../../../include/vorbis/lib/psy.h; sourceTree = "<group>"; };
960E1F895979E13B981D85C9 /* setup_22.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = setup_22.h; path = ../../../include/vorbis/lib/modes/setup_22.h; sourceTree = "<group>"; };
AB69B4CF6ED57681AD791B0F /* setup_16.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = setup_16.h; path = ../../../include/vorbis/lib/modes/setup_16.h; sourceTree = "<group>"; };
B9289C7B068B92AD7CAA92BB /* setup_44u.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = setup_44u.h; path = ../../../include/vorbis/lib/modes/setup_44u.h; sourceTree = "<group>"; };
B980BE8E4EF77DC0BD93D4CE /* codec_internal.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = codec_internal.h; path = ../../../include/vorbis/lib/codec_internal.h; sourceTree = "<group>"; };
BB48DACC03B9BEFE4858910C /* registry.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = registry.h; path = ../../../include/vorbis/lib/registry.h; sourceTree = "<group>"; };
C38A75AF76807F61C7A2DBEF /* res_books_uncoupled.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = res_books_uncoupled.h; path = ../../../include/vorbis/lib/books/uncoupled/res_books_uncoupled.h; sourceTree = "<group>"; };
C39AD0BAE5667DEC221BA6FA /* vorbisfile.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; name = vorbisfile.c; path = ../../../include/vorbis/lib/vorbisfile.c; sourceTree = "<group>"; };
C67232A0C9E304D24B4FA8E0 /* mdct.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; name = mdct.c; path = ../../../include/vorbis/lib/mdct.c; sourceTree = "<group>"; };
C97DEB5A61CAD10C9011D19A /* res_books_51.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = res_books_51.h; path = ../../../include/vorbis/lib/books/coupled/res_books_51.h; sourceTree = "<group>"; };
CB8BC3CEE29E5F00D2BA5A0E /* lookup.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = lookup.h; path = ../../../include/vorbis/lib/lookup.h; sourceTree = "<group>"; };
CEB55B76F4DB8B285BE281B6 /* smallft.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; name = smallft.c; path = ../../../include/vorbis/lib/smallft.c; sourceTree = "<group>"; };
D1E246821A532AB45EF1FCC2 /* registry.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; name = registry.c; path = ../../../include/vorbis/lib/registry.c; sourceTree = "<group>"; };
D90D21756B9AEB67D4738FB5 /* vorbisfile.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = vorbisfile.h; path = ../../../include/vorbis/include/vorbis/vorbisfile.h; sourceTree = "<group>"; };
DAF247F2DE631A245FCFBE32 /* misc.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = misc.h; path = ../../../include/vorbis/lib/misc.h; sourceTree = "<group>"; };
DBC5215DC00C298F43F9579D /* residue_44p51.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = residue_44p51.h; path = ../../../include/vorbis/lib/modes/residue_44p51.h; sourceTree = "<group>"; };
E03CFA68E3ADCC9A651A70A8 /* info.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; name = info.c; path = ../../../include/vorbis/lib/info.c; sourceTree = "<group>"; };
E7AEBC4BAB1A7DFDE9BE228B /* setup_32.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = setup_32.h; path = ../../../include/vorbis/lib/modes/setup_32.h; sourceTree = "<group>"; };
EABBD3D0332CB80277CB8A10 /* backends.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = backends.h; path = ../../../include/vorbis/lib/backends.h; sourceTree = "<group>"; };
EDFFC5E89252639AA48AAC28 /* psy.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; name = psy.c; path = ../../../include/vorbis/lib/psy.c; sourceTree = "<group>"; };
EE56303600800CE83470F676 /* floor_books.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = floor_books.h; path = ../../../include/vorbis/lib/books/floor/floor_books.h; sourceTree = "<group>"; };
F1CF92D13F328903B5518911 /* residue_8.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = residue_8.h; path = ../../../include/vorbis/lib/modes/residue_8.h; sourceTree = "<group>"; };
F3B07F31B71C40E3F5BFE571 /* psych_11.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = psych_11.h; path = ../../../include/vorbis/lib/modes/psych_11.h; sourceTree = "<group>"; };
FB9FDEF54902D527BF21D535 /* floor_all.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = floor_all.h; path = ../../../include/vorbis/lib/modes/floor_all.h; sourceTree = "<group>"; };
FE3ED69646AFBAC88B4E8CD6 /* envelope.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = envelope.h; path = ../../../include/vorbis/lib/envelope.h; sourceTree = "<group>"; };
/* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */
7C0E12287574139A690F7068 /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
FC66A059C11BF6CB758A9E99 /* openmpt-ogg.lib in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXFrameworksBuildPhase section */
/* Begin PBXCopyFilesBuildPhase section */
8DA68C947892B286C0787AD4 /* Embed Libraries */ = {
isa = PBXCopyFilesBuildPhase;
buildActionMask = 2147483647;
dstPath = "";
dstSubfolderSpec = 10;
files = (
);
name = "Embed Libraries";
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXCopyFilesBuildPhase section */
/* Begin PBXGroup section */
26717C15041C7EC7D7C10255 /* vorbis */ = {
isa = PBXGroup;
children = (
5E8C725002DF100215175890 /* include */,
8D815E5679726A08CBAA0496 /* lib */,
A6C936B49B3FADE6EA134CF4 /* Products */,
9D968EAA920D05DCE0E0A4EA /* Projects */,
);
name = vorbis;
sourceTree = "<group>";
};
5A1F78C5713213F7614E0F05 /* vorbis */ = {
isa = PBXGroup;
children = (
16F680C77237D43945921F07 /* codec.h */,
3BA7A5A17FF64B13C21D83E1 /* vorbisenc.h */,
D90D21756B9AEB67D4738FB5 /* vorbisfile.h */,
);
name = vorbis;
sourceTree = "<group>";
};
5E8C725002DF100215175890 /* include */ = {
isa = PBXGroup;
children = (
5A1F78C5713213F7614E0F05 /* vorbis */,
);
name = include;
sourceTree = "<group>";
};
77671A33BFD7FE650476D073 /* coupled */ = {
isa = PBXGroup;
children = (
C97DEB5A61CAD10C9011D19A /* res_books_51.h */,
7EC1E432F2AA5BE414F80A72 /* res_books_stereo.h */,
);
name = coupled;
sourceTree = "<group>";
};
80C578BF97D813F187F40EFF /* Products */ = {
isa = PBXGroup;
children = (
322B76417ACAB4739DF66C81 /* openmpt-ogg.lib */,
);
name = Products;
sourceTree = "<group>";
};
8D815E5679726A08CBAA0496 /* lib */ = {
isa = PBXGroup;
children = (
4AAD1098931DF4CAD7BCC6D8 /* analysis.c */,
EABBD3D0332CB80277CB8A10 /* backends.h */,
0944F5662F6B251896721BA6 /* bitrate.c */,
46FCE5106D2314C2D42A0B50 /* bitrate.h */,
777077261A5E9DD8A9847D66 /* block.c */,
EE14CC2A926769DCA49FB26A /* books */,
2A6247DC72D32C0EB771FE1C /* codebook.c */,
13C8DC265C39C058A0D89266 /* codebook.h */,
B980BE8E4EF77DC0BD93D4CE /* codec_internal.h */,
14D8424C5D49267EA1E7F88C /* envelope.c */,
FE3ED69646AFBAC88B4E8CD6 /* envelope.h */,
3AED1EF451FFBA26421BB534 /* floor0.c */,
501CFA76672F95A8574B90B6 /* floor1.c */,
374A6BCA5F85247C4720B20A /* highlevel.h */,
E03CFA68E3ADCC9A651A70A8 /* info.c */,
35F064C44D02FFF63D1EFB04 /* lookup.c */,
CB8BC3CEE29E5F00D2BA5A0E /* lookup.h */,
6B3067A02E9C29526D3FCDE0 /* lookup_data.h */,
7091344E14E3D200271C1A8E /* lpc.c */,
175A5978BBACF72ACDE53FB8 /* lpc.h */,
6F30132E1382B0E025BAF96E /* lsp.c */,
15F93858BA4BD60ACC841E98 /* lsp.h */,
379713488007F77AC4A6C988 /* mapping0.c */,
2740402E4D666FE0B46D666E /* masking.h */,
C67232A0C9E304D24B4FA8E0 /* mdct.c */,
3B10AC6A3E817E9CBFEE22AA /* mdct.h */,
DAF247F2DE631A245FCFBE32 /* misc.h */,
9547E85E399A86104BD2CE9E /* modes */,
285CE11ECBA86A50E679375E /* os.h */,
EDFFC5E89252639AA48AAC28 /* psy.c */,
94C8EB12391B88C44B53D152 /* psy.h */,
D1E246821A532AB45EF1FCC2 /* registry.c */,
BB48DACC03B9BEFE4858910C /* registry.h */,
16DFB5041A5087369BBD2B44 /* res0.c */,
6B6795D0827A310272962C10 /* scales.h */,
72897ED494552C06D10A5514 /* sharedbook.c */,
CEB55B76F4DB8B285BE281B6 /* smallft.c */,
0C6D4B2032937AD2999A7160 /* smallft.h */,
3A6CA00462A758B64A42E644 /* synthesis.c */,
92BA4166BAF4FA18A29087A6 /* vorbisenc.c */,
C39AD0BAE5667DEC221BA6FA /* vorbisfile.c */,
72232FC08935CAF27951C600 /* window.c */,
07BE8ECA1ED129FC0EED250A /* window.h */,
);
name = lib;
sourceTree = "<group>";
};
9547E85E399A86104BD2CE9E /* modes */ = {
isa = PBXGroup;
children = (
FB9FDEF54902D527BF21D535 /* floor_all.h */,
F3B07F31B71C40E3F5BFE571 /* psych_11.h */,
746BBDBB37D77F6D767B23FB /* psych_16.h */,
35CF7AFDF93B3CAF37DEE13D /* psych_44.h */,
0D82D8FD2F4E862F6C03AF3D /* psych_8.h */,
6E91170FA08A61C11A699D4F /* residue_16.h */,
1F836091517CAB43CB5BE6D1 /* residue_44.h */,
DBC5215DC00C298F43F9579D /* residue_44p51.h */,
450CC03BDA837F6D491FD67B /* residue_44u.h */,
F1CF92D13F328903B5518911 /* residue_8.h */,
2AAE7645EE1A37F72CBDDC85 /* setup_11.h */,
AB69B4CF6ED57681AD791B0F /* setup_16.h */,
960E1F895979E13B981D85C9 /* setup_22.h */,
E7AEBC4BAB1A7DFDE9BE228B /* setup_32.h */,
6CCD7211303933C36EDCD851 /* setup_44.h */,
5BED095DF163C88F60001F9D /* setup_44p51.h */,
B9289C7B068B92AD7CAA92BB /* setup_44u.h */,
90EE3C51B2B9E983EF6F1291 /* setup_8.h */,
63614891852CF5C3C1E21ED1 /* setup_X.h */,
);
name = modes;
sourceTree = "<group>";
};
9D968EAA920D05DCE0E0A4EA /* Projects */ = {
isa = PBXGroup;
children = (
386FE2DA60AA9B8C4846291A /* ogg.xcodeproj */,
);
name = Projects;
sourceTree = "<group>";
};
A6C936B49B3FADE6EA134CF4 /* Products */ = {
isa = PBXGroup;
children = (
058BB8B85C19232A349236F8 /* openmpt-vorbis.dll */,
);
name = Products;
sourceTree = "<group>";
};
E272DBD9043E890B40F3B219 /* uncoupled */ = {
isa = PBXGroup;
children = (
C38A75AF76807F61C7A2DBEF /* res_books_uncoupled.h */,
);
name = uncoupled;
sourceTree = "<group>";
};
EE14CC2A926769DCA49FB26A /* books */ = {
isa = PBXGroup;
children = (
77671A33BFD7FE650476D073 /* coupled */,
FCE62BDF13F8C7110414C21F /* floor */,
E272DBD9043E890B40F3B219 /* uncoupled */,
);
name = books;
sourceTree = "<group>";
};
FCE62BDF13F8C7110414C21F /* floor */ = {
isa = PBXGroup;
children = (
EE56303600800CE83470F676 /* floor_books.h */,
);
name = floor;
sourceTree = "<group>";
};
/* End PBXGroup section */
/* Begin PBXNativeTarget section */
6EE3599EB7543DD0FBF30FDE /* vorbis */ = {
isa = PBXNativeTarget;
buildConfigurationList = 6A495A8763AF5BF9574AB8C7 /* Build configuration list for PBXNativeTarget "vorbis" */;
buildPhases = (
EBF592C8E55B943AD8F6F108 /* Resources */,
55A2AC1F4F08AD9142A40A5F /* Sources */,
7C0E12287574139A690F7068 /* Frameworks */,
8DA68C947892B286C0787AD4 /* Embed Libraries */,
);
buildRules = (
);
dependencies = (
6E7DB5C8859050FA75AC4C08 /* PBXTargetDependency */,
);
name = vorbis;
productName = vorbis;
productReference = 058BB8B85C19232A349236F8 /* openmpt-vorbis.dll */;
productType = "com.apple.product-type.library.dynamic";
};
/* End PBXNativeTarget section */
/* Begin PBXProject section */
08FB7793FE84155DC02AAC07 /* Project object */ = {
isa = PBXProject;
buildConfigurationList = 1DEB928908733DD80010E9CD /* Build configuration list for PBXProject "vorbis" */;
compatibilityVersion = "Xcode 3.2";
hasScannedForEncodings = 1;
mainGroup = 26717C15041C7EC7D7C10255 /* vorbis */;
projectDirPath = "";
projectReferences = (
{
ProductGroup = 80C578BF97D813F187F40EFF /* Products */;
ProjectRef = 386FE2DA60AA9B8C4846291A /* ogg.xcodeproj */;
},
);
projectRoot = "";
targets = (
6EE3599EB7543DD0FBF30FDE /* openmpt-vorbis.dll */,
);
};
/* End PBXProject section */
/* Begin PBXReferenceProxy section */
322B76417ACAB4739DF66C81 /* openmpt-ogg.lib */ = {
isa = PBXReferenceProxy;
fileType = "compiled.mach-o.dylib";
path = "openmpt-ogg.lib";
remoteRef = EAF35B5FE4595CD1D7F4B99F /* PBXContainerItemProxy */;
sourceTree = BUILT_PRODUCTS_DIR;
};
/* End PBXReferenceProxy section */
/* Begin PBXResourcesBuildPhase section */
EBF592C8E55B943AD8F6F108 /* Resources */ = {
isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647;
files = (
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXResourcesBuildPhase section */
/* Begin PBXSourcesBuildPhase section */
55A2AC1F4F08AD9142A40A5F /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
BC748D10B6364982F0354B50 /* analysis.c in Sources */,
E77EFABE1862F2B02B7B28FE /* bitrate.c in Sources */,
16716A7E46033970211078BE /* block.c in Sources */,
412482943AE63F0674E540D4 /* codebook.c in Sources */,
B1D3BC04AB957876E5947A44 /* envelope.c in Sources */,
A4B9FD2CFFFB509ED3559B6C /* floor0.c in Sources */,
571301CEB254554085AEA00E /* floor1.c in Sources */,
3EA9B7E0953722526DB03620 /* info.c in Sources */,
63BC07FCBEFD5B6E9257A63C /* lookup.c in Sources */,
7C34482667206E18AF063666 /* lpc.c in Sources */,
D5E5E506C0D20AF808B7D346 /* lsp.c in Sources */,
665EF2C06020AF329A1FB100 /* mapping0.c in Sources */,
66F0DF98BD7E4A0A95F75DD8 /* mdct.c in Sources */,
16B25260019E7852498440A0 /* psy.c in Sources */,
42BABA9A3C7C770C767B78DA /* registry.c in Sources */,
FC4D923C52DAFCAE2B54107C /* res0.c in Sources */,
E344DF0C2793847E69BABD4C /* sharedbook.c in Sources */,
650BD9CE95EFD1C0A908080E /* smallft.c in Sources */,
55E0C63CC703672E7CCA147C /* synthesis.c in Sources */,
D85CD4BE497F75B0FF4622FE /* vorbisenc.c in Sources */,
A7912A52EBDFCFC42E070892 /* vorbisfile.c in Sources */,
BDB5A0B818F6F42AEC513EF8 /* window.c in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXSourcesBuildPhase section */
/* Begin PBXTargetDependency section */
6E7DB5C8859050FA75AC4C08 /* PBXTargetDependency */ = {
isa = PBXTargetDependency;
name = "openmpt-ogg.lib";
targetProxy = 3D2DCDF83693CF6A2A2F2C38 /* PBXContainerItemProxy */;
};
/* End PBXTargetDependency section */
/* Begin PBXVariantGroup section */
/* End PBXVariantGroup section */
/* Begin XCBuildConfiguration section */
1FD85444725E7F3644A2E284 /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
ARCHS = "$(NATIVE_ARCH_ACTUAL)";
CLANG_CXX_LANGUAGE_STANDARD = "c++1z";
CONFIGURATION_BUILD_DIR = "$(SYMROOT)";
CONFIGURATION_TEMP_DIR = "$(OBJROOT)";
COPY_PHASE_STRIP = NO;
GCC_ENABLE_FIX_AND_CONTINUE = YES;
GCC_OPTIMIZATION_LEVEL = 0;
GCC_PREPROCESSOR_DEFINITIONS = (
DEBUG,
MPT_BUILD_DEBUG,
);
GCC_SYMBOLS_PRIVATE_EXTERN = NO;
GCC_WARN_ABOUT_RETURN_TYPE = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
OBJROOT = obj/Debug/vorbis;
ONLY_ACTIVE_ARCH = YES;
SYMROOT = "../../../bin/debug/xcode4-ios/all";
SYSTEM_HEADER_SEARCH_PATHS = (
../../../include/ogg/include,
"$(inherited)",
);
USER_HEADER_SEARCH_PATHS = (
../../../include/vorbis/include,
../../../include/vorbis/lib,
);
};
name = Debug;
};
6BA64F7E7862FEF0ED4D6DBE /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
ARCHS = "$(NATIVE_ARCH_ACTUAL)";
CLANG_CXX_LANGUAGE_STANDARD = "c++1z";
CONFIGURATION_BUILD_DIR = "$(SYMROOT)";
CONFIGURATION_TEMP_DIR = "$(OBJROOT)";
GCC_OPTIMIZATION_LEVEL = 3;
GCC_PREPROCESSOR_DEFINITIONS = (
NDEBUG,
);
GCC_SYMBOLS_PRIVATE_EXTERN = NO;
GCC_WARN_ABOUT_RETURN_TYPE = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
OBJROOT = obj/Release/vorbis;
ONLY_ACTIVE_ARCH = NO;
SYMROOT = "../../../bin/release/xcode4-ios/all";
SYSTEM_HEADER_SEARCH_PATHS = (
../../../include/ogg/include,
"$(inherited)",
);
USER_HEADER_SEARCH_PATHS = (
../../../include/vorbis/include,
../../../include/vorbis/lib,
);
};
name = Release;
};
AC0271CDA5C42E3FDFC3300D /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
CONFIGURATION_BUILD_DIR = "../../../bin/debug/xcode4-ios/all";
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
EXECUTABLE_EXTENSION = dll;
GCC_DYNAMIC_NO_PIC = NO;
INSTALL_PATH = /usr/local/lib;
PRODUCT_NAME = "openmpt-vorbis";
};
name = Debug;
};
FD2934076E4BD4F924128247 /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
CONFIGURATION_BUILD_DIR = "../../../bin/release/xcode4-ios/all";
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
EXECUTABLE_EXTENSION = dll;
GCC_DYNAMIC_NO_PIC = NO;
INSTALL_PATH = /usr/local/lib;
PRODUCT_NAME = "openmpt-vorbis";
};
name = Release;
};
/* End XCBuildConfiguration section */
/* Begin XCConfigurationList section */
1DEB928908733DD80010E9CD /* Build configuration list for PBXProject "vorbis" */ = {
isa = XCConfigurationList;
buildConfigurations = (
1FD85444725E7F3644A2E284 /* Debug */,
6BA64F7E7862FEF0ED4D6DBE /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Debug;
};
6A495A8763AF5BF9574AB8C7 /* Build configuration list for PBXNativeTarget "openmpt-vorbis.dll" */ = {
isa = XCConfigurationList;
buildConfigurations = (
AC0271CDA5C42E3FDFC3300D /* Debug */,
FD2934076E4BD4F924128247 /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Debug;
};
/* End XCConfigurationList section */
};
rootObject = 08FB7793FE84155DC02AAC07 /* Project object */;
}

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,16 @@
<?xml version="1.0" encoding="UTF-8"?>
<Workspace
version = "1.0">
<FileRef
location = "group:libopenmpt.xcodeproj">
</FileRef>
<FileRef
location = "group:ext/mpg123.xcodeproj">
</FileRef>
<FileRef
location = "group:ext/ogg.xcodeproj">
</FileRef>
<FileRef
location = "group:ext/vorbis.xcodeproj">
</FileRef>
</Workspace>

View file

@ -0,0 +1,341 @@
// !$*UTF8*$!
{
archiveVersion = 1;
classes = {
};
objectVersion = 46;
objects = {
/* Begin PBXBuildFile section */
022CF042734F913429163E82 /* layer3.c in Sources */ = {isa = PBXBuildFile; fileRef = BAACDA4AE2E792FCCA83208A /* layer3.c */; };
022FC83459953B260BA35674 /* synth_real.c in Sources */ = {isa = PBXBuildFile; fileRef = C3CD341CF5C67ECE6FA5BA5C /* synth_real.c */; };
0DDEA7A4A06C7196094515E4 /* optimize.c in Sources */ = {isa = PBXBuildFile; fileRef = 1B61528CDECD143E1D70B8CC /* optimize.c */; };
142B46E0854DE7D23B149520 /* layer2.c in Sources */ = {isa = PBXBuildFile; fileRef = 9796B208BFD16ABAA76CF848 /* layer2.c */; };
21B328E68EDB3758906E2726 /* equalizer.c in Sources */ = {isa = PBXBuildFile; fileRef = 0F54AFAE5CB7A5E0D2D6A5EE /* equalizer.c */; };
242DF798687C9D0AAAA3D5D8 /* tabinit.c in Sources */ = {isa = PBXBuildFile; fileRef = 6B2790408CF33D72C9A86680 /* tabinit.c */; };
26299D7E974C3E704D12EBBE /* layer1.c in Sources */ = {isa = PBXBuildFile; fileRef = 748089C69CBB42788456D006 /* layer1.c */; };
2CE230149E04D10653CB7E54 /* format.c in Sources */ = {isa = PBXBuildFile; fileRef = AD3049FCD56B02AEBD06903C /* format.c */; };
2F06D05D7C69C68FF288C69D /* compat.c in Sources */ = {isa = PBXBuildFile; fileRef = A7ABBCE59297E2D7DA7DAB25 /* compat.c */; };
5BC0EB1CC8E8F98ECA7BE95C /* synth_s32.c in Sources */ = {isa = PBXBuildFile; fileRef = 739C6384C0FF59B6371E59C4 /* synth_s32.c */; };
64A7B16E5E696DE098686FAE /* synth.c in Sources */ = {isa = PBXBuildFile; fileRef = 907B4FB6D8EC33E81D8B05F6 /* synth.c */; };
6C03B21AB052578CF279905A /* feature.c in Sources */ = {isa = PBXBuildFile; fileRef = A60D55A2C7D902D4048E2BE2 /* feature.c */; };
82DB3C387C9CF8AAB69BFA78 /* parse.c in Sources */ = {isa = PBXBuildFile; fileRef = 440E80E08C7F6512D11E3720 /* parse.c */; };
8ADD039E1D6ACD90864371DE /* icy2utf8.c in Sources */ = {isa = PBXBuildFile; fileRef = C3752BE686E0ED98C5849226 /* icy2utf8.c */; };
9CA288B296644524D06346F2 /* index.c in Sources */ = {isa = PBXBuildFile; fileRef = 754AC0BABDBBA4EC025A76FA /* index.c */; };
BCB343AA29DB521C2B6E41EA /* stringbuf.c in Sources */ = {isa = PBXBuildFile; fileRef = 0BDCDC32593FD264CF5ED272 /* stringbuf.c */; };
C2065F0E06550480487C3D4E /* readers.c in Sources */ = {isa = PBXBuildFile; fileRef = 489101566A5CAE88A711D796 /* readers.c */; };
C39C716430C47FD632576FA4 /* libmpg123.c in Sources */ = {isa = PBXBuildFile; fileRef = 54E0A14CA243977E1862978C /* libmpg123.c */; };
C3D66B021F17BE74F2720942 /* id3.c in Sources */ = {isa = PBXBuildFile; fileRef = F56A100A0C7CAB3CFC98A64A /* id3.c */; };
D1E3070CCBA4C37E05A3C54C /* dct64.c in Sources */ = {isa = PBXBuildFile; fileRef = F4F6A4743D6788A682065AB4 /* dct64.c */; };
D618207A2D7D936CDF8BAEBA /* synth_8bit.c in Sources */ = {isa = PBXBuildFile; fileRef = A1E03F02D3D989B44DB8C542 /* synth_8bit.c */; };
E236244C3D7777BE10D1C28C /* icy.c in Sources */ = {isa = PBXBuildFile; fileRef = E598BBB4FCAB56E6ECC751F4 /* icy.c */; };
EAB0691E1B9461102EAC975E /* ntom.c in Sources */ = {isa = PBXBuildFile; fileRef = 5B10DD6681370D18E83E03A6 /* ntom.c */; };
EE6448D8E826054A22250718 /* frame.c in Sources */ = {isa = PBXBuildFile; fileRef = 78DBF380C14CD7B205EBA9C0 /* frame.c */; };
F155B58DD59CBDBF5989EBCD /* compat_str.c in Sources */ = {isa = PBXBuildFile; fileRef = CDD5DB15FEB9D30711D20955 /* compat_str.c */; };
/* End PBXBuildFile section */
/* Begin PBXFileReference section */
0BDCDC32593FD264CF5ED272 /* stringbuf.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; name = stringbuf.c; path = ../../../include/mpg123/src/libmpg123/stringbuf.c; sourceTree = "<group>"; };
0F54AFAE5CB7A5E0D2D6A5EE /* equalizer.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; name = equalizer.c; path = ../../../include/mpg123/src/libmpg123/equalizer.c; sourceTree = "<group>"; };
1B61528CDECD143E1D70B8CC /* optimize.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; name = optimize.c; path = ../../../include/mpg123/src/libmpg123/optimize.c; sourceTree = "<group>"; };
440E80E08C7F6512D11E3720 /* parse.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; name = parse.c; path = ../../../include/mpg123/src/libmpg123/parse.c; sourceTree = "<group>"; };
489101566A5CAE88A711D796 /* readers.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; name = readers.c; path = ../../../include/mpg123/src/libmpg123/readers.c; sourceTree = "<group>"; };
54E0A14CA243977E1862978C /* libmpg123.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; name = libmpg123.c; path = ../../../include/mpg123/src/libmpg123/libmpg123.c; sourceTree = "<group>"; };
5B10DD6681370D18E83E03A6 /* ntom.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; name = ntom.c; path = ../../../include/mpg123/src/libmpg123/ntom.c; sourceTree = "<group>"; };
6B2790408CF33D72C9A86680 /* tabinit.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; name = tabinit.c; path = ../../../include/mpg123/src/libmpg123/tabinit.c; sourceTree = "<group>"; };
739C6384C0FF59B6371E59C4 /* synth_s32.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; name = synth_s32.c; path = ../../../include/mpg123/src/libmpg123/synth_s32.c; sourceTree = "<group>"; };
748089C69CBB42788456D006 /* layer1.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; name = layer1.c; path = ../../../include/mpg123/src/libmpg123/layer1.c; sourceTree = "<group>"; };
754AC0BABDBBA4EC025A76FA /* index.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; name = index.c; path = ../../../include/mpg123/src/libmpg123/index.c; sourceTree = "<group>"; };
78DBF380C14CD7B205EBA9C0 /* frame.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; name = frame.c; path = ../../../include/mpg123/src/libmpg123/frame.c; sourceTree = "<group>"; };
907B4FB6D8EC33E81D8B05F6 /* synth.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; name = synth.c; path = ../../../include/mpg123/src/libmpg123/synth.c; sourceTree = "<group>"; };
9796B208BFD16ABAA76CF848 /* layer2.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; name = layer2.c; path = ../../../include/mpg123/src/libmpg123/layer2.c; sourceTree = "<group>"; };
A1E03F02D3D989B44DB8C542 /* synth_8bit.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; name = synth_8bit.c; path = ../../../include/mpg123/src/libmpg123/synth_8bit.c; sourceTree = "<group>"; };
A60D55A2C7D902D4048E2BE2 /* feature.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; name = feature.c; path = ../../../include/mpg123/src/libmpg123/feature.c; sourceTree = "<group>"; };
A7ABBCE59297E2D7DA7DAB25 /* compat.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; name = compat.c; path = ../../../include/mpg123/src/compat/compat.c; sourceTree = "<group>"; };
AD3049FCD56B02AEBD06903C /* format.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; name = format.c; path = ../../../include/mpg123/src/libmpg123/format.c; sourceTree = "<group>"; };
BAACDA4AE2E792FCCA83208A /* layer3.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; name = layer3.c; path = ../../../include/mpg123/src/libmpg123/layer3.c; sourceTree = "<group>"; };
C3752BE686E0ED98C5849226 /* icy2utf8.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; name = icy2utf8.c; path = ../../../include/mpg123/src/libmpg123/icy2utf8.c; sourceTree = "<group>"; };
C3CD341CF5C67ECE6FA5BA5C /* synth_real.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; name = synth_real.c; path = ../../../include/mpg123/src/libmpg123/synth_real.c; sourceTree = "<group>"; };
C6BCBF7D1D4A29EFF5C33DBD /* openmpt-mpg123.dll */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.dylib"; includeInIndex = 0; name = "openmpt-mpg123.dll"; path = "openmpt-mpg123.dll"; sourceTree = BUILT_PRODUCTS_DIR; };
CDD5DB15FEB9D30711D20955 /* compat_str.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; name = compat_str.c; path = ../../../include/mpg123/src/compat/compat_str.c; sourceTree = "<group>"; };
E598BBB4FCAB56E6ECC751F4 /* icy.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; name = icy.c; path = ../../../include/mpg123/src/libmpg123/icy.c; sourceTree = "<group>"; };
F4F6A4743D6788A682065AB4 /* dct64.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; name = dct64.c; path = ../../../include/mpg123/src/libmpg123/dct64.c; sourceTree = "<group>"; };
F56A100A0C7CAB3CFC98A64A /* id3.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; name = id3.c; path = ../../../include/mpg123/src/libmpg123/id3.c; sourceTree = "<group>"; };
/* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */
A9087E6DA26E7FDF9609DCAD /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXFrameworksBuildPhase section */
/* Begin PBXCopyFilesBuildPhase section */
E2ED1E19CDD9440B15BF0C59 /* Embed Libraries */ = {
isa = PBXCopyFilesBuildPhase;
buildActionMask = 2147483647;
dstPath = "";
dstSubfolderSpec = 10;
files = (
);
name = "Embed Libraries";
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXCopyFilesBuildPhase section */
/* Begin PBXGroup section */
0F03317AECAE342CC052B7BA /* mpg123 */ = {
isa = PBXGroup;
children = (
3E657050E1B0F982FC81C690 /* compat */,
2C61E28ACF50093C5E75E8CA /* libmpg123 */,
A6C936B49B3FADE6EA134CF4 /* Products */,
);
name = mpg123;
sourceTree = "<group>";
};
2C61E28ACF50093C5E75E8CA /* libmpg123 */ = {
isa = PBXGroup;
children = (
F4F6A4743D6788A682065AB4 /* dct64.c */,
0F54AFAE5CB7A5E0D2D6A5EE /* equalizer.c */,
A60D55A2C7D902D4048E2BE2 /* feature.c */,
AD3049FCD56B02AEBD06903C /* format.c */,
78DBF380C14CD7B205EBA9C0 /* frame.c */,
E598BBB4FCAB56E6ECC751F4 /* icy.c */,
C3752BE686E0ED98C5849226 /* icy2utf8.c */,
F56A100A0C7CAB3CFC98A64A /* id3.c */,
754AC0BABDBBA4EC025A76FA /* index.c */,
748089C69CBB42788456D006 /* layer1.c */,
9796B208BFD16ABAA76CF848 /* layer2.c */,
BAACDA4AE2E792FCCA83208A /* layer3.c */,
54E0A14CA243977E1862978C /* libmpg123.c */,
5B10DD6681370D18E83E03A6 /* ntom.c */,
1B61528CDECD143E1D70B8CC /* optimize.c */,
440E80E08C7F6512D11E3720 /* parse.c */,
489101566A5CAE88A711D796 /* readers.c */,
0BDCDC32593FD264CF5ED272 /* stringbuf.c */,
907B4FB6D8EC33E81D8B05F6 /* synth.c */,
A1E03F02D3D989B44DB8C542 /* synth_8bit.c */,
C3CD341CF5C67ECE6FA5BA5C /* synth_real.c */,
739C6384C0FF59B6371E59C4 /* synth_s32.c */,
6B2790408CF33D72C9A86680 /* tabinit.c */,
);
name = libmpg123;
sourceTree = "<group>";
};
3E657050E1B0F982FC81C690 /* compat */ = {
isa = PBXGroup;
children = (
A7ABBCE59297E2D7DA7DAB25 /* compat.c */,
CDD5DB15FEB9D30711D20955 /* compat_str.c */,
);
name = compat;
sourceTree = "<group>";
};
A6C936B49B3FADE6EA134CF4 /* Products */ = {
isa = PBXGroup;
children = (
C6BCBF7D1D4A29EFF5C33DBD /* openmpt-mpg123.dll */,
);
name = Products;
sourceTree = "<group>";
};
/* End PBXGroup section */
/* Begin PBXNativeTarget section */
6CFC1BC3B56CFFF5FA0BD203 /* mpg123 */ = {
isa = PBXNativeTarget;
buildConfigurationList = 9743C6CC90A9C83E8445250C /* Build configuration list for PBXNativeTarget "mpg123" */;
buildPhases = (
18EFFF0D1256007F05F15D4D /* Resources */,
829D18647C0319D66F9E76A4 /* Sources */,
A9087E6DA26E7FDF9609DCAD /* Frameworks */,
E2ED1E19CDD9440B15BF0C59 /* Embed Libraries */,
);
buildRules = (
);
dependencies = (
);
name = mpg123;
productName = mpg123;
productReference = C6BCBF7D1D4A29EFF5C33DBD /* openmpt-mpg123.dll */;
productType = "com.apple.product-type.library.dynamic";
};
/* End PBXNativeTarget section */
/* Begin PBXProject section */
08FB7793FE84155DC02AAC07 /* Project object */ = {
isa = PBXProject;
buildConfigurationList = 1DEB928908733DD80010E9CD /* Build configuration list for PBXProject "mpg123" */;
compatibilityVersion = "Xcode 3.2";
hasScannedForEncodings = 1;
mainGroup = 0F03317AECAE342CC052B7BA /* mpg123 */;
projectDirPath = "";
projectRoot = "";
targets = (
6CFC1BC3B56CFFF5FA0BD203 /* openmpt-mpg123.dll */,
);
};
/* End PBXProject section */
/* Begin PBXResourcesBuildPhase section */
18EFFF0D1256007F05F15D4D /* Resources */ = {
isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647;
files = (
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXResourcesBuildPhase section */
/* Begin PBXSourcesBuildPhase section */
829D18647C0319D66F9E76A4 /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
2F06D05D7C69C68FF288C69D /* compat.c in Sources */,
F155B58DD59CBDBF5989EBCD /* compat_str.c in Sources */,
D1E3070CCBA4C37E05A3C54C /* dct64.c in Sources */,
21B328E68EDB3758906E2726 /* equalizer.c in Sources */,
6C03B21AB052578CF279905A /* feature.c in Sources */,
2CE230149E04D10653CB7E54 /* format.c in Sources */,
EE6448D8E826054A22250718 /* frame.c in Sources */,
E236244C3D7777BE10D1C28C /* icy.c in Sources */,
8ADD039E1D6ACD90864371DE /* icy2utf8.c in Sources */,
C3D66B021F17BE74F2720942 /* id3.c in Sources */,
9CA288B296644524D06346F2 /* index.c in Sources */,
26299D7E974C3E704D12EBBE /* layer1.c in Sources */,
142B46E0854DE7D23B149520 /* layer2.c in Sources */,
022CF042734F913429163E82 /* layer3.c in Sources */,
C39C716430C47FD632576FA4 /* libmpg123.c in Sources */,
EAB0691E1B9461102EAC975E /* ntom.c in Sources */,
0DDEA7A4A06C7196094515E4 /* optimize.c in Sources */,
82DB3C387C9CF8AAB69BFA78 /* parse.c in Sources */,
C2065F0E06550480487C3D4E /* readers.c in Sources */,
BCB343AA29DB521C2B6E41EA /* stringbuf.c in Sources */,
64A7B16E5E696DE098686FAE /* synth.c in Sources */,
D618207A2D7D936CDF8BAEBA /* synth_8bit.c in Sources */,
022FC83459953B260BA35674 /* synth_real.c in Sources */,
5BC0EB1CC8E8F98ECA7BE95C /* synth_s32.c in Sources */,
242DF798687C9D0AAAA3D5D8 /* tabinit.c in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXSourcesBuildPhase section */
/* Begin PBXVariantGroup section */
/* End PBXVariantGroup section */
/* Begin XCBuildConfiguration section */
4C50EB499ED7163B711B7989 /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
ARCHS = "$(NATIVE_ARCH_ACTUAL)";
CLANG_CXX_LANGUAGE_STANDARD = "c++1z";
CONFIGURATION_BUILD_DIR = "$(SYMROOT)";
CONFIGURATION_TEMP_DIR = "$(OBJROOT)";
COPY_PHASE_STRIP = NO;
GCC_ENABLE_FIX_AND_CONTINUE = YES;
GCC_OPTIMIZATION_LEVEL = 0;
GCC_PREPROCESSOR_DEFINITIONS = (
DEBUG,
MPT_BUILD_DEBUG,
OPT_GENERIC,
);
GCC_SYMBOLS_PRIVATE_EXTERN = NO;
GCC_WARN_ABOUT_RETURN_TYPE = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
OBJROOT = obj/Debug/mpg123;
ONLY_ACTIVE_ARCH = YES;
SYMROOT = "../../../bin/debug/xcode4-macosx/all";
USER_HEADER_SEARCH_PATHS = (
../../../include/mpg123/ports/Xcode,
../../../include/mpg123/src/libmpg123,
../../../include/mpg123/src/compat,
../../../include/mpg123/src,
);
};
name = Debug;
};
7C31350CED53D5FEA31A834C /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
CONFIGURATION_BUILD_DIR = "../../../bin/release/xcode4-macosx/all";
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
EXECUTABLE_EXTENSION = dll;
GCC_DYNAMIC_NO_PIC = NO;
INSTALL_PATH = /usr/local/lib;
PRODUCT_NAME = "openmpt-mpg123";
};
name = Release;
};
98A0BBC3A55D6B351A47DA03 /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
ARCHS = "$(NATIVE_ARCH_ACTUAL)";
CLANG_CXX_LANGUAGE_STANDARD = "c++1z";
CONFIGURATION_BUILD_DIR = "$(SYMROOT)";
CONFIGURATION_TEMP_DIR = "$(OBJROOT)";
GCC_OPTIMIZATION_LEVEL = 3;
GCC_PREPROCESSOR_DEFINITIONS = (
NDEBUG,
OPT_GENERIC,
);
GCC_SYMBOLS_PRIVATE_EXTERN = NO;
GCC_WARN_ABOUT_RETURN_TYPE = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
OBJROOT = obj/Release/mpg123;
ONLY_ACTIVE_ARCH = NO;
SYMROOT = "../../../bin/release/xcode4-macosx/all";
USER_HEADER_SEARCH_PATHS = (
../../../include/mpg123/ports/Xcode,
../../../include/mpg123/src/libmpg123,
../../../include/mpg123/src/compat,
../../../include/mpg123/src,
);
};
name = Release;
};
9C9C6D92965E2A04D05D2BD2 /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
CONFIGURATION_BUILD_DIR = "../../../bin/debug/xcode4-macosx/all";
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
EXECUTABLE_EXTENSION = dll;
GCC_DYNAMIC_NO_PIC = NO;
INSTALL_PATH = /usr/local/lib;
PRODUCT_NAME = "openmpt-mpg123";
};
name = Debug;
};
/* End XCBuildConfiguration section */
/* Begin XCConfigurationList section */
1DEB928908733DD80010E9CD /* Build configuration list for PBXProject "mpg123" */ = {
isa = XCConfigurationList;
buildConfigurations = (
4C50EB499ED7163B711B7989 /* Debug */,
98A0BBC3A55D6B351A47DA03 /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Debug;
};
9743C6CC90A9C83E8445250C /* Build configuration list for PBXNativeTarget "openmpt-mpg123.dll" */ = {
isa = XCConfigurationList;
buildConfigurations = (
9C9C6D92965E2A04D05D2BD2 /* Debug */,
7C31350CED53D5FEA31A834C /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Debug;
};
/* End XCConfigurationList section */
};
rootObject = 08FB7793FE84155DC02AAC07 /* Project object */;
}

View file

@ -0,0 +1,255 @@
// !$*UTF8*$!
{
archiveVersion = 1;
classes = {
};
objectVersion = 46;
objects = {
/* Begin PBXBuildFile section */
9C9F8407CD837BF9E09BB247 /* bitwise.c in Sources */ = {isa = PBXBuildFile; fileRef = 1891292F3EB758E1A5BE4F6F /* bitwise.c */; };
FF0BAB212FEFA3134307D961 /* framing.c in Sources */ = {isa = PBXBuildFile; fileRef = B766F1A9DD8D215B449417E9 /* framing.c */; };
/* End PBXBuildFile section */
/* Begin PBXFileReference section */
1891292F3EB758E1A5BE4F6F /* bitwise.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; name = bitwise.c; path = ../../../include/ogg/src/bitwise.c; sourceTree = "<group>"; };
1E47F32D446E22DFAB75196D /* ogg.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = ogg.h; path = ../../../include/ogg/include/ogg/ogg.h; sourceTree = "<group>"; };
5036DE60765D0E12DD6404A0 /* openmpt-ogg.dll */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.dylib"; includeInIndex = 0; name = "openmpt-ogg.dll"; path = "openmpt-ogg.dll"; sourceTree = BUILT_PRODUCTS_DIR; };
93F6FCDFE159F3115778F31F /* os_types.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = os_types.h; path = ../../../include/ogg/include/ogg/os_types.h; sourceTree = "<group>"; };
B766F1A9DD8D215B449417E9 /* framing.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; name = framing.c; path = ../../../include/ogg/src/framing.c; sourceTree = "<group>"; };
/* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */
95F8A3D038E6CA82C80CAA10 /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXFrameworksBuildPhase section */
/* Begin PBXCopyFilesBuildPhase section */
CC7C283CE38EC36ED3AABE7C /* Embed Libraries */ = {
isa = PBXCopyFilesBuildPhase;
buildActionMask = 2147483647;
dstPath = "";
dstSubfolderSpec = 10;
files = (
);
name = "Embed Libraries";
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXCopyFilesBuildPhase section */
/* Begin PBXGroup section */
5775D4184366DFCA959E7A58 /* src */ = {
isa = PBXGroup;
children = (
1891292F3EB758E1A5BE4F6F /* bitwise.c */,
B766F1A9DD8D215B449417E9 /* framing.c */,
);
name = src;
sourceTree = "<group>";
};
5E8C725002DF100215175890 /* include */ = {
isa = PBXGroup;
children = (
BE79831562CC20C775046955 /* ogg */,
);
name = include;
sourceTree = "<group>";
};
A078B4BDABA964AF054BE2FD /* ogg */ = {
isa = PBXGroup;
children = (
5E8C725002DF100215175890 /* include */,
5775D4184366DFCA959E7A58 /* src */,
A6C936B49B3FADE6EA134CF4 /* Products */,
);
name = ogg;
sourceTree = "<group>";
};
A6C936B49B3FADE6EA134CF4 /* Products */ = {
isa = PBXGroup;
children = (
5036DE60765D0E12DD6404A0 /* openmpt-ogg.dll */,
);
name = Products;
sourceTree = "<group>";
};
BE79831562CC20C775046955 /* ogg */ = {
isa = PBXGroup;
children = (
1E47F32D446E22DFAB75196D /* ogg.h */,
93F6FCDFE159F3115778F31F /* os_types.h */,
);
name = ogg;
sourceTree = "<group>";
};
/* End PBXGroup section */
/* Begin PBXNativeTarget section */
886C6A4681D26BB8756DC886 /* ogg */ = {
isa = PBXNativeTarget;
buildConfigurationList = 8433EC2F272212E1B647F26F /* Build configuration list for PBXNativeTarget "ogg" */;
buildPhases = (
05E02470A8CE4B2237F42AB0 /* Resources */,
6F8D3DC7127B6479A1A14407 /* Sources */,
95F8A3D038E6CA82C80CAA10 /* Frameworks */,
CC7C283CE38EC36ED3AABE7C /* Embed Libraries */,
);
buildRules = (
);
dependencies = (
);
name = ogg;
productName = ogg;
productReference = 5036DE60765D0E12DD6404A0 /* openmpt-ogg.dll */;
productType = "com.apple.product-type.library.dynamic";
};
/* End PBXNativeTarget section */
/* Begin PBXProject section */
08FB7793FE84155DC02AAC07 /* Project object */ = {
isa = PBXProject;
buildConfigurationList = 1DEB928908733DD80010E9CD /* Build configuration list for PBXProject "ogg" */;
compatibilityVersion = "Xcode 3.2";
hasScannedForEncodings = 1;
mainGroup = A078B4BDABA964AF054BE2FD /* ogg */;
projectDirPath = "";
projectRoot = "";
targets = (
886C6A4681D26BB8756DC886 /* openmpt-ogg.dll */,
);
};
/* End PBXProject section */
/* Begin PBXResourcesBuildPhase section */
05E02470A8CE4B2237F42AB0 /* Resources */ = {
isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647;
files = (
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXResourcesBuildPhase section */
/* Begin PBXSourcesBuildPhase section */
6F8D3DC7127B6479A1A14407 /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
9C9F8407CD837BF9E09BB247 /* bitwise.c in Sources */,
FF0BAB212FEFA3134307D961 /* framing.c in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXSourcesBuildPhase section */
/* Begin PBXVariantGroup section */
/* End PBXVariantGroup section */
/* Begin XCBuildConfiguration section */
8F6FCF26DF8363D862019566 /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
ARCHS = "$(NATIVE_ARCH_ACTUAL)";
CLANG_CXX_LANGUAGE_STANDARD = "c++1z";
CONFIGURATION_BUILD_DIR = "$(SYMROOT)";
CONFIGURATION_TEMP_DIR = "$(OBJROOT)";
GCC_OPTIMIZATION_LEVEL = 3;
GCC_PREPROCESSOR_DEFINITIONS = (
NDEBUG,
);
GCC_SYMBOLS_PRIVATE_EXTERN = NO;
GCC_WARN_ABOUT_RETURN_TYPE = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
OBJROOT = obj/Release/ogg;
ONLY_ACTIVE_ARCH = NO;
SYMROOT = "../../../bin/release/xcode4-macosx/all";
SYSTEM_HEADER_SEARCH_PATHS = (
../../../include/ogg/include,
"$(inherited)",
);
};
name = Release;
};
C49D8BAF120081E1881F81EF /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
CONFIGURATION_BUILD_DIR = "../../../bin/release/xcode4-macosx/all";
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
EXECUTABLE_EXTENSION = dll;
GCC_DYNAMIC_NO_PIC = NO;
INSTALL_PATH = /usr/local/lib;
PRODUCT_NAME = "openmpt-ogg";
};
name = Release;
};
C86DC9EC74D08A1E3359002C /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
ARCHS = "$(NATIVE_ARCH_ACTUAL)";
CLANG_CXX_LANGUAGE_STANDARD = "c++1z";
CONFIGURATION_BUILD_DIR = "$(SYMROOT)";
CONFIGURATION_TEMP_DIR = "$(OBJROOT)";
COPY_PHASE_STRIP = NO;
GCC_ENABLE_FIX_AND_CONTINUE = YES;
GCC_OPTIMIZATION_LEVEL = 0;
GCC_PREPROCESSOR_DEFINITIONS = (
DEBUG,
MPT_BUILD_DEBUG,
);
GCC_SYMBOLS_PRIVATE_EXTERN = NO;
GCC_WARN_ABOUT_RETURN_TYPE = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
OBJROOT = obj/Debug/ogg;
ONLY_ACTIVE_ARCH = YES;
SYMROOT = "../../../bin/debug/xcode4-macosx/all";
SYSTEM_HEADER_SEARCH_PATHS = (
../../../include/ogg/include,
"$(inherited)",
);
};
name = Debug;
};
DFACBF75A3188127E1BC25B5 /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
CONFIGURATION_BUILD_DIR = "../../../bin/debug/xcode4-macosx/all";
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
EXECUTABLE_EXTENSION = dll;
GCC_DYNAMIC_NO_PIC = NO;
INSTALL_PATH = /usr/local/lib;
PRODUCT_NAME = "openmpt-ogg";
};
name = Debug;
};
/* End XCBuildConfiguration section */
/* Begin XCConfigurationList section */
1DEB928908733DD80010E9CD /* Build configuration list for PBXProject "ogg" */ = {
isa = XCConfigurationList;
buildConfigurations = (
C86DC9EC74D08A1E3359002C /* Debug */,
8F6FCF26DF8363D862019566 /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Debug;
};
8433EC2F272212E1B647F26F /* Build configuration list for PBXNativeTarget "openmpt-ogg.dll" */ = {
isa = XCConfigurationList;
buildConfigurations = (
DFACBF75A3188127E1BC25B5 /* Debug */,
C49D8BAF120081E1881F81EF /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Debug;
};
/* End XCConfigurationList section */
};
rootObject = 08FB7793FE84155DC02AAC07 /* Project object */;
}

View file

@ -0,0 +1,531 @@
// !$*UTF8*$!
{
archiveVersion = 1;
classes = {
};
objectVersion = 46;
objects = {
/* Begin PBXBuildFile section */
16716A7E46033970211078BE /* block.c in Sources */ = {isa = PBXBuildFile; fileRef = 777077261A5E9DD8A9847D66 /* block.c */; };
16B25260019E7852498440A0 /* psy.c in Sources */ = {isa = PBXBuildFile; fileRef = EDFFC5E89252639AA48AAC28 /* psy.c */; };
3EA9B7E0953722526DB03620 /* info.c in Sources */ = {isa = PBXBuildFile; fileRef = E03CFA68E3ADCC9A651A70A8 /* info.c */; };
412482943AE63F0674E540D4 /* codebook.c in Sources */ = {isa = PBXBuildFile; fileRef = 2A6247DC72D32C0EB771FE1C /* codebook.c */; };
42BABA9A3C7C770C767B78DA /* registry.c in Sources */ = {isa = PBXBuildFile; fileRef = D1E246821A532AB45EF1FCC2 /* registry.c */; };
55E0C63CC703672E7CCA147C /* synthesis.c in Sources */ = {isa = PBXBuildFile; fileRef = 3A6CA00462A758B64A42E644 /* synthesis.c */; };
571301CEB254554085AEA00E /* floor1.c in Sources */ = {isa = PBXBuildFile; fileRef = 501CFA76672F95A8574B90B6 /* floor1.c */; };
63BC07FCBEFD5B6E9257A63C /* lookup.c in Sources */ = {isa = PBXBuildFile; fileRef = 35F064C44D02FFF63D1EFB04 /* lookup.c */; };
650BD9CE95EFD1C0A908080E /* smallft.c in Sources */ = {isa = PBXBuildFile; fileRef = CEB55B76F4DB8B285BE281B6 /* smallft.c */; };
665EF2C06020AF329A1FB100 /* mapping0.c in Sources */ = {isa = PBXBuildFile; fileRef = 379713488007F77AC4A6C988 /* mapping0.c */; };
66F0DF98BD7E4A0A95F75DD8 /* mdct.c in Sources */ = {isa = PBXBuildFile; fileRef = C67232A0C9E304D24B4FA8E0 /* mdct.c */; };
7C34482667206E18AF063666 /* lpc.c in Sources */ = {isa = PBXBuildFile; fileRef = 7091344E14E3D200271C1A8E /* lpc.c */; };
A4B9FD2CFFFB509ED3559B6C /* floor0.c in Sources */ = {isa = PBXBuildFile; fileRef = 3AED1EF451FFBA26421BB534 /* floor0.c */; };
A7912A52EBDFCFC42E070892 /* vorbisfile.c in Sources */ = {isa = PBXBuildFile; fileRef = C39AD0BAE5667DEC221BA6FA /* vorbisfile.c */; };
B1D3BC04AB957876E5947A44 /* envelope.c in Sources */ = {isa = PBXBuildFile; fileRef = 14D8424C5D49267EA1E7F88C /* envelope.c */; };
BC748D10B6364982F0354B50 /* analysis.c in Sources */ = {isa = PBXBuildFile; fileRef = 4AAD1098931DF4CAD7BCC6D8 /* analysis.c */; };
BDB5A0B818F6F42AEC513EF8 /* window.c in Sources */ = {isa = PBXBuildFile; fileRef = 72232FC08935CAF27951C600 /* window.c */; };
D5E5E506C0D20AF808B7D346 /* lsp.c in Sources */ = {isa = PBXBuildFile; fileRef = 6F30132E1382B0E025BAF96E /* lsp.c */; };
D85CD4BE497F75B0FF4622FE /* vorbisenc.c in Sources */ = {isa = PBXBuildFile; fileRef = 92BA4166BAF4FA18A29087A6 /* vorbisenc.c */; };
DBA06C398F9C856B714EC279 /* openmpt-ogg.lib in Frameworks */ = {isa = PBXBuildFile; fileRef = E03059217A8A4213B6C2A761 /* openmpt-ogg.lib */; };
E344DF0C2793847E69BABD4C /* sharedbook.c in Sources */ = {isa = PBXBuildFile; fileRef = 72897ED494552C06D10A5514 /* sharedbook.c */; };
E77EFABE1862F2B02B7B28FE /* bitrate.c in Sources */ = {isa = PBXBuildFile; fileRef = 0944F5662F6B251896721BA6 /* bitrate.c */; };
FC4D923C52DAFCAE2B54107C /* res0.c in Sources */ = {isa = PBXBuildFile; fileRef = 16DFB5041A5087369BBD2B44 /* res0.c */; };
/* End PBXBuildFile section */
/* Begin PBXContainerItemProxy section */
3D2DCDF83693CF6A2A2F2C38 /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = 386FE2DA60AA9B8C4846291A /* ogg.xcodeproj */;
proxyType = 1;
remoteGlobalIDString = 886C6A4681D26BB8756DC886;
remoteInfo = "openmpt-ogg.dll";
};
EAF35B5FE4595CD1D7F4B99F /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = 386FE2DA60AA9B8C4846291A /* ogg.xcodeproj */;
proxyType = 2;
remoteGlobalIDString = 5036DE60765D0E12DD6404A0;
remoteInfo = "openmpt-ogg.dll";
};
/* End PBXContainerItemProxy section */
/* Begin PBXFileReference section */
058BB8B85C19232A349236F8 /* openmpt-vorbis.dll */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.dylib"; includeInIndex = 0; name = "openmpt-vorbis.dll"; path = "openmpt-vorbis.dll"; sourceTree = BUILT_PRODUCTS_DIR; };
07BE8ECA1ED129FC0EED250A /* window.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = window.h; path = ../../../include/vorbis/lib/window.h; sourceTree = "<group>"; };
0944F5662F6B251896721BA6 /* bitrate.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; name = bitrate.c; path = ../../../include/vorbis/lib/bitrate.c; sourceTree = "<group>"; };
0C6D4B2032937AD2999A7160 /* smallft.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = smallft.h; path = ../../../include/vorbis/lib/smallft.h; sourceTree = "<group>"; };
0D82D8FD2F4E862F6C03AF3D /* psych_8.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = psych_8.h; path = ../../../include/vorbis/lib/modes/psych_8.h; sourceTree = "<group>"; };
13C8DC265C39C058A0D89266 /* codebook.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = codebook.h; path = ../../../include/vorbis/lib/codebook.h; sourceTree = "<group>"; };
14D8424C5D49267EA1E7F88C /* envelope.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; name = envelope.c; path = ../../../include/vorbis/lib/envelope.c; sourceTree = "<group>"; };
15F93858BA4BD60ACC841E98 /* lsp.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = lsp.h; path = ../../../include/vorbis/lib/lsp.h; sourceTree = "<group>"; };
16DFB5041A5087369BBD2B44 /* res0.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; name = res0.c; path = ../../../include/vorbis/lib/res0.c; sourceTree = "<group>"; };
16F680C77237D43945921F07 /* codec.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = codec.h; path = ../../../include/vorbis/include/vorbis/codec.h; sourceTree = "<group>"; };
175A5978BBACF72ACDE53FB8 /* lpc.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = lpc.h; path = ../../../include/vorbis/lib/lpc.h; sourceTree = "<group>"; };
1F836091517CAB43CB5BE6D1 /* residue_44.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = residue_44.h; path = ../../../include/vorbis/lib/modes/residue_44.h; sourceTree = "<group>"; };
2740402E4D666FE0B46D666E /* masking.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = masking.h; path = ../../../include/vorbis/lib/masking.h; sourceTree = "<group>"; };
285CE11ECBA86A50E679375E /* os.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = os.h; path = ../../../include/vorbis/lib/os.h; sourceTree = "<group>"; };
2A6247DC72D32C0EB771FE1C /* codebook.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; name = codebook.c; path = ../../../include/vorbis/lib/codebook.c; sourceTree = "<group>"; };
2AAE7645EE1A37F72CBDDC85 /* setup_11.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = setup_11.h; path = ../../../include/vorbis/lib/modes/setup_11.h; sourceTree = "<group>"; };
35CF7AFDF93B3CAF37DEE13D /* psych_44.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = psych_44.h; path = ../../../include/vorbis/lib/modes/psych_44.h; sourceTree = "<group>"; };
35F064C44D02FFF63D1EFB04 /* lookup.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; name = lookup.c; path = ../../../include/vorbis/lib/lookup.c; sourceTree = "<group>"; };
374A6BCA5F85247C4720B20A /* highlevel.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = highlevel.h; path = ../../../include/vorbis/lib/highlevel.h; sourceTree = "<group>"; };
379713488007F77AC4A6C988 /* mapping0.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; name = mapping0.c; path = ../../../include/vorbis/lib/mapping0.c; sourceTree = "<group>"; };
386FE2DA60AA9B8C4846291A /* openmpt-ogg.lib */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = "ogg.xcodeproj"; path = ogg.xcodeproj; sourceTree = SOURCE_ROOT; };
3A6CA00462A758B64A42E644 /* synthesis.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; name = synthesis.c; path = ../../../include/vorbis/lib/synthesis.c; sourceTree = "<group>"; };
3AED1EF451FFBA26421BB534 /* floor0.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; name = floor0.c; path = ../../../include/vorbis/lib/floor0.c; sourceTree = "<group>"; };
3B10AC6A3E817E9CBFEE22AA /* mdct.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = mdct.h; path = ../../../include/vorbis/lib/mdct.h; sourceTree = "<group>"; };
3BA7A5A17FF64B13C21D83E1 /* vorbisenc.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = vorbisenc.h; path = ../../../include/vorbis/include/vorbis/vorbisenc.h; sourceTree = "<group>"; };
450CC03BDA837F6D491FD67B /* residue_44u.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = residue_44u.h; path = ../../../include/vorbis/lib/modes/residue_44u.h; sourceTree = "<group>"; };
46FCE5106D2314C2D42A0B50 /* bitrate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = bitrate.h; path = ../../../include/vorbis/lib/bitrate.h; sourceTree = "<group>"; };
4AAD1098931DF4CAD7BCC6D8 /* analysis.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; name = analysis.c; path = ../../../include/vorbis/lib/analysis.c; sourceTree = "<group>"; };
501CFA76672F95A8574B90B6 /* floor1.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; name = floor1.c; path = ../../../include/vorbis/lib/floor1.c; sourceTree = "<group>"; };
5BED095DF163C88F60001F9D /* setup_44p51.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = setup_44p51.h; path = ../../../include/vorbis/lib/modes/setup_44p51.h; sourceTree = "<group>"; };
63614891852CF5C3C1E21ED1 /* setup_X.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = setup_X.h; path = ../../../include/vorbis/lib/modes/setup_X.h; sourceTree = "<group>"; };
6B3067A02E9C29526D3FCDE0 /* lookup_data.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = lookup_data.h; path = ../../../include/vorbis/lib/lookup_data.h; sourceTree = "<group>"; };
6B6795D0827A310272962C10 /* scales.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = scales.h; path = ../../../include/vorbis/lib/scales.h; sourceTree = "<group>"; };
6CCD7211303933C36EDCD851 /* setup_44.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = setup_44.h; path = ../../../include/vorbis/lib/modes/setup_44.h; sourceTree = "<group>"; };
6E91170FA08A61C11A699D4F /* residue_16.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = residue_16.h; path = ../../../include/vorbis/lib/modes/residue_16.h; sourceTree = "<group>"; };
6F30132E1382B0E025BAF96E /* lsp.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; name = lsp.c; path = ../../../include/vorbis/lib/lsp.c; sourceTree = "<group>"; };
7091344E14E3D200271C1A8E /* lpc.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; name = lpc.c; path = ../../../include/vorbis/lib/lpc.c; sourceTree = "<group>"; };
72232FC08935CAF27951C600 /* window.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; name = window.c; path = ../../../include/vorbis/lib/window.c; sourceTree = "<group>"; };
72897ED494552C06D10A5514 /* sharedbook.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; name = sharedbook.c; path = ../../../include/vorbis/lib/sharedbook.c; sourceTree = "<group>"; };
746BBDBB37D77F6D767B23FB /* psych_16.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = psych_16.h; path = ../../../include/vorbis/lib/modes/psych_16.h; sourceTree = "<group>"; };
777077261A5E9DD8A9847D66 /* block.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; name = block.c; path = ../../../include/vorbis/lib/block.c; sourceTree = "<group>"; };
7EC1E432F2AA5BE414F80A72 /* res_books_stereo.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = res_books_stereo.h; path = ../../../include/vorbis/lib/books/coupled/res_books_stereo.h; sourceTree = "<group>"; };
90EE3C51B2B9E983EF6F1291 /* setup_8.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = setup_8.h; path = ../../../include/vorbis/lib/modes/setup_8.h; sourceTree = "<group>"; };
92BA4166BAF4FA18A29087A6 /* vorbisenc.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; name = vorbisenc.c; path = ../../../include/vorbis/lib/vorbisenc.c; sourceTree = "<group>"; };
94C8EB12391B88C44B53D152 /* psy.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = psy.h; path = ../../../include/vorbis/lib/psy.h; sourceTree = "<group>"; };
960E1F895979E13B981D85C9 /* setup_22.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = setup_22.h; path = ../../../include/vorbis/lib/modes/setup_22.h; sourceTree = "<group>"; };
AB69B4CF6ED57681AD791B0F /* setup_16.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = setup_16.h; path = ../../../include/vorbis/lib/modes/setup_16.h; sourceTree = "<group>"; };
B9289C7B068B92AD7CAA92BB /* setup_44u.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = setup_44u.h; path = ../../../include/vorbis/lib/modes/setup_44u.h; sourceTree = "<group>"; };
B980BE8E4EF77DC0BD93D4CE /* codec_internal.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = codec_internal.h; path = ../../../include/vorbis/lib/codec_internal.h; sourceTree = "<group>"; };
BB48DACC03B9BEFE4858910C /* registry.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = registry.h; path = ../../../include/vorbis/lib/registry.h; sourceTree = "<group>"; };
C38A75AF76807F61C7A2DBEF /* res_books_uncoupled.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = res_books_uncoupled.h; path = ../../../include/vorbis/lib/books/uncoupled/res_books_uncoupled.h; sourceTree = "<group>"; };
C39AD0BAE5667DEC221BA6FA /* vorbisfile.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; name = vorbisfile.c; path = ../../../include/vorbis/lib/vorbisfile.c; sourceTree = "<group>"; };
C67232A0C9E304D24B4FA8E0 /* mdct.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; name = mdct.c; path = ../../../include/vorbis/lib/mdct.c; sourceTree = "<group>"; };
C97DEB5A61CAD10C9011D19A /* res_books_51.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = res_books_51.h; path = ../../../include/vorbis/lib/books/coupled/res_books_51.h; sourceTree = "<group>"; };
CB8BC3CEE29E5F00D2BA5A0E /* lookup.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = lookup.h; path = ../../../include/vorbis/lib/lookup.h; sourceTree = "<group>"; };
CEB55B76F4DB8B285BE281B6 /* smallft.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; name = smallft.c; path = ../../../include/vorbis/lib/smallft.c; sourceTree = "<group>"; };
D1E246821A532AB45EF1FCC2 /* registry.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; name = registry.c; path = ../../../include/vorbis/lib/registry.c; sourceTree = "<group>"; };
D90D21756B9AEB67D4738FB5 /* vorbisfile.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = vorbisfile.h; path = ../../../include/vorbis/include/vorbis/vorbisfile.h; sourceTree = "<group>"; };
DAF247F2DE631A245FCFBE32 /* misc.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = misc.h; path = ../../../include/vorbis/lib/misc.h; sourceTree = "<group>"; };
DBC5215DC00C298F43F9579D /* residue_44p51.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = residue_44p51.h; path = ../../../include/vorbis/lib/modes/residue_44p51.h; sourceTree = "<group>"; };
E03CFA68E3ADCC9A651A70A8 /* info.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; name = info.c; path = ../../../include/vorbis/lib/info.c; sourceTree = "<group>"; };
E7AEBC4BAB1A7DFDE9BE228B /* setup_32.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = setup_32.h; path = ../../../include/vorbis/lib/modes/setup_32.h; sourceTree = "<group>"; };
EABBD3D0332CB80277CB8A10 /* backends.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = backends.h; path = ../../../include/vorbis/lib/backends.h; sourceTree = "<group>"; };
EDFFC5E89252639AA48AAC28 /* psy.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; name = psy.c; path = ../../../include/vorbis/lib/psy.c; sourceTree = "<group>"; };
EE56303600800CE83470F676 /* floor_books.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = floor_books.h; path = ../../../include/vorbis/lib/books/floor/floor_books.h; sourceTree = "<group>"; };
F1CF92D13F328903B5518911 /* residue_8.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = residue_8.h; path = ../../../include/vorbis/lib/modes/residue_8.h; sourceTree = "<group>"; };
F3B07F31B71C40E3F5BFE571 /* psych_11.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = psych_11.h; path = ../../../include/vorbis/lib/modes/psych_11.h; sourceTree = "<group>"; };
FB9FDEF54902D527BF21D535 /* floor_all.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = floor_all.h; path = ../../../include/vorbis/lib/modes/floor_all.h; sourceTree = "<group>"; };
FE3ED69646AFBAC88B4E8CD6 /* envelope.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = envelope.h; path = ../../../include/vorbis/lib/envelope.h; sourceTree = "<group>"; };
/* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */
7C0E12287574139A690F7068 /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
DBA06C398F9C856B714EC279 /* openmpt-ogg.lib in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXFrameworksBuildPhase section */
/* Begin PBXCopyFilesBuildPhase section */
8DA68C947892B286C0787AD4 /* Embed Libraries */ = {
isa = PBXCopyFilesBuildPhase;
buildActionMask = 2147483647;
dstPath = "";
dstSubfolderSpec = 10;
files = (
);
name = "Embed Libraries";
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXCopyFilesBuildPhase section */
/* Begin PBXGroup section */
26717C15041C7EC7D7C10255 /* vorbis */ = {
isa = PBXGroup;
children = (
5E8C725002DF100215175890 /* include */,
8D815E5679726A08CBAA0496 /* lib */,
A6C936B49B3FADE6EA134CF4 /* Products */,
9D968EAA920D05DCE0E0A4EA /* Projects */,
);
name = vorbis;
sourceTree = "<group>";
};
5A1F78C5713213F7614E0F05 /* vorbis */ = {
isa = PBXGroup;
children = (
16F680C77237D43945921F07 /* codec.h */,
3BA7A5A17FF64B13C21D83E1 /* vorbisenc.h */,
D90D21756B9AEB67D4738FB5 /* vorbisfile.h */,
);
name = vorbis;
sourceTree = "<group>";
};
5E8C725002DF100215175890 /* include */ = {
isa = PBXGroup;
children = (
5A1F78C5713213F7614E0F05 /* vorbis */,
);
name = include;
sourceTree = "<group>";
};
77671A33BFD7FE650476D073 /* coupled */ = {
isa = PBXGroup;
children = (
C97DEB5A61CAD10C9011D19A /* res_books_51.h */,
7EC1E432F2AA5BE414F80A72 /* res_books_stereo.h */,
);
name = coupled;
sourceTree = "<group>";
};
80C578BF97D813F187F40EFF /* Products */ = {
isa = PBXGroup;
children = (
E03059217A8A4213B6C2A761 /* openmpt-ogg.lib */,
);
name = Products;
sourceTree = "<group>";
};
8D815E5679726A08CBAA0496 /* lib */ = {
isa = PBXGroup;
children = (
4AAD1098931DF4CAD7BCC6D8 /* analysis.c */,
EABBD3D0332CB80277CB8A10 /* backends.h */,
0944F5662F6B251896721BA6 /* bitrate.c */,
46FCE5106D2314C2D42A0B50 /* bitrate.h */,
777077261A5E9DD8A9847D66 /* block.c */,
EE14CC2A926769DCA49FB26A /* books */,
2A6247DC72D32C0EB771FE1C /* codebook.c */,
13C8DC265C39C058A0D89266 /* codebook.h */,
B980BE8E4EF77DC0BD93D4CE /* codec_internal.h */,
14D8424C5D49267EA1E7F88C /* envelope.c */,
FE3ED69646AFBAC88B4E8CD6 /* envelope.h */,
3AED1EF451FFBA26421BB534 /* floor0.c */,
501CFA76672F95A8574B90B6 /* floor1.c */,
374A6BCA5F85247C4720B20A /* highlevel.h */,
E03CFA68E3ADCC9A651A70A8 /* info.c */,
35F064C44D02FFF63D1EFB04 /* lookup.c */,
CB8BC3CEE29E5F00D2BA5A0E /* lookup.h */,
6B3067A02E9C29526D3FCDE0 /* lookup_data.h */,
7091344E14E3D200271C1A8E /* lpc.c */,
175A5978BBACF72ACDE53FB8 /* lpc.h */,
6F30132E1382B0E025BAF96E /* lsp.c */,
15F93858BA4BD60ACC841E98 /* lsp.h */,
379713488007F77AC4A6C988 /* mapping0.c */,
2740402E4D666FE0B46D666E /* masking.h */,
C67232A0C9E304D24B4FA8E0 /* mdct.c */,
3B10AC6A3E817E9CBFEE22AA /* mdct.h */,
DAF247F2DE631A245FCFBE32 /* misc.h */,
9547E85E399A86104BD2CE9E /* modes */,
285CE11ECBA86A50E679375E /* os.h */,
EDFFC5E89252639AA48AAC28 /* psy.c */,
94C8EB12391B88C44B53D152 /* psy.h */,
D1E246821A532AB45EF1FCC2 /* registry.c */,
BB48DACC03B9BEFE4858910C /* registry.h */,
16DFB5041A5087369BBD2B44 /* res0.c */,
6B6795D0827A310272962C10 /* scales.h */,
72897ED494552C06D10A5514 /* sharedbook.c */,
CEB55B76F4DB8B285BE281B6 /* smallft.c */,
0C6D4B2032937AD2999A7160 /* smallft.h */,
3A6CA00462A758B64A42E644 /* synthesis.c */,
92BA4166BAF4FA18A29087A6 /* vorbisenc.c */,
C39AD0BAE5667DEC221BA6FA /* vorbisfile.c */,
72232FC08935CAF27951C600 /* window.c */,
07BE8ECA1ED129FC0EED250A /* window.h */,
);
name = lib;
sourceTree = "<group>";
};
9547E85E399A86104BD2CE9E /* modes */ = {
isa = PBXGroup;
children = (
FB9FDEF54902D527BF21D535 /* floor_all.h */,
F3B07F31B71C40E3F5BFE571 /* psych_11.h */,
746BBDBB37D77F6D767B23FB /* psych_16.h */,
35CF7AFDF93B3CAF37DEE13D /* psych_44.h */,
0D82D8FD2F4E862F6C03AF3D /* psych_8.h */,
6E91170FA08A61C11A699D4F /* residue_16.h */,
1F836091517CAB43CB5BE6D1 /* residue_44.h */,
DBC5215DC00C298F43F9579D /* residue_44p51.h */,
450CC03BDA837F6D491FD67B /* residue_44u.h */,
F1CF92D13F328903B5518911 /* residue_8.h */,
2AAE7645EE1A37F72CBDDC85 /* setup_11.h */,
AB69B4CF6ED57681AD791B0F /* setup_16.h */,
960E1F895979E13B981D85C9 /* setup_22.h */,
E7AEBC4BAB1A7DFDE9BE228B /* setup_32.h */,
6CCD7211303933C36EDCD851 /* setup_44.h */,
5BED095DF163C88F60001F9D /* setup_44p51.h */,
B9289C7B068B92AD7CAA92BB /* setup_44u.h */,
90EE3C51B2B9E983EF6F1291 /* setup_8.h */,
63614891852CF5C3C1E21ED1 /* setup_X.h */,
);
name = modes;
sourceTree = "<group>";
};
9D968EAA920D05DCE0E0A4EA /* Projects */ = {
isa = PBXGroup;
children = (
386FE2DA60AA9B8C4846291A /* ogg.xcodeproj */,
);
name = Projects;
sourceTree = "<group>";
};
A6C936B49B3FADE6EA134CF4 /* Products */ = {
isa = PBXGroup;
children = (
058BB8B85C19232A349236F8 /* openmpt-vorbis.dll */,
);
name = Products;
sourceTree = "<group>";
};
E272DBD9043E890B40F3B219 /* uncoupled */ = {
isa = PBXGroup;
children = (
C38A75AF76807F61C7A2DBEF /* res_books_uncoupled.h */,
);
name = uncoupled;
sourceTree = "<group>";
};
EE14CC2A926769DCA49FB26A /* books */ = {
isa = PBXGroup;
children = (
77671A33BFD7FE650476D073 /* coupled */,
FCE62BDF13F8C7110414C21F /* floor */,
E272DBD9043E890B40F3B219 /* uncoupled */,
);
name = books;
sourceTree = "<group>";
};
FCE62BDF13F8C7110414C21F /* floor */ = {
isa = PBXGroup;
children = (
EE56303600800CE83470F676 /* floor_books.h */,
);
name = floor;
sourceTree = "<group>";
};
/* End PBXGroup section */
/* Begin PBXNativeTarget section */
6EE3599EB7543DD0FBF30FDE /* vorbis */ = {
isa = PBXNativeTarget;
buildConfigurationList = 6A495A8763AF5BF9574AB8C7 /* Build configuration list for PBXNativeTarget "vorbis" */;
buildPhases = (
EBF592C8E55B943AD8F6F108 /* Resources */,
55A2AC1F4F08AD9142A40A5F /* Sources */,
7C0E12287574139A690F7068 /* Frameworks */,
8DA68C947892B286C0787AD4 /* Embed Libraries */,
);
buildRules = (
);
dependencies = (
6E7DB5C8859050FA75AC4C08 /* PBXTargetDependency */,
);
name = vorbis;
productName = vorbis;
productReference = 058BB8B85C19232A349236F8 /* openmpt-vorbis.dll */;
productType = "com.apple.product-type.library.dynamic";
};
/* End PBXNativeTarget section */
/* Begin PBXProject section */
08FB7793FE84155DC02AAC07 /* Project object */ = {
isa = PBXProject;
buildConfigurationList = 1DEB928908733DD80010E9CD /* Build configuration list for PBXProject "vorbis" */;
compatibilityVersion = "Xcode 3.2";
hasScannedForEncodings = 1;
mainGroup = 26717C15041C7EC7D7C10255 /* vorbis */;
projectDirPath = "";
projectReferences = (
{
ProductGroup = 80C578BF97D813F187F40EFF /* Products */;
ProjectRef = 386FE2DA60AA9B8C4846291A /* ogg.xcodeproj */;
},
);
projectRoot = "";
targets = (
6EE3599EB7543DD0FBF30FDE /* openmpt-vorbis.dll */,
);
};
/* End PBXProject section */
/* Begin PBXReferenceProxy section */
E03059217A8A4213B6C2A761 /* openmpt-ogg.lib */ = {
isa = PBXReferenceProxy;
fileType = "compiled.mach-o.dylib";
path = "openmpt-ogg.lib";
remoteRef = EAF35B5FE4595CD1D7F4B99F /* PBXContainerItemProxy */;
sourceTree = BUILT_PRODUCTS_DIR;
};
/* End PBXReferenceProxy section */
/* Begin PBXResourcesBuildPhase section */
EBF592C8E55B943AD8F6F108 /* Resources */ = {
isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647;
files = (
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXResourcesBuildPhase section */
/* Begin PBXSourcesBuildPhase section */
55A2AC1F4F08AD9142A40A5F /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
BC748D10B6364982F0354B50 /* analysis.c in Sources */,
E77EFABE1862F2B02B7B28FE /* bitrate.c in Sources */,
16716A7E46033970211078BE /* block.c in Sources */,
412482943AE63F0674E540D4 /* codebook.c in Sources */,
B1D3BC04AB957876E5947A44 /* envelope.c in Sources */,
A4B9FD2CFFFB509ED3559B6C /* floor0.c in Sources */,
571301CEB254554085AEA00E /* floor1.c in Sources */,
3EA9B7E0953722526DB03620 /* info.c in Sources */,
63BC07FCBEFD5B6E9257A63C /* lookup.c in Sources */,
7C34482667206E18AF063666 /* lpc.c in Sources */,
D5E5E506C0D20AF808B7D346 /* lsp.c in Sources */,
665EF2C06020AF329A1FB100 /* mapping0.c in Sources */,
66F0DF98BD7E4A0A95F75DD8 /* mdct.c in Sources */,
16B25260019E7852498440A0 /* psy.c in Sources */,
42BABA9A3C7C770C767B78DA /* registry.c in Sources */,
FC4D923C52DAFCAE2B54107C /* res0.c in Sources */,
E344DF0C2793847E69BABD4C /* sharedbook.c in Sources */,
650BD9CE95EFD1C0A908080E /* smallft.c in Sources */,
55E0C63CC703672E7CCA147C /* synthesis.c in Sources */,
D85CD4BE497F75B0FF4622FE /* vorbisenc.c in Sources */,
A7912A52EBDFCFC42E070892 /* vorbisfile.c in Sources */,
BDB5A0B818F6F42AEC513EF8 /* window.c in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXSourcesBuildPhase section */
/* Begin PBXTargetDependency section */
6E7DB5C8859050FA75AC4C08 /* PBXTargetDependency */ = {
isa = PBXTargetDependency;
name = "openmpt-ogg.lib";
targetProxy = 3D2DCDF83693CF6A2A2F2C38 /* PBXContainerItemProxy */;
};
/* End PBXTargetDependency section */
/* Begin PBXVariantGroup section */
/* End PBXVariantGroup section */
/* Begin XCBuildConfiguration section */
1FD85444725E7F3644A2E284 /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
ARCHS = "$(NATIVE_ARCH_ACTUAL)";
CLANG_CXX_LANGUAGE_STANDARD = "c++1z";
CONFIGURATION_BUILD_DIR = "$(SYMROOT)";
CONFIGURATION_TEMP_DIR = "$(OBJROOT)";
COPY_PHASE_STRIP = NO;
GCC_ENABLE_FIX_AND_CONTINUE = YES;
GCC_OPTIMIZATION_LEVEL = 0;
GCC_PREPROCESSOR_DEFINITIONS = (
DEBUG,
MPT_BUILD_DEBUG,
);
GCC_SYMBOLS_PRIVATE_EXTERN = NO;
GCC_WARN_ABOUT_RETURN_TYPE = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
OBJROOT = obj/Debug/vorbis;
ONLY_ACTIVE_ARCH = YES;
SYMROOT = "../../../bin/debug/xcode4-macosx/all";
SYSTEM_HEADER_SEARCH_PATHS = (
../../../include/ogg/include,
"$(inherited)",
);
USER_HEADER_SEARCH_PATHS = (
../../../include/vorbis/include,
../../../include/vorbis/lib,
);
};
name = Debug;
};
6BA64F7E7862FEF0ED4D6DBE /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
ARCHS = "$(NATIVE_ARCH_ACTUAL)";
CLANG_CXX_LANGUAGE_STANDARD = "c++1z";
CONFIGURATION_BUILD_DIR = "$(SYMROOT)";
CONFIGURATION_TEMP_DIR = "$(OBJROOT)";
GCC_OPTIMIZATION_LEVEL = 3;
GCC_PREPROCESSOR_DEFINITIONS = (
NDEBUG,
);
GCC_SYMBOLS_PRIVATE_EXTERN = NO;
GCC_WARN_ABOUT_RETURN_TYPE = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
OBJROOT = obj/Release/vorbis;
ONLY_ACTIVE_ARCH = NO;
SYMROOT = "../../../bin/release/xcode4-macosx/all";
SYSTEM_HEADER_SEARCH_PATHS = (
../../../include/ogg/include,
"$(inherited)",
);
USER_HEADER_SEARCH_PATHS = (
../../../include/vorbis/include,
../../../include/vorbis/lib,
);
};
name = Release;
};
AC0271CDA5C42E3FDFC3300D /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
CONFIGURATION_BUILD_DIR = "../../../bin/debug/xcode4-macosx/all";
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
EXECUTABLE_EXTENSION = dll;
GCC_DYNAMIC_NO_PIC = NO;
INSTALL_PATH = /usr/local/lib;
PRODUCT_NAME = "openmpt-vorbis";
};
name = Debug;
};
FD2934076E4BD4F924128247 /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
CONFIGURATION_BUILD_DIR = "../../../bin/release/xcode4-macosx/all";
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
EXECUTABLE_EXTENSION = dll;
GCC_DYNAMIC_NO_PIC = NO;
INSTALL_PATH = /usr/local/lib;
PRODUCT_NAME = "openmpt-vorbis";
};
name = Release;
};
/* End XCBuildConfiguration section */
/* Begin XCConfigurationList section */
1DEB928908733DD80010E9CD /* Build configuration list for PBXProject "vorbis" */ = {
isa = XCConfigurationList;
buildConfigurations = (
1FD85444725E7F3644A2E284 /* Debug */,
6BA64F7E7862FEF0ED4D6DBE /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Debug;
};
6A495A8763AF5BF9574AB8C7 /* Build configuration list for PBXNativeTarget "openmpt-vorbis.dll" */ = {
isa = XCConfigurationList;
buildConfigurations = (
AC0271CDA5C42E3FDFC3300D /* Debug */,
FD2934076E4BD4F924128247 /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Debug;
};
/* End XCConfigurationList section */
};
rootObject = 08FB7793FE84155DC02AAC07 /* Project object */;
}

View file

@ -0,0 +1,16 @@
<?xml version="1.0" encoding="UTF-8"?>
<Workspace
version = "1.0">
<FileRef
location = "group:libopenmpt.xcodeproj">
</FileRef>
<FileRef
location = "group:ext/mpg123.xcodeproj">
</FileRef>
<FileRef
location = "group:ext/ogg.xcodeproj">
</FileRef>
<FileRef
location = "group:ext/vorbis.xcodeproj">
</FileRef>
</Workspace>

View file

@ -22,33 +22,6 @@
// set windows version early so that we can deduce dependencies from SDK version
#if MPT_OS_WINDOWS
#if !defined(WINVER) && !defined(_WIN32_WINDOWS) && !defined(_WIN32_WINNT)
#if MPT_COMPILER_CLANG
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wreserved-id-macro"
#endif // MPT_COMPILER_CLANG
#define _WIN32_WINNT 0x0601 // _WIN32_WINNT_WIN7
#if MPT_COMPILER_CLANG
#pragma clang diagnostic pop
#endif // MPT_COMPILER_CLANG
#endif
#ifndef WINVER
#if defined(_WIN32_WINNT)
#define WINVER _WIN32_WINNT
#elif defined(_WIN32_WINDOWS)
#define WINVER _WIN32_WINDOWS
#endif
#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)
@ -63,160 +36,44 @@
#if defined(LIBOPENMPT_BUILD)
// Fixup dependencies which are currently not used in libopenmpt itself,
// however might be set by some build systems like autotools anyway for simplicity.
#ifdef MPT_WITH_FLAC
#undef MPT_WITH_FLAC
#endif
#endif // LIBOPENMPT_BUILD
// 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)
#if MPT_OS_WINDOWS
#if !defined(MPT_BUILD_WINESUPPORT) && !defined(MPT_BUILD_UPDATESIGNTOOL)
#define MPT_WITH_MFC
#endif // !MPT_BUILD_WINESUPPORT && !MPT_BUILD_UPDATESIGNTOOL
#endif // MPT_OS_WINDOWS
// OpenMPT-only dependencies
#define MPT_WITH_ANCIENT
#if !defined(MPT_BUILD_RETRO) && !MPT_COMPILER_CLANG && !MPT_MSVC_BEFORE(2019,0)
// disabled for VS2017 because of multiple initialization of inline variables
// https://developercommunity.visualstudio.com/t/static-inline-variable-gets-destroyed-multiple-tim/297876
#define MPT_WITH_ASIO
#endif
#if defined(MPT_BUILD_RETRO)
#define MPT_WITH_DIRECTSOUND
#define OPENMPT_BUILD_VARIANT "Retro"
#define OPENMPT_BUILD_VARIANT_MONIKER " RETRO"
#else
#if MPT_OS_WINDOWS
#if MPT_WINNT_AT_LEAST(MPT_WIN_10)
#define OPENMPT_BUILD_VARIANT "Standard"
#define OPENMPT_BUILD_VARIANT_MONIKER ""
#else
#define OPENMPT_BUILD_VARIANT "Legacy"
#define OPENMPT_BUILD_VARIANT_MONIKER ""
#endif
#else
#define OPENMPT_BUILD_VARIANT "Unknown"
#define OPENMPT_BUILD_VARIANT_MONIKER ""
#endif
#endif
#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
#define MPT_WITH_VST
// 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
#if (_WIN32_WINNT >= 0x0601)
#if MPT_WINNT_AT_LEAST(MPT_WIN_7)
#define MPT_WITH_MEDIAFOUNDATION
#endif
#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)
#if MPT_WINNT_AT_LEAST(MPT_WIN_10)
#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)
@ -283,6 +140,14 @@
#if defined(LIBOPENMPT_BUILD)
#ifdef MPT_WITH_FLAC
#error "Building libopenmpt with FLAC is useless and not a supported configuration. Please fix your build system to not list libflac as a dependency for libopenmpt itself. It is only a dependency of openmpt123."
#endif
#ifndef LIBOPENMPT_NO_DEPRECATE
#define LIBOPENMPT_NO_DEPRECATE
#endif
#if (defined(_DEBUG) || defined(DEBUG)) && !defined(MPT_BUILD_DEBUG)
#define MPT_BUILD_DEBUG
#endif
@ -342,35 +207,8 @@
#if (MPT_COMPILER_MSVC && !defined(MPT_USTRING_MODE_UTF8_FORCE)) || defined(MODPLUG_TRACKER)
// Use wide strings for MSVC because this is the native encoding on
// microsoft platforms.
// 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_COMPILER_MSVC && !defined(MPT_USTRING_MODE_UTF8_FORCE)) || MPT_OS_WINDOWS || 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::ToAString and mpt::ToWString.
#define MPT_WSTRING_CONVERT 1
#else
#define MPT_WSTRING_CONVERT 0
#endif
#define MPT_TIME_UTC_ON_DISK 0
#define MPT_TIME_UTC_ON_DISK_VERSION MPT_V("1.31.00.13")
@ -490,21 +328,6 @@
// platform configuration
#ifdef MPT_WITH_MFC
//#define MPT_MFC_FULL // use full MFC, including MFC controls
#define _CSTRING_DISABLE_NARROW_WIDE_CONVERSION
#endif // MPT_WITH_MFC
#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
@ -545,35 +368,10 @@
// stdlib configuration
#if MPT_COMPILER_CLANG
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wreserved-id-macro"
#endif
#define __STDC_CONSTANT_MACROS
#define __STDC_FORMAT_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
#pragma warning(default:4800) // Implicit conversion from 'int' to bool. Possible information loss
#pragma warning(disable:4355) // 'this' : used in base member initializer list
@ -610,47 +408,11 @@
// standard library quirks
// third-party library configuration
#if MPT_OS_WINDOWS
#ifndef UNICODE
#define MPT_CHECK_WINDOWS_IGNORE_WARNING_NO_UNICODE
#endif // !UNICODE
#endif // MPT_OS_WINDOWS
#ifdef MPT_WITH_ANCIENT
#ifdef MPT_BUILD_MSVC_SHARED
#define ANCIENT_API_DECLSPEC_DLLIMPORT
#endif
#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
#ifndef STB_VORBIS_HEADER_ONLY
#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
@ -660,12 +422,6 @@
#endif
#endif
#ifdef MPT_WITH_ZLIB
#ifdef MPT_BUILD_MSVC_SHARED
#define ZLIB_DLL
#endif
#endif
#ifdef __cplusplus

View file

@ -135,7 +135,7 @@ class ComponentLibrary
private:
typedef std::map<std::string, mpt::Library> TLibraryMap;
using TLibraryMap = std::map<std::string, mpt::Library>;
TLibraryMap m_Libraries;
bool m_BindFailed;
@ -237,7 +237,7 @@ public:
class ComponentManager;
typedef std::shared_ptr<IComponent> (*ComponentFactoryMethod)(ComponentManager &componentManager);
using ComponentFactoryMethod = std::shared_ptr<IComponent> (*)(ComponentManager &componentManager);
class IComponentFactory
@ -361,7 +361,7 @@ private:
std::shared_ptr<IComponent> instance;
std::weak_ptr<IComponent> weakInstance;
};
typedef std::map<std::string, RegisteredComponent> TComponentMap;
using TComponentMap = std::map<std::string, RegisteredComponent>;
const IComponentManagerSettings &m_Settings;
TComponentMap m_Components;
private:

View file

@ -97,7 +97,8 @@ namespace FileReaderExt
template<typename Tsize, mpt::String::ReadWriteMode mode, size_t destSize, typename TFileCursor>
bool ReadSizedString(TFileCursor &f, char (&destBuffer)[destSize], const typename TFileCursor::pos_type maxLength = std::numeric_limits<typename TFileCursor::pos_type>::max())
{
mpt::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
static_assert(mpt::is_binary_safe<Tsize>::value);
Tsize srcSize;
if(!mpt::IO::FileReader::Read(f, srcSize))
{
return false;
@ -111,7 +112,8 @@ namespace FileReaderExt
template<typename Tsize, mpt::String::ReadWriteMode mode, typename TFileCursor>
bool ReadSizedString(TFileCursor &f, std::string &dest, const typename TFileCursor::pos_type maxLength = std::numeric_limits<typename TFileCursor::pos_type>::max())
{
mpt::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
static_assert(mpt::is_binary_safe<Tsize>::value);
Tsize srcSize;
if(!mpt::IO::FileReader::Read(f, srcSize))
{
return false;
@ -125,7 +127,8 @@ namespace FileReaderExt
template<typename Tsize, mpt::String::ReadWriteMode mode, std::size_t len, typename TFileCursor>
bool ReadSizedString(TFileCursor &f, mpt::charbuf<len> &dest, const typename TFileCursor::pos_type maxLength = std::numeric_limits<typename TFileCursor::pos_type>::max())
{
mpt::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
static_assert(mpt::is_binary_safe<Tsize>::value);
Tsize srcSize;
if(!mpt::IO::FileReader::Read(f, srcSize))
{
return false;

View file

@ -15,6 +15,13 @@
namespace mpt {
inline namespace MPT_INLINE_NS {
template <typename Traits, bool allow_transcode_locale>
class BasicPathString;
struct NativePathTraits;
struct Utf8PathTraits;
using native_path = BasicPathString<NativePathTraits, true>;
namespace IO {
class FileCursorTraitsMemory;
@ -30,6 +37,7 @@ template <typename Ttraits, typename Tfilenametraits>
class FileCursor;
}
}
}
@ -50,9 +58,11 @@ class FileReader;
} // namespace detail
namespace mpt {
class PathString;
#if defined(MPT_ENABLE_CHARSET_LOCALE)
using PathString = mpt::native_path;
#else
using PathString = mpt::BasicPathString<mpt::Utf8PathTraits, false>;
#endif
} // namespace mpt
using FileCursor = detail::FileCursor<mpt::IO::FileCursorTraitsFileData, mpt::IO::FileCursorFilenameTraits<mpt::PathString>>;

View file

@ -12,6 +12,7 @@
#include "Logging.h"
#include "mpt/base/macros.hpp"
#include "mpt/io/base.hpp"
#include "mpt/io/io.hpp"
#include "mpt/io/io_stdstream.hpp"
@ -42,9 +43,9 @@ namespace log
#if !defined(MPT_LOG_GLOBAL_LEVEL_STATIC)
#if defined(MPT_LOG_GLOBAL_LEVEL)
int GlobalLogLevel = static_cast<int>(MPT_LOG_GLOBAL_LEVEL);
MPT_CONSTINIT int GlobalLogLevel = static_cast<int>(MPT_LOG_GLOBAL_LEVEL);
#else
int GlobalLogLevel = static_cast<int>(LogDebug);
MPT_CONSTINIT int GlobalLogLevel = static_cast<int>(LogDebug);
#endif
#endif
@ -52,12 +53,12 @@ int GlobalLogLevel = static_cast<int>(LogDebug);
#if defined(MODPLUG_TRACKER) && !defined(MPT_LOG_IS_DISABLED)
bool FileEnabled = false;
bool DebuggerEnabled = true;
bool ConsoleEnabled = false;
MPT_CONSTINIT bool FileEnabled = false;
MPT_CONSTINIT bool DebuggerEnabled = true;
MPT_CONSTINIT bool ConsoleEnabled = false;
static char g_FacilitySolo[1024] = {0};
static char g_FacilityBlocked[1024] = {0};
static MPT_CONSTINIT char g_FacilitySolo[1024] = {0};
static MPT_CONSTINIT char g_FacilityBlocked[1024] = {0};
void SetFacilities(const std::string &solo, const std::string &blocked)
{
@ -112,8 +113,8 @@ void GlobalLogger::SendLogMessage(const mpt::source_location &loc, LogLevel leve
#endif // MODPLUG_TRACKER
// remove eol if already present and add log level prefix
const mpt::ustring message = LogLevelToString(level) + U_(": ") + mpt::trim_right(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 file = mpt::transcode<mpt::ustring>(mpt::source_encoding, loc.file_name() ? loc.file_name() : "");
const mpt::ustring function = mpt::transcode<mpt::ustring>(mpt::source_encoding, 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
@ -134,7 +135,7 @@ void GlobalLogger::SendLogMessage(const mpt::source_location &loc, LogLevel leve
}
if(s_logfile)
{
mpt::IO::WriteText(*s_logfile, mpt::ToCharset(mpt::CharsetLogfile, MPT_UFORMAT("{}+{} {}({}): {} [{}]\n")
mpt::IO::WriteText(*s_logfile, mpt::transcode<std::string>(mpt::logfile_encoding, MPT_UFORMAT("{}+{} {}({}): {} [{}]\n")
( mpt::Date::ANSI::ToUString(cur)
, mpt::ufmt::right(6, mpt::ufmt::dec(diff))
, file
@ -170,16 +171,16 @@ void GlobalLogger::SendLogMessage(const mpt::source_location &loc, LogLevel leve
#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) << "]"
<< mpt::transcode<std::string>(mpt::stdio_encoding, file) << "(" << mpt::transcode<std::string>(mpt::stdio_encoding, line) << ")" << ": "
<< mpt::transcode<std::string>(mpt::stdio_encoding, message)
<< " [" << mpt::transcode<std::string>(mpt::stdio_encoding, 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) << "]"
<< mpt::transcode<std::string>(mpt::stdio_encoding, file) << "(" << mpt::transcode<std::string>(mpt::stdio_encoding, line) << ")" << ": "
<< mpt::transcode<std::string>(mpt::stdio_encoding, message)
<< " [" << mpt::transcode<std::string>(mpt::stdio_encoding, function) << "]"
<< std::endl;
#endif // MODPLUG_TRACKER
#endif // MPT_LOG_IS_DISABLED
@ -195,9 +196,9 @@ namespace Trace {
// Debugging functionality will use simple globals.
std::atomic<bool> g_Enabled{false};
MPT_CONSTINIT std::atomic<bool> g_Enabled{false};
static bool g_Sealed = false;
static MPT_CONSTINIT bool g_Sealed = false;
struct Entry {
uint32 Index;
@ -225,14 +226,19 @@ static MPT_FORCEINLINE bool operator < (const Entry &a, const Entry &b) noexcept
;
}
static std::vector<mpt::log::Trace::Entry> Entries;
#if MPT_COMPILER_MSVC
// VS2022 still does nto have constexpr vector default ctor
static /*MPT_CONSTINIT*/ std::vector<mpt::log::Trace::Entry> Entries;
#else
static MPT_CONSTINIT std::vector<mpt::log::Trace::Entry> Entries;
#endif
static std::atomic<uint32> NextIndex(0);
static MPT_CONSTINIT std::atomic<uint32> NextIndex(0);
static uint32 ThreadIdGUI = 0;
static uint32 ThreadIdAudio = 0;
static uint32 ThreadIdNotify = 0;
static uint32 ThreadIdWatchdir = 0;
static MPT_CONSTINIT uint32 ThreadIdGUI = 0;
static MPT_CONSTINIT uint32 ThreadIdAudio = 0;
static MPT_CONSTINIT uint32 ThreadIdNotify = 0;
static MPT_CONSTINIT uint32 ThreadIdWatchdir = 0;
void Enable(std::size_t numEntries)
{
@ -314,7 +320,7 @@ bool Dump(const mpt::PathString &filename)
mpt::ofstream f(filename);
f << "Build: OpenMPT " << mpt::ToCharset(mpt::CharsetLogfile, Build::GetVersionStringExtended()) << std::endl;
f << "Build: OpenMPT " << mpt::transcode<std::string>(mpt::logfile_encoding, Build::GetVersionStringExtended()) << std::endl;
bool qpcValid = false;
@ -326,7 +332,7 @@ bool Dump(const mpt::PathString &filename)
qpcValid = true;
}
f << "Dump: " << mpt::ToCharset(mpt::CharsetLogfile, mpt::Date::ANSI::ToUString(ftNow)) << std::endl;
f << "Dump: " << mpt::transcode<std::string>(mpt::logfile_encoding, mpt::Date::ANSI::ToUString(ftNow)) << std::endl;
f << "Captured events: " << Entries.size() << std::endl;
if(qpcValid && (Entries.size() > 0))
{
@ -343,7 +349,7 @@ bool Dump(const mpt::PathString &filename)
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) ) ) ) );
time = mpt::transcode<std::string>(mpt::logfile_encoding, 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_AFORMAT("0x{}")(mpt::afmt::hex0<16>(entry.Timestamp));

View file

@ -13,7 +13,7 @@
#include "openmpt/all/BuildSettings.hpp"
#include "mpt/base/span.hpp"
#include "mpt/exception_text/exception_text.hpp"
#include "mpt/exception/exception_text.hpp"
#include "mptAssert.h"
#include "mptBaseMacros.h"
@ -24,7 +24,6 @@
// old
#include "mptBaseUtils.h"
#include "mptStringFormat.h"
#include "mptStringParse.h"
#include "mptTime.h"
#include <stdexcept>

View file

@ -0,0 +1,123 @@
/*
* 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 "openmpt/all/BuildSettings.hpp"
#include "mpt/base/macros.hpp"
#ifdef MPT_ENABLE_ARCH_INTRINSICS
#include "mpt/arch/arch.hpp"
#endif
OPENMPT_NAMESPACE_BEGIN
namespace CPU
{
#ifdef MPT_ENABLE_ARCH_INTRINSICS
#if defined(MODPLUG_TRACKER) && !defined(MPT_BUILD_WINESUPPORT)
namespace detail
{
inline MPT_CONSTINIT mpt::arch::current::feature_flags EnabledFeatures;
inline MPT_CONSTINIT mpt::arch::current::mode_flags EnabledModes;
} // namespace detail
inline void EnableAvailableFeatures() noexcept
{
CPU::detail::EnabledFeatures = mpt::arch::get_cpu_info().get_features();
CPU::detail::EnabledModes = mpt::arch::get_cpu_info().get_modes();
}
// enabled processor features for inline asm and intrinsics
[[nodiscard]] MPT_FORCEINLINE mpt::arch::current::feature_flags GetEnabledFeatures() noexcept
{
return CPU::detail::EnabledFeatures;
}
[[nodiscard]] MPT_FORCEINLINE mpt::arch::current::mode_flags GetEnabledModes() noexcept
{
return CPU::detail::EnabledModes;
}
struct Info
{
[[nodiscard]] MPT_FORCEINLINE bool HasFeatureSet(mpt::arch::current::feature_flags features) const noexcept
{
return features == (GetEnabledFeatures() & features);
}
[[nodiscard]] MPT_FORCEINLINE bool HasModesEnabled(mpt::arch::current::mode_flags modes) const noexcept
{
return modes == (GetEnabledModes() & modes);
}
};
#else // !MODPLUG_TRACKER
struct Info
{
private:
const mpt::arch::flags_cache m_flags{mpt::arch::get_cpu_info()};
public:
[[nodiscard]] MPT_FORCEINLINE bool HasFeatureSet(mpt::arch::current::feature_flags features) const noexcept
{
return m_flags[features];
}
[[nodiscard]] MPT_FORCEINLINE bool HasModesEnabled(mpt::arch::current::mode_flags modes) const noexcept
{
return m_flags[modes];
}
};
#endif // MODPLUG_TRACKER
// legacy interface
namespace feature = mpt::arch::current::feature;
namespace mode = mpt::arch::current::mode;
[[nodiscard]] MPT_FORCEINLINE bool HasFeatureSet(mpt::arch::current::feature_flags features) noexcept
{
return CPU::Info{}.HasFeatureSet(features);
}
[[nodiscard]] MPT_FORCEINLINE bool HasModesEnabled(mpt::arch::current::mode_flags modes) noexcept
{
return CPU::Info{}.HasModesEnabled(modes);
}
#endif // MPT_ENABLE_ARCH_INTRINSICS
} // namespace CPU
OPENMPT_NAMESPACE_END

View file

@ -11,19 +11,6 @@
#include "stdafx.h"
#include "mptFileIO.h"
#if defined(MPT_ENABLE_FILEIO)
#include "mpt/io/io.hpp"
#include "mpt/io/io_stdstream.hpp"
#if defined(MODPLUG_TRACKER) && MPT_OS_WINDOWS
#include "mpt/system_error/system_error.hpp"
#include "FileReader.h"
#endif // MODPLUG_TRACKER && MPT_OS_WINDOWS
#endif // MPT_ENABLE_FILEIO
#if defined(MPT_ENABLE_FILEIO)
#include <stdexcept>
#endif // MPT_ENABLE_FILEIO
#ifdef MODPLUG_TRACKER
#if MPT_OS_WINDOWS
#include <windows.h>
@ -32,14 +19,6 @@
#endif // MPT_OS_WINDOWS
#endif // MODPLUG_TRACKER
#if defined(MPT_ENABLE_FILEIO)
#if MPT_COMPILER_MSVC
#include <stdio.h>
#include <tchar.h>
#endif // MPT_COMPILER_MSVC
#endif // MPT_ENABLE_FILEIO
OPENMPT_NAMESPACE_BEGIN
@ -47,7 +26,6 @@ OPENMPT_NAMESPACE_BEGIN
#if defined(MPT_ENABLE_FILEIO)
#if !defined(MPT_BUILD_SILENCE_LIBOPENMPT_CONFIGURATION_WARNINGS)
#if defined(MPT_COMPILER_QUIRK_WINDOWS_FSTREAM_NO_WCHAR)
@ -59,9 +37,10 @@ MPT_WARNING("Warning: MinGW with GCC earlier than 9.1 detected. Standard library
#endif // !MPT_BUILD_SILENCE_LIBOPENMPT_CONFIGURATION_WARNINGS
#ifdef MODPLUG_TRACKER
#if MPT_OS_WINDOWS
bool SetFilesystemCompression(HANDLE hFile)
{
if(hFile == INVALID_HANDLE_VALUE)
@ -73,6 +52,7 @@ bool SetFilesystemCompression(HANDLE hFile)
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)
@ -87,9 +67,10 @@ bool SetFilesystemCompression(int fd)
}
return SetFilesystemCompression(hFile);
}
bool SetFilesystemCompression(const mpt::PathString &filename)
{
DWORD attributes = GetFileAttributes(filename.AsNativePrefixed().c_str());
DWORD attributes = GetFileAttributes(mpt::support_long_path(filename.AsNative()).c_str());
if(attributes == INVALID_FILE_ATTRIBUTES)
{
return false;
@ -98,7 +79,7 @@ bool SetFilesystemCompression(const mpt::PathString &filename)
{
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);
HANDLE hFile = CreateFile(mpt::support_long_path(filename.AsNative()).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;
@ -107,501 +88,12 @@ bool SetFilesystemCompression(const mpt::PathString &filename)
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;
}
std::FILE * SafeOutputFile::internal_fopen(const mpt::PathString &filename, std::ios_base::openmode mode, FlushMode flushMode)
{
m_f = nullptr;
mpt::tstring fopen_mode = convert_mode(mode, flushMode);
if(fopen_mode.empty())
{
return nullptr;
}
std::FILE *f =
#ifdef UNICODE
_wfopen(filename.AsNativePrefixed().c_str(), fopen_mode.c_str())
#else
std::fopen(filename.AsNativePrefixed().c_str(), fopen_mode.c_str())
#endif
;
if(!f)
{
return nullptr;
}
if(mode & std::ios_base::ate)
{
if(std::fseek(f, 0, SEEK_END) != 0)
{
std::fclose(f);
f = nullptr;
return nullptr;
}
}
m_f = f;
return f;
}
#endif // MPT_COMPILER_MSVC
// cppcheck-suppress exceptThrowInDestructor
SafeOutputFile::~SafeOutputFile() noexcept(false)
{
const bool mayThrow = (std::uncaught_exceptions() == 0);
if(!stream())
{
#if MPT_COMPILER_MSVC
if(m_f)
{
std::fclose(m_f);
}
#endif // MPT_COMPILER_MSVC
if(mayThrow && (stream().exceptions() & (std::ios::badbit | std::ios::failbit)))
{
// cppcheck-suppress exceptThrowInDestructor
throw std::ios_base::failure(std::string("Error before flushing file buffers."));
}
return;
}
if(!stream().rdbuf())
{
#if MPT_COMPILER_MSVC
if(m_f)
{
std::fclose(m_f);
}
#endif // MPT_COMPILER_MSVC
if(mayThrow && (stream().exceptions() & (std::ios::badbit | std::ios::failbit)))
{
// cppcheck-suppress exceptThrowInDestructor
throw std::ios_base::failure(std::string("Error before flushing file buffers."));
}
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(std::fflush(m_f) != 0)
{
errorOnFlush = true;
}
}
if(std::fclose(m_f) != 0)
{
errorOnFlush = true;
}
#endif // MPT_COMPILER_MSVC
if(mayThrow)
{
// ignore errorOnFlush here, and re-throw the earlier exception
// cppcheck-suppress exceptThrowInDestructor
throw;
}
}
}
#if MPT_COMPILER_MSVC
if(m_FlushMode != FlushMode::None)
{
if(std::fflush(m_f) != 0)
{
errorOnFlush = true;
}
}
if(std::fclose(m_f) != 0)
{
errorOnFlush = true;
}
#endif // MPT_COMPILER_MSVC
if(mayThrow && 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, mpt::as_span(data));
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, mpt::as_span(data));
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, mpt::as_span(data));
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, mpt::as_span(buf));
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, mpt::as_span(buf));
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, mpt::as_span(buf));
return mpt::buffer_cast<std::string>(buf);
}
} // namespace mpt
#endif // MODPLUG_TRACKER
InputFile::InputFile(const mpt::PathString &filename, bool allowWholeFileCaching)
: m_IsValid(false)
, m_IsCached(false)
{
MPT_ASSERT(!filename.empty());
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(mpt::in_range<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)).size() != mpt::saturate_cast<std::size_t>(filesize))
{
m_File.close();
return false;
}
if(!mpt::IO::SeekBegin(m_File))
{
m_File.close();
return false;
}
m_IsCached = true;
m_IsValid = true;
return true;
}
}
}
m_IsValid = true;
return m_File.good();
}
bool InputFile::IsValid() const
{
return m_IsValid && m_File.good();
}
bool InputFile::IsCached() const
{
return m_IsCached;
}
mpt::PathString InputFile::GetFilename() 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);
}
#if defined(MODPLUG_TRACKER) && MPT_OS_WINDOWS
OnDiskFileWrapper::OnDiskFileWrapper(FileCursor &file, const mpt::PathString &fileNameExtension)
: m_IsTempFile(false)
{
try
{
file.Rewind();
if(!file.GetOptionalFileName())
{
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("Error creating temporary file.");
}
while(!file.EndOfFile())
{
FileCursor::PinnedView view = file.ReadPinnedView(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("Incomplete Write.");
}
towrite -= chunkSize;
written += chunkSize;
} while(towrite > 0);
}
f.close();
#else // !MPT_ONDISKFILEWRAPPER_NO_CREATEFILE
HANDLE hFile = NULL;
#if MPT_OS_WINDOWS_WINRT
hFile = mpt::windows::CheckFileHANDLE(CreateFile2(tempName.AsNative().c_str(), GENERIC_WRITE, FILE_SHARE_READ, CREATE_ALWAYS, NULL));
#else
hFile = mpt::windows::CheckFileHANDLE(CreateFile(tempName.AsNative().c_str(), GENERIC_WRITE, FILE_SHARE_READ, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_TEMPORARY, NULL));
#endif
while(!file.EndOfFile())
{
FileCursor::PinnedView view = file.ReadPinnedView(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;
try
{
mpt::windows::CheckBOOL(WriteFile(hFile, view.data() + written, chunkSize, &chunkDone, NULL));
} catch(...)
{
CloseHandle(hFile);
hFile = NULL;
throw;
}
if(chunkDone != chunkSize)
{
CloseHandle(hFile);
hFile = NULL;
throw std::runtime_error("Incomplete WriteFile().");
}
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.GetOptionalFileName().value();
}
} 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;
}
#endif // MODPLUG_TRACKER && MPT_OS_WINDOWS
#else // !MPT_ENABLE_FILEIO
MPT_MSVC_WORKAROUND_LNK4221(mptFileIO)
#endif // MPT_ENABLE_FILEIO

View file

@ -13,28 +13,17 @@
#if defined(MPT_ENABLE_FILEIO)
#include "mpt/io_read/filecursor_memory.hpp"
#include "mpt/io_read/filecursor_stdstream.hpp"
#include "mpt/base/detect_libcxx.hpp"
#include "mpt/base/namespace.hpp"
#include "mpt/io_file/fstream.hpp"
#include "mpt/io_file_read/inputfile_filecursor.hpp"
#include "../common/mptString.h"
#include "../common/mptPathString.h"
#include "../common/FileReaderFwd.h"
#if defined(MPT_COMPILER_QUIRK_WINDOWS_FSTREAM_NO_WCHAR)
#if MPT_GCC_AT_LEAST(9,1,0)
#include <filesystem>
#endif // MPT_GCC_AT_LEAST(9,1,0)
#endif // MPT_COMPILER_QUIRK_WINDOWS_FSTREAM_NO_WCHAR
#include <fstream>
#include <ios>
#include <ostream>
#include <streambuf>
#include <utility>
#if MPT_COMPILER_MSVC
#include <cstdio>
#endif // !MPT_COMPILER_MSVC
#ifdef MODPLUG_TRACKER
#if MPT_OS_WINDOWS
#include <windows.h>
@ -66,331 +55,27 @@ bool SetFilesystemCompression(const mpt::PathString &filename);
namespace mpt
{
namespace detail
{
template<typename Tbase>
inline void fstream_open(Tbase & base, const mpt::PathString & filename, std::ios_base::openmode mode)
{
#if defined(MPT_COMPILER_QUIRK_WINDOWS_FSTREAM_NO_WCHAR)
#if MPT_GCC_AT_LEAST(9,1,0)
base.open(static_cast<std::filesystem::path>(filename.AsNative()), mode);
#else // !MPT_GCC_AT_LEAST(9,1,0)
// Warning: MinGW with GCC earlier than 9.1 detected. Standard library does neither provide std::fstream wchar_t overloads nor std::filesystem with wchar_t support. Unicode filename support is thus unavailable.
base.open(mpt::ToCharset(mpt::Charset::Locale, filename.AsNative()).c_str(), mode);
#endif // MPT_GCC_AT_LEAST(9,1,0)
#else // !MPT_COMPILER_QUIRK_WINDOWS_FSTREAM_NO_WCHAR
base.open(filename.AsNativePrefixed().c_str(), mode);
#endif // MPT_COMPILER_QUIRK_WINDOWS_FSTREAM_NO_WCHAR
}
} // namespace detail
// We cannot rely on implicit conversion of mpt::PathString to std::filesystem::path when constructing std::fstream
// because of broken overload implementation in GCC libstdc++ 8, 9, 10.
// https://gcc.gnu.org/bugzilla/show_bug.cgi?id=95642
// https://gcc.gnu.org/bugzilla/show_bug.cgi?id=90704
class fstream
: public std::fstream
{
private:
typedef std::fstream Tbase;
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);
}
#if MPT_COMPILER_MSVC
protected:
fstream(std::FILE * file)
: std::fstream(file)
{
}
#endif // MPT_COMPILER_MSVC
public:
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:
ifstream() {}
ifstream(const mpt::PathString & filename, std::ios_base::openmode mode = std::ios_base::in)
{
detail::fstream_open<Tbase>(*this, filename, mode);
}
#if MPT_COMPILER_MSVC
protected:
ifstream(std::FILE * file)
: std::ifstream(file)
{
}
#endif // MPT_COMPILER_MSVC
public:
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:
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(std::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
};
inline FlushMode FlushModeFromBool(bool flush)
{
return flush ? FlushMode::Full : FlushMode::None;
}
#ifdef MODPLUG_TRACKER
class SafeOutputFile
{
private:
FlushMode m_FlushMode;
#if MPT_COMPILER_MSVC
std::FILE *m_f = nullptr;
#else // !MPT_COMPILER_MSVC
mpt::ofstream m_s;
#endif // MPT_COMPILER_MSVC
#if MPT_COMPILER_MSVC
class FILEostream
: public mpt::ofstream
{
public:
FILEostream(std::FILE * file)
: mpt::ofstream(file)
{
return;
}
};
FILEostream m_s;
static mpt::tstring convert_mode(std::ios_base::openmode mode, FlushMode flushMode);
std::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
{
if(!stream().is_open())
{
stream().setstate(mpt::ofstream::failbit);
}
}
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
using fstream = mpt::IO::fstream;
using ifstream = mpt::IO::ifstream;
using ofstream = mpt::IO::ofstream;
} // namespace mpt
class InputFile
{
private:
mpt::PathString m_Filename;
mpt::ifstream m_File;
bool m_IsValid;
bool m_IsCached;
std::vector<std::byte> m_Cache;
public:
InputFile(const mpt::PathString &filename, bool allowWholeFileCaching = false);
~InputFile();
bool IsValid() const;
bool IsCached() const;
mpt::PathString GetFilename() const;
std::istream& GetStream();
mpt::const_byte_span GetCache();
private:
bool Open(const mpt::PathString &filename, bool allowWholeFileCaching = false);
};
template <typename Targ1>
inline FileCursor make_FileCursor(Targ1 &&arg1)
{
return mpt::IO::make_FileCursor<mpt::PathString>(std::forward<Targ1>(arg1));
}
template <typename Targ1, typename Targ2>
inline FileCursor make_FileCursor(Targ1 &&arg1, Targ2 &&arg2)
{
return mpt::IO::make_FileCursor<mpt::PathString>(std::forward<Targ1>(arg1), std::forward<Targ2>(arg2));
}
// templated in order to reduce header inter-dependencies
class InputFile;
template <typename TInputFile, std::enable_if_t<std::is_same<TInputFile, InputFile>::value, bool> = true>
inline FileCursor make_FileCursor(TInputFile &file)
{
if(!file.IsValid())
{
return FileCursor();
}
if(file.IsCached())
{
return mpt::IO::make_FileCursor<mpt::PathString>(file.GetCache(), std::make_shared<mpt::PathString>(file.GetFilename()));
} else
{
return mpt::IO::make_FileCursor<mpt::PathString>(file.GetStream(), std::make_shared<mpt::PathString>(file.GetFilename()));
}
}
template <typename Targ1>
inline FileCursor GetFileReader(Targ1 &&arg1)
{
return make_FileCursor(std::forward<Targ1>(arg1));
return mpt::IO::make_FileCursor<mpt::PathString>(std::forward<Targ1>(arg1));
}
template <typename Targ1, typename Targ2>
inline FileCursor GetFileReader(Targ1 &&arg1, Targ2 &&arg2)
{
return make_FileCursor(std::forward<Targ1>(arg1), std::forward<Targ2>(arg2));
return mpt::IO::make_FileCursor<mpt::PathString>(std::forward<Targ1>(arg1), std::forward<Targ2>(arg2));
}
#if defined(MODPLUG_TRACKER) && MPT_OS_WINDOWS
class OnDiskFileWrapper
{
private:
mpt::PathString m_Filename;
bool m_IsTempFile;
public:
OnDiskFileWrapper(FileCursor& file, const mpt::PathString& fileNameExtension = P_("tmp"));
~OnDiskFileWrapper();
public:
bool IsValid() const;
mpt::PathString GetFilename() const;
}; // class OnDiskFileWrapper
#endif // MODPLUG_TRACKER && MPT_OS_WINDOWS
#endif // MPT_ENABLE_FILEIO

View file

@ -0,0 +1,114 @@
/*
* mptFileTemporary.cpp
* --------------------
* Purpose:
* 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 "mptFileTemporary.h"
#if defined(MODPLUG_TRACKER) && MPT_OS_WINDOWS
#include "mpt/fs/common_directories.hpp"
#include "mpt/fs/fs.hpp"
#include "mpt/io_file_unique/unique_basename.hpp"
#include "mpt/io_file_unique/unique_tempfilename.hpp"
#endif // MODPLUG_TRACKER && MPT_OS_WINDOWS
#include "mpt/string_transcode/transcode.hpp"
#include "mpt/uuid/uuid.hpp"
#include "mptRandom.h"
#if MPT_OS_WINDOWS
#include <windows.h>
#endif
OPENMPT_NAMESPACE_BEGIN
#if defined(MODPLUG_TRACKER) && MPT_OS_WINDOWS
namespace mpt
{
TemporaryPathname::TemporaryPathname(const mpt::PathString &fileNameExtension)
{
mpt::PathString prefix;
#if defined(LIBOPENMPT_BUILD)
prefix = P_("libopenmpt");
#else
prefix = P_("OpenMPT");
#endif
m_Path = mpt::PathString::FromNative(mpt::IO::unique_tempfilename{mpt::IO::unique_basename{prefix, mpt::UUID::GenerateLocalUseOnly(mpt::global_prng())}, fileNameExtension});
}
TempFileGuard::TempFileGuard(const mpt::TemporaryPathname &pathname)
: filename(pathname.GetPathname())
{
return;
}
mpt::PathString TempFileGuard::GetFilename() const
{
return filename;
}
TempFileGuard::~TempFileGuard()
{
if(!filename.empty())
{
DeleteFile(filename.AsNative().c_str());
}
}
TempDirGuard::TempDirGuard(const mpt::TemporaryPathname &pathname)
: dirname(pathname.GetPathname().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())
{
mpt::native_fs{}.delete_tree(dirname);
}
}
} // namespace mpt
#else
MPT_MSVC_WORKAROUND_LNK4221(mptFileTemporary)
#endif // MODPLUG_TRACKER && MPT_OS_WINDOWS
OPENMPT_NAMESPACE_END

View file

@ -0,0 +1,84 @@
/*
* mptFileTemporary.h
* ------------------
* Purpose:
* Notes : Currently none.
* Authors: OpenMPT Devs
* The OpenMPT source code is released under the BSD license. Read LICENSE for more details.
*/
#pragma once
#include "openmpt/all/BuildSettings.hpp"
#include "mpt/base/namespace.hpp"
#include "mptPathString.h"
OPENMPT_NAMESPACE_BEGIN
namespace mpt
{
#if defined(MODPLUG_TRACKER) && MPT_OS_WINDOWS
// Returns a new unique absolute path.
class TemporaryPathname
{
private:
mpt::PathString m_Path;
public:
TemporaryPathname(const mpt::PathString &fileNameExtension = P_("tmp"));
public:
mpt::PathString GetPathname() const
{
return m_Path;
}
};
// 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::TemporaryPathname &pathname = mpt::TemporaryPathname{});
mpt::PathString GetFilename() const;
~TempFileGuard();
};
// 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::TemporaryPathname &pathname = mpt::TemporaryPathname{});
mpt::PathString GetDirname() const;
~TempDirGuard();
};
#endif // MODPLUG_TRACKER && MPT_OS_WINDOWS
} // namespace mpt
OPENMPT_NAMESPACE_END

View file

@ -0,0 +1,141 @@
/*
* mptFileType.cpp
* ---------------
* Purpose:
* 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 "mptFileType.h"
OPENMPT_NAMESPACE_BEGIN
#ifdef 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;
}
#else
MPT_MSVC_WORKAROUND_LNK4221(mptFileType)
#endif // MODPLUG_TRACKER
OPENMPT_NAMESPACE_END

View file

@ -0,0 +1,95 @@
/*
* mptFileType.h
* -------------
* Purpose:
* Notes : Currently none.
* Authors: OpenMPT Devs
* The OpenMPT source code is released under the BSD license. Read LICENSE for more details.
*/
#pragma once
#include "openmpt/all/BuildSettings.hpp"
#include "mpt/base/alloc.hpp"
#include "mpt/base/namespace.hpp"
#include "mpt/string/types.hpp"
#include "openmpt/base/FlagSet.hpp"
#include <vector>
OPENMPT_NAMESPACE_BEGIN
#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)
{
mpt::append(m_MimeTypes, type.m_MimeTypes);
mpt::append(m_Extensions, type.m_Extensions);
mpt::append(m_Prefixes, type.m_Prefixes);
}
}
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

View file

@ -10,370 +10,98 @@
#include "stdafx.h"
#include "mptPathString.h"
#include "mpt/uuid/uuid.hpp"
#include "mpt/path/os_path_long.hpp"
#include "misc_util.h"
#include <vector>
#include "mptRandom.h"
#if MPT_OS_WINDOWS
#include <tchar.h>
#endif
#if MPT_OS_WINDOWS
#include <windows.h>
#if defined(MODPLUG_TRACKER)
#include <shlwapi.h>
#endif
#include <tchar.h>
#endif
OPENMPT_NAMESPACE_BEGIN
#if MPT_OS_WINDOWS
namespace mpt
{
RawPathString PathString::AsNativePrefixed() const
{
#if MPT_OS_WINDOWS_WINRT && (_WIN32_WINNT < 0x0a00)
// For WinRT on Windows 8, there is no official wy to determine an absolute path.
return path;
#else
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;
}
#endif
}
#if MPT_OS_WINDOWS
#if !MPT_OS_WINDOWS_WINRT
int PathString::CompareNoCase(const PathString & a, const PathString & b)
int PathCompareNoCase(const PathString & a, const PathString & b)
{
return lstrcmpi(a.path.c_str(), b.path.c_str());
return lstrcmpi(a.AsNative().c_str(), b.AsNative().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 defined(MODPLUG_TRACKER) && MPT_OS_WINDOWS
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 = {};
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 = {};
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 // MODPLUG_TRACKER && MPT_OS_WINDOWS
#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 AbsolutePathToRelative(const mpt::PathString &path, const mpt::PathString &relativeTo)
{
mpt::PathString result = *this;
using namespace path_literals;
using char_type = RawPathString::value_type;
mpt::PathString result = path;
if(path.empty())
{
return result;
}
if(!_tcsncicmp(relativeTo.AsNative().c_str(), AsNative().c_str(), relativeTo.AsNative().length()))
if(!_tcsncicmp(relativeTo.AsNative().c_str(), path.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))
result = mpt::PathString::FromNative(L<char_type>(".\\")); // ".\"
result += mpt::PathString::FromNative(path.AsNative().substr(relativeTo.AsNative().length()));
} else if(!_tcsncicmp(relativeTo.AsNative().c_str(), path.AsNative().c_str(), 2))
{
// Path is on the same drive as OpenMPT ("C:\Somepath" => "\Somepath")
result = mpt::PathString::FromNative(AsNative().substr(2));
result = mpt::PathString::FromNative(path.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 RelativePathToAbsolute(const mpt::PathString &path, const mpt::PathString &relativeTo)
{
mpt::PathString result = *this;
using namespace path_literals;
using char_type = RawPathString::value_type;
mpt::PathString result = path;
if(path.empty())
{
return result;
}
if(path.length() >= 2 && path[0] == PC_('\\') && path[1] != PC_('\\'))
if(path.length() >= 2 && path.AsNative()[0] == L<char_type>('\\') && path.AsNative()[1] == L<char_type>('\\'))
{
// Path is on the same drive as OpenMPT ("\Somepath\" => "C:\Somepath\"), but ignore network paths starting with "\\"
// Network / UNC paths
return result;
} if(path.length() >= 1 && path.AsNative()[0] == L<char_type>('\\'))
{
// Path is on the same drive as relativeTo ("\Somepath\" => "C:\Somepath\")
result = mpt::PathString::FromNative(relativeTo.AsNative().substr(0, 2));
result += mpt::PathString(path);
} else if(path.length() >= 2 && path.substr(0, 2) == PL_(".\\"))
} else if(path.length() >= 2 && path.AsNative().substr(0, 2) == L<char_type>(".\\"))
{
// Path is OpenMPT's directory or a sub directory (".\Somepath\" => "C:\OpenMPT\Somepath\")
// Path is in relativeTo or a sub directory (".\Somepath\" => "C:\OpenMPT\Somepath\")
result = relativeTo; // "C:\OpenMPT\"
result += mpt::PathString::FromNative(AsNative().substr(2));
result += mpt::PathString::FromNative(path.AsNative().substr(2));
} else if(path.length() < 3 || path.AsNative()[1] != L<char_type>(':') || path.AsNative()[2] != L<char_type>('\\'))
{
// Any other path not starting with drive letter
result = relativeTo; // "C:\OpenMPT\"
result += mpt::PathString(path);
}
return result;
}
@ -382,60 +110,10 @@ PathString PathString::RelativePathToAbsolute(const PathString &relativeTo) cons
#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
#if !(MPT_OS_WINDOWS_WINRT && (_WIN32_WINNT < 0x0a00))
#if !(MPT_WINRT_BEFORE(MPT_WIN_10))
mpt::PathString GetAbsolutePath(const mpt::PathString &path)
{
@ -454,415 +132,30 @@ mpt::PathString GetAbsolutePath(const mpt::PathString &path)
#endif
#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 = {};
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 defined(MODPLUG_TRACKER) && MPT_OS_WINDOWS
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());
}
#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 // MODPLUG_TRACKER && MPT_OS_WINDOWS
#if defined(MODPLUG_TRACKER) && 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(mpt::global_prng()).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());
}
}
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 && MPT_OS_WINDOWS
} // 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;
}
#if MPT_CXX_AT_LEAST(20)
static inline char8_t SanitizeFilenameChar(char8_t c)
mpt::ustring SanitizePathComponent(mpt::ustring str)
{
if( c == u8'\\' ||
c == u8'\"' ||
c == u8'/' ||
c == u8':' ||
c == u8'?' ||
c == u8'<' ||
c == u8'>' ||
c == u8'|' ||
c == u8'*')
{
c = u8'_';
}
return c;
return mpt::PathString::FromUnicode(str).AsSanitizedComponent().ToUnicode();
}
#endif
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(MPT_WITH_MFC)
void SanitizeFilename(CString &str)
CString SanitizePathComponent(CString str)
{
for(int i = 0; i < str.GetLength(); i++)
{
str.SetAt(i, SanitizeFilenameChar(str.GetAt(i)));
}
return mpt::PathString::FromCString(str).AsSanitizedComponent().ToCString();
}
#endif // MPT_WITH_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

View file

@ -12,392 +12,85 @@
#include "openmpt/all/BuildSettings.hpp"
#include "mpt/base/detect.hpp"
#include "mpt/base/namespace.hpp"
#include "mpt/path/basic_path.hpp"
#include "mpt/path/native_path.hpp"
#include "mpt/path/os_path.hpp"
#include "mpt/string/types.hpp"
#include "mptString.h"
#include "mpt/base/namespace.hpp"
#include <vector>
#include "openmpt/base/FlagSet.hpp"
#define MPT_DEPRECATED_PATH
//#define MPT_DEPRECATED_PATH [[deprecated]]
OPENMPT_NAMESPACE_BEGIN
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(PathString && other) noexcept
: path(std::move(other.path))
{
return;
}
PathString & assign(const PathString & other)
{
path = other.path;
return *this;
}
PathString & assign(PathString && other) noexcept
{
path = std::move(other.path);
return *this;
}
PathString & operator = (const PathString & other)
{
return assign(other);
}
PathString &operator = (PathString && other) noexcept
{
return assign(std::move(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 defined(MODPLUG_TRACKER) && MPT_OS_WINDOWS
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;
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(MPT_WITH_MFC)
// 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 // MPT_WITH_MFC
// Convert a path to its simplified form, i.e. remove ".\" and "..\" entries
mpt::PathString Simplify() const;
using PathString = mpt::native_path;
#else // !MPT_OS_WINDOWS
#define MPT_PATHSTRING_LITERAL(x) MPT_OS_PATH_LITERAL( x )
#define MPT_PATHSTRING(x) mpt::PathString::FromNative(MPT_OS_PATH_LITERAL( x ))
// 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); }
using PathString = mpt::BasicPathString<mpt::Utf8PathTraits, false>;
#define MPT_PATHSTRING_LITERAL(x) ( x )
#define MPT_PATHSTRING(x) mpt::PathString::FromNative( x )
#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]] inline std::string ToAString(const mpt::PathString & x) { return mpt::ToCharset(mpt::Charset::Locale, x.ToUnicode()); }
#else
MPT_DEPRECATED_PATH inline std::string ToAString(const mpt::PathString & x) { return mpt::ToCharset(mpt::Charset::Locale, x.AsNative()); }
#endif
#else
MPT_DEPRECATED_PATH inline std::string ToAString(const mpt::PathString & x) { return mpt::ToCharset(mpt::Charset::Locale, x.ToUnicode()); }
#endif
#endif
inline mpt::ustring ToUString(const mpt::PathString & x) { return x.ToUnicode(); }
#if MPT_WSTRING_FORMAT
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
using RawPathString = PathString::raw_path_type;
#define PC_(x) MPT_PATHSTRING_LITERAL(x)
#define PL_(x) MPT_PATHSTRING_LITERAL(x)
#define P_(x) MPT_PATHSTRING(x)
namespace mpt
template <typename T, typename std::enable_if<std::is_same<T, mpt::PathString>::value, bool>::type = true>
inline mpt::ustring ToUString(const T &x)
{
return x.ToUnicode();
}
bool PathIsAbsolute(const mpt::PathString &path);
#if MPT_OS_WINDOWS
#if !(MPT_OS_WINDOWS_WINRT && (_WIN32_WINNT < 0x0a00))
#if !(MPT_WINRT_BEFORE(MPT_WIN_10))
// Returns the absolute path for a potentially relative path and removes ".." or "." components. (same as GetFullPathNameW)
mpt::PathString GetAbsolutePath(const mpt::PathString &path);
#endif
#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 defined(MODPLUG_TRACKER) && MPT_OS_WINDOWS
// Returns the application executable path or an empty string (if unknown), e.g. "C:\mptrack\"
mpt::PathString GetExecutablePath();
// Relative / absolute paths conversion
mpt::PathString AbsolutePathToRelative(const mpt::PathString &p, const mpt::PathString &relativeTo); // similar to std::fs::path::lexically_approximate
mpt::PathString RelativePathToAbsolute(const mpt::PathString &p, const mpt::PathString &relativeTo);
#endif // MODPLUG_TRACKER && MPT_OS_WINDOWS
#if MPT_OS_WINDOWS
#if !MPT_OS_WINDOWS_WINRT
// Returns the system directory path, e.g. "C:\Windows\System32\"
mpt::PathString GetSystemPath();
int PathCompareNoCase(const PathString &a, const PathString &b);
#endif // !MPT_OS_WINDOWS_WINRT
#endif // MODPLUG_TRACKER && MPT_OS_WINDOWS
#if defined(MODPLUG_TRACKER) && 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"));
#endif
// 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();
};
// 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 && MPT_OS_WINDOWS
} // namespace mpt
@ -405,101 +98,15 @@ public:
#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);
}
mpt::ustring SanitizePathComponent(mpt::ustring str);
#if defined(MPT_WITH_MFC)
void SanitizeFilename(CString &str);
CString SanitizePathComponent(CString str);
#endif // MPT_WITH_MFC
#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)
{
mpt::append(m_MimeTypes, type.m_MimeTypes);
mpt::append(m_Extensions, type.m_Extensions);
mpt::append(m_Prefixes, type.m_Prefixes);
}
}
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

View file

@ -57,7 +57,7 @@ class thread_safe_prng
private:
mpt::mutex m;
public:
typedef typename Trng::result_type result_type;
using result_type = typename Trng::result_type;
public:
template <typename Trd>
explicit thread_safe_prng(Trd & rd)

View file

@ -1,838 +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 "mpt/string/types.hpp"
#include "mpt/string/utility.hpp"
#include "mpt/string_transcode/transcode.hpp"
#include <locale>
#include <string>
#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 // MPT_OS_WINDOWS
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 {
#define C(x) (mpt::char_value((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
// templated on 8bit strings because of type-safe variants
template<typename Tdststring>
static Tdststring EncodeImpl(Charset charset, const mpt::widestring &src)
{
static_assert(sizeof(typename Tdststring::value_type) == sizeof(char));
static_assert(mpt::is_character<typename Tdststring::value_type>::value);
switch(charset)
{
#if defined(MPT_ENABLE_CHARSET_LOCALE)
case Charset::Locale: return mpt::encode<Tdststring>(mpt::logical_encoding::locale, src); break;
#endif
case Charset::UTF8: return mpt::encode<Tdststring>(mpt::common_encoding::utf8, src); break;
case Charset::ASCII: return mpt::encode<Tdststring>(mpt::common_encoding::ascii, src); break;
case Charset::ISO8859_1: return mpt::encode<Tdststring>(mpt::common_encoding::iso8859_1, src); break;
case Charset::ISO8859_15: return mpt::encode<Tdststring>(mpt::common_encoding::iso8859_15, src); break;
case Charset::CP850: return mpt::encode<Tdststring>(mpt::common_encoding::cp850, src); break;
case Charset::CP437: return mpt::encode<Tdststring>(mpt::common_encoding::cp437, src); break;
case Charset::CP437AMS: return mpt::encode<Tdststring>(CharsetTableCP437AMS, src); break;
case Charset::CP437AMS2: return mpt::encode<Tdststring>(CharsetTableCP437AMS2, src); break;
case Charset::Windows1252: return mpt::encode<Tdststring>(mpt::common_encoding::windows1252, src); break;
case Charset::Amiga: return mpt::encode<Tdststring>(mpt::common_encoding::amiga, src); break;
case Charset::RISC_OS: return mpt::encode<Tdststring>(mpt::common_encoding::riscos, src); break;
case Charset::ISO8859_1_no_C1: return mpt::encode<Tdststring>(mpt::common_encoding::iso8859_1_no_c1, src); break;
case Charset::ISO8859_15_no_C1: return mpt::encode<Tdststring>(mpt::common_encoding::iso8859_15_no_c1, src); break;
case Charset::Amiga_no_C1: return mpt::encode<Tdststring>(mpt::common_encoding::amiga_no_c1, src); break;
}
return Tdststring();
}
// templated on 8bit strings because of type-safe variants
template<typename Tsrcstring>
static mpt::widestring DecodeImpl(Charset charset, const Tsrcstring &src)
{
static_assert(sizeof(typename Tsrcstring::value_type) == sizeof(char));
static_assert(mpt::is_character<typename Tsrcstring::value_type>::value);
switch(charset)
{
#if defined(MPT_ENABLE_CHARSET_LOCALE)
case Charset::Locale: return mpt::decode<Tsrcstring>(mpt::logical_encoding::locale, src); break;
#endif
case Charset::UTF8: return mpt::decode<Tsrcstring>(mpt::common_encoding::utf8, src); break;
case Charset::ASCII: return mpt::decode<Tsrcstring>(mpt::common_encoding::ascii, src); break;
case Charset::ISO8859_1: return mpt::decode<Tsrcstring>(mpt::common_encoding::iso8859_1, src); break;
case Charset::ISO8859_15: return mpt::decode<Tsrcstring>(mpt::common_encoding::iso8859_15, src); break;
case Charset::CP850: return mpt::decode<Tsrcstring>(mpt::common_encoding::cp850, src); break;
case Charset::CP437: return mpt::decode<Tsrcstring>(mpt::common_encoding::cp437, src); break;
case Charset::CP437AMS: return mpt::decode<Tsrcstring>(CharsetTableCP437AMS, src); break;
case Charset::CP437AMS2: return mpt::decode<Tsrcstring>(CharsetTableCP437AMS2, src); break;
case Charset::Windows1252: return mpt::decode<Tsrcstring>(mpt::common_encoding::windows1252, src); break;
case Charset::Amiga: return mpt::decode<Tsrcstring>(mpt::common_encoding::amiga, src); break;
case Charset::RISC_OS: return mpt::decode<Tsrcstring>(mpt::common_encoding::riscos, src); break;
case Charset::ISO8859_1_no_C1: return mpt::decode<Tsrcstring>(mpt::common_encoding::iso8859_1_no_c1, src); break;
case Charset::ISO8859_15_no_C1: return mpt::decode<Tsrcstring>(mpt::common_encoding::iso8859_15_no_c1, src); break;
case Charset::Amiga_no_C1: return mpt::decode<Tsrcstring>(mpt::common_encoding::amiga_no_c1, src); break;
}
return mpt::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 mpt::is_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(MPT_WITH_MFC)
CString ToCString(const std::wstring &str)
{
#ifdef UNICODE
return str.c_str();
#else
// cppcheck false-positive
// cppcheck-suppress returnDanglingLifetime
return ToCharset(Charset::Locale, str).c_str();
#endif
}
CString ToCString(Charset from, const std::string &str)
{
#ifdef UNICODE
// cppcheck false-positive
// cppcheck-suppress returnDanglingLifetime
return ToWide(from, str).c_str();
#else
// cppcheck false-positive
// cppcheck-suppress returnDanglingLifetime
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
// cppcheck false-positive
// cppcheck-suppress returnDanglingLifetime
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 // MPT_WITH_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(MPT_WITH_MFC)
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 // MPT_WITH_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(MPT_WITH_MFC)
CString ToCString(const mpt::ustring &str)
{
#ifdef UNICODE
// cppcheck false-positive
// cppcheck-suppress returnDanglingLifetime
return String::DecodeImpl<mpt::ustring>(mpt::Charset::UTF8, str).c_str();
#else // !UNICODE
// cppcheck false-positive
// cppcheck-suppress returnDanglingLifetime
return String::ConvertImpl<std::string, mpt::ustring>(mpt::Charset::Locale, mpt::Charset::UTF8, str).c_str();
#endif // UNICODE
}
#endif // MPT_WITH_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::has_codepage(codepage))
{
result = mpt::ToUnicode(mpt::decode<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)
{
return mpt::to_lower_ascii(c);
}
char ToUpperCaseAscii(char c)
{
return mpt::to_upper_ascii(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 = mpt::char_value(mpt::ToLowerCaseAscii(*a));
unsigned char bc = mpt::char_value(mpt::ToLowerCaseAscii(*b));
if(ac != bc)
{
return ac < bc ? -1 : 1;
} else if(!ac && !bc)
{
return 0;
}
++a;
++b;
}
return 0;
}
int CompareNoCaseAscii(std::string_view a, std::string_view b)
{
for(std::size_t i = 0; i < std::min(a.length(), b.length()); ++i)
{
unsigned char ac = mpt::char_value(mpt::ToLowerCaseAscii(a[i]));
unsigned char bc = mpt::char_value(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;
}
int CompareNoCaseAscii(const std::string &a, const std::string &b)
{
return CompareNoCaseAscii(std::string_view(a), std::string_view(b));
}
#if defined(MODPLUG_TRACKER)
mpt::ustring ToLowerCase(const mpt::ustring &s)
{
#if defined(MPT_WITH_MFC)
#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 // !MPT_WITH_MFC
std::wstring ws = mpt::ToWide(s);
std::transform(ws.begin(), ws.end(), ws.begin(), &std::towlower);
return mpt::ToUnicode(ws);
#endif // MPT_WITH_MFC
}
mpt::ustring ToUpperCase(const mpt::ustring &s)
{
#if defined(MPT_WITH_MFC)
#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 // !MPT_WITH_MFC
std::wstring ws = mpt::ToWide(s);
std::transform(ws.begin(), ws.end(), ws.begin(), &std::towupper);
return mpt::ToUnicode(ws);
#endif // MPT_WITH_MFC
}
#endif // MODPLUG_TRACKER
} // namespace mpt
OPENMPT_NAMESPACE_END

View file

@ -12,19 +12,19 @@
#include "openmpt/all/BuildSettings.hpp"
#include "mpt/base/alloc.hpp"
#include "mpt/base/span.hpp"
#include "mpt/string/types.hpp"
#include "mpt/string/utility.hpp"
#include "mptBaseTypes.h"
#include "mpt/string_transcode/transcode.hpp"
#include <algorithm>
#include <limits>
#include <string>
#include <string_view>
#include <utility>
#include <cstring>
#include <cstddef>
#if defined(MODPLUG_TRACKER)
#include <cwctype>
#endif // MODPLUG_TRACKER
@ -36,21 +36,7 @@ namespace mpt
namespace String
{
template <typename Tstring, typename Tstring2, typename Tstring3>
inline Tstring Replace(Tstring str, const Tstring2 &oldStr, const Tstring3 &newStr)
{
return mpt::replace(str, oldStr, newStr);
}
} // namespace String
enum class Charset {
enum class CharsetEnum {
UTF8,
@ -59,8 +45,23 @@ enum class Charset {
ISO8859_1,
ISO8859_15,
CP850,
CP437,
CP737,
CP775,
CP850,
CP852,
CP855,
CP857,
CP860,
CP861,
CP862,
CP863,
CP864,
CP865,
CP866,
CP869,
CP874,
CP437AMS,
CP437AMS2,
@ -68,6 +69,7 @@ enum class Charset {
Amiga,
RISC_OS,
AtariST,
ISO8859_1_no_C1,
ISO8859_15_no_C1,
@ -79,34 +81,228 @@ enum class Charset {
};
namespace CharsetTable
{
#define C(x) (mpt::char_value((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.
inline constexpr char32_t CP437AMS[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.
inline constexpr char32_t CP437AMS2[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
} // namespace CharsetTable
// source code / preprocessor (i.e. # token)
inline constexpr Charset CharsetSource = Charset::ASCII;
// debug log files
inline constexpr Charset CharsetLogfile = Charset::UTF8;
struct CharsetTranscoder
{
// std::clog / std::cout / std::cerr
#if defined(MODPLUG_TRACKER) && MPT_OS_WINDOWS && defined(MPT_ENABLE_CHARSET_LOCALE)
inline constexpr Charset CharsetStdIO = Charset::Locale;
#else
inline constexpr Charset CharsetStdIO = Charset::UTF8;
#endif
private:
CharsetEnum m_Charset;
public:
constexpr CharsetEnum GetCharset() const noexcept
{
return m_Charset;
}
constexpr CharsetTranscoder(CharsetEnum charset) noexcept
: m_Charset(charset)
{
return;
}
constexpr operator CharsetEnum() const noexcept
{
return m_Charset;
}
// templated on 8bit strings because of type-safe variants
template <typename Tdststring>
inline Tdststring encode(const mpt::widestring &src) const
{
static_assert(sizeof(typename Tdststring::value_type) == sizeof(char));
static_assert(mpt::is_character<typename Tdststring::value_type>::value);
switch(m_Charset)
{
#if defined(MPT_ENABLE_CHARSET_LOCALE)
case CharsetEnum::Locale: return mpt::encode<Tdststring>(mpt::logical_encoding::locale, src); break;
#endif
case CharsetEnum::UTF8: return mpt::encode<Tdststring>(mpt::common_encoding::utf8, src); break;
case CharsetEnum::ASCII: return mpt::encode<Tdststring>(mpt::common_encoding::ascii, src); break;
case CharsetEnum::ISO8859_1: return mpt::encode<Tdststring>(mpt::common_encoding::iso8859_1, src); break;
case CharsetEnum::ISO8859_15: return mpt::encode<Tdststring>(mpt::common_encoding::iso8859_15, src); break;
case CharsetEnum::CP437: return mpt::encode<Tdststring>(mpt::common_encoding::cp437, src); break;
case CharsetEnum::CP737: return mpt::encode<Tdststring>(mpt::common_encoding::cp737, src); break;
case CharsetEnum::CP775: return mpt::encode<Tdststring>(mpt::common_encoding::cp775, src); break;
case CharsetEnum::CP850: return mpt::encode<Tdststring>(mpt::common_encoding::cp850, src); break;
case CharsetEnum::CP852: return mpt::encode<Tdststring>(mpt::common_encoding::cp852, src); break;
case CharsetEnum::CP855: return mpt::encode<Tdststring>(mpt::common_encoding::cp855, src); break;
case CharsetEnum::CP857: return mpt::encode<Tdststring>(mpt::common_encoding::cp857, src); break;
case CharsetEnum::CP860: return mpt::encode<Tdststring>(mpt::common_encoding::cp860, src); break;
case CharsetEnum::CP861: return mpt::encode<Tdststring>(mpt::common_encoding::cp861, src); break;
case CharsetEnum::CP862: return mpt::encode<Tdststring>(mpt::common_encoding::cp862, src); break;
case CharsetEnum::CP863: return mpt::encode<Tdststring>(mpt::common_encoding::cp863, src); break;
case CharsetEnum::CP864: return mpt::encode<Tdststring>(mpt::common_encoding::cp864, src); break;
case CharsetEnum::CP865: return mpt::encode<Tdststring>(mpt::common_encoding::cp865, src); break;
case CharsetEnum::CP866: return mpt::encode<Tdststring>(mpt::common_encoding::cp866, src); break;
case CharsetEnum::CP869: return mpt::encode<Tdststring>(mpt::common_encoding::cp869, src); break;
case CharsetEnum::CP874: return mpt::encode<Tdststring>(mpt::common_encoding::cp874, src); break;
case CharsetEnum::CP437AMS: return mpt::encode<Tdststring>(CharsetTable::CP437AMS, src); break;
case CharsetEnum::CP437AMS2: return mpt::encode<Tdststring>(CharsetTable::CP437AMS2, src); break;
case CharsetEnum::Windows1252: return mpt::encode<Tdststring>(mpt::common_encoding::windows1252, src); break;
case CharsetEnum::Amiga: return mpt::encode<Tdststring>(mpt::common_encoding::amiga, src); break;
case CharsetEnum::RISC_OS: return mpt::encode<Tdststring>(mpt::common_encoding::riscos, src); break;
case CharsetEnum::AtariST: return mpt::encode<Tdststring>(mpt::common_encoding::atarist, src); break;
case CharsetEnum::ISO8859_1_no_C1: return mpt::encode<Tdststring>(mpt::common_encoding::iso8859_1_no_c1, src); break;
case CharsetEnum::ISO8859_15_no_C1: return mpt::encode<Tdststring>(mpt::common_encoding::iso8859_15_no_c1, src); break;
case CharsetEnum::Amiga_no_C1: return mpt::encode<Tdststring>(mpt::common_encoding::amiga_no_c1, src); break;
}
return Tdststring();
}
// templated on 8bit strings because of type-safe variants
template <typename Tsrcstring>
inline mpt::widestring decode(const Tsrcstring &src) const
{
static_assert(sizeof(typename Tsrcstring::value_type) == sizeof(char));
static_assert(mpt::is_character<typename Tsrcstring::value_type>::value);
switch(m_Charset)
{
#if defined(MPT_ENABLE_CHARSET_LOCALE)
case CharsetEnum::Locale: return mpt::decode<Tsrcstring>(mpt::logical_encoding::locale, src); break;
#endif
case CharsetEnum::UTF8: return mpt::decode<Tsrcstring>(mpt::common_encoding::utf8, src); break;
case CharsetEnum::ASCII: return mpt::decode<Tsrcstring>(mpt::common_encoding::ascii, src); break;
case CharsetEnum::ISO8859_1: return mpt::decode<Tsrcstring>(mpt::common_encoding::iso8859_1, src); break;
case CharsetEnum::ISO8859_15: return mpt::decode<Tsrcstring>(mpt::common_encoding::iso8859_15, src); break;
case CharsetEnum::CP437: return mpt::decode<Tsrcstring>(mpt::common_encoding::cp437, src); break;
case CharsetEnum::CP737: return mpt::decode<Tsrcstring>(mpt::common_encoding::cp737, src); break;
case CharsetEnum::CP775: return mpt::decode<Tsrcstring>(mpt::common_encoding::cp775, src); break;
case CharsetEnum::CP850: return mpt::decode<Tsrcstring>(mpt::common_encoding::cp850, src); break;
case CharsetEnum::CP852: return mpt::decode<Tsrcstring>(mpt::common_encoding::cp852, src); break;
case CharsetEnum::CP855: return mpt::decode<Tsrcstring>(mpt::common_encoding::cp855, src); break;
case CharsetEnum::CP857: return mpt::decode<Tsrcstring>(mpt::common_encoding::cp857, src); break;
case CharsetEnum::CP860: return mpt::decode<Tsrcstring>(mpt::common_encoding::cp860, src); break;
case CharsetEnum::CP861: return mpt::decode<Tsrcstring>(mpt::common_encoding::cp861, src); break;
case CharsetEnum::CP862: return mpt::decode<Tsrcstring>(mpt::common_encoding::cp862, src); break;
case CharsetEnum::CP863: return mpt::decode<Tsrcstring>(mpt::common_encoding::cp863, src); break;
case CharsetEnum::CP864: return mpt::decode<Tsrcstring>(mpt::common_encoding::cp864, src); break;
case CharsetEnum::CP865: return mpt::decode<Tsrcstring>(mpt::common_encoding::cp865, src); break;
case CharsetEnum::CP866: return mpt::decode<Tsrcstring>(mpt::common_encoding::cp866, src); break;
case CharsetEnum::CP869: return mpt::decode<Tsrcstring>(mpt::common_encoding::cp869, src); break;
case CharsetEnum::CP874: return mpt::decode<Tsrcstring>(mpt::common_encoding::cp874, src); break;
case CharsetEnum::CP437AMS: return mpt::decode<Tsrcstring>(CharsetTable::CP437AMS, src); break;
case CharsetEnum::CP437AMS2: return mpt::decode<Tsrcstring>(CharsetTable::CP437AMS2, src); break;
case CharsetEnum::Windows1252: return mpt::decode<Tsrcstring>(mpt::common_encoding::windows1252, src); break;
case CharsetEnum::Amiga: return mpt::decode<Tsrcstring>(mpt::common_encoding::amiga, src); break;
case CharsetEnum::RISC_OS: return mpt::decode<Tsrcstring>(mpt::common_encoding::riscos, src); break;
case CharsetEnum::AtariST: return mpt::decode<Tsrcstring>(mpt::common_encoding::atarist, src); break;
case CharsetEnum::ISO8859_1_no_C1: return mpt::decode<Tsrcstring>(mpt::common_encoding::iso8859_1_no_c1, src); break;
case CharsetEnum::ISO8859_15_no_C1: return mpt::decode<Tsrcstring>(mpt::common_encoding::iso8859_15_no_c1, src); break;
case CharsetEnum::Amiga_no_C1: return mpt::decode<Tsrcstring>(mpt::common_encoding::amiga_no_c1, src); break;
}
return mpt::widestring();
}
};
struct Charset
: public CharsetTranscoder
{
constexpr Charset(mpt::CharsetEnum charset) noexcept
: CharsetTranscoder(charset)
{
return;
}
constexpr Charset(mpt::CharsetTranscoder charset) noexcept
: CharsetTranscoder(charset.GetCharset())
{
return;
}
static inline constexpr auto UTF8 = mpt::CharsetTranscoder{ mpt::CharsetEnum::UTF8 };
static inline constexpr auto ASCII = mpt::CharsetTranscoder{ mpt::CharsetEnum::ASCII };
static inline constexpr auto ISO8859_1 = mpt::CharsetTranscoder{ mpt::CharsetEnum::ISO8859_1 };
static inline constexpr auto ISO8859_15 = mpt::CharsetTranscoder{ mpt::CharsetEnum::ISO8859_15 };
static inline constexpr auto CP437 = mpt::CharsetTranscoder{ mpt::CharsetEnum::CP437 };
static inline constexpr auto CP737 = mpt::CharsetTranscoder{ mpt::CharsetEnum::CP737 };
static inline constexpr auto CP775 = mpt::CharsetTranscoder{ mpt::CharsetEnum::CP775 };
static inline constexpr auto CP850 = mpt::CharsetTranscoder{ mpt::CharsetEnum::CP850 };
static inline constexpr auto CP852 = mpt::CharsetTranscoder{ mpt::CharsetEnum::CP852 };
static inline constexpr auto CP855 = mpt::CharsetTranscoder{ mpt::CharsetEnum::CP855 };
static inline constexpr auto CP857 = mpt::CharsetTranscoder{ mpt::CharsetEnum::CP857 };
static inline constexpr auto CP860 = mpt::CharsetTranscoder{ mpt::CharsetEnum::CP860 };
static inline constexpr auto CP861 = mpt::CharsetTranscoder{ mpt::CharsetEnum::CP861 };
static inline constexpr auto CP862 = mpt::CharsetTranscoder{ mpt::CharsetEnum::CP862 };
static inline constexpr auto CP863 = mpt::CharsetTranscoder{ mpt::CharsetEnum::CP863 };
static inline constexpr auto CP864 = mpt::CharsetTranscoder{ mpt::CharsetEnum::CP864 };
static inline constexpr auto CP865 = mpt::CharsetTranscoder{ mpt::CharsetEnum::CP865 };
static inline constexpr auto CP866 = mpt::CharsetTranscoder{ mpt::CharsetEnum::CP866 };
static inline constexpr auto CP869 = mpt::CharsetTranscoder{ mpt::CharsetEnum::CP869 };
static inline constexpr auto CP874 = mpt::CharsetTranscoder{ mpt::CharsetEnum::CP874 };
static inline constexpr auto CP437AMS = mpt::CharsetTranscoder{ mpt::CharsetEnum::CP437AMS };
static inline constexpr auto CP437AMS2 = mpt::CharsetTranscoder{ mpt::CharsetEnum::CP437AMS2 };
static inline constexpr auto Windows1252 = mpt::CharsetTranscoder{ mpt::CharsetEnum::Windows1252 };
static inline constexpr auto Amiga = mpt::CharsetTranscoder{ mpt::CharsetEnum::Amiga };
static inline constexpr auto RISC_OS = mpt::CharsetTranscoder{ mpt::CharsetEnum::RISC_OS };
static inline constexpr auto AtariST = mpt::CharsetTranscoder{ mpt::CharsetEnum::AtariST };
static inline constexpr auto ISO8859_1_no_C1 = mpt::CharsetTranscoder{ mpt::CharsetEnum::ISO8859_1_no_C1 };
static inline constexpr auto ISO8859_15_no_C1 = mpt::CharsetTranscoder{ mpt::CharsetEnum::ISO8859_15_no_C1 };
static inline constexpr auto Amiga_no_C1 = mpt::CharsetTranscoder{ mpt::CharsetEnum::Amiga_no_C1 };
// getenv
#if defined(MPT_ENABLE_CHARSET_LOCALE)
inline constexpr Charset CharsetEnvironment = Charset::Locale;
#else
inline constexpr Charset CharsetEnvironment = Charset::UTF8;
#endif
static inline constexpr auto Locale = mpt::CharsetTranscoder{ mpt::CharsetEnum::Locale };
#endif // MPT_ENABLE_CHARSET_LOCALE
};
// std::exception::what()
#if defined(MPT_ENABLE_CHARSET_LOCALE)
inline constexpr Charset CharsetException = Charset::Locale;
#else
inline constexpr Charset CharsetException = Charset::UTF8;
#endif
@ -117,22 +313,39 @@ inline constexpr Charset CharsetException = Charset::UTF8;
// - 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);
inline bool IsUTF8(const std::string &str)
{
return mpt::is_utf8(str);
}
#if MPT_WSTRING_CONVERT
template <typename Tsrc>
inline mpt::ustring ToUnicode(Tsrc &&str)
{
return mpt::transcode<mpt::ustring>(std::forward<Tsrc>(str));
}
template <typename Tsrc, typename Tencoding>
inline mpt::ustring ToUnicode(Tencoding &&from, Tsrc &&str)
{
return mpt::transcode<mpt::ustring>(std::forward<Tencoding>(from), std::forward<Tsrc>(str));
}
#if !defined(MPT_COMPILER_QUIRK_NO_WCHAR)
// 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.
inline std::wstring ToWide(const std::wstring &str) { return str; }
inline std::wstring ToWide(const wchar_t * str) { return (str ? std::wstring(str) : std::wstring()); }
std::wstring ToWide(Charset from, const std::string &str);
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
template <typename Tsrc>
inline std::wstring ToWide(Tsrc &&str)
{
return mpt::transcode<std::wstring>(std::forward<Tsrc>(str));
}
template <typename Tsrc, typename Tencoding>
inline std::wstring ToWide(Tencoding &&from, Tsrc &&str)
{
return mpt::transcode<std::wstring>(std::forward<Tencoding>(from), std::forward<Tsrc>(str));
}
#endif
// Convert to a string encoded in the 'to'-specified character set.
@ -141,66 +354,54 @@ std::wstring ToWide(const mpt::lstring &str);
// '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);
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);
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
template <typename Tsrc, typename Tencoding>
inline std::string ToCharset(Tencoding &&to, Tsrc &&str)
{
return mpt::transcode<std::string>(std::forward<Tencoding>(to), std::forward<Tsrc>(str));
}
template <typename Tsrc, typename Tto, typename Tfrom>
inline std::string ToCharset(Tto &&to, Tfrom &&from, Tsrc &&str)
{
return mpt::transcode<std::string>(std::forward<Tto>(to), std::forward<Tfrom>(from), std::forward<Tsrc>(str));
}
#if defined(MPT_ENABLE_CHARSET_LOCALE)
#if MPT_WSTRING_CONVERT
mpt::lstring ToLocale(const std::wstring &str);
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);
inline mpt::lstring ToLocale(Charset from, const char * str) { return ToLocale(from, str ? std::string(str): std::string()); }
inline mpt::lstring ToLocale(const mpt::lstring &str) { return str; }
template <typename Tsrc>
inline mpt::lstring ToLocale(Tsrc &&str)
{
return mpt::transcode<mpt::lstring>(std::forward<Tsrc>(str));
}
template <typename Tsrc, typename Tencoding>
inline mpt::lstring ToLocale(Tencoding &&from, Tsrc &&str)
{
return mpt::transcode<mpt::lstring>(std::forward<Tencoding>(from), std::forward<Tsrc>(str));
}
#endif // MPT_ENABLE_CHARSET_LOCALE
#if MPT_OS_WINDOWS
#if MPT_WSTRING_CONVERT
mpt::winstring ToWin(const std::wstring &str);
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);
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
template <typename Tsrc>
inline mpt::winstring ToWin(Tsrc &&str)
{
return mpt::transcode<mpt::winstring>(std::forward<Tsrc>(str));
}
template <typename Tsrc, typename Tencoding>
inline mpt::winstring ToWin(Tencoding &&from, Tsrc &&str)
{
return mpt::transcode<mpt::winstring>(std::forward<Tencoding>(from), std::forward<Tsrc>(str));
}
#endif // MPT_OS_WINDOWS
#if defined(MPT_WITH_MFC)
#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.
inline CString ToCString(const CString &str) { return str; }
CString ToCString(const std::wstring &str);
inline CString ToCString(const wchar_t * str) { return ToCString(str ? std::wstring(str) : std::wstring()); }
CString ToCString(Charset from, const std::string &str);
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);
template <typename Tsrc>
inline CString ToCString(Tsrc &&str)
{
return mpt::transcode<CString>(std::forward<Tsrc>(str));
}
template <typename Tsrc, typename Tencoding>
inline CString ToCString(Tencoding &&from, Tsrc &&str)
{
return mpt::transcode<CString>(std::forward<Tencoding>(from), std::forward<Tsrc>(str));
}
#endif // MPT_WITH_MFC
@ -211,92 +412,141 @@ std::string ToCharset(Charset to, const CString &str);
#if MPT_USTRING_MODE_WIDE
#if !(MPT_WSTRING_CONVERT)
#error "MPT_USTRING_MODE_WIDE depends on MPT_WSTRING_CONVERT)"
#endif
inline mpt::ustring ToUnicode(const std::wstring &str) { return str; }
inline mpt::ustring ToUnicode(const wchar_t * str) { return (str ? std::wstring(str) : std::wstring()); }
inline mpt::ustring ToUnicode(Charset from, const std::string &str) { return ToWide(from, str); }
inline mpt::ustring ToUnicode(Charset from, const char * str) { return ToUnicode(from, str ? std::string(str) : std::string()); }
#if defined(MPT_ENABLE_CHARSET_LOCALE)
inline mpt::ustring ToUnicode(const mpt::lstring &str) { return ToWide(str); }
#endif // MPT_ENABLE_CHARSET_LOCALE
#if defined(MPT_WITH_MFC)
inline mpt::ustring ToUnicode(const CString &str) { return ToWide(str); }
#endif // MFC
#else // !MPT_USTRING_MODE_WIDE
inline mpt::ustring ToUnicode(const mpt::ustring &str) { return str; }
#if MPT_WSTRING_CONVERT
mpt::ustring ToUnicode(const std::wstring &str);
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);
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(MPT_WITH_MFC)
mpt::ustring ToUnicode(const CString &str);
#endif // MPT_WITH_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(MPT_WITH_MFC)
CString ToCString(const mpt::ustring &str);
#endif // MPT_WITH_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)
#define MPT_UTF8(x) mpt::transcode<mpt::ustring>(mpt::common_encoding::utf8, x)
template <typename Tsrc, typename Tencoding>
inline mpt::ustring ToUnicode(uint16 codepage, Tencoding &&fallback, Tsrc &&str)
{
#if MPT_OS_WINDOWS && !defined(MPT_COMPILER_QUIRK_NO_WCHAR)
mpt::ustring result;
std::optional<mpt::common_encoding> charset = mpt::optional_encoding_from_codepage(codepage);
if(charset.has_value())
{
result = mpt::transcode<mpt::ustring>(charset.value(), std::forward<Tsrc>(str));
} else if(mpt::has_codepage(static_cast<UINT>(codepage)))
{
result = mpt::transcode<mpt::ustring>(static_cast<UINT>(codepage), std::forward<Tsrc>(str));
} else
{
result = mpt::transcode<mpt::ustring>(std::forward<Tencoding>(fallback), std::forward<Tsrc>(str));
}
return result;
#else // !MPT_OS_WINDOWS
std::optional<mpt::common_encoding> charset = mpt::optional_encoding_from_codepage(codepage);
return charset.has_value() ? mpt::transcode<mpt::ustring>(charset.value(), std::forward<Tsrc>(str)) : mpt::transcode<mpt::ustring>(std::forward<Tencoding>(fallback), std::forward<Tsrc>(str));
#endif // MPT_OS_WINDOWS
}
mpt::ustring ToUnicode(uint16 codepage, mpt::Charset fallback, const std::string &str);
inline char ToLowerCaseAscii(char c)
{
return mpt::to_lower_ascii(c);
}
inline char ToUpperCaseAscii(char c)
{
return mpt::to_upper_ascii(c);
}
inline std::string ToLowerCaseAscii(std::string s)
{
std::transform(s.begin(), s.end(), s.begin(), static_cast<char(*)(char)>(&mpt::ToLowerCaseAscii));
return s;
}
inline std::string ToUpperCaseAscii(std::string s)
{
std::transform(s.begin(), s.end(), s.begin(), static_cast<char(*)(char)>(&mpt::ToUpperCaseAscii));
return s;
}
inline int CompareNoCaseAscii(const char *a, const char *b, std::size_t n)
{
while(n--)
{
unsigned char ac = mpt::char_value(mpt::ToLowerCaseAscii(*a));
unsigned char bc = mpt::char_value(mpt::ToLowerCaseAscii(*b));
if(ac != bc)
{
return ac < bc ? -1 : 1;
} else if(!ac && !bc)
{
return 0;
}
++a;
++b;
}
return 0;
}
char ToLowerCaseAscii(char c);
char ToUpperCaseAscii(char c);
std::string ToLowerCaseAscii(std::string s);
std::string ToUpperCaseAscii(std::string s);
inline int CompareNoCaseAscii(std::string_view a, std::string_view b)
{
for(std::size_t i = 0; i < std::min(a.length(), b.length()); ++i)
{
unsigned char ac = mpt::char_value(mpt::ToLowerCaseAscii(a[i]));
unsigned char bc = mpt::char_value(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;
}
int CompareNoCaseAscii(const char *a, const char *b, std::size_t n);
int CompareNoCaseAscii(std::string_view a, std::string_view b);
int CompareNoCaseAscii(const std::string &a, const std::string &b);
inline int CompareNoCaseAscii(const std::string &a, const std::string &b)
{
return CompareNoCaseAscii(std::string_view(a), std::string_view(b));
}
#if defined(MODPLUG_TRACKER)
mpt::ustring ToLowerCase(const mpt::ustring &s);
mpt::ustring ToUpperCase(const mpt::ustring &s);
inline mpt::ustring ToLowerCase(const mpt::ustring &s)
{
#if defined(MPT_WITH_MFC)
#if defined(UNICODE)
return mpt::transcode<mpt::ustring>(mpt::transcode<CString>(s).MakeLower());
#else // !UNICODE
return mpt::transcode<mpt::ustring>(mpt::transcode<CStringW>(s).MakeLower());
#endif // UNICODE
#else // !MPT_WITH_MFC
std::wstring ws = mpt::transcode<std::wstring>(s);
std::transform(ws.begin(), ws.end(), ws.begin(), &std::towlower);
return mpt::transcode<mpt::ustring>(ws);
#endif // MPT_WITH_MFC
}
inline mpt::ustring ToUpperCase(const mpt::ustring &s)
{
#if defined(MPT_WITH_MFC)
#if defined(UNICODE)
return mpt::transcode<mpt::ustring>(mpt::transcode<CString>(s).MakeUpper());
#else // !UNICODE
return mpt::transcode<mpt::ustring>(mpt::transcode<CStringW>(s).MakeUpper());
#endif // UNICODE
#else // !MPT_WITH_MFC
std::wstring ws = mpt::transcode<std::wstring>(s);
std::transform(ws.begin(), ws.end(), ws.begin(), &std::towupper);
return mpt::transcode<mpt::ustring>(ws);
#endif // MPT_WITH_MFC
}
#endif // MODPLUG_TRACKER
@ -317,32 +567,32 @@ mpt::ustring ToUpperCase(const mpt::ustring &s);
// 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>
template <mpt::CharsetEnum charset = mpt::Charset::UTF8, bool tryUTF8 = true>
class BasicAnyString : public mpt::ustring
{
private:
static mpt::ustring From8bit(const std::string &str)
static mpt::ustring From8bit(std::string str)
{
if constexpr(charset == mpt::Charset::UTF8)
if constexpr(charset == mpt::CharsetEnum::UTF8)
{
return mpt::ToUnicode(mpt::Charset::UTF8, str);
return mpt::transcode<mpt::ustring>(mpt::common_encoding::utf8, std::move(str));
} else
{
// auto utf8 detection
if constexpr(tryUTF8)
{
if(mpt::IsUTF8(str))
if(mpt::is_utf8(str))
{
return mpt::ToUnicode(mpt::Charset::UTF8, str);
return mpt::transcode<mpt::ustring>(mpt::common_encoding::utf8, std::move(str));
} else
{
return mpt::ToUnicode(charset, str);
return mpt::transcode<mpt::ustring>(mpt::CharsetTranscoder(charset), std::move(str));
}
} else
{
return mpt::ToUnicode(charset, str);
return mpt::transcode<mpt::ustring>(mpt::CharsetTranscoder(charset), std::move(str));
}
}
}
@ -350,97 +600,83 @@ private:
public:
// 8 bit
BasicAnyString(const char *str) : mpt::ustring(From8bit(str ? str : std::string())) { }
BasicAnyString(const std::string str) : mpt::ustring(From8bit(str)) { }
BasicAnyString(const char *str)
: mpt::ustring(From8bit(str ? str : std::string()))
{
return;
}
BasicAnyString(std::string str)
: mpt::ustring(From8bit(std::move(str)))
{
return;
}
// 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(MPT_WITH_MFC)
BasicAnyString(const CString &str) : mpt::ustring(mpt::ToUnicode(str)) { }
#endif // MPT_WITH_MFC
// 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))) { }
template <typename Tstring>
BasicAnyString(Tstring &&str)
: mpt::ustring(mpt::transcode<mpt::ustring>(std::forward<Tstring>(str)))
{
return;
}
};
// AnyUnicodeString is convertable to mpt::ustring and constructable from any unicode string,
// AnyUnicodeString is convertable to mpt::ustring and constructable from any known encoding
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(MPT_WITH_MFC)
AnyUnicodeString(const CString &str) : mpt::ustring(mpt::ToUnicode(str)) { }
#endif // MPT_WITH_MFC
// 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))) { }
template <typename Tstring>
AnyUnicodeString(Tstring &&str)
: mpt::ustring(mpt::transcode<mpt::ustring>(std::forward<Tstring>(str)))
{
return;
}
};
// AnyString
// Try to do the smartest auto-magic we can do.
#if defined(MPT_ENABLE_CHARSET_LOCALE)
using AnyString = BasicAnyString<mpt::Charset::Locale, true>;
using AnyString = BasicAnyString<mpt::CharsetEnum::Locale, true>;
#elif MPT_OS_WINDOWS
using AnyString = BasicAnyString<mpt::Charset::Windows1252, true>;
using AnyString = BasicAnyString<mpt::CharsetEnum::Windows1252, true>;
#else
using AnyString = BasicAnyString<mpt::Charset::ISO8859_1, true>;
using AnyString = BasicAnyString<mpt::CharsetEnum::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>;
using AnyStringLocale = BasicAnyString<mpt::CharsetEnum::Locale, false>;
#else
using AnyStringLocale = BasicAnyString<mpt::Charset::UTF8, false>;
using AnyStringLocale = BasicAnyString<mpt::CharsetEnum::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>;
using AnyStringUTF8orLocale = BasicAnyString<mpt::CharsetEnum::Locale, true>;
#else
using AnyStringUTF8orLocale = BasicAnyString<mpt::Charset::UTF8, false>;
using AnyStringUTF8orLocale = BasicAnyString<mpt::CharsetEnum::UTF8, false>;
#endif
// AnyStringUTF8
// char-based strings are assumed to be in UTF8.
using AnyStringUTF8 = BasicAnyString<mpt::Charset::UTF8, false>;
using AnyStringUTF8 = BasicAnyString<mpt::CharsetEnum::UTF8, false>;
OPENMPT_NAMESPACE_END
template <OPENMPT_NAMESPACE::mpt::CharsetEnum charset, bool tryUTF8>
struct mpt::make_string_type<OPENMPT_NAMESPACE::BasicAnyString<charset, tryUTF8>> {
using type = mpt::ustring;
};
template <>
struct mpt::make_string_type<OPENMPT_NAMESPACE::AnyUnicodeString> {
using type = mpt::ustring;
};

View file

@ -180,7 +180,7 @@ template <std::size_t len, mpt::String::ReadWriteMode mode>
struct modecharbuf
{
public:
typedef char Tchar;
using Tchar = char;
using char_type = Tchar;
using string_type = std::basic_string<Tchar>;
public:
@ -297,3 +297,26 @@ namespace String
OPENMPT_NAMESPACE_END
template <typename Tchar>
struct mpt::make_string_type<OPENMPT_NAMESPACE::mpt::StringModeBufRefImpl<Tchar>> {
using type = std::basic_string<typename std::remove_const<Tchar>::type>;
};
template <typename Tchar>
struct mpt::make_string_view_type<OPENMPT_NAMESPACE::mpt::StringModeBufRefImpl<Tchar>> {
using type = std::basic_string_view<typename std::remove_const<Tchar>::type>;
};
template <std::size_t len, OPENMPT_NAMESPACE::mpt::String::ReadWriteMode mode>
struct mpt::make_string_type<OPENMPT_NAMESPACE::mpt::modecharbuf<len, mode>> {
using type = std::string;
};
template <std::size_t len, OPENMPT_NAMESPACE::mpt::String::ReadWriteMode mode>
struct mpt::make_string_view_type<OPENMPT_NAMESPACE::mpt::modecharbuf<len, mode>> {
using type = std::string_view;
};

View file

@ -1,143 +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"
#include "mpt/format/default_floatingpoint.hpp"
#include "mpt/format/default_integer.hpp"
#include "mpt/format/helpers.hpp"
#include "mpt/format/simple_floatingpoint.hpp"
#include "mpt/format/simple_integer.hpp"
OPENMPT_NAMESPACE_BEGIN
namespace mpt
{
std::string ToAString(const bool & x) { return mpt::format_value_default<std::string>(x); }
std::string ToAString(const signed char & x) { return mpt::format_value_default<std::string>(x); }
std::string ToAString(const unsigned char & x) { return mpt::format_value_default<std::string>(x); }
std::string ToAString(const signed short & x) { return mpt::format_value_default<std::string>(x); }
std::string ToAString(const unsigned short & x) { return mpt::format_value_default<std::string>(x); }
std::string ToAString(const signed int & x) { return mpt::format_value_default<std::string>(x); }
std::string ToAString(const unsigned int & x) { return mpt::format_value_default<std::string>(x); }
std::string ToAString(const signed long & x) { return mpt::format_value_default<std::string>(x); }
std::string ToAString(const unsigned long & x) { return mpt::format_value_default<std::string>(x); }
std::string ToAString(const signed long long & x) { return mpt::format_value_default<std::string>(x); }
std::string ToAString(const unsigned long long & x) { return mpt::format_value_default<std::string>(x); }
std::string ToAString(const float & x) { return mpt::format_value_default<std::string>(x); }
std::string ToAString(const double & x) { return mpt::format_value_default<std::string>(x); }
std::string ToAString(const long double & x) { return mpt::format_value_default<std::string>(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(MPT_WITH_MFC)
mpt::ustring ToUString(const CString & x) { return mpt::ToUnicode(x); }
#endif // MPT_WITH_MFC
mpt::ustring ToUString(const bool & x) { return mpt::format_value_default<mpt::ustring>(x); }
mpt::ustring ToUString(const signed char & x) { return mpt::format_value_default<mpt::ustring>(x); }
mpt::ustring ToUString(const unsigned char & x) { return mpt::format_value_default<mpt::ustring>(x); }
mpt::ustring ToUString(const signed short & x) { return mpt::format_value_default<mpt::ustring>(x); }
mpt::ustring ToUString(const unsigned short & x) { return mpt::format_value_default<mpt::ustring>(x); }
mpt::ustring ToUString(const signed int & x) { return mpt::format_value_default<mpt::ustring>(x); }
mpt::ustring ToUString(const unsigned int & x) { return mpt::format_value_default<mpt::ustring>(x); }
mpt::ustring ToUString(const signed long & x) { return mpt::format_value_default<mpt::ustring>(x); }
mpt::ustring ToUString(const unsigned long & x) { return mpt::format_value_default<mpt::ustring>(x); }
mpt::ustring ToUString(const signed long long & x) { return mpt::format_value_default<mpt::ustring>(x); }
mpt::ustring ToUString(const unsigned long long & x) { return mpt::format_value_default<mpt::ustring>(x); }
mpt::ustring ToUString(const float & x) { return mpt::format_value_default<mpt::ustring>(x); }
mpt::ustring ToUString(const double & x) { return mpt::format_value_default<mpt::ustring>(x); }
mpt::ustring ToUString(const long double & x) { return mpt::format_value_default<mpt::ustring>(x); }
#if MPT_WSTRING_FORMAT
#if MPT_USTRING_MODE_UTF8
std::wstring ToWString(const mpt::ustring & x) { return mpt::ToWide(x); }
#endif
#if defined(MPT_WITH_MFC)
std::wstring ToWString(const CString & x) { return mpt::ToWide(x); }
#endif // MPT_WITH_MFC
std::wstring ToWString(const bool & x) { return mpt::format_value_default<std::wstring>(x); }
std::wstring ToWString(const signed char & x) { return mpt::format_value_default<std::wstring>(x); }
std::wstring ToWString(const unsigned char & x) { return mpt::format_value_default<std::wstring>(x); }
std::wstring ToWString(const signed short & x) { return mpt::format_value_default<std::wstring>(x); }
std::wstring ToWString(const unsigned short & x) { return mpt::format_value_default<std::wstring>(x); }
std::wstring ToWString(const signed int & x) { return mpt::format_value_default<std::wstring>(x); }
std::wstring ToWString(const unsigned int & x) { return mpt::format_value_default<std::wstring>(x); }
std::wstring ToWString(const signed long & x) { return mpt::format_value_default<std::wstring>(x); }
std::wstring ToWString(const unsigned long & x) { return mpt::format_value_default<std::wstring>(x); }
std::wstring ToWString(const signed long long & x) { return mpt::format_value_default<std::wstring>(x); }
std::wstring ToWString(const unsigned long long & x) { return mpt::format_value_default<std::wstring>(x); }
std::wstring ToWString(const float & x) { return mpt::format_value_default<std::wstring>(x); }
std::wstring ToWString(const double & x) { return mpt::format_value_default<std::wstring>(x); }
std::wstring ToWString(const long double & x) { return mpt::format_value_default<std::wstring>(x); }
#endif
std::string FormatValA(const bool & x, const FormatSpec & f) { return mpt::format_simple<std::string>(x, f); }
std::string FormatValA(const signed char & x, const FormatSpec & f) { return mpt::format_simple<std::string>(x, f); }
std::string FormatValA(const unsigned char & x, const FormatSpec & f) { return mpt::format_simple<std::string>(x, f); }
std::string FormatValA(const signed short & x, const FormatSpec & f) { return mpt::format_simple<std::string>(x, f); }
std::string FormatValA(const unsigned short & x, const FormatSpec & f) { return mpt::format_simple<std::string>(x, f); }
std::string FormatValA(const signed int & x, const FormatSpec & f) { return mpt::format_simple<std::string>(x, f); }
std::string FormatValA(const unsigned int & x, const FormatSpec & f) { return mpt::format_simple<std::string>(x, f); }
std::string FormatValA(const signed long & x, const FormatSpec & f) { return mpt::format_simple<std::string>(x, f); }
std::string FormatValA(const unsigned long & x, const FormatSpec & f) { return mpt::format_simple<std::string>(x, f); }
std::string FormatValA(const signed long long & x, const FormatSpec & f) { return mpt::format_simple<std::string>(x, f); }
std::string FormatValA(const unsigned long long & x, const FormatSpec & f) { return mpt::format_simple<std::string>(x, f); }
std::string FormatValA(const float & x, const FormatSpec & f) { return mpt::format_simple<std::string>(x, f); }
std::string FormatValA(const double & x, const FormatSpec & f) { return mpt::format_simple<std::string>(x, f); }
std::string FormatValA(const long double & x, const FormatSpec & f) { return mpt::format_simple<std::string>(x, f); }
mpt::ustring FormatValU(const bool & x, const FormatSpec & f) { return mpt::format_simple<mpt::ustring>(x, f); }
mpt::ustring FormatValU(const signed char & x, const FormatSpec & f) { return mpt::format_simple<mpt::ustring>(x, f); }
mpt::ustring FormatValU(const unsigned char & x, const FormatSpec & f) { return mpt::format_simple<mpt::ustring>(x, f); }
mpt::ustring FormatValU(const signed short & x, const FormatSpec & f) { return mpt::format_simple<mpt::ustring>(x, f); }
mpt::ustring FormatValU(const unsigned short & x, const FormatSpec & f) { return mpt::format_simple<mpt::ustring>(x, f); }
mpt::ustring FormatValU(const signed int & x, const FormatSpec & f) { return mpt::format_simple<mpt::ustring>(x, f); }
mpt::ustring FormatValU(const unsigned int & x, const FormatSpec & f) { return mpt::format_simple<mpt::ustring>(x, f); }
mpt::ustring FormatValU(const signed long & x, const FormatSpec & f) { return mpt::format_simple<mpt::ustring>(x, f); }
mpt::ustring FormatValU(const unsigned long & x, const FormatSpec & f) { return mpt::format_simple<mpt::ustring>(x, f); }
mpt::ustring FormatValU(const signed long long & x, const FormatSpec & f) { return mpt::format_simple<mpt::ustring>(x, f); }
mpt::ustring FormatValU(const unsigned long long & x, const FormatSpec & f) { return mpt::format_simple<mpt::ustring>(x, f); }
mpt::ustring FormatValU(const float & x, const FormatSpec & f) { return mpt::format_simple<mpt::ustring>(x, f); }
mpt::ustring FormatValU(const double & x, const FormatSpec & f) { return mpt::format_simple<mpt::ustring>(x, f); }
mpt::ustring FormatValU(const long double & x, const FormatSpec & f) { return mpt::format_simple<mpt::ustring>(x, f); }
#if MPT_WSTRING_FORMAT
std::wstring FormatValW(const bool & x, const FormatSpec & f) { return mpt::format_simple<std::wstring>(x, f); }
std::wstring FormatValW(const signed char & x, const FormatSpec & f) { return mpt::format_simple<std::wstring>(x, f); }
std::wstring FormatValW(const unsigned char & x, const FormatSpec & f) { return mpt::format_simple<std::wstring>(x, f); }
std::wstring FormatValW(const signed short & x, const FormatSpec & f) { return mpt::format_simple<std::wstring>(x, f); }
std::wstring FormatValW(const unsigned short & x, const FormatSpec & f) { return mpt::format_simple<std::wstring>(x, f); }
std::wstring FormatValW(const signed int & x, const FormatSpec & f) { return mpt::format_simple<std::wstring>(x, f); }
std::wstring FormatValW(const unsigned int & x, const FormatSpec & f) { return mpt::format_simple<std::wstring>(x, f); }
std::wstring FormatValW(const signed long & x, const FormatSpec & f) { return mpt::format_simple<std::wstring>(x, f); }
std::wstring FormatValW(const unsigned long & x, const FormatSpec & f) { return mpt::format_simple<std::wstring>(x, f); }
std::wstring FormatValW(const signed long long & x, const FormatSpec & f) { return mpt::format_simple<std::wstring>(x, f); }
std::wstring FormatValW(const unsigned long long & x, const FormatSpec & f) { return mpt::format_simple<std::wstring>(x, f); }
std::wstring FormatValW(const float & x, const FormatSpec & f) { return mpt::format_simple<std::wstring>(x, f); }
std::wstring FormatValW(const double & x, const FormatSpec & f) { return mpt::format_simple<std::wstring>(x, f); }
std::wstring FormatValW(const long double & x, const FormatSpec & f) { return mpt::format_simple<std::wstring>(x, f); }
#endif
} // namespace mpt
OPENMPT_NAMESPACE_END

View file

@ -12,19 +12,21 @@
#include "openmpt/all/BuildSettings.hpp"
#include "mpt/base/pointer.hpp"
#include "mpt/base/detect.hpp"
#include "mpt/endian/integer.hpp"
#include "mpt/format/default_formatter.hpp"
#include "mpt/format/message.hpp"
#include "mpt/format/message_macros.hpp"
#include "mpt/format/simple.hpp"
#include "mpt/format/simple_spec.hpp"
#include "mpt/string/types.hpp"
#include <stdexcept>
#include "mptString.h"
#include "mpt/string_transcode/transcode.hpp"
#include "openmpt/base/FlagSet.hpp"
#include "mptString.h"
OPENMPT_NAMESPACE_BEGIN
#include <cstddef>
@ -66,431 +68,86 @@ OPENMPT_NAMESPACE_BEGIN
// 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 {
inline namespace MPT_INLINE_NS {
template <typename Tstring, typename Tint, mpt::endian endian>
inline auto format_value_default(const mpt::packed<Tint, endian> & x) -> decltype(mpt::default_formatter::format<Tstring, Tint>(x)) {
return mpt::default_formatter::format<Tstring, Tint>(x);
}
} // namespace MPT_INLINE_NS
} // namespace mpt
OPENMPT_NAMESPACE_BEGIN
template <typename Tstring, typename T>
inline auto format_value_default(const T & x) -> decltype(mpt::transcode<Tstring>(x.ToUString())) {
return mpt::transcode<Tstring>(x.ToUString());
}
template <typename Tstring, typename T>
inline auto format_value_default(const T & x) -> decltype(mpt::transcode<Tstring>(ToUString(x))) {
return mpt::transcode<Tstring>(ToUString(x));
}
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> [[deprecated]] auto ToAString(const T & x) -> decltype(mpt::ToCharset(mpt::Charset::UTF8, x.ToUString())) { return mpt::ToCharset(mpt::Charset::UTF8, x.ToUString()); } // unknown encoding
#else
#if defined(MPT_ENABLE_CHARSET_LOCALE)
template <typename T> [[deprecated]] auto ToAString(const T & x) -> decltype(mpt::ToCharset(mpt::Charset::Locale, x.ToUString())) { return mpt::ToCharset(mpt::Charset::Locale, x.ToUString()); } // unknown encoding
#else // !MPT_ENABLE_CHARSET_LOCALE
template <typename T> [[deprecated]] auto ToAString(const T & x) -> decltype(mpt::ToCharset(mpt::Charset::UTF8, x.ToUString())) { return mpt::ToCharset(mpt::Charset::UTF8, x.ToUString()); } // unknown encoding
#endif // MPT_ENABLE_CHARSET_LOCALE
#endif
inline std::string ToAString(const std::string & x) { return x; }
inline std::string ToAString(const char * const & x) { return x; }
std::string ToAString(const char &x) = delete; // deprecated to catch potential API mis-use, use std::string(1, x) instead
#if MPT_WSTRING_FORMAT
std::string ToAString(const std::wstring & x) = delete; // Unknown encoding.
std::string ToAString(const wchar_t * const & x) = delete; // Unknown encoding.
std::string ToAString(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 ToAString(const mpt::ustring & x) = delete; // Unknown encoding.
#endif
#if defined(MPT_WITH_MFC)
std::string ToAString(const CString & x) = delete; // unknown encoding
#endif // MPT_WITH_MFC
std::string ToAString(const bool & x);
std::string ToAString(const signed char & x);
std::string ToAString(const unsigned char & x);
std::string ToAString(const signed short & x);
std::string ToAString(const unsigned short & x);
std::string ToAString(const signed int & x);
std::string ToAString(const unsigned int & x);
std::string ToAString(const signed long & x);
std::string ToAString(const unsigned long & x);
std::string ToAString(const signed long long & x);
std::string ToAString(const unsigned long long & x);
std::string ToAString(const float & x);
std::string ToAString(const double & x);
std::string ToAString(const long double & x);
// fallback to member function ToUString()
template <typename T> auto ToUString(const T & x) -> decltype(x.ToUString()) { return x.ToUString(); }
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(MPT_WITH_MFC)
mpt::ustring ToUString(const CString & x);
#endif // MPT_WITH_MFC
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
inline std::wstring ToWString(const std::wstring & x) { return x; }
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(MPT_WITH_MFC)
std::wstring ToWString(const CString & x);
#endif // MPT_WITH_MFC
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(MPT_WITH_MFC)
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 // MPT_WITH_MFC
template <typename Tstring> struct ToStringTFunctor {};
template <> struct ToStringTFunctor<std::string> { template <typename T> inline std::string operator() (const T & x) { return ToAString(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(MPT_WITH_MFC)
template <> struct ToStringTFunctor<CString> { template <typename T> inline CString operator() (const T & x) { return mpt::ToCStringHelper<T>()(x); } };
#endif // MPT_WITH_MFC
template<typename Tstring, typename T> inline Tstring ToStringT(const T & x) { return ToStringTFunctor<Tstring>()(x); }
template <typename Tstring, typename T>
inline auto format_value_default(const T & x) -> decltype(mpt::transcode<Tstring>(x.ToUString())) {
return mpt::transcode<Tstring>(x.ToUString());
}
struct ToStringFormatter {
template <typename Tstring, typename T>
static inline Tstring format(const T& value) {
return ToStringTFunctor<Tstring>()(value);
}
};
using FormatSpec = mpt::format_simple_spec;
using FormatFlags = mpt::format_simple_flags;
using fmt_base = mpt::format_simple_base;
std::string FormatValA(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 FormatValA(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 FormatValA(const bool & x, const FormatSpec & f);
std::string FormatValA(const signed char & x, const FormatSpec & f);
std::string FormatValA(const unsigned char & x, const FormatSpec & f);
std::string FormatValA(const signed short & x, const FormatSpec & f);
std::string FormatValA(const unsigned short & x, const FormatSpec & f);
std::string FormatValA(const signed int & x, const FormatSpec & f);
std::string FormatValA(const unsigned int & x, const FormatSpec & f);
std::string FormatValA(const signed long & x, const FormatSpec & f);
std::string FormatValA(const unsigned long & x, const FormatSpec & f);
std::string FormatValA(const signed long long & x, const FormatSpec & f);
std::string FormatValA(const unsigned long long & x, const FormatSpec & f);
std::string FormatValA(const float & x, const FormatSpec & f);
std::string FormatValA(const double & x, const FormatSpec & f);
std::string FormatValA(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 FormatValA(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, FormatValA(x, f)); } };
#endif // MPT_ENABLE_CHARSET_LOCALE
#if defined(MPT_WITH_MFC)
#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 // !UNICODE
template <> struct FormatValTFunctor<CString> { template <typename T> inline CString operator() (const T & x, const FormatSpec & f) { return mpt::ToCString(mpt::Charset::Locale, FormatValA(x, f)); } };
#endif // UNICODE
#endif // MPT_WITH_MFC
template <typename Tstring, typename T>
inline auto format_value_default(const T & x) -> decltype(mpt::transcode<Tstring>(ToUString(x))) {
return mpt::transcode<Tstring>(ToUString(x));
}
template <typename Tstring>
struct fmtT : fmt_base
{
using fmtT = mpt::format<Tstring>;
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>(mpt::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>(mpt::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> afmt;
#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;
using afmt = fmtT<std::string>;
#if !defined(MPT_COMPILER_QUIRK_NO_WCHAR)
using wfmt = fmtT<std::wstring>;
#endif
using ufmt = fmtT<mpt::ustring>;
#if defined(MPT_ENABLE_CHARSET_LOCALE)
typedef fmtT<mpt::lstring> lfmt;
using lfmt = fmtT<mpt::lstring>;
#endif // MPT_ENABLE_CHARSET_LOCALE
#if MPT_OS_WINDOWS
typedef fmtT<mpt::tstring> tfmt;
using tfmt = fmtT<mpt::tstring>;
#endif
#if defined(MPT_WITH_MFC)
typedef fmtT<CString> cfmt;
using cfmt = fmtT<CString>;
#endif // MPT_WITH_MFC
#define MPT_AFORMAT(f) mpt::format_message<mpt::ToStringFormatter, mpt::parse_format_string_argument_count(f)>(f)
#define MPT_AFORMAT(f) MPT_AFORMAT_MESSAGE(f)
#if MPT_WSTRING_FORMAT
#define MPT_WFORMAT(f) mpt::format_message_typed<mpt::ToStringFormatter, mpt::parse_format_string_argument_count( L ## f ), std::wstring>( L ## f )
#if !defined(MPT_COMPILER_QUIRK_NO_WCHAR)
#define MPT_WFORMAT(f) MPT_WFORMAT_MESSAGE(f)
#endif
#define MPT_UFORMAT(f) mpt::format_message_typed<mpt::ToStringFormatter, mpt::parse_format_string_argument_count(MPT_ULITERAL(f)), mpt::ustring>(MPT_ULITERAL(f))
#define MPT_UFORMAT(f) MPT_UFORMAT_MESSAGE(f)
#if defined(MPT_ENABLE_CHARSET_LOCALE)
#define MPT_LFORMAT(f) mpt::format_message_typed<mpt::ToStringFormatter, mpt::parse_format_string_argument_count(f), mpt::lstring>(f)
#define MPT_LFORMAT(f) MPT_LFORMAT_MESSAGE(f)
#endif // MPT_ENABLE_CHARSET_LOCALE
#if MPT_OS_WINDOWS
#define MPT_TFORMAT(f) mpt::format_message_typed<mpt::ToStringFormatter, mpt::parse_format_string_argument_count(TEXT(f)), mpt::tstring>(TEXT(f))
#endif
#define MPT_TFORMAT(f) MPT_TFORMAT_MESSAGE(f)
#endif // MPT_OS_WINDOWS
#if defined(MPT_WITH_MFC)
#define MPT_CFORMAT(f) mpt::format_message_typed<mpt::ToStringFormatter, mpt::parse_format_string_argument_count(TEXT(f)), CString>(TEXT(f))
#define MPT_CFORMAT(f) MPT_CFORMAT_MESSAGE(f)
#endif // MPT_WITH_MFC
@ -498,43 +155,6 @@ typedef fmtT<CString> cfmt;
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::afmt::val(vals[i]);
}
return str;
}
} } // namespace mpt::String
template <typename enum_t, typename store_t>
mpt::ustring ToUString(FlagSet<enum_t, store_t> flagset)
{
@ -550,5 +170,4 @@ mpt::ustring ToUString(FlagSet<enum_t, store_t> flagset)
OPENMPT_NAMESPACE_END

View file

@ -1,98 +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 "mpt/parse/parse.hpp"
OPENMPT_NAMESPACE_BEGIN
template<typename T>
inline T ConvertStrToHelper(const std::string &str)
{
return mpt::ConvertStringTo<T>(str);
}
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)
{
return mpt::ConvertStringTo<T>(str);
}
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)
{
return mpt::ConvertHexStringTo<T>(str);
}
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

View file

@ -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 "openmpt/all/BuildSettings.hpp"
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(MPT_WITH_MFC)
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 // MPT_WITH_MFC
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

View file

@ -11,9 +11,19 @@
#include "stdafx.h"
#include "mptTime.h"
#if defined(MODPLUG_TRACKER) && MPT_OS_WINDOWS
#include "mpt/osinfo/windows_wine_version.hpp"
#endif // MODPLUG_TRACKER && MPT_OS_WINDOWS
#include "mptStringBuffer.h"
#include <time.h>
#if MPT_CXX_AT_LEAST(20) && !defined(MPT_LIBCXX_QUIRK_NO_CHRONO_DATE)
#include <chrono>
#endif
#if defined(MODPLUG_TRACKER) && MPT_OS_WINDOWS
#include <optional>
#endif // MODPLUG_TRACKER && MPT_OS_WINDOWS
#if MPT_OS_WINDOWS
#include <windows.h>
@ -81,22 +91,8 @@ mpt::ustring ToUString(uint64 time100ns)
#endif // MODPLUG_TRACKER
Unix::Unix()
: Value(0)
namespace nochrono
{
return;
}
Unix::Unix(int64 unixtime)
: Value(unixtime)
{
return;
}
Unix::operator int64 () const
{
return Value;
}
static int32 ToDaynum(int32 year, int32 month, int32 day)
{
@ -128,81 +124,270 @@ static void FromDaynum(int32 d, int32 & year, int32 & month, int32 & day)
day = static_cast<int32>(dd);
}
mpt::Date::Unix Unix::FromUTC(tm timeUtc)
Unix UnixFromUTC(UTC 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);
int32 daynum = ToDaynum(timeUtc.year, timeUtc.month, timeUtc.day);
int64 seconds = static_cast<int64>(daynum - ToDaynum(1970, 1, 1)) * 24 * 60 * 60 + timeUtc.hours * 60 * 60 + timeUtc.minutes * 60 + timeUtc.seconds;
return Unix{seconds};
}
tm Unix::AsUTC() const
UTC UnixAsUTC(Unix tp)
{
int64 tmp = Value;
int64 tmp = tp.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 = {};
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);
UTC result = {};
result.year = year;
result.month = month;
result.day = day;
result.hours = static_cast<int32>(hours);
result.minutes = static_cast<int32>(minutes);
result.seconds = seconds;
return result;
}
mpt::ustring ToShortenedISO8601(tm date)
#if defined(MODPLUG_TRACKER)
struct tz_error
{
};
Unix UnixFromLocal(Local timeLocal)
{
#if defined(MPT_FALLBACK_TIMEZONE_WINDOWS_HISTORIC)
try
{
if(mpt::osinfo::windows::current_is_wine())
{
throw tz_error{};
}
SYSTEMTIME sys_local{};
sys_local.wYear = static_cast<uint16>(timeLocal.year);
sys_local.wMonth = static_cast<uint16>(timeLocal.month);
sys_local.wDay = static_cast<uint16>(timeLocal.day);
sys_local.wHour = static_cast<uint16>(timeLocal.hours);
sys_local.wMinute = static_cast<uint16>(timeLocal.minutes);
sys_local.wSecond = static_cast<uint16>(timeLocal.seconds);
sys_local.wMilliseconds = 0;
DYNAMIC_TIME_ZONE_INFORMATION dtzi{};
if(GetDynamicTimeZoneInformation(&dtzi) == TIME_ZONE_ID_INVALID) // WinVista
{
throw tz_error{};
}
SYSTEMTIME sys_utc{};
if(TzSpecificLocalTimeToSystemTimeEx(&dtzi, &sys_local, &sys_utc) == FALSE) // Win7/Win8
{
throw tz_error{};
}
FILETIME ft{};
if(SystemTimeToFileTime(&sys_utc, &ft) == FALSE) // Win 2000
{
throw tz_error{};
}
ULARGE_INTEGER time_value{};
time_value.LowPart = ft.dwLowDateTime;
time_value.HighPart = ft.dwHighDateTime;
return UnixFromSeconds(static_cast<int64>((time_value.QuadPart - 116444736000000000LL) / 10000000LL));
} catch(const tz_error &)
{
// nothing
}
#endif
#if defined(MPT_FALLBACK_TIMEZONE_WINDOWS_CURRENT)
try
{
SYSTEMTIME sys_local{};
sys_local.wYear = static_cast<uint16>(timeLocal.year);
sys_local.wMonth = static_cast<uint16>(timeLocal.month);
sys_local.wDay = static_cast<uint16>(timeLocal.day);
sys_local.wHour = static_cast<uint16>(timeLocal.hours);
sys_local.wMinute = static_cast<uint16>(timeLocal.minutes);
sys_local.wSecond = static_cast<uint16>(timeLocal.seconds);
sys_local.wMilliseconds = 0;
SYSTEMTIME sys_utc{};
if(TzSpecificLocalTimeToSystemTime(NULL, &sys_local, &sys_utc) == FALSE) // WinXP
{
throw tz_error{};
}
FILETIME ft{};
if(SystemTimeToFileTime(&sys_utc, &ft) == FALSE) // Win 2000
{
throw tz_error{};
}
ULARGE_INTEGER time_value{};
time_value.LowPart = ft.dwLowDateTime;
time_value.HighPart = ft.dwHighDateTime;
return UnixFromSeconds(static_cast<int64>((time_value.QuadPart - 116444736000000000LL) / 10000000LL));
} catch(const tz_error &)
{
// nothing
}
#endif
#if defined(MPT_FALLBACK_TIMEZONE_C)
std::tm tmp{};
tmp.tm_year = timeLocal.year - 1900;
tmp.tm_mon = timeLocal.month - 1;
tmp.tm_mday = timeLocal.day;
tmp.tm_hour = timeLocal.hours;
tmp.tm_min = timeLocal.minutes;
tmp.tm_sec = static_cast<int>(timeLocal.seconds);
return UnixFromSeconds(static_cast<int64>(std::mktime(&tmp)));
#endif
}
Local UnixAsLocal(Unix tp)
{
#if defined(MPT_FALLBACK_TIMEZONE_WINDOWS_HISTORIC)
try
{
if(mpt::osinfo::windows::current_is_wine())
{
throw tz_error{};
}
ULARGE_INTEGER time_value{};
time_value.QuadPart = static_cast<int64>(UnixAsSeconds(tp)) * 10000000LL + 116444736000000000LL;
FILETIME ft{};
ft.dwLowDateTime = time_value.LowPart;
ft.dwHighDateTime = time_value.HighPart;
SYSTEMTIME sys_utc{};
if(FileTimeToSystemTime(&ft, &sys_utc) == FALSE) // WinXP
{
throw tz_error{};
}
DYNAMIC_TIME_ZONE_INFORMATION dtzi{};
if(GetDynamicTimeZoneInformation(&dtzi) == TIME_ZONE_ID_INVALID) // WinVista
{
throw tz_error{};
}
SYSTEMTIME sys_local{};
if(SystemTimeToTzSpecificLocalTimeEx(&dtzi, &sys_utc, &sys_local) == FALSE) // Win7/Win8
{
throw tz_error{};
}
Local result{};
result.year = sys_local.wYear;
result.month = sys_local.wMonth;
result.day = sys_local.wDay;
result.hours = sys_local.wHour;
result.minutes = sys_local.wMinute;
result.seconds = sys_local.wSecond;
return result;
} catch(const tz_error&)
{
// nothing
}
#endif
#if defined(MPT_FALLBACK_TIMEZONE_WINDOWS_CURRENT)
try
{
ULARGE_INTEGER time_value{};
time_value.QuadPart = static_cast<int64>(UnixAsSeconds(tp)) * 10000000LL + 116444736000000000LL;
FILETIME ft{};
ft.dwLowDateTime = time_value.LowPart;
ft.dwHighDateTime = time_value.HighPart;
SYSTEMTIME sys_utc{};
if(FileTimeToSystemTime(&ft, &sys_utc) == FALSE) // WinXP
{
throw tz_error{};
}
SYSTEMTIME sys_local{};
if(SystemTimeToTzSpecificLocalTime(NULL, &sys_utc, &sys_local) == FALSE) // Win2000
{
throw tz_error{};
}
Local result{};
result.year = sys_local.wYear;
result.month = sys_local.wMonth;
result.day = sys_local.wDay;
result.hours = sys_local.wHour;
result.minutes = sys_local.wMinute;
result.seconds = sys_local.wSecond;
return result;
} catch(const tz_error&)
{
// nothing
}
#endif
#if defined(MPT_FALLBACK_TIMEZONE_C)
std::time_t time_tp = static_cast<std::time_t>(UnixAsSeconds(tp));
std::tm *tmp = std::localtime(&time_tp);
if(!tmp)
{
return Local{};
}
std::tm local = *tmp;
Local result{};
result.year = local.tm_year + 1900;
result.month = local.tm_mon + 1;
result.day = local.tm_mday;
result.hours = local.tm_hour;
result.minutes = local.tm_min;
result.seconds = local.tm_sec;
return result;
#endif
}
#endif // MODPLUG_TRACKER
} // namespace nochrono
template <LogicalTimezone TZ>
static mpt::ustring ToShortenedISO8601Impl(mpt::Date::Gregorian<TZ> 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)
mpt::ustring tz;
if constexpr(TZ == LogicalTimezone::Unspecified)
{
tz = U_("");
} else if constexpr(TZ == LogicalTimezone::UTC)
{
tz = U_("Z");
} else
{
tz = U_("");
}
if(date.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)
result += mpt::ufmt::dec0<4>(date.year);
result += U_("-") + mpt::ufmt::dec0<2>(date.month);
result += U_("-") + mpt::ufmt::dec0<2>(date.day);
if(date.hours == 0 && date.minutes == 0 && date.seconds)
{
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)
result += mpt::ufmt::dec0<2>(date.hours) + U_(":") + mpt::ufmt::dec0<2>(date.minutes);
if(date.seconds == 0)
{
return result + tz;
}
result += U_(":") + mpt::ufmt::dec0<2>(date.tm_sec);
result += U_(":") + mpt::ufmt::dec0<2>(date.seconds);
result += tz;
return result;
}
mpt::ustring ToShortenedISO8601(mpt::Date::AnyGregorian date)
{
return ToShortenedISO8601Impl(date);
}
mpt::ustring ToShortenedISO8601(mpt::Date::UTC date)
{
return ToShortenedISO8601Impl(date);
}
#ifdef MODPLUG_TRACKER
mpt::ustring ToShortenedISO8601(Local date)
{
return ToShortenedISO8601Impl(date);
}
#endif // MODPLUG_TRACKER
} // namespace Date
} // namespace mpt

View file

@ -12,9 +12,25 @@
#include "openmpt/all/BuildSettings.hpp"
#if MPT_CXX_AT_LEAST(20) && !defined(MPT_LIBCXX_QUIRK_NO_CHRONO_DATE)
#include <chrono>
#include <exception>
#endif
#include <string>
#include <time.h>
#include <ctime>
#if MPT_WINNT_AT_LEAST(MPT_WIN_8)
#define MPT_FALLBACK_TIMEZONE_WINDOWS_HISTORIC
#define MPT_FALLBACK_TIMEZONE_WINDOWS_CURRENT
#define MPT_FALLBACK_TIMEZONE_C
#elif MPT_WINNT_AT_LEAST(MPT_WIN_XP)
#define MPT_FALLBACK_TIMEZONE_WINDOWS_CURRENT
#define MPT_FALLBACK_TIMEZONE_C
#else
#define MPT_FALLBACK_TIMEZONE_C
#endif
OPENMPT_NAMESPACE_BEGIN
@ -44,21 +60,260 @@ mpt::ustring ToUString(uint64 time100ns); // i.e. 2015-01-15 18:32:01.718
#endif // MODPLUG_TRACKER
class Unix
enum class LogicalTimezone
{
// 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;
Unspecified,
UTC,
#if defined(MODPLUG_TRACKER)
Local,
#endif // MODPLUG_TRACKER
};
mpt::ustring ToShortenedISO8601(tm date); // i.e. 2015-01-15T18:32:01Z
template <LogicalTimezone tz>
struct Gregorian
{
int year = 0;
unsigned int month = 0;
unsigned int day = 0;
int32 hours = 0;
int32 minutes = 0;
int64 seconds = 0;
friend bool operator==(const Gregorian<tz>& lhs, const Gregorian<tz>& rhs)
{
return true
&& lhs.year == rhs.year
&& lhs.month == rhs.month
&& lhs.day == rhs.day
&& lhs.hours == rhs.hours
&& lhs.minutes == rhs.minutes
&& lhs.seconds == rhs.seconds
;
}
friend bool operator!=(const Gregorian<tz>& lhs, const Gregorian<tz>& rhs)
{
return false
|| lhs.year != rhs.year
|| lhs.month != rhs.month
|| lhs.day != rhs.day
|| lhs.hours != rhs.hours
|| lhs.minutes != rhs.minutes
|| lhs.seconds != rhs.seconds
;
}
};
using AnyGregorian = Gregorian<LogicalTimezone::Unspecified>;
using UTC = Gregorian<LogicalTimezone::UTC>;
#if defined(MODPLUG_TRACKER)
using Local = Gregorian<LogicalTimezone::Local>;
#endif // MODPLUG_TRACKER
template <LogicalTimezone TZ>
inline Gregorian<TZ> interpret_as_timezone(AnyGregorian gregorian)
{
Gregorian<TZ> result;
result.year = gregorian.year;
result.month = gregorian.month;
result.day = gregorian.day;
result.hours = gregorian.hours;
result.minutes = gregorian.minutes;
result.seconds = gregorian.seconds;
return result;
}
template <LogicalTimezone TZ>
inline Gregorian<LogicalTimezone::Unspecified> forget_timezone(Gregorian<TZ> gregorian)
{
Gregorian<LogicalTimezone::Unspecified> result;
result.year = gregorian.year;
result.month = gregorian.month;
result.day = gregorian.day;
result.hours = gregorian.hours;
result.minutes = gregorian.minutes;
result.seconds = gregorian.seconds;
return result;
}
namespace nochrono
{
// int64 counts 1s since 1970-01-01T00:00Z
struct Unix
{
int64 value{};
friend bool operator==(const Unix &a, const Unix &b)
{
return a.value == b.value;
}
friend bool operator!=(const Unix &a, const Unix &b)
{
return a.value != b.value;
}
};
inline Unix UnixNow()
{
return Unix{static_cast<int64>(std::time(nullptr))};
}
inline int64 UnixAsSeconds(Unix tp)
{
return tp.value;
}
inline Unix UnixFromSeconds(int64 seconds)
{
return Unix{seconds};
}
Unix UnixFromUTC(UTC timeUtc);
UTC UnixAsUTC(Unix tp);
#if defined(MODPLUG_TRACKER)
Unix UnixFromLocal(Local timeLocal);
Local UnixAsLocal(Unix tp);
#endif // MODPLUG_TRACKER
} // namespace nochrono
#if MPT_CXX_AT_LEAST(20) && !defined(MPT_LIBCXX_QUIRK_NO_CHRONO_DATE)
using Unix = std::chrono::system_clock::time_point;
inline Unix UnixNow()
{
return std::chrono::system_clock::now();
}
inline int64 UnixAsSeconds(Unix tp)
{
return std::chrono::duration_cast<std::chrono::seconds>(tp.time_since_epoch()).count();
}
inline Unix UnixFromSeconds(int64 seconds)
{
return std::chrono::system_clock::time_point{std::chrono::seconds{seconds}};
}
inline mpt::Date::Unix UnixFromUTC(UTC utc)
{
try
{
return std::chrono::system_clock::time_point{
std::chrono::sys_days {
std::chrono::year{ utc.year } /
std::chrono::month{ utc.month } /
std::chrono::day{ utc.day }
} +
std::chrono::hours{ utc.hours } +
std::chrono::minutes{ utc.minutes } +
std::chrono::seconds{ utc.seconds }};
} catch(const std::exception &)
{
return mpt::Date::UnixFromSeconds(mpt::Date::nochrono::UnixAsSeconds(mpt::Date::nochrono::UnixFromUTC(utc)));
}
}
inline mpt::Date::UTC UnixAsUTC(Unix tp)
{
try
{
std::chrono::sys_days dp = std::chrono::floor<std::chrono::days>(tp);
std::chrono::year_month_day ymd{dp};
std::chrono::hh_mm_ss hms{tp - dp};
mpt::Date::UTC result;
result.year = static_cast<int>(ymd.year());
result.month = static_cast<unsigned int>(ymd.month());
result.day = static_cast<unsigned int>(ymd.day());
result.hours = static_cast<int32>(hms.hours().count());
result.minutes = static_cast<int32>(hms.minutes().count());
result.seconds = static_cast<int64>(hms.seconds().count());
return result;
} catch(const std::exception &)
{
return mpt::Date::nochrono::UnixAsUTC(mpt::Date::nochrono::UnixFromSeconds(mpt::Date::UnixAsSeconds(tp)));
}
}
#if defined(MODPLUG_TRACKER)
inline mpt::Date::Unix UnixFromLocal(Local local)
{
try
{
std::chrono::time_point<std::chrono::local_t, std::chrono::seconds> local_tp =
std::chrono::local_days {
std::chrono::year{ local.year } /
std::chrono::month{ local.month } /
std::chrono::day{ local.day }
} +
std::chrono::hours{ local.hours } +
std::chrono::minutes{ local.minutes } +
std::chrono::seconds{ local.seconds };
return std::chrono::zoned_time{std::chrono::current_zone(), local_tp}.get_sys_time();
} catch(const std::exception &)
{
return mpt::Date::UnixFromSeconds(mpt::Date::nochrono::UnixAsSeconds(mpt::Date::nochrono::UnixFromLocal(local)));
}
}
inline mpt::Date::Local UnixAsLocal(Unix tp)
{
try
{
std::chrono::zoned_time local_tp{ std::chrono::current_zone(), tp };
std::chrono::local_days dp = std::chrono::floor<std::chrono::days>(local_tp.get_local_time());
std::chrono::year_month_day ymd{dp};
std::chrono::hh_mm_ss hms{local_tp.get_local_time() - dp};
mpt::Date::Local result;
result.year = static_cast<int>(ymd.year());
result.month = static_cast<unsigned int>(ymd.month());
result.day = static_cast<unsigned int>(ymd.day());
result.hours = static_cast<int32>(hms.hours().count());
result.minutes = static_cast<int32>(hms.minutes().count());
result.seconds = static_cast<int64>(hms.seconds().count());
return result;
} catch(const std::exception &)
{
return mpt::Date::nochrono::UnixAsLocal(mpt::Date::nochrono::UnixFromSeconds(mpt::Date::UnixAsSeconds(tp)));
}
}
#endif // MODPLUG_TRACKER
#else
using Unix = nochrono::Unix;
using nochrono::UnixNow;
using nochrono::UnixAsSeconds;
using nochrono::UnixFromSeconds;
using nochrono::UnixFromUTC;
using nochrono::UnixAsUTC;
#if defined(MODPLUG_TRACKER)
using nochrono::UnixFromLocal;
using nochrono::UnixAsLocal;
#endif // MODPLUG_TRACKER
#endif
mpt::ustring ToShortenedISO8601(AnyGregorian date); // i.e. 2015-01-15T18:32:01
mpt::ustring ToShortenedISO8601(UTC date); // i.e. 2015-01-15T18:32:01Z
#ifdef MODPLUG_TRACKER
mpt::ustring ToShortenedISO8601(Local date); // i.e. 2015-01-15T18:32:01
#endif // MODPLUG_TRACKER
} // namespace Date
} // namespace mpt

View file

@ -12,6 +12,7 @@
#include "serialization_utils.h"
#include "mpt/base/utility.hpp"
#include "mpt/io/io.hpp"
#include "mpt/io/io_stdstream.hpp"
@ -30,18 +31,6 @@ namespace srlztn
{
#ifdef MPT_ALL_LOGGING
#define SSB_LOGGING
#endif
#ifdef SSB_LOGGING
#define SSB_LOG(x) MPT_LOG_GLOBAL(LogDebug, "serialization", x)
#else
#define SSB_LOG(x) do { } while(0)
#endif
static const uint8 HeaderId_FlagByte = 0;
// Indexing starts from 0.
@ -49,11 +38,17 @@ static inline bool Testbit(uint8 val, uint8 bitindex) {return ((val & (1 << biti
static inline void Setbit(uint8& val, uint8 bitindex, bool newval)
{
if(newval) val |= (1 << bitindex);
else val &= ~(1 << bitindex);
if(newval)
{
val |= static_cast<uint8>(1u << bitindex);
} else
{
val &= static_cast<uint8>(~(1u << bitindex));
}
}
#ifdef SSB_LOGGING
bool ID::IsPrintable() const
{
for(std::size_t i = 0; i < m_ID.length(); ++i)
@ -65,6 +60,7 @@ bool ID::IsPrintable() const
}
return true;
}
#endif
//Format: First bit tells whether the size indicator is 1 or 2 bytes.
@ -88,7 +84,7 @@ void WriteItemString(std::ostream& oStrm, const std::string &str)
}
void ReadItemString(std::istream& iStrm, std::string& str, const DataSize)
void ReadItemString(std::istream& iStrm, std::string& str, const std::size_t)
{
// bits 0,1: Bytes per char type: 1,2,3,4.
// bits 2,3: Bytes in size indicator, 1,2,3,4
@ -118,6 +114,7 @@ void ReadItemString(std::istream& iStrm, std::string& str, const DataSize)
}
#ifdef SSB_LOGGING
mpt::ustring ID::AsString() const
{
if(IsPrintable())
@ -133,13 +130,14 @@ mpt::ustring ID::AsString() const
std::memcpy(&val, m_ID.data(), m_ID.length());
return mpt::ufmt::val(val);
}
#endif
const char Ssb::s_EntryID[3] = {'2','2','8'};
Ssb::Ssb()
: m_Status(SNT_NONE)
: m_Status(Status{})
, m_nFixedEntrySize(0)
, m_posStart(0)
, m_nIdbytes(IdSizeVariable)
@ -173,59 +171,53 @@ SsbRead::SsbRead(std::istream& is)
}
void SsbWrite::AddWriteNote(const SsbStatus s)
void SsbWrite::AddWriteNote(const Status s)
{
m_Status |= s;
SSB_LOG(MPT_UFORMAT("{}: 0x{}")(U_("Write note: "), mpt::ufmt::hex(s)));
m_Status.level = static_cast<StatusLevel>(mpt::to_underlying(m_Status.level) | mpt::to_underlying(s.level));
m_Status.messages = static_cast<StatusMessages>(mpt::to_underlying(m_Status.messages) | mpt::to_underlying(s.messages));
SSB_LOG(MPT_UFORMAT("{}: 0x{} 0x{}")(U_("Write note: "), mpt::ufmt::hex(mpt::to_underlying(s.level)), mpt::ufmt::hex(mpt::to_underlying(s.messages))));
}
void SsbRead::AddReadNote(const SsbStatus s)
void SsbRead::AddReadNote(const Status s)
{
m_Status |= s;
SSB_LOG(MPT_UFORMAT("{}: 0x{}")(U_("Read note: "), mpt::ufmt::hex(s)));
m_Status.level = static_cast<StatusLevel>(mpt::to_underlying(m_Status.level) | mpt::to_underlying(s.level));
m_Status.messages = static_cast<StatusMessages>(mpt::to_underlying(m_Status.messages) | mpt::to_underlying(s.messages));
SSB_LOG(MPT_UFORMAT("{}: 0x{} 0x{}")(U_("Read note: "), mpt::ufmt::hex(mpt::to_underlying(s.level)), mpt::ufmt::hex(mpt::to_underlying(s.messages))));
}
void SsbRead::AddReadNote(const ReadEntry* const pRe, const NumType nNum)
#ifdef SSB_LOGGING
void SsbRead::LogReadEntry(const ReadEntry &pRe, const std::size_t nNum)
{
m_Status |= SNT_PROGRESS;
SSB_LOG(MPT_UFORMAT("Read entry: {{num, id, rpos, size, desc}} = {{{}, {}, {}, {}, {}}}")(
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_(""),
(pRe.nIdLength < 30 && m_Idarray.size() > 0) ? ID(&m_Idarray[pRe.nIdpos], pRe.nIdLength).AsString() : U_(""),
pRe.rposStart,
(pRe.nSize != invalidDatasize) ? mpt::ufmt::val(pRe.nSize) : U_(""),
U_("")));
#ifndef SSB_LOGGING
MPT_UNREFERENCED_PARAMETER(pRe);
MPT_UNREFERENCED_PARAMETER(nNum);
#endif
}
#endif
#ifdef SSB_LOGGING
// Called after writing an entry.
void SsbWrite::AddWriteNote(const ID &id, const NumType nEntryNum, const DataSize nBytecount, const RposType rposStart)
void SsbWrite::LogWriteEntry(const ID &id, const std::size_t nEntryNum, const std::size_t nBytecount, const std::streamoff rposStart)
{
m_Status |= SNT_PROGRESS;
SSB_LOG(MPT_UFORMAT("Wrote entry: {{num, id, rpos, size}} = {{{}, {}, {}, {}}}")(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
}
#endif
void SsbRead::ResetReadstatus()
{
m_Status = SNT_NONE;
m_Status = Status{};
m_Idarray.reserve(32);
m_Idarray.push_back(0);
}
void SsbWrite::WriteMapItem(const ID &id,
const RposType& rposDataStart,
const DataSize& nDatasize,
const char* pszDesc)
const std::streamoff& rposDataStart,
const std::size_t& nDatasize,
const std::string &pszDesc)
{
SSB_LOG(MPT_UFORMAT("Writing map entry: id={}, rpos={}, size={}")(
(id.GetSize() > 0) ? id.AsString() : U_(""),
@ -243,32 +235,21 @@ void SsbWrite::WriteMapItem(const ID &id,
mpt::IO::WriteAdaptiveInt16LE(mapStream, static_cast<uint16>(id.GetSize()));
if(id.GetSize() > 0)
mapStream.write(id.GetBytes(), id.GetSize());
mapStream.write(id.AsSpan().data(), id.AsSpan().size());
}
if (GetFlag(RwfWMapStartPosEntry)) //Startpos
if(m_Flags[RwfWMapStartPosEntry]) // Startpos
mpt::IO::WriteAdaptiveInt64LE(mapStream, rposDataStart);
if (GetFlag(RwfWMapSizeEntry)) //Entrysize
if(m_Flags[RwfWMapSizeEntry]) // Entrysize
mpt::IO::WriteAdaptiveInt64LE(mapStream, nDatasize);
if (GetFlag(RwfWMapDescEntry)) //Entry descriptions
WriteAdaptive12String(mapStream, std::string(pszDesc));
if(m_Flags[RwfWMapDescEntry]) // Entry descriptions
WriteAdaptive12String(mapStream, pszDesc);
m_MapStreamString.append(mapStream.str());
}
void SsbWrite::IncrementWriteCounter()
{
m_nCounter++;
if(m_nCounter >= static_cast<uint16>(std::numeric_limits<uint16>::max() >> 2))
{
FinishWrite();
AddWriteNote(SNW_MAX_WRITE_COUNT_REACHED);
}
}
void SsbWrite::BeginWrite(const ID &id, const uint64& nVersion)
{
SSB_LOG(MPT_UFORMAT("Write header with ID = {}")(id.AsString()));
@ -281,26 +262,26 @@ void SsbWrite::BeginWrite(const ID &id, const uint64& nVersion)
// Start bytes.
oStrm.write(s_EntryID, sizeof(s_EntryID));
m_posStart = oStrm.tellp() - Offtype(sizeof(s_EntryID));
m_posStart = static_cast<std::streamoff>(oStrm.tellp()) - static_cast<std::streamoff>(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());
if(idsize > 0) oStrm.write(id.AsSpan().data(), id.AsSpan().size());
}
// Form header.
uint8 header = 0;
SetFlag(RwfWMapStartPosEntry, GetFlag(RwfWMapStartPosEntry) && m_nFixedEntrySize == 0);
SetFlag(RwfWMapSizeEntry, GetFlag(RwfWMapSizeEntry) && m_nFixedEntrySize == 0);
m_Flags[RwfWMapStartPosEntry] = m_Flags[RwfWMapStartPosEntry] && m_nFixedEntrySize == 0;
m_Flags[RwfWMapSizeEntry] = m_Flags[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?
Setbit(header, 2, m_Flags[RwfWMapStartPosEntry]); //2 : Startpos in map?
Setbit(header, 3, m_Flags[RwfWMapSizeEntry]); //3 : Datasize in map?
Setbit(header, 4, m_Flags[RwfWVersionNum]); //4 : Version numeric field?
Setbit(header, 7, m_Flags[RwfWMapDescEntry]); //7 : Entrydescriptions in map?
// Write header
Binarywrite<uint8>(oStrm, header);
@ -333,55 +314,59 @@ void SsbWrite::BeginWrite(const ID &id, const uint64& nVersion)
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();
m_posEntrycount = static_cast<std::streamoff>(oStrm.tellp());
Binarywrite<uint16>(oStrm, 0);
SetFlag(RwfRwHasMap, (m_nIdbytes != 0 || GetFlag(RwfWMapStartPosEntry) || GetFlag(RwfWMapSizeEntry) || GetFlag(RwfWMapDescEntry)));
m_Flags[RwfRwHasMap] = (m_nIdbytes != 0 || m_Flags[RwfWMapStartPosEntry] || m_Flags[RwfWMapSizeEntry] || m_Flags[RwfWMapDescEntry]);
m_posMapPosField = oStrm.tellp();
if (GetFlag(RwfRwHasMap)) //Mapping begin pos(reserve space - actual value is written after writing data)
m_posMapPosField = static_cast<std::streamoff>(oStrm.tellp());
if(m_Flags[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)
void SsbRead::OnReadEntry(const ReadEntry* pE, const ID &id, const std::streamoff& posReadBegin)
{
if (pE != nullptr)
AddReadNote(pE, m_nCounter);
else if (GetFlag(RwfRMapHasId) == false) // Not ID's in map.
#ifdef SSB_LOGGING
if(pE)
{
LogReadEntry(*pE, m_nCounter);
} else if(!m_Flags[RwfRMapHasId]) // 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.
e.rposStart = posReadBegin - m_posStart;
e.nSize = mpt::saturate_cast<std::size_t>(static_cast<std::streamoff>(static_cast<std::streamoff>(iStrm.tellg()) - posReadBegin));
LogReadEntry(e, m_nCounter);
} else // Entry not found.
{
SSB_LOG(MPT_UFORMAT("No entry with id {} found.")(id.AsString()));
#ifndef SSB_LOGGING
MPT_UNREFERENCED_PARAMETER(id);
#endif
return EntryNotFound;
}
m_nCounter++;
return EntryRead;
#else
MPT_UNREFERENCED_PARAMETER(id);
MPT_UNREFERENCED_PARAMETER(posReadBegin);
#endif
const bool entryFound = (pE || !m_Flags[RwfRMapHasId]);
if(entryFound)
{
m_nCounter++;
}
}
void SsbWrite::OnWroteItem(const ID &id, const Postype& posBeforeWrite)
void SsbWrite::OnWroteItem(const ID &id, const std::streamoff& posBeforeWrite)
{
const Offtype nRawEntrySize = oStrm.tellp() - posBeforeWrite;
const std::streamoff nRawEntrySize = static_cast<std::streamoff>(oStrm.tellp()) - posBeforeWrite;
MPT_MAYBE_CONSTANT_IF(nRawEntrySize < 0 || static_cast<uint64>(nRawEntrySize) > std::numeric_limits<DataSize>::max())
MPT_MAYBE_CONSTANT_IF(!mpt::in_range<std::size_t>(nRawEntrySize))
{
AddWriteNote(SNW_INSUFFICIENT_DATASIZETYPE);
return;
}
if(GetFlag(RwfRMapHasSize) && (nRawEntrySize < 0 || static_cast<uint64>(nRawEntrySize) > (std::numeric_limits<DataSize>::max() >> 2)))
if(m_Flags[RwfRMapHasSize] && (static_cast<uint64>(nRawEntrySize) > (std::numeric_limits<std::size_t>::max() >> 2)))
{ AddWriteNote(SNW_DATASIZETYPE_OVERFLOW); return; }
DataSize nEntrySize = static_cast<DataSize>(nRawEntrySize);
std::size_t nEntrySize = static_cast<std::size_t>(nRawEntrySize);
// Handle fixed size entries:
if (m_nFixedEntrySize > 0)
@ -395,11 +380,19 @@ void SsbWrite::OnWroteItem(const ID &id, const Postype& posBeforeWrite)
else
{ AddWriteNote(SNW_INSUFFICIENT_FIXEDSIZE); return; }
}
if (GetFlag(RwfRwHasMap))
WriteMapItem(id, static_cast<RposType>(posBeforeWrite - m_posStart), nEntrySize, "");
if(m_Flags[RwfRwHasMap])
WriteMapItem(id, posBeforeWrite - m_posStart, nEntrySize, "");
AddWriteNote(id, m_nCounter, nEntrySize, static_cast<RposType>(posBeforeWrite - m_posStart));
IncrementWriteCounter();
#ifdef SSB_LOGGING
LogWriteEntry(id, m_nCounter, nEntrySize, posBeforeWrite - m_posStart);
#endif
m_nCounter++;
if(m_nCounter >= static_cast<uint16>(std::numeric_limits<uint16>::max() >> 2))
{
FinishWrite();
AddWriteNote(SNW_MAX_WRITE_COUNT_REACHED);
}
}
@ -412,7 +405,7 @@ void SsbRead::BeginRead(const ID &id, const uint64& nVersion)
if (!iStrm.good())
{ AddReadNote(SNRW_BADGIVEN_STREAM); return; }
m_posStart = iStrm.tellg();
m_posStart = static_cast<std::streamoff>(iStrm.tellg());
// Start bytes.
{
@ -438,7 +431,7 @@ void SsbRead::BeginRead(const ID &id, const uint64& nVersion)
{
AddReadNote(SNR_OBJECTCLASS_IDMISMATCH);
}
if ((m_Status & SNT_FAILURE) != 0)
if(HasFailed())
{
SSB_LOG(U_("ID mismatch, terminating read."));
return;
@ -452,7 +445,7 @@ void SsbRead::BeginRead(const ID &id, const uint64& nVersion)
const uint8 header = tempU8;
m_nIdbytes = ((header & 3) == 3) ? 4 : (header & 3);
if (Testbit(header, 6))
SetFlag(RwfRTwoBytesDescChar, true);
m_Flags[RwfRTwoBytesDescChar] = true;
// Read headerdata size
uint32 tempU32 = 0;
@ -502,13 +495,13 @@ void SsbRead::BeginRead(const ID &id, const uint64& nVersion)
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));
m_Flags[RwfRMapHasStartpos] = Testbit(header, 2);
m_Flags[RwfRMapHasSize] = Testbit(header, 3);
m_Flags[RwfRMapHasId] = (m_nIdbytes > 0);
m_Flags[RwfRMapHasDesc] = Testbit(header, 7);
m_Flags[RwfRwHasMap] = m_Flags[RwfRMapHasId] || m_Flags[RwfRMapHasStartpos] || m_Flags[RwfRMapHasSize] || m_Flags[RwfRMapHasDesc];
if (GetFlag(RwfRwHasMap) == false)
if(!m_Flags[RwfRwHasMap])
{
SSB_LOG(U_("No map in the file."));
}
@ -517,7 +510,7 @@ void SsbRead::BeginRead(const ID &id, const uint64& nVersion)
{
uint16 size = 0;
mpt::IO::ReadAdaptiveInt16LE(iStrm, size);
iStrm.ignore(size * (GetFlag(RwfRTwoBytesDescChar) ? 2 : 1));
iStrm.ignore(size * (m_Flags[RwfRTwoBytesDescChar] ? 2 : 1));
}
if(Testbit(flagbyte, 3))
@ -530,41 +523,41 @@ void SsbRead::BeginRead(const ID &id, const uint64& nVersion)
// 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);
m_nReadEntrycount = static_cast<std::size_t>(tempU64);
if(m_nReadEntrycount == 0)
AddReadNote(SNR_ZEROENTRYCOUNT);
// Read map rpos if map exists.
if (GetFlag(RwfRwHasMap))
if(m_Flags[RwfRwHasMap])
{
mpt::IO::ReadAdaptiveInt64LE(iStrm, tempU64);
if(tempU64 > static_cast<uint64>(std::numeric_limits<Offtype>::max()))
if(!mpt::in_range<std::streamoff>(tempU64))
{ AddReadNote(SNR_INSUFFICIENT_STREAM_OFFTYPE); return; }
}
const Offtype rawEndOfHdrData = iStrm.tellg() - m_posStart;
const std::streamoff rawEndOfHdrData = static_cast<std::streamoff>(iStrm.tellg()) - m_posStart;
MPT_MAYBE_CONSTANT_IF(rawEndOfHdrData < 0 || static_cast<uint64>(rawEndOfHdrData) > std::numeric_limits<RposType>::max())
if(rawEndOfHdrData < 0)
{
AddReadNote(SNR_INSUFFICIENT_RPOSTYPE);
return;
}
m_rposEndofHdrData = static_cast<RposType>(rawEndOfHdrData);
m_rposMapBegin = (GetFlag(RwfRwHasMap)) ? static_cast<RposType>(tempU64) : m_rposEndofHdrData;
m_rposEndofHdrData = rawEndOfHdrData;
m_rposMapBegin = (m_Flags[RwfRwHasMap]) ? static_cast<std::streamoff>(tempU64) : m_rposEndofHdrData;
if (GetFlag(RwfRwHasMap) == false)
if(!m_Flags[RwfRwHasMap])
m_posMapEnd = m_posStart + m_rposEndofHdrData;
SetFlag(RwfRHeaderIsRead, true);
m_Flags[RwfRHeaderIsRead] = true;
}
void SsbRead::CacheMap()
{
if(GetFlag(RwfRwHasMap) || m_nFixedEntrySize > 0)
if(m_Flags[RwfRwHasMap] || m_nFixedEntrySize > 0)
{
iStrm.seekg(m_posStart + m_rposMapBegin);
iStrm.seekg(m_posStart + m_rposMapBegin, std::ios::beg);
if(iStrm.fail())
{ AddReadNote(SNR_BADSTREAM_AFTER_MAPHEADERSEEK); return; }
@ -575,7 +568,7 @@ void SsbRead::CacheMap()
m_Idarray.reserve(m_nReadEntrycount * 4);
//Read map
for(NumType i = 0; i<m_nReadEntrycount; i++)
for(std::size_t i = 0; i<m_nReadEntrycount; i++)
{
if(iStrm.fail())
{ AddReadNote(SNR_BADSTREAM_AT_MAP_READ); return; }
@ -594,56 +587,56 @@ void SsbRead::CacheMap()
mapData[i].nIdpos = nOldEnd;
// Read position.
if(GetFlag(RwfRMapHasStartpos))
if(m_Flags[RwfRMapHasStartpos])
{
uint64 tempU64;
mpt::IO::ReadAdaptiveInt64LE(iStrm, tempU64);
if(tempU64 > static_cast<uint64>(std::numeric_limits<Offtype>::max()))
if(!mpt::in_range<std::streamoff>(tempU64))
{ AddReadNote(SNR_INSUFFICIENT_STREAM_OFFTYPE); return; }
mapData[i].rposStart = static_cast<RposType>(tempU64);
mapData[i].rposStart = static_cast<std::streamoff>(tempU64);
}
// Read entry size.
if (m_nFixedEntrySize > 0)
mapData[i].nSize = m_nFixedEntrySize;
else if(GetFlag(RwfRMapHasSize)) // Map has datasize field.
else if(m_Flags[RwfRMapHasSize]) // Map has datasize field.
{
uint64 tempU64;
mpt::IO::ReadAdaptiveInt64LE(iStrm, tempU64);
if(tempU64 > static_cast<uint64>(std::numeric_limits<Offtype>::max()))
if(!mpt::in_range<std::streamoff>(tempU64))
{ AddReadNote(SNR_INSUFFICIENT_STREAM_OFFTYPE); return; }
mapData[i].nSize = static_cast<DataSize>(tempU64);
mapData[i].nSize = static_cast<std::size_t>(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)
if(mapData[i].nSize != invalidDatasize && !m_Flags[RwfRMapHasStartpos])
mapData[i].rposStart = (i > 0) ? mapData[i-1].rposStart + mapData[i-1].nSize : 0;
if(GetFlag(RwfRMapHasDesc)) //Map has entrydescriptions?
if(m_Flags[RwfRMapHasDesc]) // Map has entrydescriptions?
{
uint16 size = 0;
mpt::IO::ReadAdaptiveInt16LE(iStrm, size);
if(GetFlag(RwfRTwoBytesDescChar))
if(m_Flags[RwfRTwoBytesDescChar])
iStrm.ignore(size * 2);
else
iStrm.ignore(size);
}
}
m_posMapEnd = iStrm.tellg();
m_posMapEnd = static_cast<std::streamoff>(iStrm.tellg());
SSB_LOG(MPT_UFORMAT("End of map(rpos): {}")(m_posMapEnd - m_posStart));
}
SetFlag(RwfRMapCached, true);
m_posDataBegin = (m_rposMapBegin == m_rposEndofHdrData) ? m_posMapEnd : m_posStart + Postype(m_rposEndofHdrData);
iStrm.seekg(m_posDataBegin);
m_Flags[RwfRMapCached] = true;
m_posDataBegin = (m_rposMapBegin == m_rposEndofHdrData) ? m_posMapEnd : m_posStart + m_rposEndofHdrData;
iStrm.seekg(m_posDataBegin, std::ios::beg);
// 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))
if(!m_Flags[RwfRMapHasStartpos] && (m_Flags[RwfRMapHasSize] || m_nFixedEntrySize > 0))
{
const RposType offset = static_cast<RposType>(m_posDataBegin - m_posStart);
const std::streamoff offset = m_posDataBegin - m_posStart;
for(size_t i = 0; i < m_nReadEntrycount; i++)
mapData[i].rposStart += offset;
}
@ -653,13 +646,13 @@ void SsbRead::CacheMap()
const ReadEntry* SsbRead::Find(const ID &id)
{
iStrm.clear();
if (GetFlag(RwfRMapCached) == false)
if(!m_Flags[RwfRMapCached])
CacheMap();
if (m_nFixedEntrySize > 0 && GetFlag(RwfRMapHasStartpos) == false && GetFlag(RwfRMapHasSize) == false)
iStrm.seekg(m_posDataBegin + Postype(m_nFixedEntrySize * m_nCounter));
if(m_nFixedEntrySize > 0 && !m_Flags[RwfRMapHasStartpos] && !m_Flags[RwfRMapHasSize])
iStrm.seekg(m_posDataBegin + static_cast<std::streamoff>(m_nFixedEntrySize * m_nCounter), std::ios::beg);
if (GetFlag(RwfRMapHasId) == true)
if(m_Flags[RwfRMapHasId])
{
const size_t nEntries = mapData.size();
for(size_t i0 = 0; i0 < nEntries; i0++)
@ -669,7 +662,7 @@ const ReadEntry* SsbRead::Find(const ID &id)
{
m_nNextReadHint = (i + 1) % nEntries;
if (mapData[i].rposStart != 0)
iStrm.seekg(m_posStart + Postype(mapData[i].rposStart));
iStrm.seekg(m_posStart + mapData[i].rposStart, std::ios::beg);
return &mapData[i];
}
}
@ -680,28 +673,28 @@ const ReadEntry* SsbRead::Find(const ID &id)
void SsbWrite::FinishWrite()
{
const Postype posDataEnd = oStrm.tellp();
const std::streamoff posDataEnd = static_cast<std::streamoff>(oStrm.tellp());
Postype posMapStart = oStrm.tellp();
std::streamoff posMapStart = static_cast<std::streamoff>(oStrm.tellp());
SSB_LOG(MPT_UFORMAT("Writing map to rpos: {}")(posMapStart - m_posStart));
if (GetFlag(RwfRwHasMap)) //Write map
if(m_Flags[RwfRwHasMap]) // Write map
{
oStrm.write(m_MapStreamString.c_str(), m_MapStreamString.length());
}
const Postype posMapEnd = oStrm.tellp();
const std::streamoff posMapEnd = static_cast<std::streamoff>(oStrm.tellp());
// Write entry count.
oStrm.seekp(m_posEntrycount);
oStrm.seekp(m_posEntrycount, std::ios::beg);
// 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))
if(m_Flags[RwfRwHasMap])
{ // Write map start position.
oStrm.seekp(m_posMapPosField);
oStrm.seekp(m_posMapPosField, std::ios::beg);
const uint64 rposMap = posMapStart - m_posStart;
// Write a fixed size=8 Adaptive64LE because space for this value has already been reserved berforehand.
@ -710,9 +703,9 @@ void SsbWrite::FinishWrite()
}
// Seek to end.
oStrm.seekp(std::max(posMapEnd, posDataEnd));
oStrm.seekp(std::max(posMapEnd, posDataEnd), std::ios::beg);
SSB_LOG(MPT_UFORMAT("End of stream(rpos): {}")(oStrm.tellp() - m_posStart));
SSB_LOG(MPT_UFORMAT("End of stream(rpos): {}")(static_cast<std::streamoff>(oStrm.tellp()) - m_posStart));
}
} // namespace srlztn

View file

@ -12,6 +12,7 @@
#include "openmpt/all/BuildSettings.hpp"
#include "mpt/base/alloc.hpp"
#include "mpt/io/io.hpp"
#include "mpt/io/io_stdstream.hpp"
#include "openmpt/base/Endian.hpp"
@ -29,72 +30,108 @@
#include <istream>
#include <ostream>
#include <cstddef>
#include <cstring>
OPENMPT_NAMESPACE_BEGIN
#ifdef MPT_ALL_LOGGING
#define SSB_LOGGING
#endif
#ifdef SSB_LOGGING
#define SSB_LOG(x) MPT_LOG_GLOBAL(LogDebug, "serialization", x)
#else
#define SSB_LOG(x) do { } while(0)
#endif
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.
constexpr inline std::size_t invalidDatasize = static_cast<std::size_t>(0) - 1;
const DataSize invalidDatasize = DataSize(-1);
enum
enum class StatusLevel : uint8
{
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
Failure = 0x2,
Note = 0x1,
None = 0x0,
Max = 0xff,
};
enum class StatusMessages : uint32
{
None = 0,
enum
// Read notes and warnings.
SNR_ZEROENTRYCOUNT = 0x00'00'00'01,
SNR_NO_ENTRYIDS_WITH_CUSTOMID_DEFINED = 0x00'00'00'02,
SNR_LOADING_OBJECT_WITH_LARGER_VERSION = 0x00'00'00'04,
// Read failures.
SNR_BADSTREAM_AFTER_MAPHEADERSEEK = 0x00'00'01'00,
SNR_STARTBYTE_MISMATCH = 0x00'00'02'00,
SNR_BADSTREAM_AT_MAP_READ = 0x00'00'04'00,
SNR_INSUFFICIENT_STREAM_OFFTYPE = 0x00'00'08'00,
SNR_OBJECTCLASS_IDMISMATCH = 0x00'00'10'00,
SNR_TOO_MANY_ENTRIES_TO_READ = 0x00'00'20'00,
SNR_INSUFFICIENT_RPOSTYPE = 0x00'00'40'00,
// Write failures.
SNW_INSUFFICIENT_FIXEDSIZE = 0x00'01'00'00,
SNW_CHANGING_IDSIZE_WITH_FIXED_IDSIZESETTING = 0x00'02'00'00,
SNW_DATASIZETYPE_OVERFLOW = 0x00'04'00'00,
SNW_MAX_WRITE_COUNT_REACHED = 0x00'08'00'00,
SNW_INSUFFICIENT_DATASIZETYPE = 0x00'10'00'00,
SNRW_BADGIVEN_STREAM = 0x01'00'00'00,
Max = 0xffffffff,
};
struct Status
{
StatusLevel level = StatusLevel::None;
StatusMessages messages = StatusMessages::None;
};
constexpr inline Status SNR_ZEROENTRYCOUNT = {StatusLevel::Note, StatusMessages::SNR_ZEROENTRYCOUNT};
constexpr inline Status SNR_NO_ENTRYIDS_WITH_CUSTOMID_DEFINED = {StatusLevel::Note, StatusMessages::SNR_NO_ENTRYIDS_WITH_CUSTOMID_DEFINED};
constexpr inline Status SNR_LOADING_OBJECT_WITH_LARGER_VERSION = {StatusLevel::Note, StatusMessages::SNR_LOADING_OBJECT_WITH_LARGER_VERSION};
constexpr inline Status SNR_BADSTREAM_AFTER_MAPHEADERSEEK = {StatusLevel::Failure, StatusMessages::SNR_BADSTREAM_AFTER_MAPHEADERSEEK};
constexpr inline Status SNR_STARTBYTE_MISMATCH = {StatusLevel::Failure, StatusMessages::SNR_STARTBYTE_MISMATCH};
constexpr inline Status SNR_BADSTREAM_AT_MAP_READ = {StatusLevel::Failure, StatusMessages::SNR_BADSTREAM_AT_MAP_READ};
constexpr inline Status SNR_INSUFFICIENT_STREAM_OFFTYPE = {StatusLevel::Failure, StatusMessages::SNR_INSUFFICIENT_STREAM_OFFTYPE};
constexpr inline Status SNR_OBJECTCLASS_IDMISMATCH = {StatusLevel::Failure, StatusMessages::SNR_OBJECTCLASS_IDMISMATCH};
constexpr inline Status SNR_TOO_MANY_ENTRIES_TO_READ = {StatusLevel::Failure, StatusMessages::SNR_TOO_MANY_ENTRIES_TO_READ};
constexpr inline Status SNR_INSUFFICIENT_RPOSTYPE = {StatusLevel::Failure, StatusMessages::SNR_INSUFFICIENT_RPOSTYPE};
constexpr inline Status SNW_INSUFFICIENT_FIXEDSIZE = {StatusLevel::Failure, StatusMessages::SNW_INSUFFICIENT_FIXEDSIZE};
constexpr inline Status SNW_CHANGING_IDSIZE_WITH_FIXED_IDSIZESETTING = {StatusLevel::Failure, StatusMessages::SNW_CHANGING_IDSIZE_WITH_FIXED_IDSIZESETTING};
constexpr inline Status SNW_DATASIZETYPE_OVERFLOW = {StatusLevel::Failure, StatusMessages::SNW_DATASIZETYPE_OVERFLOW};
constexpr inline Status SNW_MAX_WRITE_COUNT_REACHED = {StatusLevel::Failure, StatusMessages::SNW_MAX_WRITE_COUNT_REACHED};
constexpr inline Status SNW_INSUFFICIENT_DATASIZETYPE = {StatusLevel::Failure, StatusMessages::SNW_INSUFFICIENT_DATASIZETYPE};
constexpr inline Status SNRW_BADGIVEN_STREAM = {StatusLevel::Failure, StatusMessages::SNRW_BADGIVEN_STREAM};
enum : uint16
{
IdSizeVariable = std::numeric_limits<uint16>::max(),
IdSizeMaxFixedSize = (std::numeric_limits<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.
std::size_t nIdpos = 0; // Index of id start in ID array.
std::streamoff rposStart = 0; // Entry start position.
std::size_t nSize = invalidDatasize; // Entry size.
uint16 nIdLength = 0; // Length of id.
};
@ -173,38 +210,34 @@ inline void Binaryread(std::istream& iStrm, double& data)
//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)
inline void Binaryread(std::istream& iStrm, T& data, const std::size_t bytecount)
{
mpt::IO::ReadBinaryTruncatedLE(iStrm, data, static_cast<std::size_t>(bytecount));
mpt::IO::ReadBinaryTruncatedLE(iStrm, data, bytecount);
}
template <>
inline void Binaryread<float>(std::istream& iStrm, float& data, const Offtype bytecount)
inline void Binaryread<float>(std::istream& iStrm, float& data, const std::size_t 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)));
using T = IEEE754binary32LE;
mpt::IO::SeekRelative(iStrm, std::min(bytecount, sizeof(T)));
// There is not much we can sanely do for truncated floats,
// thus we ignore what we just read and return 0.
// thus we ignore what we could read and return 0.
data = 0.0f;
}
template <>
inline void Binaryread<double>(std::istream& iStrm, double& data, const Offtype bytecount)
inline void Binaryread<double>(std::istream& iStrm, double& data, const std::size_t 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)));
using T = IEEE754binary64LE;
mpt::IO::SeekRelative(iStrm, std::min(bytecount, sizeof(T)));
// There is not much we can sanely do for truncated floats,
// thus we ignore what we just read and return 0.
// thus we ignore what we could read and return 0.
data = 0.0;
}
template <class T>
inline void ReadItem(std::istream& iStrm, T& data, const DataSize nSize)
inline void ReadItem(std::istream& iStrm, T& data, const std::size_t nSize)
{
static_assert(std::is_trivial<T>::value == true, "");
if (nSize == sizeof(T) || nSize == invalidDatasize)
@ -213,10 +246,10 @@ inline void ReadItem(std::istream& iStrm, T& data, const DataSize nSize)
Binaryread(iStrm, data, nSize);
}
void ReadItemString(std::istream& iStrm, std::string& str, const DataSize);
void ReadItemString(std::istream& iStrm, std::string& str, const std::size_t);
template <>
inline void ReadItem<std::string>(std::istream& iStrm, std::string& str, const DataSize nSize)
inline void ReadItem<std::string>(std::istream& iStrm, std::string& str, const std::size_t nSize)
{
ReadItemString(iStrm, str, nSize);
}
@ -228,23 +261,30 @@ class ID
private:
std::string m_ID; // NOTE: can contain null characters ('\0')
public:
ID() { }
ID() = default;
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) { }
ID(const char *id) : m_ID(id ? id : "") { }
ID(const char * str, std::size_t len) : m_ID(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))));
return ID(mpt::byte_cast<const char*>(mpt::as_raw_memory(valle).data()), mpt::as_raw_memory(valle).size());
}
#ifdef SSB_LOGGING
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(); }
#endif
std::size_t GetSize() const
{
return m_ID.size();
}
mpt::span<const char> AsSpan() const
{
return mpt::as_span(m_ID);
}
bool operator == (const ID &other) const { return m_ID == other.m_ID; }
bool operator != (const ID &other) const { return m_ID != other.m_ID; }
};
@ -260,30 +300,21 @@ protected:
public:
SsbStatus GetStatus() const
bool HasFailed() const
{
return m_Status;
return (m_Status.level >= StatusLevel::Failure);
}
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;
Status 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.
std::streamoff 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::size_t m_nCounter; // Read/write: Keeps count of entries written/read.
std::bitset<RwfNumFlags> m_Flags; // Read/write: Various flags.
@ -302,16 +333,7 @@ class SsbRead
public:
enum ReadRv // Read return value.
{
EntryRead,
EntryNotFound
};
enum IdMatchStatus
{
IdMatch, IdMismatch
};
typedef std::vector<ReadEntry>::const_iterator ReadIterator;
using ReadIterator = std::vector<ReadEntry>::const_iterator;
SsbRead(std::istream& iStrm);
@ -319,7 +341,7 @@ public:
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;}
std::size_t GetNumEntries() const {return m_nReadEntrycount;}
// Returns read iterator to the beginning of entries.
// The behaviour of read iterators is undefined if map doesn't
@ -330,23 +352,23 @@ public:
ReadIterator GetReadEnd();
// Compares given id with read entry id
IdMatchStatus CompareId(const ReadIterator& iter, const ID &id);
bool MatchesId(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>);}
bool 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);
bool 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>);}
bool 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);
bool ReadIterItem(const ReadIterator& iter, T& obj, FuncObj func);
private:
@ -358,12 +380,14 @@ private:
const ReadEntry* Find(const ID &id);
// Called after reading an object.
ReadRv OnReadEntry(const ReadEntry* pE, const ID &id, const Postype& posReadBegin);
void OnReadEntry(const ReadEntry* pE, const ID &id, const std::streamoff& posReadBegin);
void AddReadNote(const SsbStatus s);
void AddReadNote(const Status s);
#ifdef SSB_LOGGING
// Called after reading entry. pRe is a pointer to associated map entry if exists.
void AddReadNote(const ReadEntry* const pRe, const NumType nNum);
void LogReadEntry(const ReadEntry &pRe, const std::size_t nNum);
#endif
void ResetReadstatus();
@ -383,13 +407,13 @@ private:
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.
std::streamoff m_rposMapBegin; // Read: If map exists, rpos of map begin, else m_rposEndofHdrData.
std::streamoff m_posMapEnd; // Read: If map exists, map end position, else pos of end of hdrData.
std::streamoff m_posDataBegin; // Read: Data begin position.
std::streamoff m_rposEndofHdrData; // Read: rpos of end of header data.
std::size_t m_nReadEntrycount; // Read: Number of entries.
NumType m_nNextReadHint; // Read: Hint where to start looking for the next read entry.
std::size_t m_nNextReadHint; // Read: Hint where to start looking for the next read entry.
};
@ -420,30 +444,34 @@ public:
private:
// Called after writing an item.
void OnWroteItem(const ID &id, const Postype& posBeforeWrite);
void OnWroteItem(const ID &id, const std::streamoff& posBeforeWrite);
void AddWriteNote(const SsbStatus s);
void AddWriteNote(const ID &id,
const NumType nEntryNum,
const DataSize nBytecount,
const RposType rposStart);
void AddWriteNote(const Status s);
#ifdef SSB_LOGGING
void LogWriteEntry(const ID &id,
const std::size_t nEntryNum,
const std::size_t nBytecount,
const std::streamoff rposStart);
#endif
// Writes mapping item to mapstream.
void WriteMapItem(const ID &id,
const RposType& rposDataStart,
const DataSize& nDatasize,
const char* pszDesc);
const std::streamoff& rposDataStart,
const std::size_t& nDatasize,
const std::string &pszDesc);
void ResetWritestatus() {m_Status = SNT_NONE;}
void IncrementWriteCounter();
void ResetWritestatus()
{
m_Status = Status{};
}
private:
std::ostream& oStrm;
Postype m_posEntrycount; // Write: Pos of entrycount field.
Postype m_posMapPosField; // Write: Pos of map position field.
std::streamoff m_posEntrycount; // Write: Pos of entrycount field.
std::streamoff m_posMapPosField; // Write: Pos of map position field.
std::string m_MapStreamString; // Write: Map stream string.
};
@ -452,45 +480,53 @@ private:
template <class T, class FuncObj>
void SsbWrite::WriteItem(const T& obj, const ID &id, FuncObj Func)
{
const Postype pos = oStrm.tellp();
const std::streamoff pos = static_cast<std::streamoff>(oStrm.tellp());
Func(oStrm, obj);
OnWroteItem(id, pos);
}
template <class T, class FuncObj>
SsbRead::ReadRv SsbRead::ReadItem(T& obj, const ID &id, FuncObj Func)
bool 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)
const std::streamoff pos = static_cast<std::streamoff>(iStrm.tellg());
const bool entryFound = (pE || !m_Flags[RwfRMapHasId]);
if(entryFound)
{
Func(iStrm, obj, (pE) ? (pE->nSize) : invalidDatasize);
return OnReadEntry(pE, id, pos);
}
OnReadEntry(pE, id, pos);
return entryFound;
}
template <class T, class FuncObj>
SsbRead::ReadRv SsbRead::ReadIterItem(const ReadIterator& iter, T& obj, FuncObj func)
bool 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();
iStrm.seekg(m_posStart + iter->rposStart);
const std::streamoff pos = static_cast<std::streamoff>(iStrm.tellg());
func(iStrm, obj, iter->nSize);
return OnReadEntry(&(*iter), ID(&m_Idarray[iter->nIdpos], iter->nIdLength), pos);
OnReadEntry(&(*iter), ID(&m_Idarray[iter->nIdpos], iter->nIdLength), pos);
return true;
}
inline SsbRead::IdMatchStatus SsbRead::CompareId(const ReadIterator& iter, const ID &id)
inline bool SsbRead::MatchesId(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;
if(iter->nIdpos >= m_Idarray.size())
{
return false;
}
return (id == ID(&m_Idarray[iter->nIdpos], iter->nIdLength));
}
inline SsbRead::ReadIterator SsbRead::GetReadBegin()
{
MPT_ASSERT(GetFlag(RwfRMapHasId) && (GetFlag(RwfRMapHasStartpos) || GetFlag(RwfRMapHasSize) || m_nFixedEntrySize > 0));
if (GetFlag(RwfRMapCached) == false)
MPT_ASSERT(m_Flags[RwfRMapHasId] && (m_Flags[RwfRMapHasStartpos] || m_Flags[RwfRMapHasSize] || m_nFixedEntrySize > 0));
if(!m_Flags[RwfRMapCached])
CacheMap();
return mapData.begin();
}
@ -498,7 +534,7 @@ inline SsbRead::ReadIterator SsbRead::GetReadBegin()
inline SsbRead::ReadIterator SsbRead::GetReadEnd()
{
if (GetFlag(RwfRMapCached) == false)
if(!m_Flags[RwfRMapCached])
CacheMap();
return mapData.end();
}

View file

@ -17,6 +17,11 @@
#include "openmpt/all/BuildSettings.hpp"
#if defined(__MINGW32__) && !defined(__MINGW64__)
#include <sys/types.h>
#endif
#if defined(MODPLUG_TRACKER)
#if defined(MPT_WITH_MFC)
@ -33,10 +38,10 @@
#include <afxcview.h>
// cppcheck-suppress missingInclude
#include <afxdlgs.h>
#ifdef MPT_MFC_FULL
#ifndef _AFX_NO_MFC_CONTROLS_IN_DIALOGS
// cppcheck-suppress missingInclude
#include <afxlistctrl.h>
#endif // MPT_MFC_FULL
#endif // !_AFX_NO_MFC_CONTROLS_IN_DIALOGS
// cppcheck-suppress missingInclude
#include <afxole.h>
@ -60,6 +65,7 @@
#include "mpt/base/span.hpp"
#include "mpt/check/compiler.hpp"
#include "mpt/check/libc.hpp"
#if defined(MPT_WITH_MFC)
#include "mpt/check/mfc.hpp"
@ -67,8 +73,10 @@
#if MPT_OS_WINDOWS
#include "mpt/check/windows.hpp"
#endif
#include "mpt/exception_text/exception_text.hpp"
#include "mpt/exception/exception.hpp"
#include "mpt/exception/exception_text.hpp"
#include "mpt/out_of_memory/out_of_memory.hpp"
#include "mpt/string/types.hpp"
#include "mpt/system_error/system_error.hpp"
#include "openmpt/base/Types.hpp"

View file

@ -10,12 +10,20 @@
#include "stdafx.h"
#include "version.h"
#include "mpt/format/join.hpp"
#include "mpt/parse/parse.hpp"
#include "mpt/string/utility.hpp"
#include "mptString.h"
#include "mptStringFormat.h"
#include "mptStringParse.h"
#include "versionNumber.h"
#if __has_include("svn_version.h")
#include "svn_version.h"
#else
#include "../build/svn_version/svn_version.h"
#endif
@ -47,10 +55,10 @@ mpt::ustring Version::GetOpenMPTVersionString() const
Version Version::Parse(const mpt::ustring &s)
{
uint32 result = 0;
std::vector<mpt::ustring> numbers = mpt::String::Split<mpt::ustring>(s, U_("."));
std::vector<mpt::ustring> numbers = mpt::split(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);
result |= (mpt::parse_hex<unsigned int>(numbers[i]) & 0xff) << ((3 - i) * 8);
}
return Version(result);
}
@ -137,7 +145,7 @@ static int GetRevision()
{
svnversion = svnversion.substr(0, svnversion.find("P"));
}
return ConvertStrTo<int>(svnversion);
return mpt::parse<int>(svnversion);
#else
MPT_WARNING_STATEMENT("SVN revision unknown. Please check your build system.");
return 0;
@ -273,14 +281,14 @@ VersionWithRevision VersionWithRevision::Parse(const mpt::ustring &s)
{
Version version = Version::Parse(mpt::ustring());
uint64 revision = 0;
const auto tokens = mpt::String::Split<mpt::ustring>(s, U_("-"));
const auto tokens = mpt::split(s, U_("-"));
if(tokens.size() >= 1)
{
version = Version::Parse(tokens[0]);
}
if(tokens.size() >= 2)
{
revision = ConvertStrTo<uint64>(tokens[1].substr(1));
revision = mpt::parse<uint64>(tokens[1].substr(1));
}
return {version, revision};
}
@ -513,7 +521,7 @@ mpt::ustring GetVersionString(FlagSet<Build::Strings> strings)
{
result.push_back(GetBuildFeaturesString());
}
return mpt::trim(mpt::String::Combine<mpt::ustring>(result, U_("")));
return mpt::trim(mpt::join_format<mpt::ustring>(result, U_("")));
}
mpt::ustring GetVersionStringPure()
@ -770,10 +778,10 @@ mpt::ustring GetFullCreditsString()
"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"
"The people in the ModPlug community 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"
"33, 8bitbubsy, AliceLR, 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"

View file

@ -79,7 +79,7 @@ public:
return m_Version;
}
MPT_FORCEINLINE Version Masked(uint32 mask) const noexcept
MPT_CONSTEXPRINLINE Version Masked(uint32 mask) const noexcept
{
return Version(m_Version & mask);
}
@ -205,7 +205,7 @@ MPT_CONSTEXPRINLINE bool operator > (const Version &a, const Version &b) noexcep
}
MPT_CONSTEXPRINLINE Version operator "" _LiteralVersionImpl (const char * str, std::size_t len)
MPT_CONSTEVAL Version operator "" _LiteralVersionImpl (const char * str, std::size_t len)
{
return Version::LiteralParser::Parse(str, len);
}
@ -213,7 +213,7 @@ MPT_CONSTEXPRINLINE Version operator "" _LiteralVersionImpl (const char * str, s
// Create Version object from version string and check syntax, all at compile time.
// cppcheck false-positive
// cppcheck-suppress preprocessorErrorDirective
#define MPT_V(strver) MPT_FORCE_CONSTEXPR(Version{( strver ## _LiteralVersionImpl ).GetRawVersion()})
#define MPT_V(strver) MPT_FORCE_CONSTEVAL_VALUE(Version{( strver ## _LiteralVersionImpl ).GetRawVersion()})

View file

@ -16,8 +16,8 @@ OPENMPT_NAMESPACE_BEGIN
// Version definitions. The only thing that needs to be changed when changing version number.
#define VER_MAJORMAJOR 1
#define VER_MAJOR 30
#define VER_MINOR 10
#define VER_MAJOR 31
#define VER_MINOR 01
#define VER_MINORMINOR 00
OPENMPT_NAMESPACE_END

View file

@ -1,8 +1,11 @@
667="gf"
669="if"
669="JN"
amf="ASYLUM Music Format V1.0\x00"
amf="AMF\x0A"
amf="DMF\x0E"
ams="Extreme"
ams="AMShdr\x1A\x02\x02"
@ -34,6 +37,8 @@ dmf="SMPD"
dsm="RIFF"
dsm="DSMF"
dsm="DSm\x1A "
dsym="\x02\x01\x13\x13\x14\x12\x01\x0B\x01"
dtm="D.T."
@ -51,6 +56,26 @@ fmt="FMTracker\x01\x01"
gdm="GDM\xFE"
gdm="GMFS"
gtk="GTK\x04"
gt2="GT2\x05"
gt2="XCOM"
gt2="TCN1"
gt2="TCN2"
gt2="TVOL"
gt2="MIXP"
#gt2="SONG"
gt2="PATS"
gt2="PATD"
gt2="TNAM"
#gt2="INST"
#gt2="VENV"
gt2="TENV"
#gt2="PENV"
#gt2="SAMP"
gt2="SAM2"
gt2="ENDC"
imf="IM10"
imf="IS10"

View file

@ -25,6 +25,26 @@
static int16_t buffer[BUFFERSIZE];
static int ErrFunc (int error, void *)
{
switch (error)
{
case OPENMPT_ERROR_INVALID_ARGUMENT:
case OPENMPT_ERROR_OUT_OF_RANGE:
case OPENMPT_ERROR_LENGTH:
case OPENMPT_ERROR_DOMAIN:
case OPENMPT_ERROR_LOGIC:
case OPENMPT_ERROR_UNDERFLOW:
case OPENMPT_ERROR_OVERFLOW:
case OPENMPT_ERROR_RANGE:
case OPENMPT_ERROR_RUNTIME:
case OPENMPT_ERROR_EXCEPTION:
abort();
default:
return OPENMPT_ERROR_FUNC_RESULT_NONE;
}
}
int main( int argc, char * argv[] ) {
static FILE * file = NULL;
static openmpt_module * mod = NULL;
@ -35,11 +55,17 @@ int main( int argc, char * argv[] ) {
__AFL_INIT();
#endif
file = fopen( argv[1], "rb" );
mod = openmpt_module_create( openmpt_stream_get_file_callbacks(), file, NULL, NULL, NULL );
mod = openmpt_module_create2( openmpt_stream_get_file_callbacks(), file, NULL, NULL, ErrFunc, NULL, NULL, NULL, NULL );
fclose( file );
if ( mod == NULL ) return 1;
if ( mod == NULL )
return 1;
// verify API contract : If the file can be loaded, header probing must be successful too.
if ( openmpt_probe_file_header_from_stream( OPENMPT_PROBE_FILE_HEADER_FLAGS_DEFAULT, openmpt_stream_get_file_callbacks(), file, NULL, NULL, ErrFunc, NULL, NULL, NULL ) == OPENMPT_PROBE_FILE_HEADER_RESULT_FAILURE )
abort();
openmpt_module_ctl_set( mod, "render.resampler.emulate_amiga", (openmpt_module_get_num_orders( mod ) & 1) ? "0" : "1" );
/* render about a second of the module for fuzzing the actual mix routines */
// render about a second of the module for fuzzing the actual mix routines
for(; i < 50; i++) {
count = openmpt_module_read_mono( mod, SAMPLERATE, BUFFERSIZE, buffer );
if ( count == 0 ) {
@ -51,7 +77,7 @@ int main( int argc, char * argv[] ) {
openmpt_module_set_position_order_row( mod, 3, 16 );
openmpt_module_read_mono( mod, SAMPLERATE, BUFFERSIZE, buffer );
/* fuzz string-related stuff */
// fuzz string-related stuff
openmpt_free_string ( openmpt_module_get_metadata( mod, "date" ) );
openmpt_free_string ( openmpt_module_get_metadata( mod, "message" ) );
openmpt_module_destroy( mod );

View file

@ -13,7 +13,7 @@ Contents:
* `fuzz-secondary[1|2].sh`: Scripts to launch the secondary fuzzing process. It
is recommended to run at least two fuzzer instances, as the deterministic and
random fuzz mode have been found to complement each other really well. The two
scripts are set up to use different exploration strategies
scripts are set up to use different exploration strategies.
* `fuzz-settings.sh`: Set up your preferences and afl settings here before the
first run.
* `fuzz.c`: A tiny C program that is used by the fuzzer to test libopenmpt.
@ -45,7 +45,7 @@ How to use
* Run `fuzz-main.sh` for the first (deterministic) instance of afl-fuzz.
* For a "secondary" instance to run on another core, run `fuzz-secondary1.sh`
and/or `fuzz-secondary2.sh`.
* If you want to make use of even more cores, create more copies
* If you want to make use of even more cores, create more copies of
`fuzz-secondary2.sh` and adjust "infile03" / "fuzzer03" to
"infile04" / "fuzzer04" and so o (they need to be unique). Try variying the
"infile04" / "fuzzer04" and so on (they need to be unique). Try varying the
fuzzing strategey (the -p parameter) to get results more quickly.

View file

@ -7,18 +7,10 @@
* The OpenMPT source code is released under the BSD license. Read LICENSE for more details.
*/
#ifndef NO_LIBMODPLUG
#ifdef LIBOPENMPT_BUILD_DLL
#undef LIBOPENMPT_BUILD_DLL
#endif
#ifdef _MSC_VER
#ifndef _CRT_SECURE_NO_WARNINGS
#define _CRT_SECURE_NO_WARNINGS
#endif
#endif /* _MSC_VER */
#include <libopenmpt/libopenmpt.h>
#include <limits.h>
@ -29,19 +21,13 @@
#include <string.h>
#define MODPLUG_BUILD
#ifdef _MSC_VER
#ifdef MPT_BUILD_MSVC_SHARED
#define DLL_EXPORT
#endif /* MPT_BUILD_MSVC_SHARED */
#ifdef MPT_BUILD_MSVC_STATIC
#if defined(_WIN32) || defined(__CYGWIN__)
#define MODPLUG_STATIC
#endif /* MPT_BUILD_MSVC_STATIC */
#endif /* _MSC_VER */
#ifdef _MSC_VER
#define LIBOPENMPT_MODPLUG_API
#else /* !_MSC_VER */
#define LIBOPENMPT_MODPLUG_API LIBOPENMPT_API_HELPER_EXPORT
#endif /* _MSC_VER */
#endif /* _WIN32 || __CYGWIN__ */
#define LIBOPENMPT_MODPLUG_API LIBOPENMPT_API_HELPER_PUBLIC
#include "libmodplug/modplug.h"
/* from libmodplug/sndfile.h */
@ -600,5 +586,3 @@ LIBOPENMPT_MODPLUG_API char ModPlug_ExportIT(ModPlugFile* file, const char* file
fprintf(stderr,"libopenmpt-modplug: error: ModPlug_ExportIT(%s) not implemented.\n",filepath);
return 0;
}
#endif /* NO_LIBMODPLUG */

View file

@ -7,8 +7,6 @@
* The OpenMPT source code is released under the BSD license. Read LICENSE for more details.
*/
#ifndef NO_LIBMODPLUG
/*
***********************************************************************
@ -23,19 +21,6 @@ Metadata and other state is not provided or updated.
*/
#ifdef UNICODE
#undef UNICODE
#endif
#ifdef _UNICODE
#undef _UNICODE
#endif
#ifdef _MSC_VER
#ifndef _CRT_SECURE_NO_WARNINGS
#define _CRT_SECURE_NO_WARNINGS
#endif
#endif /* _MSC_VER */
#include <libopenmpt/libopenmpt.hpp>
#include <string>
@ -47,15 +32,13 @@ Metadata and other state is not provided or updated.
#include <cstring>
#define MODPLUG_BUILD
#ifdef _MSC_VER
/* libmodplug C++ header is broken for MSVC DLL builds */
#if defined(_WIN32) || defined(__CYGWIN__)
#define MODPLUG_STATIC
#endif /* _MSC_VER */
#ifdef _MSC_VER
#define LIBOPENMPT_MODPLUG_API
#else /* !_MSC_VER */
#define LIBOPENMPT_MODPLUG_API LIBOPENMPT_API_HELPER_EXPORT
#endif /* _MSC_VER */
#endif /* _WIN32 || __CYGWIN__ */
#define LIBOPENMPT_MODPLUG_API LIBOPENMPT_API_HELPER_PUBLIC
class LIBOPENMPT_MODPLUG_API CSoundFile;
#include "libmodplug/stdafx.h"
#include "libmodplug/sndfile.h"
@ -882,6 +865,3 @@ UINT CSoundFile::Normalize24BitBuffer(LPBYTE pbuffer, UINT cbsizebytes, DWORD lm
#elif defined(_MSC_VER)
#pragma warning(pop)
#endif
#endif // NO_LIBMODPLUG

View file

@ -7,18 +7,10 @@
* The OpenMPT source code is released under the BSD license. Read LICENSE for more details.
*/
#ifndef NO_LIBMODPLUG
#ifdef LIBOPENMPT_BUILD_DLL
#undef LIBOPENMPT_BUILD_DLL
#endif
#ifdef _MSC_VER
#ifndef _CRT_SECURE_NO_WARNINGS
#define _CRT_SECURE_NO_WARNINGS
#endif
#endif /* _MSC_VER */
#include <libopenmpt/libopenmpt.h>
#include <limits.h>
@ -29,19 +21,13 @@
#include <string.h>
#define MODPLUG_BUILD
#ifdef _MSC_VER
#ifdef MPT_BUILD_MSVC_SHARED
#define DLL_EXPORT
#endif /* MPT_BUILD_MSVC_SHARED */
#ifdef MPT_BUILD_MSVC_STATIC
#if defined(_WIN32) || defined(__CYGWIN__)
#define MODPLUG_STATIC
#endif /* MPT_BUILD_MSVC_STATIC */
#endif /* _MSC_VER */
#ifdef _MSC_VER
#define LIBOPENMPT_MODPLUG_API
#else /* !_MSC_VER */
#define LIBOPENMPT_MODPLUG_API LIBOPENMPT_API_HELPER_EXPORT
#endif /* _MSC_VER */
#endif /* _WIN32 || __CYGWIN__ */
#define LIBOPENMPT_MODPLUG_API LIBOPENMPT_API_HELPER_PUBLIC
#include "libmodplug/modplug.h"
/* from libmodplug/sndfile.h */
@ -600,5 +586,3 @@ LIBOPENMPT_MODPLUG_API char ModPlug_ExportIT(ModPlugFile* file, const char* file
fprintf(stderr,"libopenmpt-modplug: error: ModPlug_ExportIT(%s) not implemented.\n",filepath);
return 0;
}
#endif /* NO_LIBMODPLUG */

View file

@ -7,8 +7,6 @@
* The OpenMPT source code is released under the BSD license. Read LICENSE for more details.
*/
#ifndef NO_LIBMODPLUG
/*
***********************************************************************
@ -23,19 +21,6 @@ Metadata and other state is not provided or updated.
*/
#ifdef UNICODE
#undef UNICODE
#endif
#ifdef _UNICODE
#undef _UNICODE
#endif
#ifdef _MSC_VER
#ifndef _CRT_SECURE_NO_WARNINGS
#define _CRT_SECURE_NO_WARNINGS
#endif
#endif /* _MSC_VER */
#include <libopenmpt/libopenmpt.hpp>
#include <string>
@ -47,15 +32,13 @@ Metadata and other state is not provided or updated.
#include <cstring>
#define MODPLUG_BUILD
#ifdef _MSC_VER
/* libmodplug C++ header is broken for MSVC DLL builds */
#if defined(_WIN32) || defined(__CYGWIN__)
#define MODPLUG_STATIC
#endif /* _MSC_VER */
#ifdef _MSC_VER
#define LIBOPENMPT_MODPLUG_API
#else /* !_MSC_VER */
#define LIBOPENMPT_MODPLUG_API LIBOPENMPT_API_HELPER_EXPORT
#endif /* _MSC_VER */
#endif /* _WIN32 || __CYGWIN__ */
#define LIBOPENMPT_MODPLUG_API LIBOPENMPT_API_HELPER_PUBLIC
class LIBOPENMPT_MODPLUG_API CSoundFile;
#include "libmodplug/stdafx.h"
#include "libmodplug/sndfile.h"
@ -882,6 +865,3 @@ UINT CSoundFile::Normalize24BitBuffer(LPBYTE pbuffer, UINT cbsizebytes, DWORD lm
#elif defined(_MSC_VER)
#pragma warning(pop)
#endif
#endif // NO_LIBMODPLUG

View file

@ -0,0 +1,11 @@
#!/usr/bin/env bash
set -e
rm -rf premake.git
git clone --recursive https://github.com/premake/premake-core.git premake.git
cd premake.git
make -f Bootstrap.mak linux
echo | bin/release/premake5 package master source
echo "Done."

View file

@ -11,6 +11,21 @@
* Usage: libopenmpt_example_c SOMEMODULE
*/
#if defined( unix ) || defined( __unix__ ) || defined( __unix )
#include <unistd.h>
#if defined( _POSIX_VERSION )
#if ( _POSIX_VERSION > 0 )
#ifndef POSIX
#define POSIX
#endif
#endif
#endif
#endif
#if defined( __MINGW32__ ) && !defined( __MINGW64__ )
#include <sys/types.h>
#endif
#include <memory.h>
#include <stdint.h>
#include <stdio.h>
@ -18,9 +33,36 @@
#include <string.h>
#include <libopenmpt/libopenmpt.h>
#if OPENMPT_API_VERSION_AT_LEAST( 0, 7, 0 )
#if defined( LIBOPENMPT_STREAM_CALLBACKS_FILE_MINGW ) && defined( __MINGW32__ )
#include <libopenmpt/libopenmpt_stream_callbacks_file_mingw.h>
#elif defined( LIBOPENMPT_STREAM_CALLBACKS_FILE_MSVCRT ) && ( defined( _MSC_VER ) || ( defined( __clang__ ) && defined( _WIN32 ) ) )
#include <libopenmpt/libopenmpt_stream_callbacks_file_msvcrt.h>
#elif defined( LIBOPENMPT_STREAM_CALLBACKS_FILE_POSIX ) && defined( POSIX ) && defined( _POSIX_C_SOURCE )
#if ( _POSIX_C_SOURCE > 200112L )
#include <libopenmpt/libopenmpt_stream_callbacks_file_posix.h>
#else
#include <libopenmpt/libopenmpt_stream_callbacks_file.h>
#endif
#else
#include <libopenmpt/libopenmpt_stream_callbacks_file.h>
#endif
#else
#include <libopenmpt/libopenmpt_stream_callbacks_file.h>
#endif
#if defined( __GNUC__ ) && !defined( __clang__ ) && !defined( _MSC_VER )
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wstrict-prototypes"
#endif
#include <portaudio.h>
#if defined( __GNUC__ ) && !defined( __clang__ ) && !defined( _MSC_VER )
#pragma GCC diagnostic pop
#endif
#if defined( __DJGPP__ )
#include <crt0.h>
#endif /* __DJGPP__ */
#define BUFFERSIZE 480
#define SAMPLERATE 48000
@ -72,6 +114,15 @@ static void libopenmpt_example_print_error( const char * func_name, int mod_err,
}
}
#if defined( __DJGPP__ )
/* clang-format off */
int _crt0_startup_flags = 0
| _CRT0_FLAG_NONMOVE_SBRK /* force interrupt compatible allocation */
| _CRT0_DISABLE_SBRK_ADDRESS_WRAP /* force NT compatible allocation */
| _CRT0_FLAG_LOCK_MEMORY /* lock all code and data at program startup */
| 0;
/* clang-format on */
#endif /* __DJGPP__ */
#if ( defined( _WIN32 ) || defined( WIN32 ) ) && ( defined( _UNICODE ) || defined( UNICODE ) )
#if defined( __clang__ ) && !defined( _MSC_VER )
int wmain( int argc, wchar_t * argv[] );
@ -80,6 +131,11 @@ int wmain( int argc, wchar_t * argv[] ) {
#else
int main( int argc, char * argv[] ) {
#endif
#if defined( __DJGPP__ )
/* clang-format off */
_crt0_startup_flags &= ~_CRT0_FLAG_LOCK_MEMORY; /* disable automatic locking for all further memory allocations */
/* clang-format on */
#endif /* __DJGPP__ */
int result = 0;
FILE * file = 0;
@ -114,7 +170,24 @@ int main( int argc, char * argv[] ) {
goto fail;
}
#if OPENMPT_API_VERSION_AT_LEAST( 0, 7, 0 )
#if defined( LIBOPENMPT_STREAM_CALLBACKS_FILE_MINGW ) && defined( __MINGW32__ )
mod = openmpt_module_create2( openmpt_stream_get_file_mingw_callbacks(), file, &libopenmpt_example_logfunc, NULL, &libopenmpt_example_errfunc, NULL, &mod_err, &mod_err_str, NULL );
#elif defined( LIBOPENMPT_STREAM_CALLBACKS_FILE_MSVCRT ) && ( defined( _MSC_VER ) || ( defined( __clang__ ) && defined( _WIN32 ) ) )
mod = openmpt_module_create2( openmpt_stream_get_file_msvcrt_callbacks(), file, &libopenmpt_example_logfunc, NULL, &libopenmpt_example_errfunc, NULL, &mod_err, &mod_err_str, NULL );
#elif defined( LIBOPENMPT_STREAM_CALLBACKS_FILE_POSIX ) && defined( POSIX ) && defined( _POSIX_C_SOURCE )
#if ( _POSIX_C_SOURCE > 200112L )
mod = openmpt_module_create2( openmpt_stream_get_file_posix_callbacks(), file, &libopenmpt_example_logfunc, NULL, &libopenmpt_example_errfunc, NULL, &mod_err, &mod_err_str, NULL );
#else
mod = openmpt_module_create2( openmpt_stream_get_file_callbacks2(), file, &libopenmpt_example_logfunc, NULL, &libopenmpt_example_errfunc, NULL, &mod_err, &mod_err_str, NULL );
#endif
#else
mod = openmpt_module_create2( openmpt_stream_get_file_callbacks2(), file, &libopenmpt_example_logfunc, NULL, &libopenmpt_example_errfunc, NULL, &mod_err, &mod_err_str, NULL );
#endif
#else
mod = openmpt_module_create2( openmpt_stream_get_file_callbacks(), file, &libopenmpt_example_logfunc, NULL, &libopenmpt_example_errfunc, NULL, &mod_err, &mod_err_str, NULL );
#endif
if ( !mod ) {
libopenmpt_example_print_error( "openmpt_module_create2()", mod_err, mod_err_str );
openmpt_free_string( mod_err_str );

View file

@ -11,6 +11,10 @@
* Usage: libopenmpt_example_c_mem SOMEMODULE
*/
#if defined( __MINGW32__ ) && !defined( __MINGW64__ )
#include <sys/types.h>
#endif
#include <memory.h>
#include <stdint.h>
#include <stdio.h>
@ -19,7 +23,18 @@
#include <libopenmpt/libopenmpt.h>
#if defined( __GNUC__ ) && !defined( __clang__ ) && !defined( _MSC_VER )
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wstrict-prototypes"
#endif
#include <portaudio.h>
#if defined( __GNUC__ ) && !defined( __clang__ ) && !defined( _MSC_VER )
#pragma GCC diagnostic pop
#endif
#if defined( __DJGPP__ )
#include <crt0.h>
#endif /* __DJGPP__ */
#define BUFFERSIZE 480
#define SAMPLERATE 48000
@ -163,6 +178,15 @@ cleanup:
return result;
}
#if defined( __DJGPP__ )
/* clang-format off */
int _crt0_startup_flags = 0
| _CRT0_FLAG_NONMOVE_SBRK /* force interrupt compatible allocation */
| _CRT0_DISABLE_SBRK_ADDRESS_WRAP /* force NT compatible allocation */
| _CRT0_FLAG_LOCK_MEMORY /* lock all code and data at program startup */
| 0;
/* clang-format on */
#endif /* __DJGPP__ */
#if ( defined( _WIN32 ) || defined( WIN32 ) ) && ( defined( _UNICODE ) || defined( UNICODE ) )
#if defined( __clang__ ) && !defined( _MSC_VER )
int wmain( int argc, wchar_t * argv[] );
@ -171,6 +195,11 @@ int wmain( int argc, wchar_t * argv[] ) {
#else
int main( int argc, char * argv[] ) {
#endif
#if defined( __DJGPP__ )
/* clang-format off */
_crt0_startup_flags &= ~_CRT0_FLAG_LOCK_MEMORY; /* disable automatic locking for all further memory allocations */
/* clang-format on */
#endif /* __DJGPP__ */
int result = 0;
blob_t * blob = 0;

View file

@ -22,6 +22,10 @@
#include <libopenmpt/libopenmpt.h>
#include <libopenmpt/libopenmpt_stream_callbacks_fd.h>
#if defined( __DJGPP__ )
#include <crt0.h>
#endif /* __DJGPP__ */
#define BUFFERSIZE 480
#define SAMPLERATE 48000
@ -84,6 +88,15 @@ static ssize_t xwrite( int fd, const void * buffer, size_t size ) {
static int16_t buffer[BUFFERSIZE * 2];
#if defined( __DJGPP__ )
/* clang-format off */
int _crt0_startup_flags = 0
| _CRT0_FLAG_NONMOVE_SBRK /* force interrupt compatible allocation */
| _CRT0_DISABLE_SBRK_ADDRESS_WRAP /* force NT compatible allocation */
| _CRT0_FLAG_LOCK_MEMORY /* lock all code and data at program startup */
| 0;
/* clang-format on */
#endif /* __DJGPP__ */
#if ( defined( _WIN32 ) || defined( WIN32 ) ) && ( defined( _UNICODE ) || defined( UNICODE ) )
#if defined( __clang__ ) && !defined( _MSC_VER )
int wmain( int argc, wchar_t * argv[] );
@ -92,6 +105,11 @@ int wmain( int argc, wchar_t * argv[] ) {
#else
int main( int argc, char * argv[] ) {
#endif
#if defined( __DJGPP__ )
/* clang-format off */
_crt0_startup_flags &= ~_CRT0_FLAG_LOCK_MEMORY; /* disable automatic locking for all further memory allocations */
/* clang-format on */
#endif /* __DJGPP__ */
int result = 0;
openmpt_module * mod = 0;

View file

@ -19,6 +19,10 @@
#define LIBOPENMPT_EXAMPLE_PROBE_RESULT LIBOPENMPT_EXAMPLE_PROBE_RESULT_BINARY
#if defined( __MINGW32__ ) && !defined( __MINGW64__ )
#include <sys/types.h>
#endif
#include <memory.h>
#include <stdint.h>
#include <stdio.h>
@ -28,6 +32,10 @@
#include <libopenmpt/libopenmpt.h>
#include <libopenmpt/libopenmpt_stream_callbacks_file.h>
#if defined( __DJGPP__ )
#include <crt0.h>
#endif /* __DJGPP__ */
static void libopenmpt_example_logfunc( const char * message, void * userdata ) {
(void)userdata;
@ -78,7 +86,7 @@ static int probe_file( const char * filename ) {
}
#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 = openmpt_probe_file_header_from_stream( OPENMPT_PROBE_FILE_HEADER_FLAGS_DEFAULT, openmpt_stream_get_file_callbacks2(), file, &libopenmpt_example_logfunc, NULL, &openmpt_error_func_default, NULL, &mod_err, NULL );
probe_file_header_result_str = NULL;
switch ( probe_file_header_result ) {
case OPENMPT_PROBE_FILE_HEADER_RESULT_SUCCESS:
@ -117,7 +125,7 @@ static int probe_file( const char * filename ) {
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 );
probability = openmpt_could_open_probability2( openmpt_stream_get_file_callbacks2(), 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
@ -148,6 +156,15 @@ cleanup:
return result;
}
#if defined( __DJGPP__ )
/* clang-format off */
int _crt0_startup_flags = 0
| _CRT0_FLAG_NONMOVE_SBRK /* force interrupt compatible allocation */
| _CRT0_DISABLE_SBRK_ADDRESS_WRAP /* force NT compatible allocation */
| _CRT0_FLAG_LOCK_MEMORY /* lock all code and data at program startup */
| 0;
/* clang-format on */
#endif /* __DJGPP__ */
#if ( defined( _WIN32 ) || defined( WIN32 ) ) && ( defined( _UNICODE ) || defined( UNICODE ) )
#if defined( __clang__ ) && !defined( _MSC_VER )
int wmain( int argc, wchar_t * argv[] );
@ -156,6 +173,11 @@ int wmain( int argc, wchar_t * argv[] ) {
#else
int main( int argc, char * argv[] ) {
#endif
#if defined( __DJGPP__ )
/* clang-format off */
_crt0_startup_flags &= ~_CRT0_FLAG_LOCK_MEMORY; /* disable automatic locking for all further memory allocations */
/* clang-format on */
#endif /* __DJGPP__ */
int global_result = 0;

View file

@ -11,6 +11,10 @@
* Usage: libopenmpt_example_c_stdout SOMEMODULE | aplay --file-type raw --format=dat
*/
#if defined( __MINGW32__ ) && !defined( __MINGW64__ )
#include <sys/types.h>
#endif
#include <memory.h>
#include <stdint.h>
#include <stdio.h>
@ -23,6 +27,10 @@
#include <libopenmpt/libopenmpt.h>
#include <libopenmpt/libopenmpt_stream_callbacks_file.h>
#if defined( __DJGPP__ )
#include <crt0.h>
#endif /* __DJGPP__ */
#define BUFFERSIZE 480
#define SAMPLERATE 48000
@ -85,6 +93,15 @@ static ssize_t xwrite( int fd, const void * buffer, size_t size ) {
static int16_t buffer[BUFFERSIZE * 2];
#if defined( __DJGPP__ )
/* clang-format off */
int _crt0_startup_flags = 0
| _CRT0_FLAG_NONMOVE_SBRK /* force interrupt compatible allocation */
| _CRT0_DISABLE_SBRK_ADDRESS_WRAP /* force NT compatible allocation */
| _CRT0_FLAG_LOCK_MEMORY /* lock all code and data at program startup */
| 0;
/* clang-format on */
#endif /* __DJGPP__ */
#if ( defined( _WIN32 ) || defined( WIN32 ) ) && ( defined( _UNICODE ) || defined( UNICODE ) )
#if defined( __clang__ ) && !defined( _MSC_VER )
int wmain( int argc, wchar_t * argv[] );
@ -93,6 +110,11 @@ int wmain( int argc, wchar_t * argv[] ) {
#else
int main( int argc, char * argv[] ) {
#endif
#if defined( __DJGPP__ )
/* clang-format off */
_crt0_startup_flags &= ~_CRT0_FLAG_LOCK_MEMORY; /* disable automatic locking for all further memory allocations */
/* clang-format on */
#endif /* __DJGPP__ */
int result = 0;
FILE * file = 0;
@ -125,7 +147,7 @@ int main( int argc, char * argv[] ) {
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 );
mod = openmpt_module_create2( openmpt_stream_get_file_callbacks2(), 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 );

View file

@ -12,6 +12,10 @@
* CAUTION: This simple example does no error cheking at all.
*/
#if defined( __MINGW32__ ) && !defined( __MINGW64__ )
#include <sys/types.h>
#endif
#include <memory.h>
#include <stdint.h>
#include <stdio.h>
@ -21,7 +25,18 @@
#include <libopenmpt/libopenmpt.h>
#include <libopenmpt/libopenmpt_stream_callbacks_file.h>
#if defined( __GNUC__ ) && !defined( __clang__ ) && !defined( _MSC_VER )
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wstrict-prototypes"
#endif
#include <portaudio.h>
#if defined( __GNUC__ ) && !defined( __clang__ ) && !defined( _MSC_VER )
#pragma GCC diagnostic pop
#endif
#if defined( __DJGPP__ )
#include <crt0.h>
#endif /* __DJGPP__ */
#define BUFFERSIZE 480
#define SAMPLERATE 48000
@ -30,6 +45,15 @@ static int16_t left[BUFFERSIZE];
static int16_t right[BUFFERSIZE];
static int16_t * const buffers[2] = { left, right };
#if defined( __DJGPP__ )
/* clang-format off */
int _crt0_startup_flags = 0
| _CRT0_FLAG_NONMOVE_SBRK /* force interrupt compatible allocation */
| _CRT0_DISABLE_SBRK_ADDRESS_WRAP /* force NT compatible allocation */
| _CRT0_FLAG_LOCK_MEMORY /* lock all code and data at program startup */
| 0;
/* clang-format on */
#endif /* __DJGPP__ */
#if ( defined( _WIN32 ) || defined( WIN32 ) ) && ( defined( _UNICODE ) || defined( UNICODE ) )
#if defined( __clang__ ) && !defined( _MSC_VER )
int wmain( int argc, wchar_t * argv[] );
@ -38,6 +62,11 @@ int wmain( int argc, wchar_t * argv[] ) {
#else
int main( int argc, char * argv[] ) {
#endif
#if defined( __DJGPP__ )
/* clang-format off */
_crt0_startup_flags &= ~_CRT0_FLAG_LOCK_MEMORY; /* disable automatic locking for all further memory allocations */
/* clang-format on */
#endif /* __DJGPP__ */
FILE * file = 0;
openmpt_module * mod = 0;
size_t count = 0;
@ -48,7 +77,7 @@ int main( int argc, char * argv[] ) {
#else
file = fopen( argv[1], "rb" );
#endif
mod = openmpt_module_create2( openmpt_stream_get_file_callbacks(), file, NULL, NULL, NULL, NULL, NULL, NULL, NULL );
mod = openmpt_module_create2( openmpt_stream_get_file_callbacks2(), file, NULL, NULL, NULL, NULL, NULL, NULL, NULL );
fclose( file );
Pa_Initialize();
Pa_OpenDefaultStream( &stream, 0, 2, paInt16 | paNonInterleaved, SAMPLERATE, paFramesPerBufferUnspecified, NULL, NULL );

View file

@ -11,6 +11,10 @@
* Usage: libopenmpt_example_cxx SOMEMODULE
*/
#if defined( __MINGW32__ ) && !defined( __MINGW64__ )
#include <sys/types.h>
#endif
#include <exception>
#include <fstream>
#include <iostream>
@ -33,6 +37,19 @@
#endif
#endif
#if defined( __DJGPP__ )
#include <crt0.h>
#endif /* __DJGPP__ */
#if defined( __DJGPP__ )
/* clang-format off */
extern "C" int _crt0_startup_flags = 0
| _CRT0_FLAG_NONMOVE_SBRK /* force interrupt compatible allocation */
| _CRT0_DISABLE_SBRK_ADDRESS_WRAP /* force NT compatible allocation */
| _CRT0_FLAG_LOCK_MEMORY /* lock all code and data at program startup */
| 0;
/* clang-format on */
#endif /* __DJGPP__ */
#if ( defined( _WIN32 ) || defined( WIN32 ) ) && ( defined( _UNICODE ) || defined( UNICODE ) )
#if defined( __GNUC__ ) || ( defined( __clang__ ) && !defined( _MSC_VER ) )
// 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/>).
@ -44,6 +61,11 @@ int wmain( int argc, wchar_t * argv[] ) {
#else
int main( int argc, char * argv[] ) {
#endif
#if defined( __DJGPP__ )
/* clang-format off */
_crt0_startup_flags &= ~_CRT0_FLAG_LOCK_MEMORY; /* disable automatic locking for all further memory allocations */
/* clang-format on */
#endif /* __DJGPP__ */
try {
if ( argc != 2 ) {
throw std::runtime_error( "Usage: libopenmpt_example_cxx SOMEMODULE" );

View file

@ -2,3 +2,5 @@ minimp3 library from https://github.com/lieff/minimp3
commit 50d2aaf360a53653b718fead8e258d654c3a7e41 (2021-11-27)
The following changes have been made:
* minimp3.c has been added
* some warnings have been fixed
* all modifications are marked by /* OpenMPT */

View file

@ -176,7 +176,11 @@ end:
#define VMUL_S(x, s) vmulq_f32(x, vmovq_n_f32(s))
#define VREV(x) vcombine_f32(vget_high_f32(vrev64q_f32(x)), vget_low_f32(vrev64q_f32(x)))
typedef float32x4_t f4;
#if 1 /* OpenMPT */
static int have_simd(void)
#else /* OpenMPT */
static int have_simd()
#endif /* OpenMPT */
{ /* TODO: detect neon for !MINIMP3_ONLY_SIMD */
return 1;
}

View file

@ -1,4 +1,4 @@
# Doxyfile 1.9.1
# Doxyfile 1.9.4
# This file describes the settings to be used by the documentation system
# doxygen (www.doxygen.org) for a project.
@ -12,6 +12,15 @@
# For lists, items can also be appended using:
# TAG += value [value, ...]
# Values that contain spaces should be placed between quotes (\" \").
#
# Note:
#
# Use doxygen to compare the used configuration file with the template
# configuration file:
# doxygen -x [configFile]
# Use doxygen to compare the used configuration file with the template
# configuration file without replacing the environment variables:
# doxygen -x_noenv [configFile]
#---------------------------------------------------------------------------
# Project related configuration options
@ -60,16 +69,28 @@ PROJECT_LOGO =
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
# If the CREATE_SUBDIRS tag is set to YES then doxygen will create up to 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.
# performance problems for the file system. Adapt CREATE_SUBDIRS_LEVEL to
# control the number of sub-directories.
# The default value is: NO.
CREATE_SUBDIRS = NO
# Controls the number of sub-directories that will be created when
# CREATE_SUBDIRS tag is set to YES. Level 0 represents 16 directories, and every
# level increment doubles the number of directories, resulting in 4096
# directories at level 8 which is the default and also the maximum value. The
# sub-directories are organized in 2 levels, the first level always has a fixed
# numer of 16 directories.
# Minimum value: 0, maximum value: 8, default value: 8.
# This tag requires that the tag CREATE_SUBDIRS is set to YES.
CREATE_SUBDIRS_LEVEL = 8
# 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
@ -81,26 +102,18 @@ 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.
# Possible values are: Afrikaans, Arabic, Armenian, Brazilian, Bulgarian,
# Catalan, Chinese, Chinese-Traditional, Croatian, Czech, Danish, Dutch, English
# (United States), Esperanto, Farsi (Persian), Finnish, French, German, Greek,
# Hindi, 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
# The OUTPUT_TEXT_DIRECTION tag is used to specify the direction in which all
# documentation generated by doxygen is written. Doxygen will use this
# information to generate all generated output in the proper direction.
# Possible values are: None, LTR, RTL and Context.
# The default value is: None.
OUTPUT_TEXT_DIRECTION = None
# 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.
@ -248,16 +261,16 @@ TAB_SIZE = 2
# the documentation. An alias has the form:
# name=value
# For example adding
# "sideeffect=@par Side Effects:\n"
# "sideeffect=@par Side Effects:^^"
# 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 (in the resulting output). You can put ^^ in the value part of an
# alias to insert a newline as if a physical newline was in the original file.
# When you need a literal { or } or , in the value part of an alias you have to
# escape them by means of a backslash (\), this can lead to conflicts with the
# commands \{ and \} for these it is advised to use the version @{ and @} or use
# a double escape (\\{ and \\})
# "Side Effects:". Note that you cannot put \n's in the value part of an alias
# to insert newlines (in the resulting output). You can put ^^ in the value part
# of an alias to insert a newline as if a physical newline was in the original
# file. When you need a literal { or } or , in the value part of an alias you
# have to escape them by means of a backslash (\), this can lead to conflicts
# with the commands \{ and \} for these it is advised to use the version @{ and
# @} or use a double escape (\\{ and \\})
ALIASES =
@ -302,8 +315,8 @@ OPTIMIZE_OUTPUT_SLICE = NO
# 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,
# Csharp (C#), C, C++, D, PHP, md (Markdown), Objective-C, Python, Slice, VHDL,
# Fortran (fixed format Fortran: FortranFixed, free formatted Fortran:
# Csharp (C#), C, C++, Lex, D, PHP, md (Markdown), Objective-C, Python, Slice,
# VHDL, 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). For instance to make doxygen treat .inc files
@ -450,13 +463,13 @@ TYPEDEF_HIDES_STRUCT = NO
LOOKUP_CACHE_SIZE = 0
# The NUM_PROC_THREADS specifies the number threads doxygen is allowed to use
# The NUM_PROC_THREADS specifies the number of threads doxygen is allowed to use
# during processing. When set to 0 doxygen will based this on the number of
# cores available in the system. You can set it explicitly to a value larger
# than 0 to get more control over the balance between CPU load and processing
# speed. At this moment only the input processing can be done using multiple
# threads. Since this is still an experimental feature the default is set to 1,
# which efficively disables parallel processing. Please report any issues you
# which effectively disables parallel processing. Please report any issues you
# encounter. Generating dot graphs in parallel is controlled by the
# DOT_NUM_THREADS setting.
# Minimum value: 0, maximum value: 32, default value: 1.
@ -575,7 +588,7 @@ INTERNAL_DOCS = NO
# filesystem is case sensitive (i.e. it supports files in the same directory
# whose names only differ in casing), the option must be set to YES to properly
# deal with such files in case they appear in the input. For filesystems that
# are not case sensitive the option should be be set to NO to properly deal with
# are not case sensitive the option should be set to NO to properly deal with
# output files written for symbols that only differ in casing, such as for two
# classes, one named CLASS and the other named Class, and to also support
# references to files without having to specify the exact matching casing. On
@ -600,6 +613,12 @@ HIDE_SCOPE_NAMES = NO
HIDE_COMPOUND_REFERENCE= NO
# If the SHOW_HEADERFILE tag is set to YES then the documentation for a class
# will show which file needs to be included to use the class.
# The default value is: YES.
SHOW_HEADERFILE = YES
# 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.
@ -757,7 +776,8 @@ FILE_VERSION_FILTER =
# 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.
# will be used as the name of the layout file. See also section "Changing the
# layout of pages" for information.
#
# 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
@ -803,18 +823,26 @@ WARNINGS = 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.
# potential errors in the documentation, such as documenting some parameters in
# a documented function twice, or documenting parameters that don't exist or
# using markup commands wrongly.
# The default value is: YES.
WARN_IF_DOC_ERROR = YES
# If WARN_IF_INCOMPLETE_DOC is set to YES, doxygen will warn about incomplete
# function parameter documentation. If set to NO, doxygen will accept that some
# parameters have no documentation without warning.
# The default value is: YES.
WARN_IF_INCOMPLETE_DOC = 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. If
# EXTRACT_ALL is set to YES then this flag will automatically be disabled.
# value. If set to NO, doxygen will only warn about wrong parameter
# documentation, but not about the absence of documentation. If EXTRACT_ALL is
# set to YES then this flag will automatically be disabled. See also
# WARN_IF_INCOMPLETE_DOC
# The default value is: NO.
WARN_NO_PARAMDOC = NO
@ -834,13 +862,27 @@ WARN_AS_ERROR = NO
# 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)
# See also: WARN_LINE_FORMAT
# The default value is: $file:$line: $text.
WARN_FORMAT = "$file:$line: $text"
# In the $text part of the WARN_FORMAT command it is possible that a reference
# to a more specific place is given. To make it easier to jump to this place
# (outside of doxygen) the user can define a custom "cut" / "paste" string.
# Example:
# WARN_LINE_FORMAT = "'vi $file +$line'"
# See also: WARN_FORMAT
# The default value is: at line $line of file $file.
WARN_LINE_FORMAT = "at line $line of file $file"
# 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).
# error (stderr). In case the file specified cannot be opened for writing the
# warning and error messages are written to standard error. When as file - is
# specified the warning and error messages are written to standard output
# (stdout).
WARN_LOGFILE =
@ -854,22 +896,26 @@ WARN_LOGFILE =
# spaces. See also FILE_PATTERNS and EXTENSION_MAPPING
# Note: If this tag is empty the current directory is searched.
INPUT = libopenmpt/dox/index.dox \
INPUT = doc/libopenmpt/index.dox \
README.md \
libopenmpt/dox/dependencies.md \
libopenmpt/dox/gettingstarted.md \
libopenmpt/dox/packaging.md \
doc/libopenmpt/dependencies.md \
doc/libopenmpt/gettingstarted.md \
doc/libopenmpt/packaging.md \
doc/contributing.md \
doc/libopenmpt_styleguide.md \
doc/openmpt_styleguide.md \
libopenmpt/dox/tests.md \
libopenmpt/dox/changelog.md \
doc/libopenmpt/tests.md \
doc/libopenmpt/changelog.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_stream_callbacks_file_mingw.h \
libopenmpt/libopenmpt_stream_callbacks_file_msvcrt.h \
libopenmpt/libopenmpt_stream_callbacks_file_posix.h \
libopenmpt/libopenmpt_stream_callbacks_file_posix_lfs64.h \
libopenmpt/libopenmpt_config.h \
libopenmpt/libopenmpt_version.h \
libopenmpt/libopenmpt_ext.hpp \
@ -897,10 +943,10 @@ INPUT_ENCODING = UTF-8
#
# 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 (to be provided as doxygen C comment),
# *.py, *.pyw, *.f90, *.f95, *.f03, *.f08, *.f18, *.f, *.for, *.vhd, *.vhdl,
# *.ucf, *.qsf and *.ice.
# *.hh, *.hxx, *.hpp, *.h++, *.l, *.cs, *.d, *.php, *.php4, *.php5, *.phtml,
# *.inc, *.m, *.markdown, *.md, *.mm, *.dox (to be provided as doxygen C
# comment), *.py, *.pyw, *.f90, *.f95, *.f03, *.f08, *.f18, *.f, *.for, *.vhd,
# *.vhdl, *.ucf, *.qsf and *.ice.
FILE_PATTERNS =
@ -939,7 +985,7 @@ EXCLUDE_PATTERNS =
# (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
# ANamespace::AClass, ANamespace::*Test
#
# Note that the wildcards are matched against the file with absolute path, so to
# exclude all test directories use the pattern */test/*
@ -1134,9 +1180,11 @@ VERBATIM_HEADERS = YES
CLANG_ASSISTED_PARSING = NO
# If clang assisted parsing is enabled and the CLANG_ADD_INC_PATHS tag is set to
# YES then doxygen will add the directory of each input to the include path.
# If the CLANG_ASSISTED_PARSING tag is set to YES and the CLANG_ADD_INC_PATHS
# tag is set to YES then doxygen will add the directory of each input to the
# include path.
# The default value is: YES.
# This tag requires that the tag CLANG_ASSISTED_PARSING is set to YES.
CLANG_ADD_INC_PATHS = YES
@ -1271,7 +1319,7 @@ 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
# this color. Hue is specified as an angle on a color-wheel, see
# https://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.
@ -1281,7 +1329,7 @@ HTML_EXTRA_FILES =
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
# in the HTML output. For a value of 0 the output will use gray-scales 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.
@ -1363,6 +1411,13 @@ GENERATE_DOCSET = NO
DOCSET_FEEDNAME = "Doxygen generated docs"
# This tag determines the URL 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.
# This tag requires that the tag GENERATE_DOCSET is set to YES.
DOCSET_FEEDURL =
# 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.
@ -1388,8 +1443,12 @@ 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:
# https://www.microsoft.com/en-us/download/details.aspx?id=21138) on Windows.
# on Windows. In the beginning of 2021 Microsoft took the original page, with
# a.o. the download links, offline the HTML help workshop was already many years
# in maintenance mode). You can download the HTML help workshop from the web
# archives at Installation executable (see:
# http://web.archive.org/web/20160201063255/http://download.microsoft.com/downlo
# ad/0/A/9/0A939EF6-E31C-430F-A3DF-DFAE7960D564/htmlhelp.exe).
#
# 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
@ -1548,16 +1607,28 @@ DISABLE_INDEX = NO
# 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.
# further fine tune the look of the index (see "Fine-tuning the output"). 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
# When both GENERATE_TREEVIEW and DISABLE_INDEX are set to YES, then the
# FULL_SIDEBAR option determines if the side bar is limited to only the treeview
# area (value NO) or if it should extend to the full height of the window (value
# YES). Setting this to YES gives a layout similar to
# https://docs.readthedocs.io with more room for contents, but less room for the
# project logo, title, and description. If either GENERATE_TREEVIEW or
# DISABLE_INDEX is set to NO, this option has no effect.
# The default value is: NO.
# This tag requires that the tag GENERATE_HTML is set to YES.
FULL_SIDEBAR = NO
# 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.
#
@ -1582,6 +1653,13 @@ TREEVIEW_WIDTH = 250
EXT_LINKS_IN_WINDOW = NO
# If the OBFUSCATE_EMAILS tag is set to YES, doxygen will obfuscate email
# addresses.
# The default value is: YES.
# This tag requires that the tag GENERATE_HTML is set to YES.
OBFUSCATE_EMAILS = YES
# If the HTML_FORMULA_FORMAT option is set to svg, doxygen will use the pdf2svg
# tool (see https://github.com/dawbarton/pdf2svg) or inkscape (see
# https://inkscape.org) to generate formulas as SVG images instead of PNGs for
@ -1630,11 +1708,29 @@ FORMULA_MACROFILE =
USE_MATHJAX = NO
# With MATHJAX_VERSION it is possible to specify the MathJax version to be used.
# Note that the different versions of MathJax have different requirements with
# regards to the different settings, so it is possible that also other MathJax
# settings have to be changed when switching between the different MathJax
# versions.
# Possible values are: MathJax_2 and MathJax_3.
# The default value is: MathJax_2.
# This tag requires that the tag USE_MATHJAX is set to YES.
MATHJAX_VERSION = MathJax_2
# 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/v2.7-latest/output.html) for more details.
# the MathJax output. For more details about the output format see MathJax
# version 2 (see:
# http://docs.mathjax.org/en/v2.7-latest/output.html) and MathJax version 3
# (see:
# http://docs.mathjax.org/en/latest/web/components/output.html).
# Possible values are: HTML-CSS (which is slower, but has the best
# compatibility), NativeMML (i.e. MathML) and SVG.
# compatibility. This is the name for Mathjax version 2, for MathJax version 3
# this will be translated into chtml), NativeMML (i.e. MathML. Only supported
# for NathJax 2. For MathJax version 3 chtml will be used instead.), chtml (This
# is the name for Mathjax version 3, for MathJax version 2 this will be
# translated into HTML-CSS) and SVG.
# The default value is: HTML-CSS.
# This tag requires that the tag USE_MATHJAX is set to YES.
@ -1647,15 +1743,21 @@ MATHJAX_FORMAT = HTML-CSS
# 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 https://www.mathjax.org before deployment.
# The default value is: https://cdn.jsdelivr.net/npm/mathjax@2.
# MathJax from https://www.mathjax.org before deployment. The default value is:
# - in case of MathJax version 2: https://cdn.jsdelivr.net/npm/mathjax@2
# - in case of MathJax version 3: https://cdn.jsdelivr.net/npm/mathjax@3
# 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
# for MathJax version 2 (see
# https://docs.mathjax.org/en/v2.7-latest/tex.html#tex-and-latex-extensions):
# MATHJAX_EXTENSIONS = TeX/AMSmath TeX/AMSsymbols
# For example for MathJax version 3 (see
# http://docs.mathjax.org/en/latest/input/tex/extensions/index.html):
# MATHJAX_EXTENSIONS = ams
# This tag requires that the tag USE_MATHJAX is set to YES.
MATHJAX_EXTENSIONS =
@ -1835,29 +1937,31 @@ PAPER_TYPE = a4
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.
# The LATEX_HEADER tag can be used to specify a user-defined 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. It
# is highly recommended to start with a default header using
# doxygen -w latex new_header.tex new_footer.tex new_stylesheet.sty
# and then modify the file new_header.tex. See also section "Doxygen usage" for
# information on how to generate the default header that doxygen normally uses.
#
# 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.
# Note: Only use a user-defined header if you know what you are doing!
# Note: The header is subject to change so you typically have to regenerate the
# default header when upgrading to a newer version of doxygen. The following
# commands have a special meaning inside the header (and footer): For a
# description of the possible markers and block names see the documentation.
# 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
# The LATEX_FOOTER tag can be used to specify a user-defined 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!
# 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. 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 =
@ -1902,8 +2006,7 @@ 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.
# if errors occur, instead of asking the user for help.
# The default value is: NO.
# This tag requires that the tag GENERATE_LATEX is set to YES.
@ -1916,16 +2019,6 @@ LATEX_BATCHMODE = NO
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
# https://en.wikipedia.org/wiki/BibTeX and \cite for more info.
@ -2006,16 +2099,6 @@ RTF_STYLESHEET_FILE =
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
#---------------------------------------------------------------------------
@ -2112,15 +2195,6 @@ GENERATE_DOCBOOK = NO
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
#---------------------------------------------------------------------------
@ -2207,7 +2281,8 @@ 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.
# preprocessor. Note that the INCLUDE_PATH is not recursive, so the setting of
# RECURSIVE has no effect here.
# This tag requires that the tag SEARCH_INCLUDES is set to YES.
INCLUDE_PATH =
@ -2299,15 +2374,6 @@ EXTERNAL_PAGES = YES
# 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 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.
@ -2364,11 +2430,14 @@ DOT_FONTSIZE = 10
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.
# If the CLASS_GRAPH tag is set to YES (or GRAPH) then doxygen will generate a
# graph for each documented class showing the direct and indirect inheritance
# relations. In case HAVE_DOT is set as well dot will be used to draw the graph,
# otherwise the built-in generator will be used. If the CLASS_GRAPH tag is set
# to TEXT the direct and indirect inheritance relations will be shown as texts /
# links.
# Possible values are: NO, YES, TEXT and GRAPH.
# The default value is: YES.
# This tag requires that the tag HAVE_DOT is set to YES.
CLASS_GRAPH = YES
@ -2382,7 +2451,8 @@ CLASS_GRAPH = 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.
# groups, showing the direct groups dependencies. See also the chapter Grouping
# in the manual.
# The default value is: YES.
# This tag requires that the tag HAVE_DOT is set to YES.
@ -2497,6 +2567,13 @@ GRAPHICAL_HIERARCHY = YES
DIRECTORY_GRAPH = YES
# The DIR_GRAPH_MAX_DEPTH tag can be used to limit the maximum number of levels
# of child directories generated in directory dependency graphs by dot.
# Minimum value: 1, maximum value: 25, default value: 1.
# This tag requires that the tag DIRECTORY_GRAPH is set to YES.
DIR_GRAPH_MAX_DEPTH = 1
# 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:
@ -2504,10 +2581,9 @@ DIRECTORY_GRAPH = YES
# 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
# Possible values are: png, 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.
@ -2552,10 +2628,10 @@ MSCFILE_DIRS =
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.
# path where java can find the plantuml.jar file or to the filename of jar file
# to be used. 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 =
@ -2617,6 +2693,8 @@ 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.
# Note: This tag requires that UML_LOOK isn't set, i.e. the doxygen internal
# graphical representation for inheritance and collaboration diagrams is used.
# The default value is: YES.
# This tag requires that the tag HAVE_DOT is set to YES.
@ -2625,8 +2703,8 @@ GENERATE_LEGEND = YES
# If the DOT_CLEANUP tag is set to YES, doxygen will remove the intermediate
# files that are used to generate the various graphs.
#
# Note: This setting is not only used for dot files but also for msc and
# plantuml temporary files.
# Note: This setting is not only used for dot files but also for msc temporary
# files.
# The default value is: YES.
DOT_CLEANUP = YES

View file

@ -469,13 +469,13 @@ Const OPENMPT_PROBE_FILE_HEADER_FLAGS_DEFAULT = OPENMPT_PROBE_FILE_HEADER_FLAGS_
'* 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
'* Possible return values for openmpt_probe_file_header() and openmpt_probe_file_header_without_filesize(): The file will most likely be supported by libopenmpt. \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
'* Possible return values for openmpt_probe_file_header() and openmpt_probe_file_header_without_filesize(): The file is not supported by libopenmpt. \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
'* Possible return values for openmpt_probe_file_header() and openmpt_probe_file_header_without_filesize(): An answer could not be determined with the amount of data provided. \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
'* Possible return values for openmpt_probe_file_header() and openmpt_probe_file_header_without_filesize(): An internal error occurred. \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
@ -1076,9 +1076,18 @@ Declare Function openmpt_module_get_current_speed(ByVal module As openmpt_module
\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.
\deprecated Please use openmpt_module_get_current_tempo2().
'/
Declare Function openmpt_module_get_current_tempo(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.
\since 0.7.0
'/
Declare Function openmpt_module_get_current_tempo2(ByVal module As openmpt_module Ptr) As Long
/'* \brief Get the current order
\param module The module handle to work on.
@ -1357,11 +1366,11 @@ Declare Function openmpt_module_highlight_pattern_row_channel_ Alias "openmpt_mo
- 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.
- seek.sync_samples: Set to "0" to not 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:
- play.at_end (text): Chooses the behaviour when the end of song is reached. The song end is considered to be reached after the number of reptitions set by openmpt_module_set_repeat_count was played, so if the song is set to repeat infinitely, its end is never considered to be 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.
- "continue": Returns 0 rendered frames when the song end is reached. Subsequent reads will continue playing from the loop start (if the song is not programmed to loop, playback resumsed from the song 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.

View file

@ -134,6 +134,7 @@ Type openmpt_module_ext_interface_interactive
\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
\deprecated Please use openmpt_module_ext_interface_interactive3.set_current_tempo2().
'/
set_current_tempo As Function(ByVal mod_ext As openmpt_module_ext Ptr, ByVal tempo As Long) As Long
@ -348,6 +349,23 @@ Type openmpt_module_ext_interface_interactive2
get_note_finetune As Function(ByVal mod_ext As openmpt_module_ext Ptr, ByVal channel As Long) As Double
End Type
#define LIBOPENMPT_EXT_C_INTERFACE_INTERACTIVE3 "interactive3"
Type openmpt_module_ext_interface_interactive3
/'* 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_tempo2
\since 0.7.0
'/
set_current_tempo As Function(ByVal mod_ext As openmpt_module_ext Ptr, ByVal tempo As Double) As Long
End Type
End Extern
/'* \brief Construct an openmpt_module_ext

View file

@ -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.

View file

@ -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.

File diff suppressed because it is too large Load diff

View file

@ -1,122 +0,0 @@
Dependencies {#dependencies}
============
Dependencies
------------
### libopenmpt
* Supported compilers for building libopenmpt:
* **Microsoft Visual Studio 2017** or higher, running on a amd64 build
system (other target systems are supported)
Please note that we do not support building with a later Visual Studio
installation with an earlier compiler version. This is because, while
later Visual Studio versions allow installing earlier compilers to be
available via the later version's environment, in this configuration,
the earlier compiler will still use the later C and C++ runtime's
headers and implementation, which significantly increases the matrix of
possible configurations to test.
* **GCC 8.1** or higher
* **Clang 7** or higher
* **MinGW-W64 8.1** or higher (it is recommended to preferably use
posix threading model as opposed to win32 threading model)
* **emscripten 1.39.1** or higher
* **DJGPP GCC 8.1** or higher
* any other **C++17 compliant** compiler
libopenmpt makes the following assumptions about the C++ implementation
used for building:
* `std::numeric_limits<unsigned char>::digits == 8` (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 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
libopenmpt can optionally support certain incomplete C++
implementations:
* platforms without `wchar_t` support (like DJGPP)
* platforms without working `std::random_device` (like Emscripten when
running in `AudioWorkletProcessor` context)
* platforms without working `std::high_resolution_clock` (like
Emscripten when running in `AudioWorkletProcessor` context)
* 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** (or **miniz** can be used internally)
* **MO3** support requires:
* **libmpg123 >= 1.14.0** (or **minimp3 by Lion (github.com/lieff)** can
be used internally)
* **libogg**, **libvorbis**, and **libvorbisfile** (or **stb_vorbis** can
be used internally)
* 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
* Live sound output requires one of:
* **PulseAudio**
* **SDL 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
* awk (mawk)
* git
* gzip
* help2man
* libtool
* subversion
* tar
* xpath (libxml-xpath-perl)
* zip

View file

@ -1,207 +0,0 @@
Getting Started {#gettingstarted}
===============
How to compile
--------------
### libopenmpt and openmpt123
- 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 in the matching
`build/vsVERSIONwinWINDOWSVERSION/` folder.
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 amd64 or ARM64 when
building with Visual Studio.
- In order to build libopenmpt for Windows XP, the Visual Studio 2017 XP
targetting toolset as well as the Windows 8.1 SDK need to be installed.
The SDK is optionally included with Visual Studio 2017, but must be
separately installed with later Visual Studio versions.
The Windows 8.1 SDK is available from
<https://developer.microsoft.com/en-us/windows/downloads/sdk-archive/>
or directly from
<https://download.microsoft.com/download/B/0/C/B0C80BA3-8AD6-4958-810B-6882485230B5/standalonesdk/sdksetup.exe>
.
- 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.
- native build:
Simply run
make
which will try to guess the compiler based on your operating system.
- gcc or clang (on Unix-like systems, including Mac OS X with MacPorts,
and Haiku (32-bit Hybrid and 64-bit)):
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 you want to use gcc, run:
make CONFIG=gcc
When you want to use clang, it is recommended to do:
make CONFIG=clang
- mingw-w64:
make CONFIG=mingw64-win32 # for win32
make CONFIG=mingw64-win64 # for win64
- emscripten (on Unix-like systems):
Run:
# generates WebAssembly with JavaScript fallback
make CONFIG=emscripten EMSCRIPTEN_TARGET=all
or
# generates WebAssembly
make CONFIG=emscripten EMSCRIPTEN_TARGET=wasm
or
# generates JavaScript 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. 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 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 source
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 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`.

View file

@ -1,43 +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 md_README "README"
* - \ref dependencies "Dependencies"
* - \ref gettingstarted "Getting Started"
* - \ref packaging "Packaging"
* - \ref md_doc_contributing "Contributing"
* - \ref md_doc_libopenmpt_styleguide "libopenmpt Style Guide"
* - \ref md_doc_openmpt_styleguide "OpenMPT Style Guide"
* - \ref tests "Tests"
* - \ref changelog "Changelog"
* - \ref md_doc_module_formats "Implementing new Module Formats"
* - <a href="https://bugs.openmpt.org/">Issue Tracker</a>
* \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
*
*/

View file

@ -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
compatibility 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).

View file

@ -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.

View file

@ -1,587 +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
#if !defined(WINVER) && !defined(_WIN32_WINDOWS)
#ifndef _WIN32_WINNT
#define _WIN32_WINNT 0x0501 // _WIN32_WINNT_WINXP
#endif
#endif
#if !defined(MPT_BUILD_RETRO)
#if defined(_MSC_VER)
#define MPT_WITH_MFC
#endif
#else
#if defined(_WIN32_WINNT)
#if (_WIN32_WINNT >= 0x0501)
#if defined(_MSC_VER)
#define MPT_WITH_MFC
#endif
#endif
#endif
#endif
#if defined(MPT_WITH_MFC)
#define _AFX_NO_MFC_CONTROLS_IN_DIALOGS // Avoid binary bloat from linking unused MFC controls
#endif // MPT_WITH_MFC
#ifndef NOMINMAX
#define NOMINMAX
#endif
#if defined(MPT_WITH_MFC)
#include <afxwin.h>
#include <afxcmn.h>
#endif // MPT_WITH_MFC
#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_settings.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>
#ifdef UNICODE
#define UNICODE_INPUT_PLUGIN
#endif
#ifndef _MSC_VER
#define _MSC_VER 1300
#endif
#include "winamp/Winamp/IN2.H"
#include "winamp/Winamp/wa_ipc.h"
#include <algorithm>
#include <fstream>
#include <iostream>
#include <iterator>
#include <sstream>
#include <cstring>
#include <tchar.h>
#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];
}
#if defined(UNICODE)
static std::wstring StringToWINAPI( const std::wstring & src )
{
return src;
}
#else
static std::string StringToWINAPI( const std::wstring & src )
{
return StringEncode( src, CP_ACP );
}
#endif
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::basic_string<TCHAR> cached_filename;
std::basic_string<TCHAR> cached_title;
int cached_length;
std::basic_string<TCHAR> 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::basic_string<TCHAR>();
cached_title = std::basic_string<TCHAR>();
cached_length = 0;
cached_infotext = std::basic_string<TCHAR>();
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_boolean( "render.resampler.emulate_amiga", self->settings.use_amiga_resampler ? true : false );
switch ( self->settings.amiga_filter_type ) {
case 0:
self->mod->ctl_set_text( "render.resampler.emulate_amiga_type", "auto" );
break;
case 1:
self->mod->ctl_set_text( "render.resampler.emulate_amiga_type", "unfiltered" );
break;
case 0xA500:
self->mod->ctl_set_text( "render.resampler.emulate_amiga_type", "a500" );
break;
case 0xA1200:
self->mod->ctl_set_text( "render.resampler.emulate_amiga_type", "a1200" );
break;
}
}
self->settings.save();
}
extern In_Module inmod;
static DWORD WINAPI DecodeThread( LPVOID );
static std::basic_string<TCHAR> generate_infotext( const std::basic_string<TCHAR> & filename, const openmpt::module & mod ) {
std::basic_ostringstream<TCHAR> str;
str << TEXT("filename: ") << filename << std::endl;
str << TEXT("duration: ") << mod.get_duration_seconds() << TEXT("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 << StringToWINAPI( StringDecode( *key, CP_UTF8 ) ) << TEXT(": ") << StringToWINAPI( StringDecode( mod.get_metadata(*key), CP_UTF8 ) ) << std::endl;
}
return str.str();
}
static void config( HWND hwndParent ) {
#if 1
libopenmpt::plugin::gui_edit_settings( &self->settings, hwndParent, TEXT(SHORT_TITLE) );
#else
static_cast<void>(hwndParent);
#endif
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-2023 OpenMPT Project Developers and Contributors (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, StringToWINAPI( 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" );
#if 1
libopenmpt::plugin::gui_show_file_info( hwndParent, TEXT(SHORT_TITLE), StringToWINAPI( StringReplace( StringDecode( credits.str(), CP_UTF8 ), L"\n", L"\r\n" ) ) );
#else
MessageBox( hwndParent, StringToWINAPI( StringReplace(StringDecode(credits.str(), CP_UTF8 ), L"\n", L"\r\n" ) ).c_str(), TEXT(SHORT_TITLE), MB_OK );
#endif
}
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 = StringToWINAPI( 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::basic_string<TCHAR>(fn) ) {
try {
std::ifstream s( fn, std::ios::binary );
openmpt::module mod( s );
#if 1
libopenmpt::plugin::gui_show_file_info( hWndParent, TEXT(SHORT_TITLE), StringReplace( generate_infotext( fn, mod ), TEXT("\n"), TEXT("\r\n") ) );
#else
MessageBox( hWndParent, StringReplace( generate_infotext( fn, mod ), TEXT("\n"), TEXT("\r\n") ).c_str(), TEXT(SHORT_TITLE), MB_OK );
#endif
} catch ( ... ) {
}
} else {
#if 1
libopenmpt::plugin::gui_show_file_info( hWndParent, TEXT(SHORT_TITLE), StringReplace( self->cached_infotext, TEXT("\n"), TEXT("\r\n") ) );
#else
MessageBox( hWndParent, StringReplace( self->cached_infotext, TEXT("\n"), TEXT("\r\n") ).c_str(), TEXT(SHORT_TITLE), MB_OK );
#endif
}
return INFOBOX_UNCHANGED;
}
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::basic_string<TCHAR> truncated_title = self->cached_title;
if ( truncated_title.length() >= GETFILEINFO_TITLE_LENGTH ) {
truncated_title.resize( GETFILEINFO_TITLE_LENGTH - 1 );
}
_tcscpy( 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::basic_string<TCHAR> truncated_title = StringToWINAPI( StringDecode( mod.get_metadata("title"), CP_UTF8 ) );
if ( truncated_title.length() >= GETFILEINFO_TITLE_LENGTH ) {
truncated_title.resize( GETFILEINFO_TITLE_LENGTH - 1 );
}
_tcscpy( 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;
}
#if defined(__GNUC__)
extern In_Module inmod;
#endif
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();
extern "C" __declspec(dllexport) In_Module * winampGetInModule2() {
return &inmod;
}
#if defined(MPT_WITH_MFC)
#ifdef _MFC_VER
namespace libopenmpt {
namespace plugin {
void DllMainAttach() {
// nothing
}
void DllMainDetach() {
// nothing
}
} // namespace plugin
} // namespace libopenmpt
#else
// nothing
#endif
#endif // MPT_WITH_MFC
#endif // NO_WINAMP

Some files were not shown because too many files have changed in this diff Show more