summaryrefslogtreecommitdiff
path: root/externals
diff options
context:
space:
mode:
Diffstat (limited to 'externals')
-rw-r--r--externals/CMakeLists.txt97
m---------externals/SDL0
m---------externals/Vulkan-Headers0
m---------externals/cpp-httplib0
m---------externals/cubeb0
-rw-r--r--externals/demangle/ItaniumDemangle.cpp4
-rw-r--r--externals/demangle/llvm/Demangle/Demangle.h (renamed from externals/demangle/Demangle.h)0
-rw-r--r--externals/demangle/llvm/Demangle/DemangleConfig.h (renamed from externals/demangle/DemangleConfig.h)0
-rw-r--r--externals/demangle/llvm/Demangle/ItaniumDemangle.h (renamed from externals/demangle/ItaniumDemangle.h)0
-rw-r--r--externals/demangle/llvm/Demangle/StringView.h (renamed from externals/demangle/StringView.h)0
-rw-r--r--externals/demangle/llvm/Demangle/Utility.h (renamed from externals/demangle/Utility.h)0
m---------externals/dynarmic0
-rw-r--r--externals/ffmpeg/CMakeLists.txt75
-rw-r--r--externals/glad/CMakeLists.txt2
m---------externals/libadrenotools0
m---------externals/libressl0
-rw-r--r--externals/libusb/CMakeLists.txt2
-rw-r--r--externals/microprofile/microprofile.h8
-rw-r--r--externals/nx_tzdb/CMakeLists.txt101
-rw-r--r--externals/nx_tzdb/ListFilesInDirectory.cmake8
-rw-r--r--externals/nx_tzdb/NxTzdbCreateHeader.cmake46
-rw-r--r--externals/nx_tzdb/include/nx_tzdb.h27
-rw-r--r--externals/nx_tzdb/tzdb_template.h.in18
m---------externals/nx_tzdb/tzdb_to_nx0
-rw-r--r--externals/opus/CMakeLists.txt2
-rw-r--r--externals/stb/stb_dxt.cpp765
-rw-r--r--externals/stb/stb_dxt.h36
m---------externals/vcpkg0
m---------externals/vma/VulkanMemoryAllocator0
-rw-r--r--externals/vma/vma.cpp8
30 files changed, 1135 insertions, 64 deletions
diff --git a/externals/CMakeLists.txt b/externals/CMakeLists.txt
index 94dd8bb62..0184289eb 100644
--- a/externals/CMakeLists.txt
+++ b/externals/CMakeLists.txt
@@ -8,15 +8,21 @@ set(CMAKE_POLICY_DEFAULT_CMP0077 NEW)
8# Disable tests in all externals supporting the standard option name 8# Disable tests in all externals supporting the standard option name
9set(BUILD_TESTING OFF) 9set(BUILD_TESTING OFF)
10 10
11# Build only static externals
12set(BUILD_SHARED_LIBS OFF)
13
14# Skip install rules for all externals
15set_directory_properties(PROPERTIES EXCLUDE_FROM_ALL ON)
16
11# xbyak 17# xbyak
12if ((ARCHITECTURE_x86 OR ARCHITECTURE_x86_64) AND NOT TARGET xbyak::xbyak) 18if ((ARCHITECTURE_x86 OR ARCHITECTURE_x86_64) AND NOT TARGET xbyak::xbyak)
13 add_subdirectory(xbyak EXCLUDE_FROM_ALL) 19 add_subdirectory(xbyak)
14endif() 20endif()
15 21
16# Dynarmic 22# Dynarmic
17if ((ARCHITECTURE_x86_64 OR ARCHITECTURE_arm64) AND NOT TARGET dynarmic::dynarmic) 23if ((ARCHITECTURE_x86_64 OR ARCHITECTURE_arm64) AND NOT TARGET dynarmic::dynarmic)
18 set(DYNARMIC_IGNORE_ASSERTS ON) 24 set(DYNARMIC_IGNORE_ASSERTS ON)
19 add_subdirectory(dynarmic EXCLUDE_FROM_ALL) 25 add_subdirectory(dynarmic)
20 add_library(dynarmic::dynarmic ALIAS dynarmic) 26 add_library(dynarmic::dynarmic ALIAS dynarmic)
21endif() 27endif()
22 28
@@ -34,7 +40,7 @@ if (NOT TARGET inih::INIReader)
34endif() 40endif()
35 41
36# mbedtls 42# mbedtls
37add_subdirectory(mbedtls EXCLUDE_FROM_ALL) 43add_subdirectory(mbedtls)
38target_include_directories(mbedtls PUBLIC ./mbedtls/include) 44target_include_directories(mbedtls PUBLIC ./mbedtls/include)
39 45
40# MicroProfile 46# MicroProfile
@@ -48,7 +54,7 @@ endif()
48 54
49# libusb 55# libusb
50if (ENABLE_LIBUSB AND NOT TARGET libusb::usb) 56if (ENABLE_LIBUSB AND NOT TARGET libusb::usb)
51 add_subdirectory(libusb EXCLUDE_FROM_ALL) 57 add_subdirectory(libusb)
52endif() 58endif()
53 59
54# SDL2 60# SDL2
@@ -57,8 +63,9 @@ if (YUZU_USE_EXTERNAL_SDL2)
57 # Yuzu itself needs: Atomic Audio Events Joystick Haptic Sensor Threads Timers 63 # Yuzu itself needs: Atomic Audio Events Joystick Haptic Sensor Threads Timers
58 # Since 2.0.18 Atomic+Threads required for HIDAPI/libusb (see https://github.com/libsdl-org/SDL/issues/5095) 64 # Since 2.0.18 Atomic+Threads required for HIDAPI/libusb (see https://github.com/libsdl-org/SDL/issues/5095)
59 # Yuzu-cmd also needs: Video (depends on Loadso/Dlopen) 65 # Yuzu-cmd also needs: Video (depends on Loadso/Dlopen)
66 # CPUinfo also required for SDL Audio, at least until 2.28.0 (see https://github.com/libsdl-org/SDL/issues/7809)
60 set(SDL_UNUSED_SUBSYSTEMS 67 set(SDL_UNUSED_SUBSYSTEMS
61 CPUinfo File Filesystem 68 File Filesystem
62 Locale Power Render) 69 Locale Power Render)
63 foreach(_SUB ${SDL_UNUSED_SUBSYSTEMS}) 70 foreach(_SUB ${SDL_UNUSED_SUBSYSTEMS})
64 string(TOUPPER ${_SUB} _OPT) 71 string(TOUPPER ${_SUB} _OPT)
@@ -67,18 +74,16 @@ if (YUZU_USE_EXTERNAL_SDL2)
67 74
68 set(HIDAPI ON) 75 set(HIDAPI ON)
69 endif() 76 endif()
70 set(SDL_STATIC ON)
71 set(SDL_SHARED OFF)
72 if (APPLE) 77 if (APPLE)
73 set(SDL_FILE ON) 78 set(SDL_FILE ON)
74 endif() 79 endif()
75 80
76 add_subdirectory(SDL EXCLUDE_FROM_ALL) 81 add_subdirectory(SDL)
77endif() 82endif()
78 83
79# ENet 84# ENet
80if (NOT TARGET enet::enet) 85if (NOT TARGET enet::enet)
81 add_subdirectory(enet EXCLUDE_FROM_ALL) 86 add_subdirectory(enet)
82 target_include_directories(enet INTERFACE ./enet/include) 87 target_include_directories(enet INTERFACE ./enet/include)
83 add_library(enet::enet ALIAS enet) 88 add_library(enet::enet ALIAS enet)
84endif() 89endif()
@@ -86,62 +91,39 @@ endif()
86# Cubeb 91# Cubeb
87if (ENABLE_CUBEB AND NOT TARGET cubeb::cubeb) 92if (ENABLE_CUBEB AND NOT TARGET cubeb::cubeb)
88 set(BUILD_TESTS OFF) 93 set(BUILD_TESTS OFF)
89 add_subdirectory(cubeb EXCLUDE_FROM_ALL) 94 set(BUILD_TOOLS OFF)
95 add_subdirectory(cubeb)
90 add_library(cubeb::cubeb ALIAS cubeb) 96 add_library(cubeb::cubeb ALIAS cubeb)
91endif() 97endif()
92 98
93# DiscordRPC 99# DiscordRPC
94if (USE_DISCORD_PRESENCE AND NOT TARGET DiscordRPC::discord-rpc) 100if (USE_DISCORD_PRESENCE AND NOT TARGET DiscordRPC::discord-rpc)
95 add_subdirectory(discord-rpc EXCLUDE_FROM_ALL) 101 set(BUILD_EXAMPLES OFF)
102 add_subdirectory(discord-rpc)
96 target_include_directories(discord-rpc INTERFACE ./discord-rpc/include) 103 target_include_directories(discord-rpc INTERFACE ./discord-rpc/include)
97 add_library(DiscordRPC::discord-rpc ALIAS discord-rpc) 104 add_library(DiscordRPC::discord-rpc ALIAS discord-rpc)
98endif() 105endif()
99 106
100# Sirit 107# Sirit
101add_subdirectory(sirit EXCLUDE_FROM_ALL) 108add_subdirectory(sirit)
102 109
103# httplib 110# httplib
104if (ENABLE_WEB_SERVICE AND NOT TARGET httplib::httplib) 111if (ENABLE_WEB_SERVICE AND NOT TARGET httplib::httplib)
105 if (NOT WIN32) 112 set(HTTPLIB_REQUIRE_OPENSSL ON)
106 find_package(OpenSSL 1.1) 113 add_subdirectory(cpp-httplib)
107 if (OPENSSL_FOUND)
108 set(OPENSSL_LIBRARIES OpenSSL::SSL OpenSSL::Crypto)
109 endif()
110 endif()
111
112 if (WIN32 OR NOT OPENSSL_FOUND)
113 # LibreSSL
114 set(LIBRESSL_SKIP_INSTALL ON)
115 set(OPENSSLDIR "/etc/ssl/")
116 add_subdirectory(libressl EXCLUDE_FROM_ALL)
117 target_include_directories(ssl INTERFACE ./libressl/include)
118 target_compile_definitions(ssl PRIVATE -DHAVE_INET_NTOP)
119 get_directory_property(OPENSSL_LIBRARIES
120 DIRECTORY libressl
121 DEFINITION OPENSSL_LIBS)
122 endif()
123
124 add_library(httplib INTERFACE)
125 target_include_directories(httplib INTERFACE ./cpp-httplib)
126 target_compile_definitions(httplib INTERFACE -DCPPHTTPLIB_OPENSSL_SUPPORT)
127 target_link_libraries(httplib INTERFACE ${OPENSSL_LIBRARIES})
128 if (WIN32)
129 target_link_libraries(httplib INTERFACE crypt32 cryptui ws2_32)
130 endif()
131 add_library(httplib::httplib ALIAS httplib)
132endif() 114endif()
133 115
134# cpp-jwt 116# cpp-jwt
135if (ENABLE_WEB_SERVICE AND NOT TARGET cpp-jwt::cpp-jwt) 117if (ENABLE_WEB_SERVICE AND NOT TARGET cpp-jwt::cpp-jwt)
136 add_library(cpp-jwt INTERFACE) 118 set(CPP_JWT_BUILD_EXAMPLES OFF)
137 target_include_directories(cpp-jwt INTERFACE ./cpp-jwt/include) 119 set(CPP_JWT_BUILD_TESTS OFF)
138 target_compile_definitions(cpp-jwt INTERFACE CPP_JWT_USE_VENDORED_NLOHMANN_JSON) 120 set(CPP_JWT_USE_VENDORED_NLOHMANN_JSON OFF)
139 add_library(cpp-jwt::cpp-jwt ALIAS cpp-jwt) 121 add_subdirectory(cpp-jwt)
140endif() 122endif()
141 123
142# Opus 124# Opus
143if (NOT TARGET Opus::opus) 125if (NOT TARGET Opus::opus)
144 add_subdirectory(opus EXCLUDE_FROM_ALL) 126 add_subdirectory(opus)
145endif() 127endif()
146 128
147# FFMpeg 129# FFMpeg
@@ -155,9 +137,28 @@ endif()
155 137
156# Vulkan-Headers 138# Vulkan-Headers
157if (YUZU_USE_EXTERNAL_VULKAN_HEADERS) 139if (YUZU_USE_EXTERNAL_VULKAN_HEADERS)
158 add_subdirectory(Vulkan-Headers EXCLUDE_FROM_ALL) 140 add_subdirectory(Vulkan-Headers)
159endif() 141endif()
160 142
161add_library(demangle STATIC) 143# TZDB (Time Zone Database)
162target_include_directories(demangle PUBLIC ./demangle) 144add_subdirectory(nx_tzdb)
163target_sources(demangle PRIVATE demangle/ItaniumDemangle.cpp) 145
146# VMA
147add_library(vma vma/vma.cpp)
148target_include_directories(vma PUBLIC ./vma/VulkanMemoryAllocator/include)
149target_link_libraries(vma PRIVATE Vulkan::Headers)
150
151if (NOT TARGET LLVM::Demangle)
152 add_library(demangle demangle/ItaniumDemangle.cpp)
153 target_include_directories(demangle PUBLIC ./demangle)
154 add_library(LLVM::Demangle ALIAS demangle)
155endif()
156
157add_library(stb stb/stb_dxt.cpp)
158target_include_directories(stb PUBLIC ./stb)
159
160if (ANDROID)
161 if (ARCHITECTURE_arm64)
162 add_subdirectory(libadrenotools)
163 endif()
164endif()
diff --git a/externals/SDL b/externals/SDL
Subproject f17058b562c8a1090c0c996b42982721ace9090 Subproject 491fba1d06a4810645092b2559b9cc94abeb23b
diff --git a/externals/Vulkan-Headers b/externals/Vulkan-Headers
Subproject 00671c64ba5c488ade22ad572a0ef81d5e64c80 Subproject 63af1cf1ee906ba4dcd5a324bdd0201d4f4bfd1
diff --git a/externals/cpp-httplib b/externals/cpp-httplib
Subproject 305a7abcb9b4e9e349843c6d563212e6c1bbbf2 Subproject 6d963fbe8d415399d65e94db7910bbd22fe3741
diff --git a/externals/cubeb b/externals/cubeb
Subproject 75d9d125ee655ef80f3bfcd97ae5a805931042b Subproject 48689ae7a73caeb747953f9ed664dc71d2f918d
diff --git a/externals/demangle/ItaniumDemangle.cpp b/externals/demangle/ItaniumDemangle.cpp
index 5e078e3e2..b055a2fd7 100644
--- a/externals/demangle/ItaniumDemangle.cpp
+++ b/externals/demangle/ItaniumDemangle.cpp
@@ -11,8 +11,8 @@
11// file does not yet support: 11// file does not yet support:
12// - C++ modules TS 12// - C++ modules TS
13 13
14#include "Demangle.h" 14#include "llvm/Demangle/Demangle.h"
15#include "ItaniumDemangle.h" 15#include "llvm/Demangle/ItaniumDemangle.h"
16 16
17#include <cassert> 17#include <cassert>
18#include <cctype> 18#include <cctype>
diff --git a/externals/demangle/Demangle.h b/externals/demangle/llvm/Demangle/Demangle.h
index 5b673e4e1..5b673e4e1 100644
--- a/externals/demangle/Demangle.h
+++ b/externals/demangle/llvm/Demangle/Demangle.h
diff --git a/externals/demangle/DemangleConfig.h b/externals/demangle/llvm/Demangle/DemangleConfig.h
index a8aef9df1..a8aef9df1 100644
--- a/externals/demangle/DemangleConfig.h
+++ b/externals/demangle/llvm/Demangle/DemangleConfig.h
diff --git a/externals/demangle/ItaniumDemangle.h b/externals/demangle/llvm/Demangle/ItaniumDemangle.h
index 64b35c142..64b35c142 100644
--- a/externals/demangle/ItaniumDemangle.h
+++ b/externals/demangle/llvm/Demangle/ItaniumDemangle.h
diff --git a/externals/demangle/StringView.h b/externals/demangle/llvm/Demangle/StringView.h
index 44d2b18a3..44d2b18a3 100644
--- a/externals/demangle/StringView.h
+++ b/externals/demangle/llvm/Demangle/StringView.h
diff --git a/externals/demangle/Utility.h b/externals/demangle/llvm/Demangle/Utility.h
index 50d05c6b1..50d05c6b1 100644
--- a/externals/demangle/Utility.h
+++ b/externals/demangle/llvm/Demangle/Utility.h
diff --git a/externals/dynarmic b/externals/dynarmic
Subproject befe547d5631024a70d81d2ccee808bbfcb3854 Subproject 7da378033a7764f955516f75194856d87bbcd7a
diff --git a/externals/ffmpeg/CMakeLists.txt b/externals/ffmpeg/CMakeLists.txt
index 0baac8e17..0a926e399 100644
--- a/externals/ffmpeg/CMakeLists.txt
+++ b/externals/ffmpeg/CMakeLists.txt
@@ -1,7 +1,7 @@
1# SPDX-FileCopyrightText: 2021 yuzu Emulator Project 1# SPDX-FileCopyrightText: 2021 yuzu Emulator Project
2# SPDX-License-Identifier: GPL-2.0-or-later 2# SPDX-License-Identifier: GPL-2.0-or-later
3 3
4if (NOT WIN32) 4if (NOT WIN32 AND NOT ANDROID)
5 # Build FFmpeg from externals 5 # Build FFmpeg from externals
6 message(STATUS "Using FFmpeg from externals") 6 message(STATUS "Using FFmpeg from externals")
7 7
@@ -44,10 +44,12 @@ if (NOT WIN32)
44 endforeach() 44 endforeach()
45 45
46 find_package(PkgConfig REQUIRED) 46 find_package(PkgConfig REQUIRED)
47 pkg_check_modules(LIBVA libva) 47 if (NOT ANDROID)
48 pkg_check_modules(CUDA cuda) 48 pkg_check_modules(LIBVA libva)
49 pkg_check_modules(FFNVCODEC ffnvcodec) 49 pkg_check_modules(CUDA cuda)
50 pkg_check_modules(VDPAU vdpau) 50 pkg_check_modules(FFNVCODEC ffnvcodec)
51 pkg_check_modules(VDPAU vdpau)
52 endif()
51 53
52 set(FFmpeg_HWACCEL_LIBRARIES) 54 set(FFmpeg_HWACCEL_LIBRARIES)
53 set(FFmpeg_HWACCEL_FLAGS) 55 set(FFmpeg_HWACCEL_FLAGS)
@@ -121,6 +123,26 @@ if (NOT WIN32)
121 list(APPEND FFmpeg_HWACCEL_FLAGS --disable-vdpau) 123 list(APPEND FFmpeg_HWACCEL_FLAGS --disable-vdpau)
122 endif() 124 endif()
123 125
126 find_program(BASH_PROGRAM bash REQUIRED)
127
128 set(FFmpeg_CROSS_COMPILE_FLAGS "")
129 if (ANDROID)
130 string(TOLOWER "${CMAKE_HOST_SYSTEM_NAME}" FFmpeg_HOST_SYSTEM_NAME)
131 set(TOOLCHAIN "${ANDROID_NDK}/toolchains/llvm/prebuilt/${FFmpeg_HOST_SYSTEM_NAME}-${CMAKE_HOST_SYSTEM_PROCESSOR}")
132 set(SYSROOT "${TOOLCHAIN}/sysroot")
133 set(FFmpeg_CPU "armv8-a")
134 list(APPEND FFmpeg_CROSS_COMPILE_FLAGS
135 --arch=arm64
136 #--cpu=${FFmpeg_CPU}
137 --enable-cross-compile
138 --cross-prefix=${TOOLCHAIN}/bin/aarch64-linux-android-
139 --sysroot=${SYSROOT}
140 --target-os=android
141 --extra-ldflags="--ld-path=${TOOLCHAIN}/bin/ld.lld"
142 --extra-ldflags="-nostdlib"
143 )
144 endif()
145
124 # `configure` parameters builds only exactly what yuzu needs from FFmpeg 146 # `configure` parameters builds only exactly what yuzu needs from FFmpeg
125 # `--disable-vdpau` is needed to avoid linking issues 147 # `--disable-vdpau` is needed to avoid linking issues
126 set(FFmpeg_CC ${CMAKE_C_COMPILER_LAUNCHER} ${CMAKE_C_COMPILER}) 148 set(FFmpeg_CC ${CMAKE_C_COMPILER_LAUNCHER} ${CMAKE_C_COMPILER})
@@ -129,9 +151,8 @@ if (NOT WIN32)
129 OUTPUT 151 OUTPUT
130 ${FFmpeg_MAKEFILE} 152 ${FFmpeg_MAKEFILE}
131 COMMAND 153 COMMAND
132 /bin/bash ${FFmpeg_PREFIX}/configure 154 ${BASH_PROGRAM} ${FFmpeg_PREFIX}/configure
133 --disable-avdevice 155 --disable-avdevice
134 --disable-avfilter
135 --disable-avformat 156 --disable-avformat
136 --disable-doc 157 --disable-doc
137 --disable-everything 158 --disable-everything
@@ -143,15 +164,18 @@ if (NOT WIN32)
143 --enable-decoder=h264 164 --enable-decoder=h264
144 --enable-decoder=vp8 165 --enable-decoder=vp8
145 --enable-decoder=vp9 166 --enable-decoder=vp9
167 --enable-filter=yadif
146 --cc="${FFmpeg_CC}" 168 --cc="${FFmpeg_CC}"
147 --cxx="${FFmpeg_CXX}" 169 --cxx="${FFmpeg_CXX}"
148 ${FFmpeg_HWACCEL_FLAGS} 170 ${FFmpeg_HWACCEL_FLAGS}
171 ${FFmpeg_CROSS_COMPILE_FLAGS}
149 WORKING_DIRECTORY 172 WORKING_DIRECTORY
150 ${FFmpeg_BUILD_DIR} 173 ${FFmpeg_BUILD_DIR}
151 ) 174 )
152 unset(FFmpeg_CC) 175 unset(FFmpeg_CC)
153 unset(FFmpeg_CXX) 176 unset(FFmpeg_CXX)
154 unset(FFmpeg_HWACCEL_FLAGS) 177 unset(FFmpeg_HWACCEL_FLAGS)
178 unset(FFmpeg_CROSS_COMPILE_FLAGS)
155 179
156 # Workaround for Ubuntu 18.04's older version of make not being able to call make as a child 180 # Workaround for Ubuntu 18.04's older version of make not being able to call make as a child
157 # with context of the jobserver. Also helps ninja users. 181 # with context of the jobserver. Also helps ninja users.
@@ -197,19 +221,50 @@ if (NOT WIN32)
197 else() 221 else()
198 message(FATAL_ERROR "FFmpeg not found") 222 message(FATAL_ERROR "FFmpeg not found")
199 endif() 223 endif()
200else(WIN32) 224elseif(ANDROID)
225 # Use yuzu FFmpeg binaries
226 if (ARCHITECTURE_arm64)
227 set(FFmpeg_EXT_NAME "ffmpeg-android-v5.1.LTS-aarch64")
228 elseif (ARCHITECTURE_x86_64)
229 set(FFmpeg_EXT_NAME "ffmpeg-android-v5.1.LTS-x86_64")
230 else()
231 message(FATAL_ERROR "Unsupported architecture for Android FFmpeg")
232 endif()
233 set(FFmpeg_PATH "${CMAKE_BINARY_DIR}/externals/${FFmpeg_EXT_NAME}")
234 download_bundled_external("ffmpeg/" ${FFmpeg_EXT_NAME} "")
235 set(FFmpeg_FOUND YES)
236 set(FFmpeg_INCLUDE_DIR "${FFmpeg_PATH}/include" CACHE PATH "Path to FFmpeg headers" FORCE)
237 set(FFmpeg_LIBRARY_DIR "${FFmpeg_PATH}/lib" CACHE PATH "Path to FFmpeg library directory" FORCE)
238 set(FFmpeg_LDFLAGS "" CACHE STRING "FFmpeg linker flags" FORCE)
239 set(FFmpeg_LIBRARIES
240 ${FFmpeg_LIBRARY_DIR}/libavcodec.so
241 ${FFmpeg_LIBRARY_DIR}/libavdevice.so
242 ${FFmpeg_LIBRARY_DIR}/libavfilter.so
243 ${FFmpeg_LIBRARY_DIR}/libavformat.so
244 ${FFmpeg_LIBRARY_DIR}/libavutil.so
245 ${FFmpeg_LIBRARY_DIR}/libswresample.so
246 ${FFmpeg_LIBRARY_DIR}/libswscale.so
247 ${FFmpeg_LIBRARY_DIR}/libvpx.a
248 ${FFmpeg_LIBRARY_DIR}/libx264.a
249 CACHE PATH "Paths to FFmpeg libraries" FORCE)
250 # exported variables
251 set(FFmpeg_PATH "${FFmpeg_PATH}" PARENT_SCOPE)
252 set(FFmpeg_LDFLAGS "${FFmpeg_LDFLAGS}" PARENT_SCOPE)
253 set(FFmpeg_LIBRARIES "${FFmpeg_LIBRARIES}" PARENT_SCOPE)
254 set(FFmpeg_INCLUDE_DIR "${FFmpeg_INCLUDE_DIR}" PARENT_SCOPE)
255elseif(WIN32)
201 # Use yuzu FFmpeg binaries 256 # Use yuzu FFmpeg binaries
202 set(FFmpeg_EXT_NAME "ffmpeg-4.4") 257 set(FFmpeg_EXT_NAME "ffmpeg-5.1.3")
203 set(FFmpeg_PATH "${CMAKE_BINARY_DIR}/externals/${FFmpeg_EXT_NAME}") 258 set(FFmpeg_PATH "${CMAKE_BINARY_DIR}/externals/${FFmpeg_EXT_NAME}")
204 download_bundled_external("ffmpeg/" ${FFmpeg_EXT_NAME} "") 259 download_bundled_external("ffmpeg/" ${FFmpeg_EXT_NAME} "")
205 set(FFmpeg_FOUND YES) 260 set(FFmpeg_FOUND YES)
206 set(FFmpeg_INCLUDE_DIR "${FFmpeg_PATH}/include" CACHE PATH "Path to FFmpeg headers" FORCE) 261 set(FFmpeg_INCLUDE_DIR "${FFmpeg_PATH}/include" CACHE PATH "Path to FFmpeg headers" FORCE)
207 set(FFmpeg_LIBRARY_DIR "${FFmpeg_PATH}/bin" CACHE PATH "Path to FFmpeg library directory" FORCE) 262 set(FFmpeg_LIBRARY_DIR "${FFmpeg_PATH}/bin" CACHE PATH "Path to FFmpeg library directory" FORCE)
208 set(FFmpeg_LDFLAGS "" CACHE STRING "FFmpeg linker flags" FORCE) 263 set(FFmpeg_LDFLAGS "" CACHE STRING "FFmpeg linker flags" FORCE)
209 set(FFmpeg_DLL_DIR "${FFmpeg_PATH}/bin" CACHE PATH "Path to FFmpeg dll's" FORCE)
210 set(FFmpeg_LIBRARIES 264 set(FFmpeg_LIBRARIES
211 ${FFmpeg_LIBRARY_DIR}/swscale.lib 265 ${FFmpeg_LIBRARY_DIR}/swscale.lib
212 ${FFmpeg_LIBRARY_DIR}/avcodec.lib 266 ${FFmpeg_LIBRARY_DIR}/avcodec.lib
267 ${FFmpeg_LIBRARY_DIR}/avfilter.lib
213 ${FFmpeg_LIBRARY_DIR}/avutil.lib 268 ${FFmpeg_LIBRARY_DIR}/avutil.lib
214 CACHE PATH "Paths to FFmpeg libraries" FORCE) 269 CACHE PATH "Paths to FFmpeg libraries" FORCE)
215 # exported variables 270 # exported variables
diff --git a/externals/glad/CMakeLists.txt b/externals/glad/CMakeLists.txt
index 3dfcac2fd..0c8e285a4 100644
--- a/externals/glad/CMakeLists.txt
+++ b/externals/glad/CMakeLists.txt
@@ -1,7 +1,7 @@
1# SPDX-FileCopyrightText: 2015 Yuri Kunde Schlesner <yuriks@yuriks.net> 1# SPDX-FileCopyrightText: 2015 Yuri Kunde Schlesner <yuriks@yuriks.net>
2# SPDX-License-Identifier: GPL-2.0-or-later 2# SPDX-License-Identifier: GPL-2.0-or-later
3 3
4add_library(glad STATIC 4add_library(glad
5 src/glad.c 5 src/glad.c
6 include/KHR/khrplatform.h 6 include/KHR/khrplatform.h
7 include/glad/glad.h 7 include/glad/glad.h
diff --git a/externals/libadrenotools b/externals/libadrenotools
new file mode 160000
Subproject 5cd3f5c5ceea6d9e9d435ccdd922d9b99e55d10
diff --git a/externals/libressl b/externals/libressl
deleted file mode 160000
Subproject 8929f818fd748fd31a34fec7c04558399e13014
diff --git a/externals/libusb/CMakeLists.txt b/externals/libusb/CMakeLists.txt
index 6317ea807..6757b59da 100644
--- a/externals/libusb/CMakeLists.txt
+++ b/externals/libusb/CMakeLists.txt
@@ -122,7 +122,7 @@ else() # MINGW OR (${CMAKE_SYSTEM_NAME} MATCHES "Linux")
122 add_compile_options(/utf-8) 122 add_compile_options(/utf-8)
123 endif() 123 endif()
124 124
125 add_library(usb STATIC EXCLUDE_FROM_ALL 125 add_library(usb
126 libusb/libusb/core.c 126 libusb/libusb/core.c
127 libusb/libusb/core.c 127 libusb/libusb/core.c
128 libusb/libusb/descriptor.c 128 libusb/libusb/descriptor.c
diff --git a/externals/microprofile/microprofile.h b/externals/microprofile/microprofile.h
index 639f3618c..8f75a25aa 100644
--- a/externals/microprofile/microprofile.h
+++ b/externals/microprofile/microprofile.h
@@ -1697,7 +1697,13 @@ void MicroProfileFlip()
1697 { 1697 {
1698 int nTimer = MicroProfileLogTimerIndex(LE); 1698 int nTimer = MicroProfileLogTimerIndex(LE);
1699 uint8_t nGroup = pTimerToGroup[nTimer]; 1699 uint8_t nGroup = pTimerToGroup[nTimer];
1700 MP_ASSERT(nStackPos < MICROPROFILE_STACK_MAX); 1700
1701 // To avoid crashing due to OOB memory accesses/asserts
1702 // simply skip this iteration
1703 // MP_ASSERT(nStackPos < MICROPROFILE_STACK_MAX);
1704 if (nStackPos >= MICROPROFILE_STACK_MAX) {
1705 break;
1706 }
1701 MP_ASSERT(nGroup < MICROPROFILE_MAX_GROUPS); 1707 MP_ASSERT(nGroup < MICROPROFILE_MAX_GROUPS);
1702 pGroupStackPos[nGroup]++; 1708 pGroupStackPos[nGroup]++;
1703 pStack[nStackPos++] = k; 1709 pStack[nStackPos++] = k;
diff --git a/externals/nx_tzdb/CMakeLists.txt b/externals/nx_tzdb/CMakeLists.txt
new file mode 100644
index 000000000..593786250
--- /dev/null
+++ b/externals/nx_tzdb/CMakeLists.txt
@@ -0,0 +1,101 @@
1# SPDX-FileCopyrightText: 2023 yuzu Emulator Project
2# SPDX-License-Identifier: GPL-2.0-or-later
3
4set(NX_TZDB_INCLUDE_DIR "${CMAKE_CURRENT_BINARY_DIR}/include")
5
6add_library(nx_tzdb INTERFACE)
7
8find_program(GIT git)
9find_program(GNU_MAKE make)
10find_program(DATE_PROG date)
11
12set(CAN_BUILD_NX_TZDB true)
13
14if (NOT GIT)
15 set(CAN_BUILD_NX_TZDB false)
16endif()
17if (NOT GNU_MAKE)
18 set(CAN_BUILD_NX_TZDB false)
19endif()
20if (NOT DATE_PROG)
21 set(CAN_BUILD_NX_TZDB false)
22endif()
23if (CMAKE_SYSTEM_NAME STREQUAL "Windows" OR ANDROID)
24 # tzdb_to_nx currently requires a posix-compliant host
25 # MinGW and Android are handled here due to the executable format being different from the host system
26 # TODO (lat9nq): cross-compiling support
27 set(CAN_BUILD_NX_TZDB false)
28endif()
29
30set(NX_TZDB_VERSION "220816")
31set(NX_TZDB_ARCHIVE "${CMAKE_CURRENT_BINARY_DIR}/${NX_TZDB_VERSION}.zip")
32
33set(NX_TZDB_ROMFS_DIR "${CMAKE_CURRENT_BINARY_DIR}/nx_tzdb")
34
35if ((NOT CAN_BUILD_NX_TZDB OR YUZU_DOWNLOAD_TIME_ZONE_DATA) AND NOT EXISTS ${NX_TZDB_ARCHIVE})
36 set(NX_TZDB_DOWNLOAD_URL "https://github.com/lat9nq/tzdb_to_nx/releases/download/${NX_TZDB_VERSION}/${NX_TZDB_VERSION}.zip")
37
38 message(STATUS "Downloading time zone data from ${NX_TZDB_DOWNLOAD_URL}...")
39 file(DOWNLOAD ${NX_TZDB_DOWNLOAD_URL} ${NX_TZDB_ARCHIVE}
40 STATUS NX_TZDB_DOWNLOAD_STATUS)
41 list(GET NX_TZDB_DOWNLOAD_STATUS 0 NX_TZDB_DOWNLOAD_STATUS_CODE)
42 if (NOT NX_TZDB_DOWNLOAD_STATUS_CODE EQUAL 0)
43 message(FATAL_ERROR "Time zone data download failed (status code ${NX_TZDB_DOWNLOAD_STATUS_CODE})")
44 endif()
45
46 file(ARCHIVE_EXTRACT
47 INPUT
48 ${NX_TZDB_ARCHIVE}
49 DESTINATION
50 ${NX_TZDB_ROMFS_DIR})
51elseif (CAN_BUILD_NX_TZDB AND NOT YUZU_DOWNLOAD_TIME_ZONE_DATA)
52 add_subdirectory(tzdb_to_nx)
53 add_dependencies(nx_tzdb x80e)
54
55 set(NX_TZDB_ROMFS_DIR "${NX_TZDB_DIR}")
56endif()
57
58target_include_directories(nx_tzdb
59 INTERFACE ${CMAKE_CURRENT_SOURCE_DIR}/include
60 INTERFACE ${NX_TZDB_INCLUDE_DIR})
61
62function(CreateHeader ZONE_PATH HEADER_NAME)
63 set(HEADER_PATH "${NX_TZDB_INCLUDE_DIR}/nx_tzdb/${HEADER_NAME}.h")
64 add_custom_command(
65 OUTPUT
66 ${NX_TZDB_INCLUDE_DIR}/nx_tzdb/${HEADER_NAME}.h
67 COMMAND
68 ${CMAKE_COMMAND} -P ${CMAKE_CURRENT_SOURCE_DIR}/NxTzdbCreateHeader.cmake
69 ${ZONE_PATH}
70 ${HEADER_NAME}
71 ${NX_TZDB_INCLUDE_DIR}
72 ${CMAKE_CURRENT_SOURCE_DIR}
73 DEPENDS
74 tzdb_template.h.in
75 NxTzdbCreateHeader.cmake)
76
77 target_sources(nx_tzdb PRIVATE ${HEADER_PATH})
78endfunction()
79
80CreateHeader(${NX_TZDB_ROMFS_DIR} base)
81CreateHeader(${NX_TZDB_ROMFS_DIR}/zoneinfo zoneinfo)
82CreateHeader(${NX_TZDB_ROMFS_DIR}/zoneinfo/Africa africa)
83CreateHeader(${NX_TZDB_ROMFS_DIR}/zoneinfo/America america)
84CreateHeader(${NX_TZDB_ROMFS_DIR}/zoneinfo/America/Argentina america_argentina)
85CreateHeader(${NX_TZDB_ROMFS_DIR}/zoneinfo/America/Indiana america_indiana)
86CreateHeader(${NX_TZDB_ROMFS_DIR}/zoneinfo/America/Kentucky america_kentucky)
87CreateHeader(${NX_TZDB_ROMFS_DIR}/zoneinfo/America/North_Dakota america_north_dakota)
88CreateHeader(${NX_TZDB_ROMFS_DIR}/zoneinfo/Antarctica antarctica)
89CreateHeader(${NX_TZDB_ROMFS_DIR}/zoneinfo/Arctic arctic)
90CreateHeader(${NX_TZDB_ROMFS_DIR}/zoneinfo/Asia asia)
91CreateHeader(${NX_TZDB_ROMFS_DIR}/zoneinfo/Atlantic atlantic)
92CreateHeader(${NX_TZDB_ROMFS_DIR}/zoneinfo/Australia australia)
93CreateHeader(${NX_TZDB_ROMFS_DIR}/zoneinfo/Brazil brazil)
94CreateHeader(${NX_TZDB_ROMFS_DIR}/zoneinfo/Canada canada)
95CreateHeader(${NX_TZDB_ROMFS_DIR}/zoneinfo/Chile chile)
96CreateHeader(${NX_TZDB_ROMFS_DIR}/zoneinfo/Etc etc)
97CreateHeader(${NX_TZDB_ROMFS_DIR}/zoneinfo/Europe europe)
98CreateHeader(${NX_TZDB_ROMFS_DIR}/zoneinfo/Indian indian)
99CreateHeader(${NX_TZDB_ROMFS_DIR}/zoneinfo/Mexico mexico)
100CreateHeader(${NX_TZDB_ROMFS_DIR}/zoneinfo/Pacific pacific)
101CreateHeader(${NX_TZDB_ROMFS_DIR}/zoneinfo/US us)
diff --git a/externals/nx_tzdb/ListFilesInDirectory.cmake b/externals/nx_tzdb/ListFilesInDirectory.cmake
new file mode 100644
index 000000000..35a9e726a
--- /dev/null
+++ b/externals/nx_tzdb/ListFilesInDirectory.cmake
@@ -0,0 +1,8 @@
1# SPDX-FileCopyrightText: 2023 yuzu Emulator Project
2# SPDX-License-Identifier: GPL-2.0-or-later
3
4# CMake does not have a way to list the files in a specific directory,
5# so we need this script to do that for us in a platform-agnostic fashion
6
7file(GLOB FILE_LIST LIST_DIRECTORIES false RELATIVE ${CMAKE_SOURCE_DIR} "*")
8execute_process(COMMAND ${CMAKE_COMMAND} -E echo "${FILE_LIST};")
diff --git a/externals/nx_tzdb/NxTzdbCreateHeader.cmake b/externals/nx_tzdb/NxTzdbCreateHeader.cmake
new file mode 100644
index 000000000..8c29e1167
--- /dev/null
+++ b/externals/nx_tzdb/NxTzdbCreateHeader.cmake
@@ -0,0 +1,46 @@
1# SPDX-FileCopyrightText: 2023 yuzu Emulator Project
2# SPDX-License-Identifier: GPL-2.0-or-later
3
4set(ZONE_PATH ${CMAKE_ARGV3})
5set(HEADER_NAME ${CMAKE_ARGV4})
6set(NX_TZDB_INCLUDE_DIR ${CMAKE_ARGV5})
7set(NX_TZDB_SOURCE_DIR ${CMAKE_ARGV6})
8
9execute_process(
10 COMMAND ${CMAKE_COMMAND} -P ${NX_TZDB_SOURCE_DIR}/ListFilesInDirectory.cmake
11 WORKING_DIRECTORY ${ZONE_PATH}
12 OUTPUT_VARIABLE FILE_LIST)
13
14set(DIRECTORY_NAME ${HEADER_NAME})
15
16set(FILE_DATA "")
17foreach(ZONE_FILE ${FILE_LIST})
18 if (ZONE_FILE STREQUAL "\n")
19 continue()
20 endif()
21
22 string(APPEND FILE_DATA "{\"${ZONE_FILE}\",\n{")
23
24 file(READ ${ZONE_PATH}/${ZONE_FILE} ZONE_DATA HEX)
25 string(LENGTH "${ZONE_DATA}" ZONE_DATA_LEN)
26 foreach(I RANGE 0 ${ZONE_DATA_LEN} 2)
27 math(EXPR BREAK_LINE "(${I} + 2) % 38")
28
29 string(SUBSTRING "${ZONE_DATA}" "${I}" 2 HEX_DATA)
30 if (NOT HEX_DATA)
31 break()
32 endif()
33
34 string(APPEND FILE_DATA "0x${HEX_DATA},")
35 if (BREAK_LINE EQUAL 0)
36 string(APPEND FILE_DATA "\n")
37 else()
38 string(APPEND FILE_DATA " ")
39 endif()
40 endforeach()
41
42 string(APPEND FILE_DATA "}},\n")
43endforeach()
44
45file(READ ${NX_TZDB_SOURCE_DIR}/tzdb_template.h.in NX_TZDB_TEMPLATE_H_IN)
46file(CONFIGURE OUTPUT ${NX_TZDB_INCLUDE_DIR}/nx_tzdb/${HEADER_NAME}.h CONTENT "${NX_TZDB_TEMPLATE_H_IN}")
diff --git a/externals/nx_tzdb/include/nx_tzdb.h b/externals/nx_tzdb/include/nx_tzdb.h
new file mode 100644
index 000000000..1f7c6069a
--- /dev/null
+++ b/externals/nx_tzdb/include/nx_tzdb.h
@@ -0,0 +1,27 @@
1// SPDX-FileCopyrightText: 2023 yuzu Emulator Project
2// SPDX-License-Identifier: GPL-2.0-or-later
3
4#pragma once
5
6#include "nx_tzdb/africa.h"
7#include "nx_tzdb/america.h"
8#include "nx_tzdb/america_argentina.h"
9#include "nx_tzdb/america_indiana.h"
10#include "nx_tzdb/america_kentucky.h"
11#include "nx_tzdb/america_north_dakota.h"
12#include "nx_tzdb/antarctica.h"
13#include "nx_tzdb/arctic.h"
14#include "nx_tzdb/asia.h"
15#include "nx_tzdb/atlantic.h"
16#include "nx_tzdb/australia.h"
17#include "nx_tzdb/base.h"
18#include "nx_tzdb/brazil.h"
19#include "nx_tzdb/canada.h"
20#include "nx_tzdb/chile.h"
21#include "nx_tzdb/etc.h"
22#include "nx_tzdb/europe.h"
23#include "nx_tzdb/indian.h"
24#include "nx_tzdb/mexico.h"
25#include "nx_tzdb/pacific.h"
26#include "nx_tzdb/us.h"
27#include "nx_tzdb/zoneinfo.h"
diff --git a/externals/nx_tzdb/tzdb_template.h.in b/externals/nx_tzdb/tzdb_template.h.in
new file mode 100644
index 000000000..289d002ea
--- /dev/null
+++ b/externals/nx_tzdb/tzdb_template.h.in
@@ -0,0 +1,18 @@
1// SPDX-FileCopyrightText: 2023 yuzu Emulator Project
2// SPDX-License-Identifier: GPL-2.0-or-later
3
4#pragma once
5
6#include <cstdint>
7#include <map>
8#include <vector>
9
10namespace NxTzdb {
11
12// clang-format off
13const static std::map<const char*, const std::vector<uint8_t>> @DIRECTORY_NAME@ =
14{
15@FILE_DATA@};
16// clang-format on
17
18} // namespace NxTzdb
diff --git a/externals/nx_tzdb/tzdb_to_nx b/externals/nx_tzdb/tzdb_to_nx
new file mode 160000
Subproject 212afa2394a74226dcf1b7996a570aae17debb6
diff --git a/externals/opus/CMakeLists.txt b/externals/opus/CMakeLists.txt
index 410ff7c08..d9a03423d 100644
--- a/externals/opus/CMakeLists.txt
+++ b/externals/opus/CMakeLists.txt
@@ -23,7 +23,7 @@ else()
23 endif() 23 endif()
24endif() 24endif()
25 25
26add_library(opus STATIC 26add_library(opus
27 # CELT sources 27 # CELT sources
28 opus/celt/bands.c 28 opus/celt/bands.c
29 opus/celt/celt.c 29 opus/celt/celt.c
diff --git a/externals/stb/stb_dxt.cpp b/externals/stb/stb_dxt.cpp
new file mode 100644
index 000000000..64f1f3d03
--- /dev/null
+++ b/externals/stb/stb_dxt.cpp
@@ -0,0 +1,765 @@
1// SPDX-FileCopyrightText: fabian "ryg" giesen
2// SPDX-License-Identifier: MIT
3
4// stb_dxt.h - v1.12 - DXT1/DXT5 compressor
5
6#include <stb_dxt.h>
7
8#include <stdlib.h>
9#include <string.h>
10
11#if !defined(STBD_FABS)
12#include <math.h>
13#endif
14
15#ifndef STBD_FABS
16#define STBD_FABS(x) fabs(x)
17#endif
18
19static const unsigned char stb__OMatch5[256][2] = {
20 {0, 0}, {0, 0}, {0, 1}, {0, 1}, {1, 0}, {1, 0}, {1, 0}, {1, 1}, {1, 1},
21 {1, 1}, {1, 2}, {0, 4}, {2, 1}, {2, 1}, {2, 1}, {2, 2}, {2, 2}, {2, 2},
22 {2, 3}, {1, 5}, {3, 2}, {3, 2}, {4, 0}, {3, 3}, {3, 3}, {3, 3}, {3, 4},
23 {3, 4}, {3, 4}, {3, 5}, {4, 3}, {4, 3}, {5, 2}, {4, 4}, {4, 4}, {4, 5},
24 {4, 5}, {5, 4}, {5, 4}, {5, 4}, {6, 3}, {5, 5}, {5, 5}, {5, 6}, {4, 8},
25 {6, 5}, {6, 5}, {6, 5}, {6, 6}, {6, 6}, {6, 6}, {6, 7}, {5, 9}, {7, 6},
26 {7, 6}, {8, 4}, {7, 7}, {7, 7}, {7, 7}, {7, 8}, {7, 8}, {7, 8}, {7, 9},
27 {8, 7}, {8, 7}, {9, 6}, {8, 8}, {8, 8}, {8, 9}, {8, 9}, {9, 8}, {9, 8},
28 {9, 8}, {10, 7}, {9, 9}, {9, 9}, {9, 10}, {8, 12}, {10, 9}, {10, 9}, {10, 9},
29 {10, 10}, {10, 10}, {10, 10}, {10, 11}, {9, 13}, {11, 10}, {11, 10}, {12, 8}, {11, 11},
30 {11, 11}, {11, 11}, {11, 12}, {11, 12}, {11, 12}, {11, 13}, {12, 11}, {12, 11}, {13, 10},
31 {12, 12}, {12, 12}, {12, 13}, {12, 13}, {13, 12}, {13, 12}, {13, 12}, {14, 11}, {13, 13},
32 {13, 13}, {13, 14}, {12, 16}, {14, 13}, {14, 13}, {14, 13}, {14, 14}, {14, 14}, {14, 14},
33 {14, 15}, {13, 17}, {15, 14}, {15, 14}, {16, 12}, {15, 15}, {15, 15}, {15, 15}, {15, 16},
34 {15, 16}, {15, 16}, {15, 17}, {16, 15}, {16, 15}, {17, 14}, {16, 16}, {16, 16}, {16, 17},
35 {16, 17}, {17, 16}, {17, 16}, {17, 16}, {18, 15}, {17, 17}, {17, 17}, {17, 18}, {16, 20},
36 {18, 17}, {18, 17}, {18, 17}, {18, 18}, {18, 18}, {18, 18}, {18, 19}, {17, 21}, {19, 18},
37 {19, 18}, {20, 16}, {19, 19}, {19, 19}, {19, 19}, {19, 20}, {19, 20}, {19, 20}, {19, 21},
38 {20, 19}, {20, 19}, {21, 18}, {20, 20}, {20, 20}, {20, 21}, {20, 21}, {21, 20}, {21, 20},
39 {21, 20}, {22, 19}, {21, 21}, {21, 21}, {21, 22}, {20, 24}, {22, 21}, {22, 21}, {22, 21},
40 {22, 22}, {22, 22}, {22, 22}, {22, 23}, {21, 25}, {23, 22}, {23, 22}, {24, 20}, {23, 23},
41 {23, 23}, {23, 23}, {23, 24}, {23, 24}, {23, 24}, {23, 25}, {24, 23}, {24, 23}, {25, 22},
42 {24, 24}, {24, 24}, {24, 25}, {24, 25}, {25, 24}, {25, 24}, {25, 24}, {26, 23}, {25, 25},
43 {25, 25}, {25, 26}, {24, 28}, {26, 25}, {26, 25}, {26, 25}, {26, 26}, {26, 26}, {26, 26},
44 {26, 27}, {25, 29}, {27, 26}, {27, 26}, {28, 24}, {27, 27}, {27, 27}, {27, 27}, {27, 28},
45 {27, 28}, {27, 28}, {27, 29}, {28, 27}, {28, 27}, {29, 26}, {28, 28}, {28, 28}, {28, 29},
46 {28, 29}, {29, 28}, {29, 28}, {29, 28}, {30, 27}, {29, 29}, {29, 29}, {29, 30}, {29, 30},
47 {30, 29}, {30, 29}, {30, 29}, {30, 30}, {30, 30}, {30, 30}, {30, 31}, {30, 31}, {31, 30},
48 {31, 30}, {31, 30}, {31, 31}, {31, 31},
49};
50static const unsigned char stb__OMatch6[256][2] = {
51 {0, 0}, {0, 1}, {1, 0}, {1, 1}, {1, 1}, {1, 2}, {2, 1}, {2, 2}, {2, 2},
52 {2, 3}, {3, 2}, {3, 3}, {3, 3}, {3, 4}, {4, 3}, {4, 4}, {4, 4}, {4, 5},
53 {5, 4}, {5, 5}, {5, 5}, {5, 6}, {6, 5}, {6, 6}, {6, 6}, {6, 7}, {7, 6},
54 {7, 7}, {7, 7}, {7, 8}, {8, 7}, {8, 8}, {8, 8}, {8, 9}, {9, 8}, {9, 9},
55 {9, 9}, {9, 10}, {10, 9}, {10, 10}, {10, 10}, {10, 11}, {11, 10}, {8, 16}, {11, 11},
56 {11, 12}, {12, 11}, {9, 17}, {12, 12}, {12, 13}, {13, 12}, {11, 16}, {13, 13}, {13, 14},
57 {14, 13}, {12, 17}, {14, 14}, {14, 15}, {15, 14}, {14, 16}, {15, 15}, {15, 16}, {16, 14},
58 {16, 15}, {17, 14}, {16, 16}, {16, 17}, {17, 16}, {18, 15}, {17, 17}, {17, 18}, {18, 17},
59 {20, 14}, {18, 18}, {18, 19}, {19, 18}, {21, 15}, {19, 19}, {19, 20}, {20, 19}, {20, 20},
60 {20, 20}, {20, 21}, {21, 20}, {21, 21}, {21, 21}, {21, 22}, {22, 21}, {22, 22}, {22, 22},
61 {22, 23}, {23, 22}, {23, 23}, {23, 23}, {23, 24}, {24, 23}, {24, 24}, {24, 24}, {24, 25},
62 {25, 24}, {25, 25}, {25, 25}, {25, 26}, {26, 25}, {26, 26}, {26, 26}, {26, 27}, {27, 26},
63 {24, 32}, {27, 27}, {27, 28}, {28, 27}, {25, 33}, {28, 28}, {28, 29}, {29, 28}, {27, 32},
64 {29, 29}, {29, 30}, {30, 29}, {28, 33}, {30, 30}, {30, 31}, {31, 30}, {30, 32}, {31, 31},
65 {31, 32}, {32, 30}, {32, 31}, {33, 30}, {32, 32}, {32, 33}, {33, 32}, {34, 31}, {33, 33},
66 {33, 34}, {34, 33}, {36, 30}, {34, 34}, {34, 35}, {35, 34}, {37, 31}, {35, 35}, {35, 36},
67 {36, 35}, {36, 36}, {36, 36}, {36, 37}, {37, 36}, {37, 37}, {37, 37}, {37, 38}, {38, 37},
68 {38, 38}, {38, 38}, {38, 39}, {39, 38}, {39, 39}, {39, 39}, {39, 40}, {40, 39}, {40, 40},
69 {40, 40}, {40, 41}, {41, 40}, {41, 41}, {41, 41}, {41, 42}, {42, 41}, {42, 42}, {42, 42},
70 {42, 43}, {43, 42}, {40, 48}, {43, 43}, {43, 44}, {44, 43}, {41, 49}, {44, 44}, {44, 45},
71 {45, 44}, {43, 48}, {45, 45}, {45, 46}, {46, 45}, {44, 49}, {46, 46}, {46, 47}, {47, 46},
72 {46, 48}, {47, 47}, {47, 48}, {48, 46}, {48, 47}, {49, 46}, {48, 48}, {48, 49}, {49, 48},
73 {50, 47}, {49, 49}, {49, 50}, {50, 49}, {52, 46}, {50, 50}, {50, 51}, {51, 50}, {53, 47},
74 {51, 51}, {51, 52}, {52, 51}, {52, 52}, {52, 52}, {52, 53}, {53, 52}, {53, 53}, {53, 53},
75 {53, 54}, {54, 53}, {54, 54}, {54, 54}, {54, 55}, {55, 54}, {55, 55}, {55, 55}, {55, 56},
76 {56, 55}, {56, 56}, {56, 56}, {56, 57}, {57, 56}, {57, 57}, {57, 57}, {57, 58}, {58, 57},
77 {58, 58}, {58, 58}, {58, 59}, {59, 58}, {59, 59}, {59, 59}, {59, 60}, {60, 59}, {60, 60},
78 {60, 60}, {60, 61}, {61, 60}, {61, 61}, {61, 61}, {61, 62}, {62, 61}, {62, 62}, {62, 62},
79 {62, 63}, {63, 62}, {63, 63}, {63, 63},
80};
81
82static int stb__Mul8Bit(int a, int b) {
83 int t = a * b + 128;
84 return (t + (t >> 8)) >> 8;
85}
86
87static void stb__From16Bit(unsigned char* out, unsigned short v) {
88 int rv = (v & 0xf800) >> 11;
89 int gv = (v & 0x07e0) >> 5;
90 int bv = (v & 0x001f) >> 0;
91
92 // expand to 8 bits via bit replication
93 out[0] = static_cast<unsigned char>((rv * 33) >> 2);
94 out[1] = static_cast<unsigned char>((gv * 65) >> 4);
95 out[2] = static_cast<unsigned char>((bv * 33) >> 2);
96 out[3] = 0;
97}
98
99static unsigned short stb__As16Bit(int r, int g, int b) {
100 return (unsigned short)((stb__Mul8Bit(r, 31) << 11) + (stb__Mul8Bit(g, 63) << 5) +
101 stb__Mul8Bit(b, 31));
102}
103
104// linear interpolation at 1/3 point between a and b, using desired rounding
105// type
106static int stb__Lerp13(int a, int b) {
107#ifdef STB_DXT_USE_ROUNDING_BIAS
108 // with rounding bias
109 return a + stb__Mul8Bit(b - a, 0x55);
110#else
111 // without rounding bias
112 // replace "/ 3" by "* 0xaaab) >> 17" if your compiler sucks or you really
113 // need every ounce of speed.
114 return (2 * a + b) / 3;
115#endif
116}
117
118// linear interpolation at 1/2 point between a and b
119static int stb__Lerp12(int a, int b) {
120 return (a + b) / 2;
121}
122
123// lerp RGB color
124static void stb__Lerp13RGB(unsigned char* out, unsigned char* p1, unsigned char* p2) {
125 out[0] = (unsigned char)stb__Lerp13(p1[0], p2[0]);
126 out[1] = (unsigned char)stb__Lerp13(p1[1], p2[1]);
127 out[2] = (unsigned char)stb__Lerp13(p1[2], p2[2]);
128}
129
130static void stb__Lerp12RGB(unsigned char* out, unsigned char* p1, unsigned char* p2) {
131 out[0] = (unsigned char)stb__Lerp12(p1[0], p2[0]);
132 out[1] = (unsigned char)stb__Lerp12(p1[1], p2[1]);
133 out[2] = (unsigned char)stb__Lerp12(p1[2], p2[2]);
134}
135
136/****************************************************************************/
137
138static void stb__Eval4Colors(unsigned char* color, unsigned short c0, unsigned short c1) {
139 stb__From16Bit(color + 0, c0);
140 stb__From16Bit(color + 4, c1);
141 stb__Lerp13RGB(color + 8, color + 0, color + 4);
142 stb__Lerp13RGB(color + 12, color + 4, color + 0);
143}
144
145static void stb__Eval3Colors(unsigned char* color, unsigned short c0, unsigned short c1) {
146 stb__From16Bit(color + 0, c0);
147 stb__From16Bit(color + 4, c1);
148 stb__Lerp12RGB(color + 8, color + 0, color + 4);
149}
150
151// The color matching function
152static unsigned int stb__MatchColorsBlock(unsigned char* block, unsigned char* color) {
153 unsigned int mask = 0;
154 int dirr = color[0 * 4 + 0] - color[1 * 4 + 0];
155 int dirg = color[0 * 4 + 1] - color[1 * 4 + 1];
156 int dirb = color[0 * 4 + 2] - color[1 * 4 + 2];
157 int dots[16];
158 int stops[4];
159 int i;
160 int c0Point, halfPoint, c3Point;
161
162 for (i = 0; i < 16; i++)
163 dots[i] = block[i * 4 + 0] * dirr + block[i * 4 + 1] * dirg + block[i * 4 + 2] * dirb;
164
165 for (i = 0; i < 4; i++)
166 stops[i] = color[i * 4 + 0] * dirr + color[i * 4 + 1] * dirg + color[i * 4 + 2] * dirb;
167
168 // think of the colors as arranged on a line; project point onto that line,
169 // then choose next color out of available ones. we compute the crossover
170 // points for "best color in top half"/"best in bottom half" and then the same
171 // inside that subinterval.
172 //
173 // relying on this 1d approximation isn't always optimal in terms of euclidean
174 // distance, but it's very close and a lot faster.
175 // http://cbloomrants.blogspot.com/2008/12/12-08-08-dxtc-summary.html
176
177 c0Point = (stops[1] + stops[3]);
178 halfPoint = (stops[3] + stops[2]);
179 c3Point = (stops[2] + stops[0]);
180
181 for (i = 15; i >= 0; i--) {
182 int dot = dots[i] * 2;
183 mask <<= 2;
184
185 if (dot < halfPoint)
186 mask |= (dot < c0Point) ? 1 : 3;
187 else
188 mask |= (dot < c3Point) ? 2 : 0;
189 }
190
191 return mask;
192}
193
194static unsigned int stb__MatchColorsAlphaBlock(unsigned char* block, unsigned char* color) {
195 unsigned int mask = 0;
196 int dirr = color[0 * 4 + 0] - color[1 * 4 + 0];
197 int dirg = color[0 * 4 + 1] - color[1 * 4 + 1];
198 int dirb = color[0 * 4 + 2] - color[1 * 4 + 2];
199 int dots[16];
200 int stops[3];
201 int i;
202 int c0Point, c2Point;
203
204 for (i = 0; i < 16; i++)
205 dots[i] = block[i * 4 + 0] * dirr + block[i * 4 + 1] * dirg + block[i * 4 + 2] * dirb;
206
207 for (i = 0; i < 3; i++)
208 stops[i] = color[i * 4 + 0] * dirr + color[i * 4 + 1] * dirg + color[i * 4 + 2] * dirb;
209
210 c0Point = (stops[1] + stops[2]);
211 c2Point = (stops[2] + stops[0]);
212
213 for (i = 15; i >= 0; i--) {
214 int dot = dots[i] * 2;
215 mask <<= 2;
216
217 if (block[i * 4 + 3] == 0)
218 mask |= 3;
219 else if (dot < c2Point)
220 mask |= (dot < c0Point) ? 0 : 2;
221 else
222 mask |= (dot < c0Point) ? 1 : 0;
223 }
224
225 return mask;
226}
227
228static void stb__ReorderColors(unsigned short* pmax16, unsigned short* pmin16) {
229 if (*pmin16 < *pmax16) {
230 unsigned short t = *pmin16;
231 *pmin16 = *pmax16;
232 *pmax16 = t;
233 }
234}
235
236static void stb__FinalizeColors(unsigned short* pmax16, unsigned short* pmin16,
237 unsigned int* pmask) {
238 if (*pmax16 < *pmin16) {
239 unsigned short t = *pmin16;
240 *pmin16 = *pmax16;
241 *pmax16 = t;
242 *pmask ^= 0x55555555;
243 }
244}
245
246// The color optimization function. (Clever code, part 1)
247static void stb__OptimizeColorsBlock(unsigned char* block, unsigned short* pmax16,
248 unsigned short* pmin16) {
249 int mind, maxd;
250 unsigned char *minp, *maxp;
251 double magn;
252 int v_r, v_g, v_b;
253 static const int nIterPower = 4;
254 float covf[6], vfr, vfg, vfb;
255
256 // determine color distribution
257 int cov[6];
258 int mu[3], min[3], max[3];
259 int ch, i, iter;
260
261 for (ch = 0; ch < 3; ch++) {
262 const unsigned char* bp = ((const unsigned char*)block) + ch;
263 int muv, minv, maxv;
264
265 muv = minv = maxv = bp[0];
266 for (i = 4; i < 64; i += 4) {
267 muv += bp[i];
268 if (bp[i] < minv)
269 minv = bp[i];
270 else if (bp[i] > maxv)
271 maxv = bp[i];
272 }
273
274 mu[ch] = (muv + 8) >> 4;
275 min[ch] = minv;
276 max[ch] = maxv;
277 }
278
279 // determine covariance matrix
280 for (i = 0; i < 6; i++)
281 cov[i] = 0;
282
283 for (i = 0; i < 16; i++) {
284 int r = block[i * 4 + 0] - mu[0];
285 int g = block[i * 4 + 1] - mu[1];
286 int b = block[i * 4 + 2] - mu[2];
287
288 cov[0] += r * r;
289 cov[1] += r * g;
290 cov[2] += r * b;
291 cov[3] += g * g;
292 cov[4] += g * b;
293 cov[5] += b * b;
294 }
295
296 // convert covariance matrix to float, find principal axis via power iter
297 for (i = 0; i < 6; i++)
298 covf[i] = static_cast<float>(cov[i]) / 255.0f;
299
300 vfr = (float)(max[0] - min[0]);
301 vfg = (float)(max[1] - min[1]);
302 vfb = (float)(max[2] - min[2]);
303
304 for (iter = 0; iter < nIterPower; iter++) {
305 float r = vfr * covf[0] + vfg * covf[1] + vfb * covf[2];
306 float g = vfr * covf[1] + vfg * covf[3] + vfb * covf[4];
307 float b = vfr * covf[2] + vfg * covf[4] + vfb * covf[5];
308
309 vfr = r;
310 vfg = g;
311 vfb = b;
312 }
313
314 magn = STBD_FABS(vfr);
315 if (STBD_FABS(vfg) > magn)
316 magn = STBD_FABS(vfg);
317 if (STBD_FABS(vfb) > magn)
318 magn = STBD_FABS(vfb);
319
320 if (magn < 4.0f) { // too small, default to luminance
321 v_r = 299; // JPEG YCbCr luma coefs, scaled by 1000.
322 v_g = 587;
323 v_b = 114;
324 } else {
325 magn = 512.0 / magn;
326 v_r = (int)(vfr * magn);
327 v_g = (int)(vfg * magn);
328 v_b = (int)(vfb * magn);
329 }
330
331 minp = maxp = block;
332 mind = maxd = block[0] * v_r + block[1] * v_g + block[2] * v_b;
333 // Pick colors at extreme points
334 for (i = 1; i < 16; i++) {
335 int dot = block[i * 4 + 0] * v_r + block[i * 4 + 1] * v_g + block[i * 4 + 2] * v_b;
336
337 if (dot < mind) {
338 mind = dot;
339 minp = block + i * 4;
340 }
341
342 if (dot > maxd) {
343 maxd = dot;
344 maxp = block + i * 4;
345 }
346 }
347
348 *pmax16 = stb__As16Bit(maxp[0], maxp[1], maxp[2]);
349 *pmin16 = stb__As16Bit(minp[0], minp[1], minp[2]);
350 stb__ReorderColors(pmax16, pmin16);
351}
352
353static void stb__OptimizeColorsAlphaBlock(unsigned char* block, unsigned short* pmax16,
354 unsigned short* pmin16) {
355 int mind, maxd;
356 unsigned char *minp, *maxp;
357 double magn;
358 int v_r, v_g, v_b;
359 static const int nIterPower = 4;
360 float covf[6], vfr, vfg, vfb;
361
362 // determine color distribution
363 int cov[6];
364 int mu[3], min[3], max[3];
365 int ch, i, iter;
366
367 for (ch = 0; ch < 3; ch++) {
368 const unsigned char* bp = ((const unsigned char*)block) + ch;
369 int muv = 0, minv = 256, maxv = -1;
370 int num = 0;
371
372 for (i = 0; i < 64; i += 4) {
373 if (bp[3 - ch] == 0) {
374 continue;
375 }
376
377 muv += bp[i];
378 if (bp[i] < minv)
379 minv = bp[i];
380 else if (bp[i] > maxv)
381 maxv = bp[i];
382
383 num++;
384 }
385
386 mu[ch] = num > 0 ? (muv + 8) / num : 0;
387 min[ch] = minv;
388 max[ch] = maxv;
389 }
390
391 // determine covariance matrix
392 for (i = 0; i < 6; i++)
393 cov[i] = 0;
394
395 for (i = 0; i < 16; i++) {
396 if (block[i * 4 + 3] == 0) {
397 continue;
398 }
399
400 int r = block[i * 4 + 0] - mu[0];
401 int g = block[i * 4 + 1] - mu[1];
402 int b = block[i * 4 + 2] - mu[2];
403
404 cov[0] += r * r;
405 cov[1] += r * g;
406 cov[2] += r * b;
407 cov[3] += g * g;
408 cov[4] += g * b;
409 cov[5] += b * b;
410 }
411
412 // convert covariance matrix to float, find principal axis via power iter
413 for (i = 0; i < 6; i++)
414 covf[i] = static_cast<float>(cov[i]) / 255.0f;
415
416 vfr = (float)(max[0] - min[0]);
417 vfg = (float)(max[1] - min[1]);
418 vfb = (float)(max[2] - min[2]);
419
420 for (iter = 0; iter < nIterPower; iter++) {
421 float r = vfr * covf[0] + vfg * covf[1] + vfb * covf[2];
422 float g = vfr * covf[1] + vfg * covf[3] + vfb * covf[4];
423 float b = vfr * covf[2] + vfg * covf[4] + vfb * covf[5];
424
425 vfr = r;
426 vfg = g;
427 vfb = b;
428 }
429
430 magn = STBD_FABS(vfr);
431 if (STBD_FABS(vfg) > magn)
432 magn = STBD_FABS(vfg);
433 if (STBD_FABS(vfb) > magn)
434 magn = STBD_FABS(vfb);
435
436 if (magn < 4.0f) { // too small, default to luminance
437 v_r = 299; // JPEG YCbCr luma coefs, scaled by 1000.
438 v_g = 587;
439 v_b = 114;
440 } else {
441 magn = 512.0 / magn;
442 v_r = (int)(vfr * magn);
443 v_g = (int)(vfg * magn);
444 v_b = (int)(vfb * magn);
445 }
446
447 minp = maxp = NULL;
448 mind = 0x7fffffff;
449 maxd = -0x80000000;
450
451 // Pick colors at extreme points
452 for (i = 0; i < 16; i++) {
453 if (block[i * 4 + 3] == 0) {
454 continue;
455 }
456
457 int dot = block[i * 4 + 0] * v_r + block[i * 4 + 1] * v_g + block[i * 4 + 2] * v_b;
458
459 if (dot < mind) {
460 mind = dot;
461 minp = block + i * 4;
462 }
463
464 if (dot > maxd) {
465 maxd = dot;
466 maxp = block + i * 4;
467 }
468 }
469
470 if (!maxp) {
471 // all alpha, no color
472 *pmin16 = 0xffff;
473 *pmax16 = 0;
474 } else {
475 // endpoint colors found
476 *pmax16 = stb__As16Bit(maxp[0], maxp[1], maxp[2]);
477 *pmin16 = stb__As16Bit(minp[0], minp[1], minp[2]);
478
479 if (*pmax16 == *pmin16) {
480 // modify the endpoints to indicate presence of an alpha block
481 if (*pmax16 > 0) {
482 (*pmax16)--;
483 } else {
484 (*pmin16)++;
485 }
486 }
487
488 stb__ReorderColors(pmax16, pmin16);
489 }
490}
491
492static const float stb__midpoints5[32] = {
493 0.015686f, 0.047059f, 0.078431f, 0.111765f, 0.145098f, 0.176471f, 0.207843f, 0.241176f,
494 0.274510f, 0.305882f, 0.337255f, 0.370588f, 0.403922f, 0.435294f, 0.466667f, 0.5f,
495 0.533333f, 0.564706f, 0.596078f, 0.629412f, 0.662745f, 0.694118f, 0.725490f, 0.758824f,
496 0.792157f, 0.823529f, 0.854902f, 0.888235f, 0.921569f, 0.952941f, 0.984314f, 1.0f};
497
498static const float stb__midpoints6[64] = {
499 0.007843f, 0.023529f, 0.039216f, 0.054902f, 0.070588f, 0.086275f, 0.101961f, 0.117647f,
500 0.133333f, 0.149020f, 0.164706f, 0.180392f, 0.196078f, 0.211765f, 0.227451f, 0.245098f,
501 0.262745f, 0.278431f, 0.294118f, 0.309804f, 0.325490f, 0.341176f, 0.356863f, 0.372549f,
502 0.388235f, 0.403922f, 0.419608f, 0.435294f, 0.450980f, 0.466667f, 0.482353f, 0.500000f,
503 0.517647f, 0.533333f, 0.549020f, 0.564706f, 0.580392f, 0.596078f, 0.611765f, 0.627451f,
504 0.643137f, 0.658824f, 0.674510f, 0.690196f, 0.705882f, 0.721569f, 0.737255f, 0.754902f,
505 0.772549f, 0.788235f, 0.803922f, 0.819608f, 0.835294f, 0.850980f, 0.866667f, 0.882353f,
506 0.898039f, 0.913725f, 0.929412f, 0.945098f, 0.960784f, 0.976471f, 0.992157f, 1.0f};
507
508static unsigned short stb__Quantize5(float x) {
509 unsigned short q;
510 x = x < 0 ? 0 : x > 1 ? 1 : x; // saturate
511 q = (unsigned short)(x * 31);
512 q += (x > stb__midpoints5[q]);
513 return q;
514}
515
516static unsigned short stb__Quantize6(float x) {
517 unsigned short q;
518 x = x < 0 ? 0 : x > 1 ? 1 : x; // saturate
519 q = (unsigned short)(x * 63);
520 q += (x > stb__midpoints6[q]);
521 return q;
522}
523
524// The refinement function. (Clever code, part 2)
525// Tries to optimize colors to suit block contents better.
526// (By solving a least squares system via normal equations+Cramer's rule)
527static int stb__RefineBlock(unsigned char* block, unsigned short* pmax16, unsigned short* pmin16,
528 unsigned int mask) {
529 static const int w1Tab[4] = {3, 0, 2, 1};
530 static const int prods[4] = {0x090000, 0x000900, 0x040102, 0x010402};
531 // ^some magic to save a lot of multiplies in the accumulating loop...
532 // (precomputed products of weights for least squares system, accumulated
533 // inside one 32-bit register)
534
535 float f;
536 unsigned short oldMin, oldMax, min16, max16;
537 int i, akku = 0, xx, xy, yy;
538 int At1_r, At1_g, At1_b;
539 int At2_r, At2_g, At2_b;
540 unsigned int cm = mask;
541
542 oldMin = *pmin16;
543 oldMax = *pmax16;
544
545 if ((mask ^ (mask << 2)) < 4) // all pixels have the same index?
546 {
547 // yes, linear system would be singular; solve using optimal
548 // single-color match on average color
549 int r = 8, g = 8, b = 8;
550 for (i = 0; i < 16; ++i) {
551 r += block[i * 4 + 0];
552 g += block[i * 4 + 1];
553 b += block[i * 4 + 2];
554 }
555
556 r >>= 4;
557 g >>= 4;
558 b >>= 4;
559
560 max16 = static_cast<unsigned short>((stb__OMatch5[r][0] << 11) | (stb__OMatch6[g][0] << 5) |
561 stb__OMatch5[b][0]);
562 min16 = static_cast<unsigned short>((stb__OMatch5[r][1] << 11) | (stb__OMatch6[g][1] << 5) |
563 stb__OMatch5[b][1]);
564 } else {
565 At1_r = At1_g = At1_b = 0;
566 At2_r = At2_g = At2_b = 0;
567 for (i = 0; i < 16; ++i, cm >>= 2) {
568 int step = cm & 3;
569 int w1 = w1Tab[step];
570 int r = block[i * 4 + 0];
571 int g = block[i * 4 + 1];
572 int b = block[i * 4 + 2];
573
574 akku += prods[step];
575 At1_r += w1 * r;
576 At1_g += w1 * g;
577 At1_b += w1 * b;
578 At2_r += r;
579 At2_g += g;
580 At2_b += b;
581 }
582
583 At2_r = 3 * At2_r - At1_r;
584 At2_g = 3 * At2_g - At1_g;
585 At2_b = 3 * At2_b - At1_b;
586
587 // extract solutions and decide solvability
588 xx = akku >> 16;
589 yy = (akku >> 8) & 0xff;
590 xy = (akku >> 0) & 0xff;
591
592 f = 3.0f / 255.0f / static_cast<float>(xx * yy - xy * xy);
593
594 max16 = static_cast<unsigned short>(
595 stb__Quantize5(static_cast<float>(At1_r * yy - At2_r * xy) * f) << 11);
596 max16 |= static_cast<unsigned short>(
597 stb__Quantize6(static_cast<float>(At1_g * yy - At2_g * xy) * f) << 5);
598 max16 |= static_cast<unsigned short>(
599 stb__Quantize5(static_cast<float>(At1_b * yy - At2_b * xy) * f) << 0);
600
601 min16 = static_cast<unsigned short>(
602 stb__Quantize5(static_cast<float>(At2_r * xx - At1_r * xy) * f) << 11);
603 min16 |= static_cast<unsigned short>(
604 stb__Quantize6(static_cast<float>(At2_g * xx - At1_g * xy) * f) << 5);
605 min16 |= static_cast<unsigned short>(
606 stb__Quantize5(static_cast<float>(At2_b * xx - At1_b * xy) * f) << 0);
607 }
608
609 *pmin16 = min16;
610 *pmax16 = max16;
611 stb__ReorderColors(pmax16, pmin16);
612
613 return oldMin != min16 || oldMax != max16;
614}
615
616// Color block compression
617static void stb__CompressColorBlock(unsigned char* dest, unsigned char* block, int alpha,
618 int mode) {
619 unsigned int mask;
620 int i;
621 int refinecount;
622 unsigned short max16, min16;
623 unsigned char color[4 * 4];
624
625 refinecount = (mode & STB_DXT_HIGHQUAL) ? 2 : 1;
626
627 // check if block is constant
628 for (i = 1; i < 16; i++)
629 if (((unsigned int*)block)[i] != ((unsigned int*)block)[0])
630 break;
631
632 if (i == 16 && block[3] == 0 && alpha) { // constant alpha
633 mask = 0xffffffff;
634 max16 = 0;
635 min16 = 0xffff;
636 } else if (i == 16) { // constant color
637 int r = block[0], g = block[1], b = block[2];
638 mask = 0xaaaaaaaa;
639 max16 = static_cast<unsigned short>((stb__OMatch5[r][0] << 11) | (stb__OMatch6[g][0] << 5) |
640 stb__OMatch5[b][0]);
641 min16 = static_cast<unsigned short>((stb__OMatch5[r][1] << 11) | (stb__OMatch6[g][1] << 5) |
642 stb__OMatch5[b][1]);
643 } else if (alpha) {
644 stb__OptimizeColorsAlphaBlock(block, &max16, &min16);
645 stb__Eval3Colors(color, max16, min16);
646 mask = stb__MatchColorsAlphaBlock(block, color);
647 } else {
648 // first step: PCA+map along principal axis
649 stb__OptimizeColorsBlock(block, &max16, &min16);
650 if (max16 != min16) {
651 stb__Eval4Colors(color, max16, min16);
652 mask = stb__MatchColorsBlock(block, color);
653 } else
654 mask = 0;
655
656 // third step: refine (multiple times if requested)
657 for (i = 0; i < refinecount; i++) {
658 unsigned int lastmask = mask;
659
660 if (stb__RefineBlock(block, &max16, &min16, mask)) {
661 if (max16 != min16) {
662 stb__Eval4Colors(color, max16, min16);
663 mask = stb__MatchColorsBlock(block, color);
664 } else {
665 mask = 0;
666 break;
667 }
668 }
669
670 if (mask == lastmask)
671 break;
672 }
673 }
674
675 // write the color block
676 if (!alpha)
677 stb__FinalizeColors(&max16, &min16, &mask);
678
679 dest[0] = (unsigned char)(max16);
680 dest[1] = (unsigned char)(max16 >> 8);
681 dest[2] = (unsigned char)(min16);
682 dest[3] = (unsigned char)(min16 >> 8);
683 dest[4] = (unsigned char)(mask);
684 dest[5] = (unsigned char)(mask >> 8);
685 dest[6] = (unsigned char)(mask >> 16);
686 dest[7] = (unsigned char)(mask >> 24);
687}
688
689// Alpha block compression (this is easy for a change)
690static void stb__CompressAlphaBlock(unsigned char* dest, unsigned char* src, int stride) {
691 int i, dist, bias, dist4, dist2, bits, mask;
692
693 // find min/max color
694 int mn, mx;
695 mn = mx = src[0];
696
697 for (i = 1; i < 16; i++) {
698 if (src[i * stride] < mn)
699 mn = src[i * stride];
700 else if (src[i * stride] > mx)
701 mx = src[i * stride];
702 }
703
704 // encode them
705 dest[0] = (unsigned char)mx;
706 dest[1] = (unsigned char)mn;
707 dest += 2;
708
709 // determine bias and emit color indices
710 // given the choice of mx/mn, these indices are optimal:
711 // http://fgiesen.wordpress.com/2009/12/15/dxt5-alpha-block-index-determination/
712 dist = mx - mn;
713 dist4 = dist * 4;
714 dist2 = dist * 2;
715 bias = (dist < 8) ? (dist - 1) : (dist / 2 + 2);
716 bias -= mn * 7;
717 bits = 0, mask = 0;
718
719 for (i = 0; i < 16; i++) {
720 int a = src[i * stride] * 7 + bias;
721 int ind, t;
722
723 // select index. this is a "linear scale" lerp factor between 0 (val=min)
724 // and 7 (val=max).
725 t = (a >= dist4) ? -1 : 0;
726 ind = t & 4;
727 a -= dist4 & t;
728 t = (a >= dist2) ? -1 : 0;
729 ind += t & 2;
730 a -= dist2 & t;
731 ind += (a >= dist);
732
733 // turn linear scale into DXT index (0/1 are extremal pts)
734 ind = -ind & 7;
735 ind ^= (2 > ind);
736
737 // write index
738 mask |= ind << bits;
739 if ((bits += 3) >= 8) {
740 *dest++ = (unsigned char)mask;
741 mask >>= 8;
742 bits -= 8;
743 }
744 }
745}
746
747void stb_compress_bc1_block(unsigned char* dest, const unsigned char* src, int alpha, int mode) {
748 stb__CompressColorBlock(dest, (unsigned char*)src, alpha, mode);
749}
750
751void stb_compress_bc3_block(unsigned char* dest, const unsigned char* src, int mode) {
752 unsigned char data[16][4];
753 int i;
754
755 stb__CompressAlphaBlock(dest, (unsigned char*)src + 3, 4);
756 dest += 8;
757 // make a new copy of the data in which alpha is opaque,
758 // because code uses a fast test for color constancy
759 memcpy(data, src, 4 * 16);
760 for (i = 0; i < 16; ++i)
761 data[i][3] = 255;
762 src = &data[0][0];
763
764 stb__CompressColorBlock(dest, (unsigned char*)src, 0, mode);
765}
diff --git a/externals/stb/stb_dxt.h b/externals/stb/stb_dxt.h
new file mode 100644
index 000000000..07d1d1de4
--- /dev/null
+++ b/externals/stb/stb_dxt.h
@@ -0,0 +1,36 @@
1// SPDX-FileCopyrightText: fabian "ryg" giesen
2// SPDX-License-Identifier: MIT
3
4// stb_dxt.h - v1.12 - DXT1/DXT5 compressor
5
6#ifndef STB_INCLUDE_STB_DXT_H
7#define STB_INCLUDE_STB_DXT_H
8
9#ifdef __cplusplus
10extern "C" {
11#endif
12
13#ifdef STB_DXT_STATIC
14#define STBDDEF static
15#else
16#define STBDDEF extern
17#endif
18
19// compression mode (bitflags)
20#define STB_DXT_NORMAL 0
21#define STB_DXT_DITHER 1 // use dithering. was always dubious, now deprecated. does nothing!
22#define STB_DXT_HIGHQUAL \
23 2 // high quality mode, does two refinement steps instead of 1. ~30-40% slower.
24
25STBDDEF void stb_compress_bc1_block(unsigned char* dest,
26 const unsigned char* src_rgba_four_bytes_per_pixel, int alpha,
27 int mode);
28
29STBDDEF void stb_compress_bc3_block(unsigned char* dest, const unsigned char* src, int mode);
30
31#define STB_COMPRESS_DXT_BLOCK
32
33#ifdef __cplusplus
34}
35#endif
36#endif // STB_INCLUDE_STB_DXT_H
diff --git a/externals/vcpkg b/externals/vcpkg
Subproject 9b22b40c6c61bf0da2d46346dd44a11e90972cc Subproject cbf56573a987527b39272e88cbdd11389b78c6e
diff --git a/externals/vma/VulkanMemoryAllocator b/externals/vma/VulkanMemoryAllocator
new file mode 160000
Subproject 0aa3989b8f382f185fdf646cc83a1d16fa31d6a
diff --git a/externals/vma/vma.cpp b/externals/vma/vma.cpp
new file mode 100644
index 000000000..1fe2cf52b
--- /dev/null
+++ b/externals/vma/vma.cpp
@@ -0,0 +1,8 @@
1// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
2// SPDX-License-Identifier: GPL-2.0-or-later
3
4#define VMA_IMPLEMENTATION
5#define VMA_STATIC_VULKAN_FUNCTIONS 0
6#define VMA_DYNAMIC_VULKAN_FUNCTIONS 1
7
8#include <vk_mem_alloc.h> \ No newline at end of file