Merge pull request #16 from project-slippi/upstream-merge-2024-02-09

chore: upstream merge to 5.0-21088
This commit is contained in:
Nikhil Narayana 2024-02-14 21:29:53 -08:00 committed by GitHub
commit bdd9005675
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2170 changed files with 255084 additions and 290565 deletions

View file

@ -32,7 +32,7 @@ jobs:
name: Verify SlippiRustExtensions Commit is in Main
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v4
- name: Main Branch Check
shell: bash
run: |
@ -59,7 +59,7 @@ jobs:
runs-on: windows-2022
steps:
- name: "Checkout"
uses: actions/checkout@v3
uses: actions/checkout@v4
with:
submodules: recursive
- id: rust_ver
@ -72,7 +72,7 @@ jobs:
toolchain: ${{ steps.rust_ver.outputs.rust_ver }} # Pin to our specific Rust version.
rustflags: "" # Disable default injection of warnings = errors.
- name: Cache Utils
uses: actions/cache@v3
uses: actions/cache@v4
with:
path: |
./CodeSignTool/
@ -117,9 +117,9 @@ jobs:
echo "not release, skipping code signing"
exit 0;
}
mkdir CodeSignTool
cd .\CodeSignTool
if (!(Test-Path ".\CodeSignTool\CodeSignTool.bat" -PathType Leaf)) {
if (!(Test-Path ".\CodeSignTool\CodeSignTool.bat" -PathType Leaf)) {
mkdir CodeSignTool
cd .\CodeSignTool
Invoke-WebRequest -Uri https://www.ssl.com/download/codesigntool-for-windows/ -UseBasicParsing -OutFile ".\CodeSignTool.zip"
7z x CodeSignTool.zip
Remove-Item CodeSignTool.zip
@ -136,7 +136,7 @@ jobs:
7z a $FILE_NAME .\*
move $FILE_NAME ..\..\artifact\
- name: "Publish"
uses: actions/upload-artifact@v3
uses: actions/upload-artifact@v4
with:
name: ${{ matrix.artifact_name }}
path: "./artifact/"
@ -158,7 +158,7 @@ jobs:
runs-on: ubuntu-22.04
steps:
- name: "Checkout"
uses: actions/checkout@v3
uses: actions/checkout@v4
with:
submodules: recursive
- id: rust_ver
@ -216,6 +216,7 @@ jobs:
libegl1-mesa-dev \
libpng-dev \
qt6-base-private-dev \
libqt6svg6-dev \
libxxf86vm-dev \
x11proto-xinerama-dev \
libfuse2
@ -240,7 +241,7 @@ jobs:
popd
mv "${FILE_NAME}" ./artifact/
- name: "Publish"
uses: actions/upload-artifact@v3
uses: actions/upload-artifact@v4
with:
name: ${{ matrix.artifact_name }}
path: "./artifact/"
@ -262,7 +263,7 @@ jobs:
runs-on: macos-12
steps:
- name: "Checkout"
uses: actions/checkout@v3
uses: actions/checkout@v4
with:
submodules: recursive
- id: rust_ver
@ -349,7 +350,7 @@ jobs:
/usr/bin/codesign -f -s "${{ secrets.APPLE_IDENTITY_HASH }}" --deep --options runtime ./artifact/${{ env.FILE_NAME }}.dmg
chmod +x Tools/notarize_netplay.sh && ./Tools/notarize_netplay.sh ./artifact/${{ env.FILE_NAME }}.dmg
- name: "Publish"
uses: actions/upload-artifact@v3
uses: actions/upload-artifact@v4
with:
name: ${{ matrix.artifact_name }}
path: "./artifact/"

24
.gitmodules vendored
View file

@ -57,3 +57,27 @@
[submodule "Externals/SlippiRustExtensions"]
path = Externals/SlippiRustExtensions
url = https://github.com/project-slippi/slippi-rust-extensions.git
[submodule "Externals/rcheevos/rcheevos"]
path = Externals/rcheevos/rcheevos
url = https://github.com/RetroAchievements/rcheevos.git
[submodule "Externals/libadrenotools"]
path = Externals/libadrenotools
url = https://github.com/bylaws/libadrenotools.git
[submodule "Externals/curl/curl"]
path = Externals/curl/curl
url = https://github.com/curl/curl.git
[submodule "Externals/fmt/fmt"]
path = Externals/fmt/fmt
url = https://github.com/fmtlib/fmt.git
[submodule "Externals/lz4/lz4"]
path = Externals/lz4/lz4
url = https://github.com/lz4/lz4
[submodule "Externals/xxhash/xxHash"]
path = Externals/xxhash/xxHash
url = https://github.com/Cyan4973/xxHash.git
[submodule "Externals/enet/enet"]
path = Externals/enet/enet
url = https://github.com/lsalzman/enet.git
[submodule "hidapi-src"]
path = Externals/hidapi/hidapi-src
url = https://github.com/libusb/hidapi

View file

@ -76,7 +76,10 @@ DEFAULT_CONFIG = {
"steam": False,
# Whether our autoupdate functionality is enabled or not.
"autoupdate": True
"autoupdate": True,
# The distributor for this build.
"distributor": "None"
}
# Architectures to build for. This is explicity left out of the command line
@ -136,6 +139,11 @@ def parse_args(conf=DEFAULT_CONFIG):
action=argparse.BooleanOptionalAction,
default=conf["autoupdate"])
parser.add_argument(
"--distributor",
help="Sets the distributor for this build",
default=conf["distributor"])
parser.add_argument(
"--codesign",
help="Code signing identity to use to sign the applications",
@ -316,6 +324,7 @@ def build(config):
+ python_to_cmake_bool(config["steam"]),
"-DENABLE_AUTOUPDATE="
+ python_to_cmake_bool(config["autoupdate"]),
'-DDISTRIBUTOR=' + config['distributor']
],
env=env, cwd=arch)

View file

@ -21,6 +21,8 @@ function(check_and_add_flag var flag)
set(genexp_config_test "1")
if(ARGV2 STREQUAL "DEBUG_ONLY")
set(genexp_config_test "$<CONFIG:Debug>")
elseif(ARGV2 STREQUAL "NO_DEBINFO_ONLY")
set(genexp_config_test "$<NOT:$<OR:$<CONFIG:Debug>,$<CONFIG:RelWithDebInfo>>>")
elseif(ARGV2 STREQUAL "RELEASE_ONLY")
set(genexp_config_test "$<NOT:$<CONFIG:Debug>>")
elseif(ARGV2)

View file

@ -1,29 +0,0 @@
# When packaging Dolphin for an OS distribution, distro vendors usually prefer
# to limit vendored ("Externals") dependencies as much as possible, in favor of
# using system provided libraries. This modules provides an option to allow
# only specific vendored dependencies and error-out at configuration time for
# non-approved ones.
#
# Usage:
# $ cmake -D APPROVED_VENDORED_DEPENDENCIES="a;b;c;..."
#
# Unless the option is explicitly used, vendored dependencies control is
# disabled.
#
# If you want to disallow all vendored dependencies, put "none" in the approved
# dependencies list.
set(APPROVED_VENDORED_DEPENDENCIES "" CACHE STRING "\
Semicolon separated list of approved vendored dependencies. See docstring in \
CMake/CheckVendoringApproved.cmake.")
function(check_vendoring_approved dep)
if(APPROVED_VENDORED_DEPENDENCIES)
if(NOT dep IN_LIST APPROVED_VENDORED_DEPENDENCIES)
message(SEND_ERROR "\
Library ${dep} was not found systemwide and was not approved for vendoring. \
Vendored dependencies control is enabled. Add \"${dep}\" to the \
APPROVED_VENDORED_DEPENDENCIES list to bypass this error.")
endif()
endif()
endfunction()

View file

@ -18,3 +18,78 @@ function(dolphin_make_imported_target_if_missing target lib)
add_library(${target} ALIAS _${lib})
endif()
endfunction()
function(dolphin_optional_system_library library)
string(TOUPPER ${library} upperlib)
set(USE_SYSTEM_${upperlib} "" CACHE STRING "Use system ${library} instead of bundled. ON - Always use system and fail if unavailable, OFF - Always use bundled, AUTO - Use system if available, otherwise use bundled, blank - Delegate to USE_SYSTEM_LIBS. Default is blank.")
if("${USE_SYSTEM_${upperlib}}" STREQUAL "")
if(APPROVED_VENDORED_DEPENDENCIES)
string(TOLOWER ${library} lowerlib)
if(lowerlib IN_LIST APPROVED_VENDORED_DEPENDENCIES)
set(RESOLVED_USE_SYSTEM_${upperlib} AUTO PARENT_SCOPE)
else()
set(RESOLVED_USE_SYSTEM_${upperlib} ON PARENT_SCOPE)
endif()
else()
set(RESOLVED_USE_SYSTEM_${upperlib} ${USE_SYSTEM_LIBS} PARENT_SCOPE)
endif()
else()
set(RESOLVED_USE_SYSTEM_${upperlib} ${USE_SYSTEM_${upperlib}} PARENT_SCOPE)
endif()
endfunction()
function(dolphin_add_bundled_library library bundled_path)
string(TOUPPER ${library} upperlib)
if (${RESOLVED_USE_SYSTEM_${upperlib}} STREQUAL "AUTO")
message(STATUS "No system ${library} was found. Using static ${library} from Externals.")
else()
message(STATUS "Using static ${library} from Externals")
endif()
if (NOT EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/${bundled_path}/CMakeLists.txt")
message(FATAL_ERROR "No bundled ${library} was found. Did you forget to checkout submodules?")
endif()
add_subdirectory(${bundled_path} EXCLUDE_FROM_ALL)
endfunction()
function(dolphin_find_optional_system_library library bundled_path)
dolphin_optional_system_library(${library})
string(TOUPPER ${library} upperlib)
if(RESOLVED_USE_SYSTEM_${upperlib})
find_package(${library} ${ARGN})
# Yay for cmake packages being inconsistent
if(DEFINED ${library}_FOUND)
set(prefix ${library})
else()
set(prefix ${upperlib})
endif()
if((NOT ${found}) AND (NOT ${RESOLVED_USE_SYSTEM_${upperlib}} STREQUAL "AUTO"))
message(FATAL_ERROR "No system ${library} was found. Please install it or set USE_SYSTEM_${upperlib} to AUTO or OFF.")
endif()
endif()
if(${prefix}_FOUND)
message(STATUS "Using system ${library}")
set(${prefix}_TYPE "System" PARENT_SCOPE)
else()
dolphin_add_bundled_library(${library} ${bundled_path})
set(${prefix}_TYPE "Bundled" PARENT_SCOPE)
endif()
endfunction()
function(dolphin_find_optional_system_library_pkgconfig library search alias bundled_path)
dolphin_optional_system_library(${library})
string(TOUPPER ${library} upperlib)
if(RESOLVED_USE_SYSTEM_${upperlib})
pkg_check_modules(${library} ${search} ${ARGN} IMPORTED_TARGET)
if((NOT ${library}_FOUND) AND (NOT ${RESOLVED_USE_SYSTEM_${upperlib}} STREQUAL "AUTO"))
message(FATAL_ERROR "No system ${library} was found. Please install it or set USE_SYSTEM_${upperlib} to AUTO or OFF.")
endif()
endif()
if(${library}_FOUND)
message(STATUS "Using system ${library}")
dolphin_alias_library(${alias} PkgConfig::${library})
set(${library}_TYPE "System" PARENT_SCOPE)
else()
dolphin_add_bundled_library(${library} ${bundled_path})
set(${library}_TYPE "Bundled" PARENT_SCOPE)
endif()
endfunction()

View file

@ -6,7 +6,7 @@ include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(CUBEB DEFAULT_MSG
CUBEB_INCLUDE_DIR CUBEB_LIBRARY)
if(CUBEB_FOUND AND NOT TARGET CUBEB)
if(CUBEB_FOUND AND NOT TARGET cubeb::cubeb)
add_library(cubeb::cubeb UNKNOWN IMPORTED)
set_target_properties(cubeb::cubeb PROPERTIES
IMPORTED_LOCATION "${CUBEB_LIBRARY}"

101
CMake/FindIconv.cmake Normal file
View file

@ -0,0 +1,101 @@
# Based on CMake's FindIconv.cmake
# Modified to prefer non-built-in iconv over the built-in one
# See https://gitlab.kitware.com/cmake/cmake/-/issues/24695 for details
# This file can be deleted once that issue has been closed and the fix has
# made it into a satisfactory number of cmake versions. FreeBSD is the only
# system known to hit this so far, so "satisfactory" can probably be defined
# as "enough that most FreeBSD users have a fixed cmake".
find_path(Iconv_INCLUDE_DIR
NAMES "iconv.h"
DOC "iconv include directory")
mark_as_advanced(Iconv_INCLUDE_DIR)
find_library(Iconv_LIBRARY
NAMES iconv libiconv
NAMES_PER_DIR
DOC "iconv library (if not in the C library)")
mark_as_advanced(Iconv_LIBRARY)
# iconv can only be provided in libc on a POSIX system.
if(UNIX AND (NOT Iconv_INCLUDE_DIR OR NOT Iconv_LIBRARY))
include(CMakePushCheckState)
include(CheckCXXSourceCompiles)
cmake_push_check_state(RESET)
# We always suppress the message here: Otherwise on supported systems
# not having iconv in their C library (e.g. those using libiconv)
# would always display a confusing "Looking for iconv - not found" message
set(CMAKE_FIND_QUIETLY TRUE)
# The following code will not work, but it's sufficient to see if it compiles.
# Note: libiconv will define the iconv functions as macros, so CheckSymbolExists
# will not yield correct results.
set(Iconv_IMPLICIT_TEST_CODE
"
#include <stddef.h>
#include <iconv.h>
int main() {
char *a, *b;
size_t i, j;
iconv_t ic;
ic = iconv_open(\"to\", \"from\");
iconv(ic, &a, &i, &b, &j);
iconv_close(ic);
}
"
)
check_cxx_source_compiles("${Iconv_IMPLICIT_TEST_CODE}" Iconv_IS_BUILT_IN)
cmake_pop_check_state()
if(Iconv_IS_BUILT_IN)
unset(Iconv_INCLUDE_DIR)
unset(Iconv_LIBRARY)
endif()
else()
set(Iconv_IS_BUILT_IN FALSE)
endif()
set(_Iconv_REQUIRED_VARS)
if(Iconv_IS_BUILT_IN)
set(_Iconv_REQUIRED_VARS _Iconv_IS_BUILT_IN_MSG)
set(_Iconv_IS_BUILT_IN_MSG "built in to C library")
else()
set(_Iconv_REQUIRED_VARS Iconv_LIBRARY Iconv_INCLUDE_DIR)
endif()
# NOTE: glibc's iconv.h does not define _LIBICONV_VERSION
if(Iconv_INCLUDE_DIR AND EXISTS "${Iconv_INCLUDE_DIR}/iconv.h")
file(STRINGS ${Iconv_INCLUDE_DIR}/iconv.h Iconv_VERSION_DEFINE REGEX "_LIBICONV_VERSION (.*)")
if(Iconv_VERSION_DEFINE MATCHES "(0x[A-Fa-f0-9]+)")
set(Iconv_VERSION_NUMBER "${CMAKE_MATCH_1}")
# encoding -> version number: (major<<8) + minor
math(EXPR Iconv_VERSION_MAJOR "${Iconv_VERSION_NUMBER} >> 8" OUTPUT_FORMAT HEXADECIMAL)
math(EXPR Iconv_VERSION_MINOR "${Iconv_VERSION_NUMBER} - (${Iconv_VERSION_MAJOR} << 8)" OUTPUT_FORMAT HEXADECIMAL)
math(EXPR Iconv_VERSION_MAJOR "${Iconv_VERSION_MAJOR}" OUTPUT_FORMAT DECIMAL)
math(EXPR Iconv_VERSION_MINOR "${Iconv_VERSION_MINOR}" OUTPUT_FORMAT DECIMAL)
set(Iconv_VERSION "${Iconv_VERSION_MAJOR}.${Iconv_VERSION_MINOR}")
endif()
unset(Iconv_VERSION_DEFINE)
unset(Iconv_VERSION_NUMBER)
endif()
include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(Iconv
REQUIRED_VARS ${_Iconv_REQUIRED_VARS}
VERSION_VAR Iconv_VERSION)
if(Iconv_FOUND)
if(Iconv_IS_BUILT_IN)
set(Iconv_INCLUDE_DIRS "")
set(Iconv_LIBRARIES "")
else()
set(Iconv_INCLUDE_DIRS "${Iconv_INCLUDE_DIR}")
set(Iconv_LIBRARIES "${Iconv_LIBRARY}")
endif()
if(NOT TARGET Iconv::Iconv)
add_library(Iconv::Iconv INTERFACE IMPORTED)
set_property(TARGET Iconv::Iconv PROPERTY INTERFACE_INCLUDE_DIRECTORIES "${Iconv_INCLUDE_DIRS}")
set_property(TARGET Iconv::Iconv PROPERTY INTERFACE_LINK_LIBRARIES "${Iconv_LIBRARIES}")
endif()
endif()

15
CMake/FindLZO.cmake Normal file
View file

@ -0,0 +1,15 @@
find_path(LZO_INCLUDE_DIR lzo/lzo1x.h)
find_library(LZO_LIBRARY lzo2)
mark_as_advanced(LZO_INCLUDE_DIR LZO_LIBRARY)
include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(LZO DEFAULT_MSG
LZO_INCLUDE_DIR LZO_LIBRARY)
if(LZO_FOUND AND NOT TARGET LZO::LZO)
add_library(LZO::LZO UNKNOWN IMPORTED)
set_target_properties(LZO::LZO PROPERTIES
IMPORTED_LOCATION "${LZO_LIBRARY}"
INTERFACE_INCLUDE_DIRECTORIES "${LZO_INCLUDE_DIR}"
)
endif()

View file

@ -40,4 +40,11 @@ elseif (NOT LIBUSB_FOUND)
mark_as_advanced(LIBUSB_INCLUDE_DIR LIBUSB_LIBRARIES)
endif ()
if(LIBUSB_FOUND AND NOT TARGET LibUSB::LibUSB)
add_library(LibUSB::LibUSB UNKNOWN IMPORTED)
set_target_properties(LibUSB::LibUSB PROPERTIES
IMPORTED_LOCATION "${LIBUSB_LIBRARIES}"
INTERFACE_INCLUDE_DIRECTORIES "${LIBUSB_INCLUDE_DIR}"
)
endif()

View file

@ -1,23 +1,59 @@
find_path(MBEDTLS_INCLUDE_DIR mbedtls/ssl.h)
find_path(MBEDTLS_INCLUDE_DIR mbedtls/ssl.h PATH_SUFFIXES mbedtls2)
find_library(MBEDTLS_LIBRARY mbedtls)
find_library(MBEDX509_LIBRARY mbedx509)
find_library(MBEDCRYPTO_LIBRARY mbedcrypto)
find_library(MBEDTLS_LIBRARY mbedtls PATH_SUFFIXES mbedtls2)
find_library(MBEDX509_LIBRARY mbedx509 PATH_SUFFIXES mbedtls2)
find_library(MBEDCRYPTO_LIBRARY mbedcrypto PATH_SUFFIXES mbedtls2)
set(MBEDTLS_INCLUDE_DIRS ${MBEDTLS_INCLUDE_DIR})
set(MBEDTLS_LIBRARIES ${MBEDTLS_LIBRARY} ${MBEDX509_LIBRARY} ${MBEDCRYPTO_LIBRARY})
set(CMAKE_REQUIRED_INCLUDES ${MBEDTLS_INCLUDE_DIRS})
check_cxx_source_compiles("
#include <mbedtls/version.h>
#if MBEDTLS_VERSION_NUMBER < 0x021C0000
#error \"Your mbed TLS version is too old.\"
#endif
int main() {}"
MBEDTLS_VERSION_OK)
if(NOT MBEDTLS_INCLUDE_DIR STREQUAL "MBEDTLS_INCLUDE_DIR-NOTFOUND")
if(EXISTS ${MBEDTLS_INCLUDE_DIR}/mbedtls/build_info.h)
file(STRINGS ${MBEDTLS_INCLUDE_DIR}/mbedtls/build_info.h MBEDTLS_VERSION_STR REGEX "^#define[ \t]+MBEDTLS_VERSION_STRING[\t ].*")
else()
file(STRINGS ${MBEDTLS_INCLUDE_DIR}/mbedtls/version.h MBEDTLS_VERSION_STR REGEX "^#define[ \t]+MBEDTLS_VERSION_STRING[\t ].*")
endif()
string(REGEX REPLACE "^#define[\t ]+MBEDTLS_VERSION_STRING[\t ]+\"([.0-9]+)\".*" "\\1" MBEDTLS_VERSION ${MBEDTLS_VERSION_STR})
endif()
include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(MBEDTLS DEFAULT_MSG
MBEDTLS_INCLUDE_DIR MBEDTLS_LIBRARY MBEDX509_LIBRARY MBEDCRYPTO_LIBRARY MBEDTLS_VERSION_OK)
if(NOT MBEDTLS_INCLUDE_DIR STREQUAL "MBEDTLS_INCLUDE_DIR-NOTFOUND" AND MBEDTLS_VERSION VERSION_GREATER_EQUAL 3)
# Once CMake 3.19 is required, we can enable HANDLE_VERSION_RANGE and use that
if(MBEDTLS_FIND_REQUIRED)
set(type FATAL_ERROR)
else()
set(type STATUS)
endif()
if(MBEDTLS_FIND_REQUIRED OR NOT MBEDTLS_FIND_QUIETLY)
message(${type} "Could NOT find MBEDTLS: Found unsuitable version \"${MBEDTLS_VERSION}\", but a 2.x version is required (found ${MBEDTLS_INCLUDE_DIR})")
endif()
set(MBEDTLS_FOUND FALSE)
else()
include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(MBEDTLS
REQUIRED_VARS MBEDTLS_INCLUDE_DIR MBEDTLS_LIBRARY MBEDX509_LIBRARY MBEDCRYPTO_LIBRARY
VERSION_VAR MBEDTLS_VERSION)
endif()
mark_as_advanced(MBEDTLS_INCLUDE_DIR MBEDTLS_LIBRARY MBEDX509_LIBRARY MBEDCRYPTO_LIBRARY)
if(MBEDTLS_FOUND)
add_library(MbedTLS::mbedcrypto UNKNOWN IMPORTED)
set_target_properties(MbedTLS::mbedcrypto PROPERTIES
IMPORTED_LOCATION "${MBEDCRYPTO_LIBRARY}"
INTERFACE_INCLUDE_DIRECTORIES "${MBEDTLS_INCLUDE_DIR}"
)
add_library(MbedTLS::mbedx509 UNKNOWN IMPORTED)
set_target_properties(MbedTLS::mbedx509 PROPERTIES
IMPORTED_LOCATION "${MBEDX509_LIBRARY}"
INTERFACE_INCLUDE_DIRECTORIES "${MBEDTLS_INCLUDE_DIR}"
INTERFACE_LINK_LIBRARIES MbedTLS::mbedcrypto
)
add_library(MbedTLS::mbedtls UNKNOWN IMPORTED)
set_target_properties(MbedTLS::mbedtls PROPERTIES
IMPORTED_LOCATION "${MBEDTLS_LIBRARY}"
INTERFACE_INCLUDE_DIRECTORIES "${MBEDTLS_INCLUDE_DIR}"
INTERFACE_LINK_LIBRARIES MbedTLS::mbedx509
)
endif()

View file

@ -5,14 +5,17 @@ find_path(MINIUPNPC_INCLUDE_DIR miniupnpc.h PATH_SUFFIXES miniupnpc)
find_library(MINIUPNPC_LIBRARY miniupnpc)
if(MINIUPNPC_INCLUDE_DIR)
file(STRINGS "${MINIUPNPC_INCLUDE_DIR}/miniupnpc.h" MINIUPNPC_API_VERSION_STR REGEX "^#define[\t ]+MINIUPNPC_API_VERSION[\t ]+[0-9]+")
if(MINIUPNPC_API_VERSION_STR)
string(REGEX REPLACE "^#define[\t ]+MINIUPNPC_API_VERSION[\t ]+([0-9]+)" "\\1" MINIUPNPC_API_VERSION ${MINIUPNPC_API_VERSION_STR})
file(STRINGS "${MINIUPNPC_INCLUDE_DIR}/miniupnpc.h" MINIUPNPC_VERSION_STR REGEX "^#define[\t ]+MINIUPNPC_VERSION[\t ]+.*")
if(MINIUPNPC_VERSION_STR)
string(REGEX REPLACE "^#define[\t ]+MINIUPNPC_VERSION[\t ]+\"([.0-9]+)\"" "\\1" MINIUPNPC_VERSION ${MINIUPNPC_VERSION_STR})
endif()
endif()
include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(MINIUPNPC DEFAULT_MSG MINIUPNPC_INCLUDE_DIR MINIUPNPC_LIBRARY MINIUPNPC_API_VERSION)
find_package_handle_standard_args(MINIUPNPC
REQUIRED_VARS MINIUPNPC_INCLUDE_DIR MINIUPNPC_LIBRARY
VERSION_VAR MINIUPNPC_VERSION
)
set(MINIUPNPC_LIBRARIES ${MINIUPNPC_LIBRARY})
set(MINIUPNPC_INCLUDE_DIRS ${MINIUPNPC_INCLUDE_DIR})

View file

@ -1,250 +0,0 @@
# - Find SDL2
# Find the SDL2 headers and libraries
#
# SDL2::SDL2 - Imported target to use for building a library
# SDL2::SDL2main - Imported interface target to use if you want SDL and SDLmain.
# SDL2_FOUND - True if SDL2 was found.
# SDL2_DYNAMIC - If we found a DLL version of SDL (meaning you might want to copy a DLL from SDL2::SDL2)
#
# Original Author:
# 2015 Ryan Pavlik <ryan.pavlik@gmail.com> <abiryan@ryand.net>
#
# Copyright Sensics, Inc. 2015.
# Distributed under the Boost Software License, Version 1.0.
# (See accompanying file LICENSE_1_0.txt or copy at
# http://www.boost.org/LICENSE_1_0.txt)
# Set up architectures (for windows) and prefixes (for mingw builds)
if(WIN32)
if(MINGW)
include(MinGWSearchPathExtras OPTIONAL)
if(MINGWSEARCH_TARGET_TRIPLE)
set(SDL2_PREFIX ${MINGWSEARCH_TARGET_TRIPLE})
endif()
endif()
if(CMAKE_SIZEOF_VOID_P EQUAL 8)
set(SDL2_LIB_PATH_SUFFIX lib/x64)
if(NOT MSVC AND NOT SDL2_PREFIX)
set(SDL2_PREFIX x86_64-w64-mingw32)
endif()
else()
set(SDL2_LIB_PATH_SUFFIX lib/x86)
if(NOT MSVC AND NOT SDL2_PREFIX)
set(SDL2_PREFIX i686-w64-mingw32)
endif()
endif()
endif()
if(SDL2_PREFIX)
set(SDL2_ORIGPREFIXPATH ${CMAKE_PREFIX_PATH})
if(SDL2_ROOT_DIR)
list(APPEND CMAKE_PREFIX_PATH "${SDL2_ROOT_DIR}")
endif()
if(CMAKE_PREFIX_PATH)
foreach(_prefix ${CMAKE_PREFIX_PATH})
list(APPEND CMAKE_PREFIX_PATH "${_prefix}/${SDL2_PREFIX}")
endforeach()
endif()
if(MINGWSEARCH_PREFIXES)
list(APPEND CMAKE_PREFIX_PATH ${MINGWSEARCH_PREFIXES})
endif()
endif()
# Invoke pkgconfig for hints
find_package(PkgConfig QUIET)
set(SDL2_INCLUDE_HINTS)
set(SDL2_LIB_HINTS)
if(PKG_CONFIG_FOUND)
pkg_search_module(SDL2PC QUIET sdl2)
if(SDL2PC_INCLUDE_DIRS)
set(SDL2_INCLUDE_HINTS ${SDL2PC_INCLUDE_DIRS})
endif()
if(SDL2PC_LIBRARY_DIRS)
set(SDL2_LIB_HINTS ${SDL2PC_LIBRARY_DIRS})
endif()
endif()
include(FindPackageHandleStandardArgs)
find_library(SDL2_LIBRARY
NAMES
SDL2
HINTS
${SDL2_LIB_HINTS}
PATHS
${SDL2_ROOT_DIR}
ENV SDL2DIR
PATH_SUFFIXES lib SDL2 ${SDL2_LIB_PATH_SUFFIX})
set(_sdl2_framework FALSE)
# Some special-casing if we've found/been given a framework.
# Handles whether we're given the library inside the framework or the framework itself.
if(APPLE AND "${SDL2_LIBRARY}" MATCHES "(/[^/]+)*.framework(/.*)?$")
set(_sdl2_framework TRUE)
set(SDL2_FRAMEWORK "${SDL2_LIBRARY}")
# Move up in the directory tree as required to get the framework directory.
while("${SDL2_FRAMEWORK}" MATCHES "(/[^/]+)*.framework(/.*)$" AND NOT "${SDL2_FRAMEWORK}" MATCHES "(/[^/]+)*.framework$")
get_filename_component(SDL2_FRAMEWORK "${SDL2_FRAMEWORK}" DIRECTORY)
endwhile()
if("${SDL2_FRAMEWORK}" MATCHES "(/[^/]+)*.framework$")
set(SDL2_FRAMEWORK_NAME ${CMAKE_MATCH_1})
# If we found a framework, do a search for the header ahead of time that will be more likely to get the framework header.
find_path(SDL2_INCLUDE_DIR
NAMES
SDL_haptic.h # this file was introduced with SDL2
HINTS
"${SDL2_FRAMEWORK}/Headers/")
else()
# For some reason we couldn't get the framework directory itself.
# Shouldn't happen, but might if something is weird.
unset(SDL2_FRAMEWORK)
endif()
endif()
find_path(SDL2_INCLUDE_DIR
NAMES
SDL_haptic.h # this file was introduced with SDL2
HINTS
${SDL2_INCLUDE_HINTS}
PATHS
${SDL2_ROOT_DIR}
ENV SDL2DIR
PATH_SUFFIXES include include/sdl2 include/SDL2 SDL2)
if(WIN32 AND SDL2_LIBRARY)
find_file(SDL2_RUNTIME_LIBRARY
NAMES
SDL2.dll
libSDL2.dll
HINTS
${SDL2_LIB_HINTS}
PATHS
${SDL2_ROOT_DIR}
ENV SDL2DIR
PATH_SUFFIXES bin lib ${SDL2_LIB_PATH_SUFFIX})
endif()
if(WIN32 OR ANDROID OR IOS OR (APPLE AND NOT _sdl2_framework))
set(SDL2_EXTRA_REQUIRED SDL2_SDLMAIN_LIBRARY)
find_library(SDL2_SDLMAIN_LIBRARY
NAMES
SDL2main
PATHS
${SDL2_ROOT_DIR}
ENV SDL2DIR
PATH_SUFFIXES lib ${SDL2_LIB_PATH_SUFFIX})
endif()
if(MINGW AND NOT SDL2PC_FOUND)
find_library(SDL2_MINGW_LIBRARY mingw32)
find_library(SDL2_MWINDOWS_LIBRARY mwindows)
endif()
if(SDL2_PREFIX)
# Restore things the way they used to be.
set(CMAKE_PREFIX_PATH ${SDL2_ORIGPREFIXPATH})
endif()
# handle the QUIETLY and REQUIRED arguments and set QUATLIB_FOUND to TRUE if
# all listed variables are TRUE
include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(SDL2
DEFAULT_MSG
SDL2_LIBRARY
SDL2_INCLUDE_DIR
${SDL2_EXTRA_REQUIRED})
if(SDL2_FOUND)
if(NOT TARGET SDL2::SDL2)
# Create SDL2::SDL2
if(WIN32 AND SDL2_RUNTIME_LIBRARY)
set(SDL2_DYNAMIC TRUE)
add_library(SDL2::SDL2 SHARED IMPORTED)
set_target_properties(SDL2::SDL2
PROPERTIES
IMPORTED_IMPLIB "${SDL2_LIBRARY}"
IMPORTED_LOCATION "${SDL2_RUNTIME_LIBRARY}"
INTERFACE_INCLUDE_DIRECTORIES "${SDL2_INCLUDE_DIR}"
)
else()
add_library(SDL2::SDL2 UNKNOWN IMPORTED)
if(SDL2_FRAMEWORK AND SDL2_FRAMEWORK_NAME)
# Handle the case that SDL2 is a framework and we were able to decompose it above.
set_target_properties(SDL2::SDL2 PROPERTIES
IMPORTED_LOCATION "${SDL2_FRAMEWORK}/${SDL2_FRAMEWORK_NAME}")
elseif(_sdl2_framework AND SDL2_LIBRARY MATCHES "(/[^/]+)*.framework$")
# Handle the case that SDL2 is a framework and SDL_LIBRARY is just the framework itself.
# This takes the basename of the framework, without the extension,
# and sets it (as a child of the framework) as the imported location for the target.
# This is the library symlink inside of the framework.
set_target_properties(SDL2::SDL2 PROPERTIES
IMPORTED_LOCATION "${SDL2_LIBRARY}/${CMAKE_MATCH_1}")
else()
# Handle non-frameworks (including non-Mac), as well as the case that we're given the library inside of the framework
set_target_properties(SDL2::SDL2 PROPERTIES
IMPORTED_LOCATION "${SDL2_LIBRARY}")
endif()
set_target_properties(SDL2::SDL2
PROPERTIES
INTERFACE_INCLUDE_DIRECTORIES "${SDL2_INCLUDE_DIR}"
)
endif()
if(APPLE)
# Need Cocoa here, is always a framework
find_library(SDL2_COCOA_LIBRARY Cocoa)
list(APPEND SDL2_EXTRA_REQUIRED SDL2_COCOA_LIBRARY)
if(SDL2_COCOA_LIBRARY)
set_target_properties(SDL2::SDL2 PROPERTIES
IMPORTED_LINK_INTERFACE_LIBRARIES ${SDL2_COCOA_LIBRARY})
endif()
endif()
# Compute what to do with SDL2main
set(SDL2MAIN_LIBRARIES SDL2::SDL2)
add_library(SDL2::SDL2main INTERFACE IMPORTED)
if(SDL2_SDLMAIN_LIBRARY)
add_library(SDL2::SDL2main_real STATIC IMPORTED)
set_target_properties(SDL2::SDL2main_real
PROPERTIES
IMPORTED_LOCATION "${SDL2_SDLMAIN_LIBRARY}")
set(SDL2MAIN_LIBRARIES SDL2::SDL2main_real ${SDL2MAIN_LIBRARIES})
endif()
if(MINGW)
# MinGW requires some additional libraries to appear earlier in the link line.
if(SDL2PC_LIBRARIES)
# Use pkgconfig-suggested extra libraries if available.
list(REMOVE_ITEM SDL2PC_LIBRARIES SDL2main SDL2)
set(SDL2MAIN_LIBRARIES ${SDL2PC_LIBRARIES} ${SDL2MAIN_LIBRARIES})
else()
# fall back to extra libraries specified in pkg-config in
# an official binary distro of SDL2 for MinGW I downloaded
if(SDL2_MINGW_LIBRARY)
set(SDL2MAIN_LIBRARIES ${SDL2_MINGW_LIBRARY} ${SDL2MAIN_LIBRARIES})
endif()
if(SDL2_MWINDOWS_LIBRARY)
set(SDL2MAIN_LIBRARIES ${SDL2_MWINDOWS_LIBRARY} ${SDL2MAIN_LIBRARIES})
endif()
endif()
set_target_properties(SDL2::SDL2main
PROPERTIES
INTERFACE_COMPILE_DEFINITIONS "main=SDL_main")
endif()
set_target_properties(SDL2::SDL2main
PROPERTIES
INTERFACE_LINK_LIBRARIES "${SDL2MAIN_LIBRARIES}")
endif()
mark_as_advanced(SDL2_ROOT_DIR)
endif()
mark_as_advanced(SDL2_LIBRARY
SDL2_RUNTIME_LIBRARY
SDL2_INCLUDE_DIR
SDL2_SDLMAIN_LIBRARY
SDL2_COCOA_LIBRARY
SDL2_MINGW_LIBRARY
SDL2_MWINDOWS_LIBRARY)

View file

@ -206,4 +206,20 @@ endif()
# handle success
if(SFML_FOUND)
message(STATUS "Found SFML ${SFML_VERSION_MAJOR}.${SFML_VERSION_MINOR} in ${SFML_INCLUDE_DIR}")
foreach(FIND_SFML_COMPONENT ${SFML_FIND_COMPONENTS})
string(TOLOWER ${FIND_SFML_COMPONENT} FIND_SFML_COMPONENT_LOWER)
string(TOUPPER ${FIND_SFML_COMPONENT} FIND_SFML_COMPONENT_UPPER)
if(NOT TARGET sfml-${FIND_SFML_COMPONENT_LOWER})
add_library(sfml-${FIND_SFML_COMPONENT_LOWER} UNKNOWN IMPORTED)
set_target_properties(sfml-${FIND_SFML_COMPONENT_LOWER} PROPERTIES
IMPORTED_LOCATION "${SFML_${FIND_SFML_COMPONENT_UPPER}_LIBRARY}"
INTERFACE_INCLUDE_DIRECTORIES "${SFML_INCLUDE_DIR}"
)
if(NOT ${FIND_SFML_COMPONENT_LOWER} STREQUAL system)
set_target_properties(sfml-${FIND_SFML_COMPONENT_LOWER} PROPERTIES
INTERFACE_LINK_LIBRARIES sfml-system
)
endif()
endif()
endforeach()
endif()

53
CMake/ScmRevGen.cmake Normal file
View file

@ -0,0 +1,53 @@
cmake_minimum_required(VERSION 3.13)
# for revision info
if(GIT_FOUND)
# defines DOLPHIN_WC_REVISION
execute_process(WORKING_DIRECTORY ${PROJECT_SOURCE_DIR} COMMAND ${GIT_EXECUTABLE} rev-parse HEAD
OUTPUT_VARIABLE DOLPHIN_WC_REVISION
OUTPUT_STRIP_TRAILING_WHITESPACE)
# defines DOLPHIN_WC_DESCRIBE
execute_process(WORKING_DIRECTORY ${PROJECT_SOURCE_DIR} COMMAND ${GIT_EXECUTABLE} describe --always --long --dirty
OUTPUT_VARIABLE DOLPHIN_WC_DESCRIBE
OUTPUT_STRIP_TRAILING_WHITESPACE)
# remove hash (and trailing "-0" if needed) from description
string(REGEX REPLACE "(-0)?-[^-]+((-dirty)?)$" "\\2" DOLPHIN_WC_DESCRIBE "${DOLPHIN_WC_DESCRIBE}")
# defines DOLPHIN_WC_BRANCH
execute_process(WORKING_DIRECTORY ${PROJECT_SOURCE_DIR} COMMAND ${GIT_EXECUTABLE} rev-parse --abbrev-ref HEAD
OUTPUT_VARIABLE DOLPHIN_WC_BRANCH
OUTPUT_STRIP_TRAILING_WHITESPACE)
endif()
# version number
set(DOLPHIN_VERSION_MAJOR "5")
set(DOLPHIN_VERSION_MINOR "0")
if(DOLPHIN_WC_BRANCH STREQUAL "stable")
set(DOLPHIN_VERSION_PATCH "0")
else()
set(DOLPHIN_VERSION_PATCH ${DOLPHIN_WC_REVISION})
endif()
# If Dolphin is not built from a Git repository, default the version info to
# reasonable values.
if(NOT DOLPHIN_WC_REVISION)
set(DOLPHIN_WC_DESCRIBE "${DOLPHIN_VERSION_MAJOR}.${DOLPHIN_VERSION_MINOR}")
set(DOLPHIN_WC_REVISION "${DOLPHIN_WC_DESCRIBE} (no further info)")
set(DOLPHIN_WC_BRANCH "master")
endif()
if(DOLPHIN_WC_BRANCH STREQUAL "master" OR DOLPHIN_WC_BRANCH STREQUAL "stable")
set(DOLPHIN_WC_IS_STABLE "1")
else()
set(DOLPHIN_WC_IS_STABLE "0")
endif()
configure_file(
"${PROJECT_SOURCE_DIR}/Source/Core/Common/scmrev.h.in"
"${PROJECT_BINARY_DIR}/Source/Core/Common/scmrev.h.tmp"
)
execute_process(COMMAND ${CMAKE_COMMAND} -E copy_if_different "${PROJECT_BINARY_DIR}/Source/Core/Common/scmrev.h.tmp" "${PROJECT_BINARY_DIR}/Source/Core/Common/scmrev.h")
file(REMOVE "${PROJECT_BINARY_DIR}/Source/Core/Common/scmrev.h.tmp")

View file

@ -6,6 +6,10 @@ cmake_minimum_required(VERSION 3.13)
cmake_policy(SET CMP0079 NEW) # let target_link_libraries() link to a target defined in a different directory
cmake_policy(SET CMP0080 OLD) # allow using BundleUtilities at configure time
if (POLICY CMP0099)
cmake_policy(SET CMP0099 NEW) # Propagate INTERFACE_LINK_OPTIONS from private dependencies, used by MacOS framework builds of SDL
endif()
# Weird chicken-and-egg problem: We can't check the compiler before the project() call, but we have to set the policies before it.
# So we do this in two steps: Set the policies if they exist, then error out afterwards if we end up being MSVC and they don't exist.
if (POLICY CMP0117)
@ -38,6 +42,31 @@ if (MSVC)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
endif()
set(COMPILER ${CMAKE_CXX_COMPILER_ID})
if (COMPILER STREQUAL "GNU")
set(COMPILER "GCC") # perfer printing GCC instead of GNU
endif()
# Enforce minimium compiler versions that support the c++20 features we use
set (GCC_min_version 10)
set (Clang_min_version 12)
set (AppleClang_min_version 13.0.0)
set (min_xcode_version "13.0") # corrosponding xcode version for AppleClang_min_version
set (MSVC_min_version 14.32)
set (min_vs_version "2022 17.2.3") # corrosponding Visual Studio version for MSVC_min_version
message(STATUS "Using ${COMPILER} ${CMAKE_CXX_COMPILER_VERSION}")
if ("-" STREQUAL "${${COMPILER}_min_version}-")
message(WARNING "Unknown compiler ${COMPILER}, assuming it is new enough")
else()
if (CMAKE_CXX_COMPILER_VERSION VERSION_LESS ${${COMPILER}_min_version})
message(FATAL_ERROR "Requires GCC ${GCC_min_version}, Clang ${Clang_min_version},"
" AppleClang ${AppleClang_min_version} (Xcode ${min_xcode_version}),"
" or MSVC ${MSVC_min_version} (Visual Studio ${min_vs_version}) or higher")
endif()
endif()
# Name of the Dolphin distributor. If you redistribute Dolphin builds (forks,
# unofficial builds) please consider identifying your distribution with a
# unique name here.
@ -56,7 +85,11 @@ if(NOT ANDROID)
option(ENABLE_CLI_TOOL "Enable dolphin-tool, a CLI-based utility for functions such as managing disc images" OFF)
endif()
option(USE_SHARED_ENET "Use shared libenet if found rather than Dolphin's soon-to-compatibly-diverge version" OFF)
set(USE_SYSTEM_LIBS "AUTO" CACHE STRING "Use system libraries instead of bundled libraries. ON - Always use system and fail if unavailable, OFF - Always use bundled, AUTO - Use system if available, otherwise use bundled. Default is AUTO")
if(APPROVED_VENDORED_DEPENDENCIES)
message(WARNING "APPROVED_VENDORED_DEPENDENCIES is deprecated. Please migrate to setting USE_SYSTEM_LIBS to ON and setting USE_SYSTEM_<dependency> to either AUTO or OFF to allow bundled libs.")
endif()
option(USE_UPNP "Enables UPnP port mapping support" ON)
option(ENABLE_NOGUI "Enable NoGUI frontend" ON)
option(ENABLE_QT "Enable Qt (Default)" ON)
@ -72,6 +105,7 @@ option(USE_DISCORD_PRESENCE "Enables Discord Rich Presence, show the current gam
option(USE_MGBA "Enables GBA controllers emulation using libmgba" OFF)
option(ENABLE_AUTOUPDATE "Enables support for automatic updates" OFF)
option(STEAM "Creates a build for Steam" OFF)
option(USE_RETRO_ACHIEVEMENTS "Enables integration with retroachievements.org" ON)
# Maintainers: if you consider blanket disabling this for your users, please
# consider the following points:
@ -94,8 +128,8 @@ option(OPROFILING "Enable profiling" OFF)
# TODO: Add DSPSpy
option(DSPTOOL "Build dsptool" OFF)
# Enable SDL for default on operating systems that aren't Android or Linux.
if(NOT ANDROID AND NOT CMAKE_SYSTEM_NAME STREQUAL "Linux")
# Enable SDL by default on operating systems that aren't Android.
if(NOT ANDROID)
option(ENABLE_SDL "Enables SDL as a generic controller backend" ON)
else()
option(ENABLE_SDL "Enables SDL as a generic controller backend" OFF)
@ -132,7 +166,6 @@ list(APPEND CMAKE_MODULE_PATH
# Support functions
include(CheckAndAddFlag)
include(CheckCCompilerFlag)
include(CheckVendoringApproved)
include(DolphinCompileDefinitions)
include(DolphinDisableWarningsMSVC)
include(DolphinLibraryTools)
@ -170,59 +203,6 @@ endif()
# setup CCache
include(CCache)
# for revision info
find_package(Git)
if(GIT_FOUND)
# make sure version information gets re-run when the current Git HEAD changes
execute_process(WORKING_DIRECTORY ${PROJECT_SOURCE_DIR} COMMAND ${GIT_EXECUTABLE} rev-parse --git-path HEAD
OUTPUT_VARIABLE dolphin_git_head_filename
OUTPUT_STRIP_TRAILING_WHITESPACE)
set_property(DIRECTORY APPEND PROPERTY CMAKE_CONFIGURE_DEPENDS "${dolphin_git_head_filename}")
execute_process(WORKING_DIRECTORY ${PROJECT_SOURCE_DIR} COMMAND ${GIT_EXECUTABLE} rev-parse --symbolic-full-name HEAD
OUTPUT_VARIABLE dolphin_git_head_symbolic
OUTPUT_STRIP_TRAILING_WHITESPACE)
execute_process(WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}
COMMAND ${GIT_EXECUTABLE} rev-parse --git-path ${dolphin_git_head_symbolic}
OUTPUT_VARIABLE dolphin_git_head_symbolic_filename
OUTPUT_STRIP_TRAILING_WHITESPACE)
set_property(DIRECTORY APPEND PROPERTY CMAKE_CONFIGURE_DEPENDS "${dolphin_git_head_symbolic_filename}")
# defines DOLPHIN_WC_REVISION
execute_process(WORKING_DIRECTORY ${PROJECT_SOURCE_DIR} COMMAND ${GIT_EXECUTABLE} rev-parse HEAD
OUTPUT_VARIABLE DOLPHIN_WC_REVISION
OUTPUT_STRIP_TRAILING_WHITESPACE)
# defines DOLPHIN_WC_DESCRIBE
execute_process(WORKING_DIRECTORY ${PROJECT_SOURCE_DIR} COMMAND ${GIT_EXECUTABLE} describe --always --long --dirty
OUTPUT_VARIABLE DOLPHIN_WC_DESCRIBE
OUTPUT_STRIP_TRAILING_WHITESPACE)
# remove hash (and trailing "-0" if needed) from description
string(REGEX REPLACE "(-0)?-[^-]+((-dirty)?)$" "\\2" DOLPHIN_WC_DESCRIBE "${DOLPHIN_WC_DESCRIBE}")
# defines DOLPHIN_WC_BRANCH
execute_process(WORKING_DIRECTORY ${PROJECT_SOURCE_DIR} COMMAND ${GIT_EXECUTABLE} rev-parse --abbrev-ref HEAD
OUTPUT_VARIABLE DOLPHIN_WC_BRANCH
OUTPUT_STRIP_TRAILING_WHITESPACE)
endif()
# version number
set(DOLPHIN_VERSION_MAJOR "5")
set(DOLPHIN_VERSION_MINOR "0")
if(DOLPHIN_WC_BRANCH STREQUAL "stable")
set(DOLPHIN_VERSION_PATCH "0")
else()
set(DOLPHIN_VERSION_PATCH ${DOLPHIN_WC_REVISION})
endif()
# If Dolphin is not built from a Git repository, default the version info to
# reasonable values.
if(NOT DOLPHIN_WC_REVISION)
set(DOLPHIN_WC_DESCRIBE "${DOLPHIN_VERSION_MAJOR}.${DOLPHIN_VERSION_MINOR}")
set(DOLPHIN_WC_REVISION "${DOLPHIN_WC_DESCRIBE} (no further info)")
set(DOLPHIN_WC_BRANCH "master")
endif()
# Architecture detection and arch specific settings
message(STATUS "Detected architecture: ${CMAKE_SYSTEM_PROCESSOR}")
@ -243,9 +223,7 @@ if(ENABLE_GENERIC)
set(_M_GENERIC 1)
add_definitions(-D_M_GENERIC=1)
elseif(_ARCH_64 AND CMAKE_SYSTEM_PROCESSOR MATCHES "x86_64|amd64|AMD64")
set(_M_X86 1)
set(_M_X86_64 1)
add_definitions(-D_M_X86=1)
add_definitions(-D_M_X86_64=1)
check_and_add_flag(HAVE_SSE2 -msse2)
elseif(_ARCH_64 AND CMAKE_SYSTEM_PROCESSOR MATCHES "aarch64|arm64")
@ -259,12 +237,6 @@ else()
" Enable generic build if you really want a JIT-less binary.")
endif()
# Enforce minimum GCC version
if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU" AND CMAKE_CXX_COMPILER_VERSION VERSION_LESS 7.0)
message(FATAL_ERROR "Dolphin requires at least GCC 7.0 (found ${CMAKE_CXX_COMPILER_VERSION})")
endif()
if(CMAKE_GENERATOR MATCHES "Ninja")
check_and_add_flag(DIAGNOSTICS_COLOR -fdiagnostics-color)
elseif(CMAKE_GENERATOR MATCHES "Visual Studio")
@ -330,7 +302,7 @@ if(MSVC)
# Note: In msbuild build, this gets set by msbuild by default
add_compile_options(/Zc:inline)
# Fix various other non-conformant behaviors
add_compile_options(/Zc:__cplusplus,enumTypes,externConstexpr,preprocessor,throwingNew)
add_compile_options(/Zc:__cplusplus,enumTypes,externConstexpr,preprocessor,templateScope,throwingNew)
# Enforce strict volatile semantics as per ISO C++
add_compile_options(/volatile:iso)
@ -352,7 +324,7 @@ else()
check_and_add_flag(VISIBILITY_INLINES_HIDDEN -fvisibility-inlines-hidden)
check_and_add_flag(VISIBILITY_HIDDEN -fvisibility=hidden)
check_and_add_flag(FOMIT_FRAME_POINTER -fomit-frame-pointer RELEASE_ONLY)
check_and_add_flag(FOMIT_FRAME_POINTER -fomit-frame-pointer NO_DEBINFO_ONLY)
dolphin_compile_definitions(_DEBUG DEBUG_ONLY)
check_and_add_flag(GGDB -ggdb DEBUG_ONLY)
@ -621,32 +593,7 @@ if(UNIX)
endif()
if(ENABLE_SDL)
find_package(SDL2)
if(SDL2_FOUND)
message(STATUS "Using system SDL2")
else()
message(STATUS "Using static SDL2 from Externals")
option(SDL2_DISABLE_SDL2MAIN "" ON)
option(SDL2_DISABLE_INSTALL "" ON)
option(SDL2_DISABLE_UNINSTALL "" ON)
set(SDL_SHARED OFF)
set(SDL_SHARED_ENABLED_BY_DEFAULT OFF)
set(SDL_STATIC ON)
set(SDL_STATIC_ENABLED_BY_DEFAULT ON)
set(SDL_TEST OFF)
set(SDL_TEST_ENABLED_BY_DEFAULT OFF)
set(OPT_DEF_LIBC ON)
add_subdirectory(Externals/SDL/SDL)
if (TARGET SDL2)
dolphin_disable_warnings_msvc(SDL2)
endif()
if (TARGET SDL2-static)
dolphin_disable_warnings_msvc(SDL2-static)
endif()
set(SDL2_FOUND TRUE)
endif()
add_definitions(-DHAVE_SDL2=1)
dolphin_find_optional_system_library(SDL2 Externals/SDL 2.26.0)
endif()
if(ENABLE_ANALYTICS)
@ -687,28 +634,26 @@ endif()
# - place the CMakeLists.txt in the first-level subdirectory, e.g.
# Externals/zlib/CMakeLists.txt (that is: NOT in some Src/ subdirectory)
#
if (_M_X86)
if (_M_X86_64)
add_subdirectory(Externals/Bochs_disasm)
endif()
add_subdirectory(Externals/cpp-optparse)
find_package(fmt 8)
if(fmt_FOUND)
message(STATUS "Using shared fmt ${fmt_VERSION}")
else()
check_vendoring_approved(fmt)
message(STATUS "Using static fmt from Externals")
add_subdirectory(Externals/fmt EXCLUDE_FROM_ALL)
include_directories(Externals/fmt/include)
endif()
dolphin_find_optional_system_library(fmt Externals/fmt 10.1)
add_subdirectory(Externals/imgui)
add_subdirectory(Externals/implot)
add_subdirectory(Externals/glslang)
# SPIRV-Cross is used on Windows for GLSL to HLSL conversion for the Direct3D 11 and Direct3D 12
# video backends, and on Apple devices for the Metal video backend.
if(WIN32 OR APPLE)
add_subdirectory(Externals/spirv_cross)
endif()
# slippi includes
include_directories(Externals/nlohmann)
add_subdirectory(Externals/semver)
include_directories(Externals/semver/include)
add_subdirectory(Externals/open-vcdiff)
add_subdirectory(Externals/spirv_cross)
include_directories(Externals)
if(ENABLE_VULKAN)
@ -717,6 +662,11 @@ if(ENABLE_VULKAN)
if(APPLE AND USE_BUNDLED_MOLTENVK)
add_subdirectory(Externals/MoltenVK)
endif()
if (ANDROID AND _M_ARM_64)
add_subdirectory(Externals/libadrenotools)
endif()
endif()
if(NOT WIN32 OR (NOT (CMAKE_SYSTEM_PROCESSOR STREQUAL "aarch64")))
@ -724,114 +674,29 @@ if(NOT WIN32 OR (NOT (CMAKE_SYSTEM_PROCESSOR STREQUAL "aarch64")))
add_definitions(-DHAS_OPENGL)
endif()
find_package(pugixml)
if(NOT pugixml_FOUND)
check_vendoring_approved(pugixml)
message(STATUS "Using static pugixml from Externals")
add_subdirectory(Externals/pugixml)
endif()
dolphin_find_optional_system_library(pugixml Externals/pugixml)
if(USE_SHARED_ENET)
check_lib(ENET libenet enet enet/enet.h QUIET)
include(CheckSymbolExists)
if (ENET_FOUND)
set(CMAKE_REQUIRED_INCLUDES ${ENET_INCLUDE_DIRS})
# hack: LDFLAGS already contains -lenet but all flags but the first are
# dropped; ugh, cmake
set(CMAKE_REQUIRED_FLAGS ${ENET_LDFLAGS})
set(CMAKE_REQUIRED_LIBRARIES ${ENET_LIBRARIES})
check_symbol_exists(enet_socket_get_address enet/enet.h ENET_HAVE_SGA)
set(CMAKE_REQUIRED_INCLUDES)
set(CMAKE_REQUIRED_FLAGS)
set(CMAKE_REQUIRED_LIBRARIES)
if (NOT ENET_HAVE_SGA)
# enet is too old
set(ENET_FOUND FALSE)
endif()
endif()
endif()
if (ENET_FOUND)
message(STATUS "Using shared enet")
else()
check_vendoring_approved(enet)
message(STATUS "Using static enet from Externals")
include_directories(Externals/enet/include)
add_subdirectory(Externals/enet)
endif()
dolphin_find_optional_system_library_pkgconfig(ENET libenet>=1.3.18 enet::enet Externals/enet)
if(NOT XXHASH_FOUND)
message(STATUS "Using static xxhash from Externals")
add_subdirectory(Externals/xxhash)
endif()
dolphin_find_optional_system_library_pkgconfig(xxhash libxxhash>=0.8.2 xxhash::xxhash Externals/xxhash)
find_package(BZip2)
if(BZIP2_FOUND)
message(STATUS "Using shared bzip2")
else()
check_vendoring_approved(bzip2)
message(STATUS "Shared bzip2 not found, falling back to the static library")
add_subdirectory(Externals/bzip2)
endif()
dolphin_find_optional_system_library(BZip2 Externals/bzip2)
# macOS ships with liblzma.dylib but no headers, so check for the headers too
find_package(LibLZMA)
if(LIBLZMA_FOUND)
# Imported target added in CMake 3.14
dolphin_make_imported_target_if_missing(LibLZMA::LibLZMA LIBLZMA)
message(STATUS "Using shared lzma")
else()
check_vendoring_approved(lzma)
message(STATUS "Shared lzma not found, falling back to the static library")
add_subdirectory(Externals/liblzma)
endif()
dolphin_find_optional_system_library(LibLZMA Externals/liblzma)
# Imported target added in CMake 3.14
dolphin_make_imported_target_if_missing(LibLZMA::LibLZMA LIBLZMA)
pkg_check_modules(ZSTD QUIET libzstd>=1.4.0 IMPORTED_TARGET)
# if(ZSTD_FOUND AND NOT APPLE)
if(ZSTD_FOUND)
message(STATUS "Using shared zstd version: " ${ZSTD_VERSION})
dolphin_alias_library(zstd::zstd PkgConfig::ZSTD)
else()
check_vendoring_approved(zstd)
message(STATUS "Shared zstd not found, falling back to the static library")
add_subdirectory(Externals/zstd)
endif()
dolphin_find_optional_system_library_pkgconfig(ZSTD libzstd>=1.4.0 zstd::zstd Externals/zstd)
add_subdirectory(Externals/zlib-ng)
dolphin_find_optional_system_library_pkgconfig(ZLIB zlib-ng ZLIB::ZLIB Externals/zlib-ng)
find_package(ZLIB REQUIRED)
dolphin_find_optional_system_library_pkgconfig(MINIZIP minizip>=3.0.0 minizip::minizip Externals/minizip)
pkg_check_modules(MINIZIP minizip>=3.0.0)
if(MINIZIP_FOUND)
message(STATUS "Using shared minizip")
include_directories(${MINIZIP_INCLUDE_DIRS})
else()
check_vendoring_approved(minizip)
message(STATUS "Shared minizip not found, falling back to the static library")
add_subdirectory(Externals/minizip)
include_directories(External/minizip)
endif()
dolphin_find_optional_system_library(LZO Externals/LZO)
if(NOT APPLE)
check_lib(LZO "(no .pc for lzo2)" lzo2 lzo/lzo1x.h QUIET)
endif()
if(LZO_FOUND)
message(STATUS "Using shared lzo")
else()
check_vendoring_approved(lzo)
message(STATUS "Using static lzo from Externals")
add_subdirectory(Externals/LZO)
set(LZO lzo2)
endif()
dolphin_find_optional_system_library_pkgconfig(lz4 liblz4>=1.8 LZ4::LZ4 Externals/lz4)
pkg_check_modules(pc_spng IMPORTED_TARGET spng)
if (pc_spng_FOUND AND TARGET PkgConfig::pc_spng)
message(STATUS "Using the system libspng")
set(spng_target PkgConfig::pc_spng)
else()
message(STATUS "Using static libspng from Externals")
add_subdirectory(Externals/libspng)
set(spng_target spng)
endif()
dolphin_find_optional_system_library_pkgconfig(SPNG spng spng::spng Externals/libspng)
# Using static FreeSurround from Externals
# There is no system FreeSurround library.
@ -849,108 +714,33 @@ endif()
add_subdirectory(Externals/soundtouch)
include_directories(Externals/soundtouch)
find_package(CUBEB)
if(CUBEB_FOUND)
message(STATUS "Using the system cubeb")
else()
check_vendoring_approved(cubeb)
message(STATUS "Using static cubeb from Externals")
add_subdirectory(Externals/cubeb EXCLUDE_FROM_ALL)
endif()
dolphin_find_optional_system_library(CUBEB Externals/cubeb)
if(NOT ANDROID)
dolphin_find_optional_system_library(LibUSB Externals/libusb)
add_definitions(-D__LIBUSB__)
if(NOT APPLE)
find_package(LibUSB)
endif()
if(LIBUSB_FOUND AND NOT APPLE)
message(STATUS "Using shared LibUSB")
include_directories(${LIBUSB_INCLUDE_DIR})
else()
check_vendoring_approved(libusb)
message(STATUS "Using static LibUSB from Externals")
add_subdirectory(Externals/libusb)
set(LIBUSB_LIBRARIES usb)
endif()
set(LIBUSB_FOUND true)
endif()
set(SFML_REQD_VERSION 2.1)
if(NOT APPLE)
find_package(SFML ${SFML_REQD_VERSION} COMPONENTS network system)
endif()
if(SFML_FOUND)
message(STATUS "Using shared SFML")
else()
check_vendoring_approved(sfml)
message(STATUS "Using static SFML ${SFML_REQD_VERSION} from Externals")
add_definitions(-DSFML_STATIC)
add_subdirectory(Externals/SFML)
include_directories(BEFORE Externals/SFML/include)
endif()
dolphin_find_optional_system_library(SFML Externals/SFML 2.1 COMPONENTS network system)
if(USE_UPNP)
if(NOT APPLE)
find_package(MINIUPNPC)
endif()
if(MINIUPNPC_FOUND AND MINIUPNPC_API_VERSION GREATER 8)
message(STATUS "Using shared miniupnpc")
else()
check_vendoring_approved(miniupnpc)
message(STATUS "Using static miniupnpc from Externals")
add_subdirectory(Externals/miniupnpc)
endif()
dolphin_find_optional_system_library(MINIUPNPC Externals/miniupnpc 1.6)
add_definitions(-DUSE_UPNP)
endif()
if(NOT APPLE)
find_package(MBEDTLS)
endif()
if(MBEDTLS_FOUND)
message(STATUS "Using shared mbed TLS")
include_directories(${MBEDTLS_INCLUDE_DIRS})
else()
check_vendoring_approved(mbedtls)
message(STATUS "Using static mbed TLS from Externals")
set(MBEDTLS_LIBRARIES mbedtls mbedcrypto mbedx509)
add_subdirectory(Externals/mbedtls/ EXCLUDE_FROM_ALL)
include_directories(Externals/mbedtls/include)
endif()
dolphin_find_optional_system_library(MBEDTLS Externals/mbedtls 2.28)
find_package(CURL)
if(CURL_FOUND)
message(STATUS "Using shared libcurl")
include_directories(${CURL_INCLUDE_DIRS})
else()
check_vendoring_approved(curl)
message(STATUS "Using static libcurl from Externals")
add_subdirectory(Externals/curl)
set(CURL_LIBRARIES curl)
include_directories(BEFORE Externals/curl/include)
endif()
dolphin_find_optional_system_library(CURL Externals/curl)
if (NOT ANDROID)
find_library(ICONV_LIBRARIES NAMES iconv libiconv libiconv-2 c)
find_path(ICONV_INCLUDE_DIR NAMES iconv.h)
endif()
if (NOT ANDROID AND ICONV_LIBRARIES AND ICONV_INCLUDE_DIR)
mark_as_advanced(ICONV_INCLUDE_DIR ICONV_LIBRARIES)
if(NOT ANDROID)
dolphin_find_optional_system_library(Iconv Externals/libiconv-1.14)
else()
check_vendoring_approved(iconv)
message(STATUS "Using static iconv from Externals")
include_directories(Externals/libiconv-1.14/include)
add_subdirectory(Externals/libiconv-1.14)
set(ICONV_LIBRARIES iconv)
add_subdirectory(Externals/libiconv-1.14 EXCLUDE_FROM_ALL)
endif()
if(NOT ANDROID)
find_package(HIDAPI)
if(NOT HIDAPI_FOUND)
check_vendoring_approved(hidapi)
message(STATUS "Using static HIDAPI from Externals")
add_subdirectory(Externals/hidapi EXCLUDE_FROM_ALL)
endif()
dolphin_find_optional_system_library(HIDAPI Externals/hidapi)
endif()
if(USE_DISCORD_PRESENCE)
@ -963,11 +753,7 @@ if(NOT ENABLE_QT)
set(USE_MGBA 0)
endif()
if(USE_MGBA)
find_package(LIBMGBA)
if(NOT LIBMGBA_FOUND)
message(STATUS "Using static libmgba from Externals")
add_subdirectory(Externals/mGBA)
endif()
dolphin_find_optional_system_library(LIBMGBA Externals/mGBA)
endif()
find_package(SYSTEMD)
@ -995,33 +781,51 @@ add_subdirectory(Externals/rangeset)
add_subdirectory(Externals/FatFs)
if (USE_RETRO_ACHIEVEMENTS)
add_subdirectory(Externals/rcheevos)
endif()
########################################
# Pre-build events: Define configuration variables and write SCM info header
#
if(DOLPHIN_WC_BRANCH STREQUAL "master" OR DOLPHIN_WC_BRANCH STREQUAL "stable")
set(DOLPHIN_WC_IS_STABLE "1")
else()
set(DOLPHIN_WC_IS_STABLE "0")
endif()
# Remove in-tree revision information generated by Visual Studio
# This is because the compiler will check in-tree first and use this, even if it is outdated
file(REMOVE "${PROJECT_SOURCE_DIR}/Source/Core/Common/scmrev.h")
configure_file(
"${PROJECT_SOURCE_DIR}/Source/Core/Common/scmrev.h.in"
"${PROJECT_BINARY_DIR}/Source/Core/Common/scmrev.h"
file(MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/Source/Core/Common)
if (NOT EXISTS ${CMAKE_CURRENT_BINARY_DIR}/Source/Core/Common/scmrev.h)
file(TOUCH ${CMAKE_CURRENT_BINARY_DIR}/Source/Core/Common/scmrev.h)
endif()
find_package(Git)
if(NOT GIT_FOUND)
set(GIT_EXECUTABLE "")
endif()
add_custom_target(
dolphin_scmrev
${CMAKE_COMMAND} -DPROJECT_SOURCE_DIR=${PROJECT_SOURCE_DIR} -DPROJECT_BINARY_DIR=${PROJECT_BINARY_DIR} -DDISTRIBUTOR=${DISTRIBUTOR} -DDOLPHIN_DEFAULT_UPDATE_TRACK=${DOLPHIN_DEFAULT_UPDATE_TRACK} -DGIT_FOUND=${GIT_FOUND} -DGIT_EXECUTABLE=${GIT_EXECUTABLE} -DDOLPHIN_WC_REVISION=${DOLPHIN_WC_REVISION} -DDOLPHIN_WC_DESCRIBE=${DOLPHIN_WC_DESCRIBE} -DDOLPHIN_WC_BRANCH=${DOLPHIN_WC_BRANCH} -P ${CMAKE_SOURCE_DIR}/CMake/ScmRevGen.cmake
BYPRODUCTS ${CMAKE_CURRENT_BINARY_DIR}/Source/Core/Common/scmrev.h
VERBATIM
)
# This is here so #include "Common/scmrev.h" finds the generated header.
include_directories("${PROJECT_BINARY_DIR}/Source/Core")
########################################
# Unit testing.
#
if(ENABLE_TESTS)
message(STATUS "Using static gtest from Externals")
find_package(GTest)
if (GTEST_FOUND)
message(STATUS "Using the system gtest")
include_directories(${GTEST_INCLUDE_DIRS})
else()
message(STATUS "Using static gtest from Externals")
add_subdirectory(Externals/gtest EXCLUDE_FROM_ALL)
endif()
# Force gtest to link the C runtime dynamically on Windows in order to avoid runtime mismatches.
set(gtest_force_shared_crt ON CACHE BOOL "" FORCE)
add_subdirectory(Externals/gtest EXCLUDE_FROM_ALL)
else()
message(STATUS "Unit tests are disabled")
endif()

View file

@ -1,17 +1,32 @@
# <a name="main-heading"></a>Dolphin Coding Style & Licensing
# <a name="main-section-overview"></a>Dolphin Coding Style & Legal Requirements
If you make any contributions to Dolphin after December 1st, 2014, you are agreeing that any code you have contributed will be licensed under the GNU GPL version 2 (or any later version).
# <a name="main-section-overview"></a>Main sections
- [Introduction](#introduction)
- [Legal](#legal)
- [Coding style introduction](#introduction)
- [C++ coding style and formatting](#cpp-coding-style-and-formatting)
- [C++ code-specific guidelines](#cpp-code-specific-guidelines)
- [Android](#android)
- [Help](#help)
# <a name="legal"></a>Legal
# <a name="introduction"></a>Introduction
Summary:
- [Trade secrets](#trade-secrets)
- [Code licensing](#code-licensing)
## <a name="trade-secrets"></a>Trade secrets
Following all relevant laws is of utmost importance for an emulation project like Dolphin.
If you know any confidential information related to the GameCube, Wii, or Triforce, either because you signed a non-disclosure agreement or because you looked at leaked materials, we ask that you don't contribute code to Dolphin **at all**. While accepting code from contributors who know confidential information is legal if the code is unrelated to the confidential information, we refuse to accept code from such contributors because it greatly increases our review burden and increases the legal risk we take.
Also, this probably goes without saying, but piracy is strictly forbidden both on GitHub and in all other Dolphin channels.
## <a name="code-licensing"></a>Code licensing
If you make any contributions to Dolphin after December 1st, 2014, you are agreeing that any code you have contributed will be licensed under the GNU GPL version 2 (or any later version).
# <a name="introduction"></a>Coding style introduction
Summary:
@ -173,7 +188,8 @@ Summary:
- [Classes and Structs](#cpp-code-classes-and-structs)
## <a name="cpp-code-general"></a>General
- The codebase currently uses C++17.
- The codebase currently uses C++20, though not all compilers support all C++20 features.
- See CMakeLists.txt "Enforce minimium compiler versions" for the currently supported compilers.
- Use the [nullptr](https://en.cppreference.com/w/cpp/language/nullptr) type over the macro `NULL`.
- If a [range-based for loop](https://en.cppreference.com/w/cpp/language/range-for) can be used instead of container iterators, use it.
- Obviously, try not to use `goto` unless you have a *really* good reason for it.

View file

@ -0,0 +1,15 @@
{
"meta":
{
"title": "DOF Removal",
"author": "Dolphin Team",
"description": "Skips drawing DOF effects. May be preferable when using a DOF solution from Dolphin's post processing shaders or a third party tool."
},
"features":
[
{
"group": "DOF",
"action": "skip"
}
]
}

View file

@ -0,0 +1,20 @@
{
"meta":
{
"title": "Native Resolution DOF",
"author": "Dolphin Team",
"description": "Scales DOF effects to draw at their native resolution, regardless of internal resolution. Results in DOF looking much more natural at higher resolutions but may cause shimmering."
},
"features":
[
{
"group": "DOF",
"action": "scale",
"action_data": {
"X": 1.0,
"Y": 1.0,
"Z": 1.0
}
}
]
}

View file

@ -0,0 +1,307 @@
{
"meta":
{
"title": "Dragon Ball Z: Budokai Tenkaichi 3 Definitions",
"author": "Seedonator"
},
"groups":
[
{
"name": "Bloom",
"targets": [
{
"type": "efb",
"texture_filename": "efb1_n000014_128x128_4"
}
]
},
{
"name": "HUD",
"targets": [
{
"type": "draw_started",
"prettyname": "HUD Backdrop",
"texture_filename": "tex1_256x64_50e9493ab5ecd6e9_5efd0133152917bc_9"
},
{
"type": "draw_started",
"prettyname": "Max Power Lightning",
"texture_filename": "tex1_256x128_76ee22f289405f4f_0a3363fc16e5200b_9"
},
{
"type": "draw_started",
"prettyname": "Timer Backdrop",
"texture_filename": "tex1_64x64_1b0bd43920520089_894789000b300d35_9"
},
{
"type": "draw_started",
"prettyname": "Teammate Backdrop",
"texture_filename": "tex1_64x64_76189a0850bac928_d5586441a9651de1_9"
},
{
"type": "draw_started",
"prettyname": "HUD Backdrop 2",
"texture_filename": "tex1_256x64_4751a5dd9b515483_6ef5db463bf9b5fe_9"
},
{
"type": "draw_started",
"prettyname": "Meters Colored",
"texture_filename": "tex1_256x64_974aae7fb39dd3fe_dc826162c7781cf3_9"
},
{
"type": "draw_started",
"prettyname": "Meters Colored 2",
"texture_filename": "tex1_256x64_974aae7fb39dd3fe_c0adc9c4480c91c1_9"
},
{
"type": "draw_started",
"prettyname": "Meters Red",
"texture_filename": "tex1_256x64_974aae7fb39dd3fe_65f3d25263258092_9"
},
{
"type": "draw_started",
"prettyname": "Meters Overlay",
"texture_filename": "tex1_256x64_974aae7fb39dd3fe_37c76c0d16ef044d_9"
},
{
"type": "draw_started",
"prettyname": "Meter Glow",
"texture_filename": "tex1_64x64_1c31b3c28a7aef47_1c42ae23afd2f40f_9"
},
{
"type": "draw_started",
"prettyname": "Meter Teammate",
"texture_filename": "tex1_128x32_277ce02a6f60e609_30b338ab0d636ab2_9"
},
{
"type": "draw_started",
"prettyname": "Stat Bonus Ki Damage",
"texture_filename": "tex1_32x32_20bc4452577d1f49_85422f750ab42532_8"
},
{
"type": "draw_started",
"prettyname": "Stat Bonus Charge Speed",
"texture_filename": "tex1_32x32_af9478cb6ebc0b7a_5ba8f3ea380bfdcf_8"
},
{
"type": "draw_started",
"prettyname": "Stat Bonus Defense",
"texture_filename": "tex1_32x32_c7cf9020318a2959_5d41872b1fcd6199_8"
},
{
"type": "draw_started",
"prettyname": "Stat Bonus Melee Damage",
"texture_filename": "tex1_32x32_e4c8e81a7318fa25_6e21f60b0c990c98_8"
},
{
"type": "draw_started",
"prettyname": "Blast Stock Number",
"texture_filename": "tex1_128x64_00ba91db7d176946_0ecdf6905c577ddb_9"
},
{
"type": "draw_started",
"prettyname": "Blast Stock Number Glow",
"texture_filename": "tex1_128x64_53d69bea13e150ab_24a4df43c24b0515_9"
},
{
"type": "draw_started",
"prettyname": "Timer Value",
"texture_filename": "tex1_128x128_6976151439efad50_501b3bc09a6958d7_8"
},
{
"type": "draw_started",
"prettyname": "Hit Text",
"texture_filename": "tex1_128x64_9366938c3344b862_83be965a88f28a40_9"
},
{
"type": "draw_started",
"prettyname": "Hit Counter",
"texture_filename": "tex1_128x128_273f16293f4d7a40_8a29b5887317abf8_8"
},
{
"type": "draw_started",
"prettyname": "Damage Counter",
"texture_filename": "tex1_128x128_1588ef89e137fc24_1cce6b863d92c9a0_8"
},
{
"type": "draw_started",
"prettyname": "Announcer Max Power",
"texture_filename": "tex1_128x64_482f78c5dfc14eab_0e7513b77d82c9ae_9"
},
{
"type": "draw_started",
"prettyname": "Announcer First Attack",
"texture_filename": "tex1_128x64_b92d24567ae12b3a_14d61fafa74e6334_9"
},
{
"type": "draw_started",
"prettyname": "Announcer Counter",
"texture_filename": "tex1_128x64_bbdfacdc36d171ec_85047913fd8df9aa_9"
},
{
"type": "draw_started",
"prettyname": "Announcer Lock On",
"texture_filename": "tex1_128x64_3ba4b1f803afd256_93ba5384bd764946_9"
},
{
"type": "draw_started",
"prettyname": "Announcer Boost",
"texture_filename": "tex1_128x64_09d5b89f7dbf0590_2abc7134cbb2138b_9"
},
{
"type": "draw_started",
"prettyname": "Buttom Prompt Y",
"texture_filename": "tex1_32x32_15f350b2b7f46481_66860824280a89bf_8"
},
{
"type": "draw_started",
"prettyname": "Button Prompt Y Hold",
"texture_filename": "tex1_32x32_00d2fb316a25d017_a889bebad6535a02_8"
},
{
"type": "draw_started",
"prettyname": "Button Prompt Y Mash",
"texture_filename": "tex1_64x64_8934f812b54f87c4_66860824280a89bf_8"
},
{
"type": "draw_started",
"prettyname": "Buttom Prompt B",
"texture_filename": "tex1_32x32_ce62786fc1170192_70b585e07941e91c_8"
},
{
"type": "draw_started",
"prettyname": "Button Prompt B Hold",
"texture_filename": "tex1_32x32_2841b917a7c23834_bdbd0425eb2f4b52_8"
},
{
"type": "draw_started",
"prettyname": "Button Prompt B Mash",
"texture_filename": "tex1_64x64_23b176984035b44c_8204be59ecb7c469_8"
},
{
"type": "draw_started",
"prettyname": "Buttom Prompt X",
"texture_filename": "tex1_32x32_b52817e68be0e2d7_d1b283ce04ce1c7c_8"
},
{
"type": "draw_started",
"prettyname": "Button Prompt X Mash",
"texture_filename": "tex1_64x64_cb8aa5843b3cc31c_ccbcbdf9c811ed5d_8"
},
{
"type": "draw_started",
"prettyname": "Buttom Prompt A",
"texture_filename": "tex1_32x32_630cfa888a9d005a_d95570935377e345_8"
},
{
"type": "draw_started",
"prettyname": "Button Prompt A Mash",
"texture_filename": "tex1_64x64_eef97dc696b0edd6_758bf7c8a0397add_8"
},
{
"type": "draw_started",
"prettyname": "Button Prompt Hold Hand",
"texture_filename": "tex1_32x32_80eec4ab54c12b14_2fbe88721f145bc3_8"
},
{
"type": "draw_started",
"prettyname": "Button Prompt LStick Up",
"texture_filename": "tex1_32x32_56eb18736158692a_831cb2dcaee7d9c7_8"
},
{
"type": "draw_started",
"prettyname": "Button Prompt LStick Down",
"texture_filename": "tex1_32x32_4f6911885cbfd6b7_b01602f981cf7194_8"
},
{
"type": "draw_started",
"prettyname": "Button Prompt LStick Left",
"texture_filename": "tex1_32x32_de66fb7b17f39fb2_723568783ce8af39_8"
},
{
"type": "draw_started",
"prettyname": "Button Prompt LStick Right",
"texture_filename": "tex1_32x32_4a3ce686c4d7d216_d9a6c961c9883e00_8"
},
{
"type": "draw_started",
"prettyname": "Button Prompt LStick Clash N",
"texture_filename": "tex1_64x64_0e45133195ab2db7_8061698fc3e81ec4_8"
},
{
"type": "draw_started",
"prettyname": "Button Prompt LStick Clash NE",
"texture_filename": "tex1_64x64_23a7ebdcad6f294c_961413a3996f1955_8"
},
{
"type": "draw_started",
"prettyname": "Button Prompt LStick Clash E",
"texture_filename": "tex1_64x64_fc736187474b6d87_5db58dd7fedde1e4_8"
},
{
"type": "draw_started",
"prettyname": "Button Prompt LStick Clash SE",
"texture_filename": "tex1_64x64_847d2a027ba61a6d_da6f9db59fa7a52b_8"
},
{
"type": "draw_started",
"prettyname": "Button Prompt LStick Clash S",
"texture_filename": "tex1_64x64_2fd46476d6eeb2a5_8cf71f59f3f4f61d_8"
},
{
"type": "draw_started",
"prettyname": "Button Prompt LStick Clash Neutral",
"texture_filename": "tex1_64x64_e63e59943072d5ba_13e4b338982e9dbc_8"
},
{
"type": "draw_started",
"prettyname": "Button Prompt Plus",
"texture_filename": "tex1_32x32_214dbb89f41af76c_ee10bcb01a356553_8"
},
{
"type": "draw_started",
"prettyname": "Button Prompt Mash Backdrop",
"texture_filename": "tex1_64x64_c7be948af15370ea_104c0c86a865a442_9"
},
{
"type": "draw_started",
"prettyname": "Text Font Main",
"texture_filename": "tex1_512x128_b38c0db36dfc6ac3_71a440118950d6cd_8"
},
{
"type": "draw_started",
"prettyname": "Text Font Special",
"texture_filename": "tex1_512x128_b38c0db36dfc6ac3_561056e6b4e21980_8"
}
]
}
]
}

View file

@ -0,0 +1,36 @@
{
"meta":
{
"title": "Bloom and DOF Texture Definitions",
"author": "linckandrea"
},
"groups":
[
{
"name": "Bloom",
"targets": [
{
"type": "efb",
"texture_filename": "efb1_n09_20x15_1"
},
{
"type": "efb",
"texture_filename": "efb1_n21_20x15_1"
}
]
},
{
"name": "DOF",
"targets": [
{
"type": "efb",
"texture_filename": "efb1_n10_320x240_4"
},
{
"type": "efb",
"texture_filename": "efb1_n11_320x240_1"
}
]
}
]
}

View file

@ -0,0 +1,19 @@
{
"meta":
{
"title": "Bloom Texture Definitions",
"author": "SuperSamus"
},
"groups":
[
{
"name": "Bloom",
"targets": [
{
"type": "efb",
"texture_filename": "efb1_n000008_80x57_6"
}
]
}
]
}

View file

@ -49,6 +49,10 @@
{
"type": "efb",
"texture_filename": "efb1_n000000_256x256_1"
},
{
"type": "efb",
"texture_filename": "efb1_n000000_512x512_1"
}
]
}

View file

@ -1,7 +1,7 @@
{
"meta":
{
"title": "Bloom and HUD Texture Definitions",
"title": "Bloom, DOF and HUD Texture Definitions",
"author": "iwubcode"
},
"groups":
@ -20,6 +20,61 @@
"pretty_name": "faces",
"texture_filename": "tex1_512x256_ff742945bb1f5cd6_14"
},
{
"type": "draw_started",
"pretty_name": "faces2",
"texture_filename": "tex1_512x256_bf69f6bcc9fa1c84_14"
},
{
"type": "projection",
"value": "2d",
"pretty_name": "faces2",
"texture_filename": "tex1_512x256_bf69f6bcc9fa1c84_14"
},
{
"type": "draw_started",
"pretty_name": "faces3",
"texture_filename": "tex1_512x256_6a7db9462722f3f2_14"
},
{
"type": "projection",
"value": "2d",
"pretty_name": "faces3",
"texture_filename": "tex1_512x256_6a7db9462722f3f2_14"
},
{
"type": "draw_started",
"pretty_name": "faces4",
"texture_filename": "tex1_512x256_9c3091b878ecc5d5_14"
},
{
"type": "projection",
"value": "2d",
"pretty_name": "faces4",
"texture_filename": "tex1_512x256_9c3091b878ecc5d5_14"
},
{
"type": "draw_started",
"pretty_name": "faces5",
"texture_filename": "tex1_512x256_8787a867fd0d1f6c_14"
},
{
"type": "projection",
"value": "2d",
"pretty_name": "faces5",
"texture_filename": "tex1_512x256_8787a867fd0d1f6c_14"
},
{
"type": "draw_started",
"pretty_name": "faces5",
"texture_filename": "tex1_512x256_a47bcf54cfeeaafd_14"
},
{
"type": "projection",
"value": "2d",
"pretty_name": "faces5",
"texture_filename": "tex1_512x256_a47bcf54cfeeaafd_14"
},
{
"type": "draw_started",
"pretty_name": "text",
@ -97,6 +152,17 @@
"pretty_name": "text7",
"texture_filename": "tex1_128x128_73d3f8a2f0347b4a_0"
},
{
"type": "draw_started",
"pretty_name": "text8",
"texture_filename": "tex1_32x32_8261c7f3bc24e3a7_0"
},
{
"type": "projection",
"value": "2d",
"pretty_name": "text8",
"texture_filename": "tex1_32x32_8261c7f3bc24e3a7_0"
},
{
"type": "draw_started",
"pretty_name": "large numbers",
@ -129,6 +195,39 @@
"value": "2d",
"pretty_name": "life outline",
"texture_filename": "tex1_128x64_deeeaa33ca3dc0f1_14"
},
{
"type": "draw_started",
"pretty_name": "ability bar",
"texture_filename": "tex1_64x64_59345b5687ee93e6_14"
},
{
"type": "projection",
"value": "2d",
"pretty_name": "ability bar",
"texture_filename": "tex1_64x64_59345b5687ee93e6_14"
},
{
"type": "draw_started",
"pretty_name": "ability bar2",
"texture_filename": "tex1_128x128_84ede5f362602f6b_14"
},
{
"type": "projection",
"value": "2d",
"pretty_name": "ability bar2",
"texture_filename": "tex1_128x128_84ede5f362602f6b_14"
},
{
"type": "draw_started",
"pretty_name": "ability bar2",
"texture_filename": "tex1_256x512_4cac4a78235f5e94_14"
},
{
"type": "projection",
"value": "2d",
"pretty_name": "ability bar2",
"texture_filename": "tex1_256x512_4cac4a78235f5e94_14"
}
]
},
@ -146,7 +245,12 @@
{
"type": "efb",
"texture_filename": "efb1_n359_160x112_1"
},
}
]
},
{
"name": "DOF",
"targets": [
{
"type": "efb",
"texture_filename": "efb1_n432_320x224_6"

Binary file not shown.

Before

Width:  |  Height:  |  Size: 926 B

View file

@ -0,0 +1,69 @@
// Based on https://github.com/Filoppi/PumboAutoHDR
/*
[configuration]
[OptionRangeFloat]
GUIName = HDR Display Max Nits
OptionName = HDR_DISPLAY_MAX_NITS
MinValue = 80
MaxValue = 2000
StepAmount = 1
DefaultValue = 400
[OptionRangeFloat]
GUIName = Shoulder Start Alpha
OptionName = AUTO_HDR_SHOULDER_START_ALPHA
MinValue = 0
MaxValue = 1
StepAmount = 0.01
DefaultValue = 0
[OptionRangeFloat]
GUIName = Shoulder Pow
OptionName = AUTO_HDR_SHOULDER_POW
MinValue = 1
MaxValue = 10
StepAmount = 0.05
DefaultValue = 2.5
[/configuration]
*/
float luminance(float3 color)
{
return dot(color, float3(0.2126f, 0.7152f, 0.0722f));
}
void main()
{
float4 color = Sample();
// Nothing to do here, we are in SDR
if (!OptionEnabled(hdr_output) || !OptionEnabled(linear_space_output))
{
SetOutput(color);
return;
}
const float hdr_paper_white = hdr_paper_white_nits / hdr_sdr_white_nits;
// Restore the original SDR (0-1) brightness (we might or might not restore it later)
color.rgb /= hdr_paper_white;
// Find the color luminance (it works better than average)
float sdr_ratio = luminance(color.rgb);
const float auto_hdr_max_white = max(HDR_DISPLAY_MAX_NITS / (hdr_paper_white_nits / hdr_sdr_white_nits), hdr_sdr_white_nits) / hdr_sdr_white_nits;
if (sdr_ratio > AUTO_HDR_SHOULDER_START_ALPHA && AUTO_HDR_SHOULDER_START_ALPHA < 1.0)
{
const float auto_hdr_shoulder_ratio = 1.0 - (max(1.0 - sdr_ratio, 0.0) / (1.0 - AUTO_HDR_SHOULDER_START_ALPHA));
const float auto_hdr_extra_ratio = pow(auto_hdr_shoulder_ratio, AUTO_HDR_SHOULDER_POW) * (auto_hdr_max_white - 1.0);
const float auto_hdr_total_ratio = sdr_ratio + auto_hdr_extra_ratio;
color.rgb *= auto_hdr_total_ratio / sdr_ratio;
}
color.rgb *= hdr_paper_white;
SetOutput(color);
}

View file

@ -0,0 +1,485 @@
/*
[configuration]
[OptionBool]
GUIName = Use target window resolution
OptionName = USE_WINDOW_RES
DefaultValue = true
[OptionBool]
GUIName = Debug: Calculate only one character per subgroup
OptionName = DEBUG_ONLY_ONE_CHAR
DefaultValue = false
[/configuration]
*/
const uint MAX_CHARS = 96u; // max 96, must be a multiple of 32
const bool HAVE_FULL_FEATURE_FALLBACK = false; // terrible slow, can easily softlock the GPU
const uint UNROLL_FALLBACK = 4;
const uint UNROLL_SIMD = 3; // max MAX_CHARS / 32
// #undef SUPPORTS_SUBGROUP_REDUCTION
#ifdef API_VULKAN
// By default, subgroupBroadcast only supports compile time constants as index.
// However we need an uniform instead. This is always supported in OpenGL,
// but in Vulkan only in SPIR-V >= 1.5.
// So fall back to subgroupShuffle on Vulkan instead.
#define subgroupBroadcast subgroupShuffle
#endif
/*
The header-only font
We have 96 (ASCII) characters, each of them is 12 pixels high and 8 pixels wide.
To store the boolean value per pixel, 96 bits per character is needed.
So three 32 bit integers are used per character.
This takes in total roughly 1 kB of constant buffer.
The first character must be all-one for the optimized implementation below.
*/
const uint char_width = 8;
const uint char_height = 12;
const uint char_count = 96;
const uint char_pixels = char_width * char_height;
const float2 char_dim = float2(char_width, char_height);
const uint rasters[char_count][(char_pixels + 31) / 32] = {
{0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF}, {0x18181818, 0x00181818, 0x00181800},
{0x6c6c6c6c, 0x00000000, 0x00000000}, {0x66660000, 0xff6666ff, 0x00006666},
{0x1bff7e18, 0xd8f87e1f, 0x00187eff}, {0x6edb1b0e, 0x760c1830, 0x0070d8db},
{0x3333361c, 0x1b0e0e1b, 0x00fe63f3}, {0x18383070, 0x00000000, 0x00000000},
{0x0c0c1830, 0x0c0c0c0c, 0x0030180c}, {0x3030180c, 0x30303030, 0x000c1830},
{0x5a990000, 0x5a3cff3c, 0x00000099}, {0x18180000, 0x18ffff18, 0x00001818},
{0x00000000, 0x38000000, 0x000c1838}, {0x00000000, 0x00ffff00, 0x00000000},
{0x00000000, 0x00000000, 0x00001c1c}, {0x6060c0c0, 0x18183030, 0x06060c0c},
{0xe3c3663c, 0xc7cfdbf3, 0x003c66c3}, {0x181e1c18, 0x18181818, 0x007e1818},
{0x60c0e77e, 0x060c1830, 0x00ff0303}, {0xc0c0e77e, 0xc0e07ee0, 0x007ee7c0},
{0x363c3830, 0x3030ff33, 0x00303030}, {0x030303ff, 0xc0e07f03, 0x007ee7c0},
{0x0303e77e, 0xc3e37f03, 0x007ee7c3}, {0xc0c0c0ff, 0x0c183060, 0x000c0c0c},
{0xc3c3e77e, 0xc3e77ee7, 0x007ee7c3}, {0xc3c3e77e, 0xc0c0fee7, 0x007ee7c0},
{0x00000000, 0x00001c1c, 0x00001c1c}, {0x38000000, 0x38000038, 0x000c1838},
{0x0c183060, 0x0c060306, 0x00603018}, {0x00000000, 0xff00ffff, 0x000000ff},
{0x30180c06, 0x3060c060, 0x00060c18}, {0xc0c3c37e, 0x18183060, 0x00180000},
{0x7e000000, 0xdbcbbbc3, 0x00fc06f3}, {0xc3663c18, 0xc3ffc3c3, 0x00c3c3c3},
{0xc3c3e37f, 0xc3e37fe3, 0x007fe3c3}, {0x0303e77e, 0x03030303, 0x007ee703},
{0xc3e3733f, 0xc3c3c3c3, 0x003f73e3}, {0x030303ff, 0x03033f03, 0x00ff0303},
{0x030303ff, 0x0303033f, 0x00030303}, {0x0303e77e, 0xc3f30303, 0x007ee7c3},
{0xc3c3c3c3, 0xc3c3ffc3, 0x00c3c3c3}, {0x1818187e, 0x18181818, 0x007e1818},
{0x60606060, 0x60606060, 0x003e7763}, {0x1b3363c3, 0x1b0f070f, 0x00c36333},
{0x03030303, 0x03030303, 0x00ff0303}, {0xffffe7c3, 0xc3c3c3db, 0x00c3c3c3},
{0xcfcfc7c7, 0xf3fbdbdf, 0x00e3e3f3}, {0xc3c3e77e, 0xc3c3c3c3, 0x007ee7c3},
{0xc3c3e37f, 0x03037fe3, 0x00030303}, {0xc3c3663c, 0xdbc3c3c3, 0x00fc76fb},
{0xc3c3e37f, 0x1b0f7fe3, 0x00c36333}, {0x0303e77e, 0xc0e07e07, 0x007ee7c0},
{0x181818ff, 0x18181818, 0x00181818}, {0xc3c3c3c3, 0xc3c3c3c3, 0x007ee7c3},
{0xc3c3c3c3, 0x6666c3c3, 0x00183c3c}, {0xc3c3c3c3, 0xffdbdbc3, 0x00c3e7ff},
{0x3c6666c3, 0x3c3c183c, 0x00c36666}, {0x3c6666c3, 0x1818183c, 0x00181818},
{0x60c0c0ff, 0x060c7e30, 0x00ff0303}, {0x0c0c0c3c, 0x0c0c0c0c, 0x003c0c0c},
{0x0c0c0606, 0x30301818, 0xc0c06060}, {0x3030303c, 0x30303030, 0x003c3030},
{0xc3663c18, 0x00000000, 0x00000000}, {0x00000000, 0x00000000, 0xff000000},
{0x181c0c0e, 0x00000000, 0x00000000}, {0x00000000, 0xfec0c37e, 0x00fec3c3},
{0x03030303, 0xc3c37f03, 0x007fc3c3}, {0x00000000, 0x0303c37e, 0x007ec303},
{0xc0c0c0c0, 0xc3c3fec0, 0x00fec3c3}, {0x00000000, 0x7fc3c37e, 0x00fe0303},
{0x0c0ccc78, 0x0c0c3f0c, 0x000c0c0c}, {0x00000000, 0xc3c3c37e, 0xc3c0c0fe},
{0x03030303, 0xc3c3c37f, 0x00c3c3c3}, {0x00001800, 0x18181818, 0x00181818},
{0x00003000, 0x30303030, 0x36303030}, {0x03030303, 0x0f1b3363, 0x0063331f},
{0x1818181e, 0x18181818, 0x007e1818}, {0x00000000, 0xdbdbdb7f, 0x00dbdbdb},
{0x00000000, 0x6363633f, 0x00636363}, {0x00000000, 0x6363633e, 0x003e6363},
{0x00000000, 0xc3c3c37f, 0x03037fc3}, {0x00000000, 0xc3c3c3fe, 0xc0c0fec3},
{0x00000000, 0x0303077f, 0x00030303}, {0x00000000, 0x7e0303fe, 0x007fc0c0},
{0x0c0c0c00, 0x0c0c0c3f, 0x00386c0c}, {0x00000000, 0x63636363, 0x007e6363},
{0x00000000, 0x6666c3c3, 0x00183c3c}, {0x00000000, 0xdbc3c3c3, 0x00c3e7ff},
{0x00000000, 0x183c66c3, 0x00c3663c}, {0x00000000, 0x3c6666c3, 0x06060c18},
{0x00000000, 0x183060ff, 0x00ff060c}, {0x181818f0, 0x181c0f1c, 0x00f01818},
{0x18181818, 0x18181818, 0x18181818}, {0x1818180f, 0x1838f038, 0x000f1818},
{0x06000000, 0x0060f18f, 0x00000000}, {0x00000000, 0x00000000, 0x00000000}};
// Precalculated sum of all pixels per character
const uint raster_active_pixels[char_count] = {
96, 18, 16, 40, 56, 42, 46, 10, 22, 22, 32, 28, 10, 16, 6, 24, 52, 29, 36, 44, 35, 42, 50, 28,
58, 51, 12, 16, 22, 32, 22, 26, 41, 46, 57, 38, 52, 38, 32, 46, 48, 30, 31, 43, 28, 56, 64, 52,
42, 52, 52, 44, 28, 48, 42, 58, 42, 32, 38, 26, 24, 26, 14, 8, 10, 34, 40, 26, 40, 32, 30, 33,
39, 16, 20, 37, 28, 43, 30, 30, 34, 34, 20, 28, 27, 30, 26, 36, 26, 24, 26, 30, 24, 30, 14, 0};
// Get one sample of the font: (pixel index, character index)
float SampleFont(uint2 pos)
{
return (rasters[pos.y][pos.x / 32] >> (pos.x % 32)) & uint(1);
}
// Get one sample of the framebuffer: (character position in screen space, pixel index)
float3 SampleTex(uint2 char_pos, uint pixel)
{
float2 inv_resoltion =
OptionEnabled(USE_WINDOW_RES) ? GetInvWindowResolution() : GetInvResolution();
float2 tex_pos = char_pos * char_dim + float2(pixel % char_width, pixel / char_width) + 0.5;
return SampleLocation(tex_pos * inv_resoltion).xyz;
}
struct CharResults
{
float3 fg; // font color
float3 bg; // background color
float err; // MSE of this configuration
uint c; // character index
};
// Calculate the font and background color and the MSE for a given character
CharResults CalcCharRes(uint c, float3 t, float3 ft)
{
CharResults o;
o.c = c;
// Inputs:
// tt: sum of all texture samples squared
// t: sum of all texture samples
// ff: sum of all font samples squared
// f: sum of all font samples
// ft: sum of all font samples * texture samples
// The font is either 1.0 or 0.0, so ff == f
// As the font is constant, this is pre-calculated
float f = raster_active_pixels[c];
float ff = f;
// The calculation isn't stable if the font is all-one. Return max err
// instead.
if (f == char_pixels)
{
o.err = char_pixels * char_pixels;
return o;
}
// tt is only used as constant offset for the error, define it as zero
float3 tt = float3(0.0, 0.0, 0.0);
// The next lines are a bit harder, hf :-)
// The idea is to find the perfect char with the perfect background color
// and the perfect font color. As this is an equation with three unknowns,
// we can't just try all chars and color combinations.
// As criterion how "perfect" the selection is, we compare the "mean
// squared error" of the resulted colors of all chars. So, now the big
// issue: how to calculate the MSE without knowing the two colors ...
// In the next steps, "a" is the font color, "b" is the background color,
// "f" is the font value at this pixel, "t" is the texture value
// So the square error of one pixel is:
// e = ( t - a⋅f - b⋅(1-f) ) ^ 2
// In longer:
// e = a^2⋅f^2 - 2⋅a⋅b⋅f^2 + 2⋅a⋅b⋅f - 2⋅a⋅f⋅t + b^2⋅f^2 - 2⋅b^2⋅f + b^2 +
// 2⋅b⋅f⋅t - 2⋅b⋅t + t^2
// The sum of all errors is: (as shortcut, ff,f,ft,t,tt are now the sums
// like declared above, sum(1) is the count of pixels) sum(e) = a^2⋅ff -
// 2⋅a^2⋅ff + 2⋅a⋅b⋅f - 2⋅a⋅ft + b^2⋅ff - 2⋅b^2⋅f + b^2⋅sum(1) + 2⋅b⋅ft -
// 2⋅b⋅t + tt
// tt is only used as a constant offset, so its value has no effect on a,b or
// on the relative error. So it can be completely dropped.
// To find the minimum, we have to derive this by "a" and "b":
// d/da sum(e) = 2⋅a⋅ff + 2⋅b⋅f - 2⋅b⋅ff - 2⋅ft
// d/db sum(e) = 2⋅a⋅f - 2⋅a⋅ff - 4⋅b⋅f + 2⋅b⋅ff + 2⋅b⋅sum(1) + 2⋅ft - 2⋅t
// So, both equations must be zero at minimum and there is only one
// solution.
float3 a = (ft * (f - float(char_pixels)) + t * (f - ff)) / (f * f - ff * float(char_pixels));
float3 b = (ft * f - t * ff) / (f * f - ff * float(char_pixels));
float3 e = a * a * ff + 2.0 * a * b * (f - ff) - 2.0 * a * ft +
b * b * (-2.0 * f + ff + float(char_pixels)) + 2.0 * b * ft - 2.0 * b * t + tt;
o.err = dot(e, float3(1.0, 1.0, 1.0));
o.fg = a;
o.bg = b;
o.c = c;
return o;
}
// Get the color of the pixel of this invocation based on the character details
float3 GetFinalPixel(CharResults char_out)
{
float2 resolution = OptionEnabled(USE_WINDOW_RES) ? GetWindowResolution() : GetResolution();
uint2 char_pos = uint2(floor(GetCoordinates() * resolution / char_dim));
uint2 pixel_offset = uint2(floor(GetCoordinates() * resolution) - char_pos * char_dim);
float font = SampleFont(int2(pixel_offset.x + char_width * pixel_offset.y, char_out.c));
return char_out.fg * font + char_out.bg * (1.0 - font);
}
/*
This shader performs some kind of brute force evaluation, which character fits best.
for c in characters:
for p in pixels:
ft += font(c,p) * texture(p)
res = CalcCharRes(ft)
min(res.err)
Terrible in performance, only for reference.
*/
CharResults CalcCharTrivial(uint2 char_pos)
{
float3 t;
CharResults char_out;
char_out.err = char_pixels * char_pixels;
for (uint c = 0; c < MAX_CHARS; c += 1)
{
float3 ft = float3(0.0, 0.0, 0.0);
for (uint pixel = 0; pixel < char_pixels; pixel += 1)
{
float3 tex = SampleTex(char_pos, pixel);
float font = SampleFont(uint2(pixel, c));
ft += font * tex;
}
if (c == 0)
t = ft;
CharResults res = CalcCharRes(c, t, ft);
if (res.err < char_out.err)
char_out = res;
}
return char_out;
}
/*
However for better performance, some characters are tested at once. This saves some expensive
texture() calls. Also split the loop over the pixels in groups of 32 for only fetching the uint32
of the font once.
*/
CharResults CalcCharFallback(uint2 char_pos)
{
float3 t;
CharResults char_out;
char_out.err = char_pixels * char_pixels;
for (uint c = 0; c < MAX_CHARS; c += UNROLL_FALLBACK)
{
// Declare ft
float3 ft[UNROLL_FALLBACK];
for (uint i = 0; i < UNROLL_FALLBACK; i++)
ft[i] = float3(0.0, 0.0, 0.0);
// Split `for p : pixels` in groups of 32. This makes accessing the texture (bit in uint32)
// easier.
for (uint pixel = 0; pixel < char_pixels; pixel += 32)
{
uint font_i[UNROLL_FALLBACK];
for (uint i = 0; i < UNROLL_FALLBACK; i++)
font_i[i] = rasters[c + i][pixel / 32];
for (uint pixel_offset = 0; pixel_offset < 32; pixel_offset += 1)
{
float3 tex = SampleTex(char_pos, pixel + pixel_offset);
// Inner kernel of `ft += font * tex`. Most time is spend in here.
for (uint i = 0; i < UNROLL_FALLBACK; i++)
{
float font = (font_i[i] >> pixel_offset) & uint(1);
ft[i] += font * tex;
}
}
}
if (c == 0)
{
// First char has font := 1, so t = ft. Cache this value for the next iterations.
t = ft[0];
}
// Check if this character fits better than the last one.
for (uint i = 0; i < UNROLL_FALLBACK; i++)
{
CharResults res = CalcCharRes(c + i, t, ft[i]);
if (res.err < char_out.err)
char_out = res;
}
}
return char_out;
}
/*
SIMD optimized version with subgroup intrinsics
- distribute all characters over the lanes and check for them in parallel
- distribute the uniform texture access and broadcast each back to each lane
*/
CharResults CalcCharSIMD(uint2 char_pos, uint simd_width)
{
// Font color, bg color, character, error -- of character with minimum error
CharResults char_out;
char_out.err = char_pixels * char_pixels;
float3 t;
#ifdef SUPPORTS_SUBGROUP_REDUCTION
// Hack: Work in hard-codeded fixed SIMD mode
if (gl_SubgroupInvocationID < simd_width)
{
// Loop over all characters
for (uint c = 0; c < MAX_CHARS; c += UNROLL_SIMD * simd_width)
{
// registers for "sum of font * texture"
float3 ft[UNROLL_SIMD];
for (uint i = 0; i < UNROLL_SIMD; i++)
ft[i] = float3(0.0, 0.0, 0.0);
for (uint pixel = 0; pixel < char_pixels; pixel += 32)
{
// Preload the font uint32 for the next 32 pixels
uint font_i[UNROLL_SIMD];
for (uint i = 0; i < UNROLL_SIMD; i++)
font_i[i] = rasters[c + UNROLL_SIMD * gl_SubgroupInvocationID + i][pixel / 32];
for (uint pixel_offset = 0; pixel_offset < 32; pixel_offset += simd_width)
{
// Copy one full WRAP of textures into registers and shuffle them around for later usage.
// This avoids one memory transaction per tested pixel & character.
float3 tex_simd = SampleTex(char_pos, pixel + pixel_offset + gl_SubgroupInvocationID);
for (uint k = 0; k < simd_width; k += 1)
{
float3 tex = subgroupBroadcast(tex_simd, k);
// Note: As pixel iterates based on power-of-two gl_SubgroupSize,
// the const memory access to rasters is CSE'd and the inner loop
// after unrolling only contains: testing one bit + shuffle +
// conditional add
for (uint i = 0; i < UNROLL_SIMD; i++)
{
float font = (font_i[i] >> (k + pixel_offset % 32)) & uint(1);
ft[i] += font * tex;
}
}
}
}
if (c == 0)
{
// font[0] is a hardcoded 1 font, so t = ft
t = subgroupBroadcast(ft[0], 0);
}
for (uint i = 0; i < UNROLL_SIMD; i++)
{
CharResults res = CalcCharRes(c + UNROLL_SIMD * gl_SubgroupInvocationID + i, t, ft[i]);
if (res.err < char_out.err)
char_out = res;
}
}
}
// Broadcast to get the best character of all threads
float err_min = subgroupMin(char_out.err);
uint smallest = subgroupBallotFindLSB(subgroupBallot(err_min == char_out.err));
char_out.fg = subgroupBroadcast(char_out.fg, smallest);
char_out.bg = subgroupBroadcast(char_out.bg, smallest);
char_out.c = subgroupBroadcast(char_out.c, smallest);
char_out.err = err_min;
#endif
return char_out;
}
bool supportsSIMD(uint simd_width)
{
#ifdef SUPPORTS_SUBGROUP_REDUCTION
const uint mask = simd_width == 32u ? 0xFFFFFFFFu : (1u << simd_width) - 1;
return (subgroupBallot(true)[0] & mask) == mask;
#else
return false;
#endif
}
// "Error: The AsciiArt shader requires the missing GPU extention KHR_shader_subgroup."
const uint missing_subgroup_warning_len = 82;
const uint missing_subgroup_warning[missing_subgroup_warning_len] = {
37, 82, 82, 79, 82, 26, 95, 52, 72, 69, 95, 33, 83, 67, 73, 73, 33, 82, 84, 95, 83,
72, 65, 68, 69, 82, 95, 82, 69, 81, 85, 73, 82, 69, 83, 95, 84, 72, 69, 95, 77, 73,
83, 83, 73, 78, 71, 95, 39, 48, 53, 95, 69, 88, 84, 69, 78, 84, 73, 79, 78, 95, 43,
40, 50, 63, 83, 72, 65, 68, 69, 82, 63, 83, 85, 66, 71, 82, 79, 85, 80, 14};
float3 ShowWarning(uint2 char_pos)
{
CharResults char_out;
char_out.fg = float3(1.0, 1.0, 1.0);
char_out.bg = float3(0.0, 0.0, 0.0);
char_out.c = 95u; // just background
if (char_pos.y == 0u && char_pos.x < missing_subgroup_warning_len)
{
char_out.c = missing_subgroup_warning[char_pos.x];
}
return GetFinalPixel(char_out);
}
void main()
{
// Calculate the character position of this pixel
float2 resolution = OptionEnabled(USE_WINDOW_RES) ? GetWindowResolution() : GetResolution();
uint2 char_pos_self = uint2(floor(GetCoordinates() * resolution / char_dim));
float3 color_out;
#ifdef SUPPORTS_SUBGROUP_REDUCTION
if (supportsSIMD(8))
{
// Loop over all character positions covered by this wave
bool pixel_active = !gl_HelperInvocation;
CharResults char_out;
while (true)
{
// Fetch the next active character position
uint4 active_lanes = subgroupBallot(pixel_active);
if (active_lanes == uint4(0, 0, 0, 0))
{
break;
}
uint2 char_pos = subgroupBroadcast(char_pos_self, subgroupBallotFindLSB(active_lanes));
// And calculate everything for this character position
if (supportsSIMD(32))
{
char_out = CalcCharSIMD(char_pos, 32);
}
else if (supportsSIMD(16))
{
char_out = CalcCharSIMD(char_pos, 16);
}
else if (supportsSIMD(8))
{
char_out = CalcCharSIMD(char_pos, 8);
}
// Draw the character on screen
if (char_pos == char_pos_self)
{
color_out = GetFinalPixel(char_out);
pixel_active = false;
}
if (OptionEnabled(DEBUG_ONLY_ONE_CHAR))
{
break;
}
}
}
else
#else
if (char_pos_self.y <= 1u)
{
color_out = ShowWarning(char_pos_self);
}
else
#endif
if (HAVE_FULL_FEATURE_FALLBACK)
{
color_out = GetFinalPixel(CalcCharFallback(char_pos_self));
}
else
{
color_out = Sample().xyz;
}
SetOutput(float4(color_out, 1.0));
}

View file

@ -0,0 +1,408 @@
/***** COLOR CORRECTION *****/
// Color Space references:
// https://www.unravel.com.au/understanding-color-spaces
// SMPTE 170M - BT.601 (NTSC-M) -> BT.709
mat3 from_NTSCM = transpose(mat3(
0.939497225737661, 0.0502268452914346, 0.0102759289709032,
0.0177558637510127, 0.965824605885027, 0.0164195303639603,
-0.00162163209967010, -0.00437400622653655, 1.00599563832621));
// ARIB TR-B9 (9300K+27MPCD with chromatic adaptation) (NTSC-J) -> BT.709
mat3 from_NTSCJ = transpose(mat3(
0.823613036967492, -0.0943227111084757, 0.00799341532931119,
0.0289258355537324, 1.02310733489462, 0.00243547111576797,
-0.00569501554980891, 0.0161828357559315, 1.22328453915712));
// EBU - BT.470BG/BT.601 (PAL) -> BT.709
mat3 from_PAL = transpose(mat3(
1.04408168421813, -0.0440816842181253, 0.000000000000000,
0.000000000000000, 1.00000000000000, 0.000000000000000,
0.000000000000000, 0.0118044782106489, 0.988195521789351));
float3 LinearTosRGBGamma(float3 color)
{
const float a = 0.055;
for (int i = 0; i < 3; ++i)
{
float x = color[i];
if (x <= 0.0031308)
x = x * 12.92;
else
x = (1.0 + a) * pow(x, 1.0 / 2.4) - a;
color[i] = x;
}
return color;
}
/***** COLOR SAMPLING *****/
// Non filtered gamma corrected sample (nearest neighbor)
float4 QuickSample(float3 uvw, float gamma)
{
#if 0 // Test sampling range
const float threshold = 0.00000001;
float2 xy = uvw.xy * GetResolution();
// Sampling outside the valid range, draw in yellow
if (xy.x < (0.0 - threshold) || xy.x > (GetResolution().x + threshold) || xy.y < (0.0 - threshold) || xy.y > (GetResolution().y + threshold))
return float4(1.0, 1.0, 0.0, 1);
// Sampling at the edges, draw in purple
if (xy.x < 1.0 || xy.x > (GetResolution().x - 1.0) || xy.y < 1.0 || xy.y > (GetResolution().y - 1.0))
return float4(0.5, 0, 0.5, 1);
#endif
float4 color = texture(samp1, uvw);
color.rgb = pow(color.rgb, float3(gamma));
return color;
}
float4 QuickSample(float2 uv, float w, float gamma)
{
return QuickSample(float3(uv, w), gamma);
}
float4 QuickSampleByPixel(float2 xy, float w, float gamma)
{
float3 uvw = float3(xy * GetInvResolution(), w);
return QuickSample(uvw, gamma);
}
/***** Bilinear Interpolation *****/
float4 BilinearSample(float3 uvw, float gamma)
{
// This emulates the (bi)linear filtering done directly from GPUs HW.
// Note that GPUs might natively filter red green and blue differently, but we don't do it.
// They might also use different filtering between upscaling and downscaling.
float2 source_size = GetResolution();
float2 pixel = (uvw.xy * source_size) - 0.5; // Try to find the matching pixel top left corner
// Find the integer and floating point parts
float2 int_pixel = floor(pixel);
float2 frac_pixel = fract(pixel);
// Take 4 samples around the original uvw
float4 c11 = QuickSampleByPixel(int_pixel + float2(0.5, 0.5), uvw.z, gamma);
float4 c21 = QuickSampleByPixel(int_pixel + float2(1.5, 0.5), uvw.z, gamma);
float4 c12 = QuickSampleByPixel(int_pixel + float2(0.5, 1.5), uvw.z, gamma);
float4 c22 = QuickSampleByPixel(int_pixel + float2(1.5, 1.5), uvw.z, gamma);
// Blend the 4 samples by their weight
return lerp(lerp(c11, c21, frac_pixel.x), lerp(c12, c22, frac_pixel.x), frac_pixel.y);
}
/***** Bicubic Interpolation *****/
// Formula derived from:
// https://en.wikipedia.org/wiki/Mitchell%E2%80%93Netravali_filters#Definition
// Values from:
// https://guideencodemoe-mkdocs.readthedocs.io/encoding/resampling/#mitchell-netravali-bicubic
// Other references:
// https://www.codeproject.com/Articles/236394/Bi-Cubic-and-Bi-Linear-Interpolation-with-GLSL
// https://github.com/ValveSoftware/gamescope/pull/740
// https://stackoverflow.com/questions/13501081/efficient-bicubic-filtering-code-in-glsl
#define CUBIC_COEFF_GEN(B, C) \
(mat4(/* t^0 */ ((B) / 6.0), (-(B) / 3.0 + 1.0), ((B) / 6.0), (0.0), \
/* t^1 */ (-(B) / 2.0 - (C)), (0.0), ((B) / 2.0 + (C)), (0.0), \
/* t^2 */ ((B) / 2.0 + 2.0 * (C)), (2.0 * (B) + (C)-3.0), \
(-5.0 * (B) / 2.0 - 2.0 * (C) + 3.0), (-(C)), \
/* t^3 */ (-(B) / 6.0 - (C)), (-3.0 * (B) / 2.0 - (C) + 2.0), \
(3.0 * (B) / 2.0 + (C)-2.0), ((B) / 6.0 + (C))))
float4 CubicCoeffs(float t, mat4 coeffs)
{
return coeffs * float4(1.0, t, t * t, t * t * t);
}
float4 CubicMix(float4 c0, float4 c1, float4 c2, float4 c3, float4 coeffs)
{
return c0 * coeffs[0] + c1 * coeffs[1] + c2 * coeffs[2] + c3 * coeffs[3];
}
// By Sam Belliveau. Public Domain license.
// Simple 16 tap, gamma correct, implementation of bicubic filtering.
float4 BicubicSample(float3 uvw, float gamma, mat4 coeffs)
{
float2 pixel = (uvw.xy * GetResolution()) - 0.5;
float2 int_pixel = floor(pixel);
float2 frac_pixel = fract(pixel);
float4 c00 = QuickSampleByPixel(int_pixel + float2(-0.5, -0.5), uvw.z, gamma);
float4 c10 = QuickSampleByPixel(int_pixel + float2(+0.5, -0.5), uvw.z, gamma);
float4 c20 = QuickSampleByPixel(int_pixel + float2(+1.5, -0.5), uvw.z, gamma);
float4 c30 = QuickSampleByPixel(int_pixel + float2(+2.5, -0.5), uvw.z, gamma);
float4 c01 = QuickSampleByPixel(int_pixel + float2(-0.5, +0.5), uvw.z, gamma);
float4 c11 = QuickSampleByPixel(int_pixel + float2(+0.5, +0.5), uvw.z, gamma);
float4 c21 = QuickSampleByPixel(int_pixel + float2(+1.5, +0.5), uvw.z, gamma);
float4 c31 = QuickSampleByPixel(int_pixel + float2(+2.5, +0.5), uvw.z, gamma);
float4 c02 = QuickSampleByPixel(int_pixel + float2(-0.5, +1.5), uvw.z, gamma);
float4 c12 = QuickSampleByPixel(int_pixel + float2(+0.5, +1.5), uvw.z, gamma);
float4 c22 = QuickSampleByPixel(int_pixel + float2(+1.5, +1.5), uvw.z, gamma);
float4 c32 = QuickSampleByPixel(int_pixel + float2(+2.5, +1.5), uvw.z, gamma);
float4 c03 = QuickSampleByPixel(int_pixel + float2(-0.5, +2.5), uvw.z, gamma);
float4 c13 = QuickSampleByPixel(int_pixel + float2(+0.5, +2.5), uvw.z, gamma);
float4 c23 = QuickSampleByPixel(int_pixel + float2(+1.5, +2.5), uvw.z, gamma);
float4 c33 = QuickSampleByPixel(int_pixel + float2(+2.5, +2.5), uvw.z, gamma);
float4 cx = CubicCoeffs(frac_pixel.x, coeffs);
float4 cy = CubicCoeffs(frac_pixel.y, coeffs);
float4 x0 = CubicMix(c00, c10, c20, c30, cx);
float4 x1 = CubicMix(c01, c11, c21, c31, cx);
float4 x2 = CubicMix(c02, c12, c22, c32, cx);
float4 x3 = CubicMix(c03, c13, c23, c33, cx);
return CubicMix(x0, x1, x2, x3, cy);
}
/***** Sharp Bilinear Filtering *****/
// Based on https://github.com/libretro/slang-shaders/blob/master/interpolation/shaders/sharp-bilinear.slang
// by Themaister, Public Domain license
// Does a bilinear stretch, with a preapplied Nx nearest-neighbor scale,
// giving a sharper image than plain bilinear.
float4 SharpBilinearSample(float3 uvw, float gamma)
{
float2 source_size = GetResolution();
float2 inverted_source_size = GetInvResolution();
float2 target_size = GetWindowResolution();
float2 texel = uvw.xy * source_size;
float2 texel_floored = floor(texel);
float2 s = fract(texel);
float scale = max(floor(max(target_size.x * inverted_source_size.x, target_size.y * inverted_source_size.y)), 1.f);
float region_range = 0.5 - (0.5 / scale);
// Figure out where in the texel to sample to get correct pre-scaled bilinear.
float2 center_dist = s - 0.5;
float2 f = ((center_dist - clamp(center_dist, -region_range, region_range)) * scale) + 0.5;
float2 mod_texel = texel_floored + f;
uvw.xy = mod_texel * inverted_source_size;
return BilinearSample(uvw, gamma);
}
/***** Area Sampling *****/
// By Sam Belliveau and Filippo Tarpini. Public Domain license.
// Effectively a more accurate sharp bilinear filter when upscaling,
// that also works as a mathematically perfect downscale filter.
// https://entropymine.com/imageworsener/pixelmixing/
// https://github.com/obsproject/obs-studio/pull/1715
// https://legacy.imagemagick.org/Usage/filter/
float4 AreaSampling(float3 uvw, float gamma)
{
// Determine the sizes of the source and target images.
float2 source_size = GetResolution();
float2 target_size = GetWindowResolution();
float2 inverted_target_size = GetInvWindowResolution();
// Compute the top-left and bottom-right corners of the target pixel box.
float2 t_beg = floor(uvw.xy * target_size);
float2 t_end = t_beg + float2(1.0, 1.0);
// Convert the target pixel box to source pixel box.
float2 beg = t_beg * inverted_target_size * source_size;
float2 end = t_end * inverted_target_size * source_size;
// Compute the top-left and bottom-right corners of the pixel box.
float2 f_beg = floor(beg);
float2 f_end = floor(end);
// Compute how much of the start and end pixels are covered horizontally & vertically.
float area_w = 1.0 - fract(beg.x);
float area_n = 1.0 - fract(beg.y);
float area_e = fract(end.x);
float area_s = fract(end.y);
// Compute the areas of the corner pixels in the pixel box.
float area_nw = area_n * area_w;
float area_ne = area_n * area_e;
float area_sw = area_s * area_w;
float area_se = area_s * area_e;
// Initialize the color accumulator.
float4 avg_color = float4(0.0, 0.0, 0.0, 0.0);
// Prevents rounding errors due to the coordinates flooring above
const float2 offset = float2(0.5, 0.5);
// Accumulate corner pixels.
avg_color += area_nw * QuickSampleByPixel(float2(f_beg.x, f_beg.y) + offset, uvw.z, gamma);
avg_color += area_ne * QuickSampleByPixel(float2(f_end.x, f_beg.y) + offset, uvw.z, gamma);
avg_color += area_sw * QuickSampleByPixel(float2(f_beg.x, f_end.y) + offset, uvw.z, gamma);
avg_color += area_se * QuickSampleByPixel(float2(f_end.x, f_end.y) + offset, uvw.z, gamma);
// Determine the size of the pixel box.
int x_range = int(f_end.x - f_beg.x - 0.5);
int y_range = int(f_end.y - f_beg.y - 0.5);
// Workaround to compile the shader with DX11/12.
// If this isn't done, it will complain that the loop could have too many iterations.
// This number should be enough to guarantee downscaling from very high to very small resolutions.
// Note that this number might be referenced in the UI.
const int max_iterations = 16;
// Fix up the average calculations in case we reached the upper limit
x_range = min(x_range, max_iterations);
y_range = min(y_range, max_iterations);
// Accumulate top and bottom edge pixels.
for (int ix = 0; ix < max_iterations; ++ix)
{
if (ix < x_range)
{
float x = f_beg.x + 1.0 + float(ix);
avg_color += area_n * QuickSampleByPixel(float2(x, f_beg.y) + offset, uvw.z, gamma);
avg_color += area_s * QuickSampleByPixel(float2(x, f_end.y) + offset, uvw.z, gamma);
}
}
// Accumulate left and right edge pixels and all the pixels in between.
for (int iy = 0; iy < max_iterations; ++iy)
{
if (iy < y_range)
{
float y = f_beg.y + 1.0 + float(iy);
avg_color += area_w * QuickSampleByPixel(float2(f_beg.x, y) + offset, uvw.z, gamma);
avg_color += area_e * QuickSampleByPixel(float2(f_end.x, y) + offset, uvw.z, gamma);
for (int ix = 0; ix < max_iterations; ++ix)
{
if (ix < x_range)
{
float x = f_beg.x + 1.0 + float(ix);
avg_color += QuickSampleByPixel(float2(x, y) + offset, uvw.z, gamma);
}
}
}
}
// Compute the area of the pixel box that was sampled.
float area_corners = area_nw + area_ne + area_sw + area_se;
float area_edges = float(x_range) * (area_n + area_s) + float(y_range) * (area_w + area_e);
float area_center = float(x_range) * float(y_range);
// Return the normalized average color.
return avg_color / (area_corners + area_edges + area_center);
}
/***** Main Functions *****/
// Returns an accurate (gamma corrected) sample of a gamma space space texture.
// Outputs in linear space for simplicity.
float4 LinearGammaCorrectedSample(float gamma)
{
float3 uvw = v_tex0;
float4 color = float4(0, 0, 0, 1);
if (resampling_method <= 1) // Bilinear
{
color = BilinearSample(uvw, gamma);
}
else if (resampling_method == 2) // Bicubic: B-Spline
{
color = BicubicSample(uvw, gamma, CUBIC_COEFF_GEN(1.0, 0.0));
}
else if (resampling_method == 3) // Bicubic: Mitchell-Netravali
{
color = BicubicSample(uvw, gamma, CUBIC_COEFF_GEN(1.0 / 3.0, 1.0 / 3.0));
}
else if (resampling_method == 4) // Bicubic: Catmull-Rom
{
color = BicubicSample(uvw, gamma, CUBIC_COEFF_GEN(0.0, 0.5));
}
else if (resampling_method == 5) // Sharp Bilinear
{
color = SharpBilinearSample(uvw, gamma);
}
else if (resampling_method == 6) // Area Sampling
{
color = AreaSampling(uvw, gamma);
}
else if (resampling_method == 7) // Nearest Neighbor
{
color = QuickSample(uvw, gamma);
}
else if (resampling_method == 8) // Bicubic: Hermite
{
color = BicubicSample(uvw, gamma, CUBIC_COEFF_GEN(0.0, 0.0));
}
return color;
}
void main()
{
// This tries to fall back on GPU HW sampling if it can (it won't be gamma corrected).
bool raw_resampling = resampling_method <= 0;
bool needs_rescaling = GetResolution() != GetWindowResolution();
bool needs_resampling = needs_rescaling && (OptionEnabled(hdr_output) || OptionEnabled(correct_gamma) || !raw_resampling);
float4 color;
if (needs_resampling)
{
// Doing linear sampling in "gamma space" on linear texture formats isn't correct.
// If the source and target resolutions don't match, the GPU will return a color
// that is the average of 4 gamma space colors, but gamma space colors can't be blended together,
// gamma neeeds to be de-applied first. This makes a big difference if colors change
// drastically between two pixels.
color = LinearGammaCorrectedSample(game_gamma);
}
else
{
// Default GPU HW sampling. Bilinear is identical to Nearest Neighbor if the input and output resolutions match.
if (needs_rescaling)
color = texture(samp0, v_tex0);
else
color = texture(samp1, v_tex0);
// Convert to linear before doing any other of follow up operations.
color.rgb = pow(color.rgb, float3(game_gamma));
}
if (OptionEnabled(correct_color_space))
{
if (game_color_space == 0)
color.rgb = color.rgb * from_NTSCM;
else if (game_color_space == 1)
color.rgb = color.rgb * from_NTSCJ;
else if (game_color_space == 2)
color.rgb = color.rgb * from_PAL;
}
if (OptionEnabled(hdr_output))
{
float hdr_paper_white = hdr_paper_white_nits / hdr_sdr_white_nits;
color.rgb *= hdr_paper_white;
}
if (OptionEnabled(linear_space_output))
{
// Nothing to do here
}
// Correct the SDR gamma for sRGB (PC/Monitor) or ~2.2 (Common TV gamma)
else if (OptionEnabled(correct_gamma))
{
if (OptionEnabled(sdr_display_gamma_sRGB))
color.rgb = LinearTosRGBGamma(color.rgb);
else
color.rgb = pow(color.rgb, float3(1.0 / sdr_display_custom_gamma));
}
// Restore the original gamma without changes
else
{
color.rgb = pow(color.rgb, float3(1.0 / game_gamma));
}
SetOutput(color);
}

View file

@ -81,7 +81,7 @@ void main()
float2 uv = (widenedRadial/2.0f) + float2(0.5f, 0.5f) + float2(offsetAdd, 0.0f);
// Sample the texture at the source location
if(any(clamp(uv, 0.0, 1.0) != uv))
if (clamp(uv, 0.0, 1.0) != uv)
{
// black if beyond bounds
SetOutput(float4(0.0, 0.0, 0.0, 0.0));

View file

@ -1,47 +0,0 @@
// Based on https://github.com/libretro/slang-shaders/blob/master/interpolation/shaders/sharp-bilinear.slang
// by Themaister, Public Domain license
// Does a bilinear stretch, with a preapplied Nx nearest-neighbor scale,
// giving a sharper image than plain bilinear.
/*
[configuration]
[OptionRangeFloat]
GUIName = Prescale Factor (set to 0 for automatic)
OptionName = PRESCALE_FACTOR
MinValue = 0.0
MaxValue = 16.0
StepAmount = 1.0
DefaultValue = 0.0
[/configuration]
*/
float CalculatePrescale(float config_scale) {
if (config_scale == 0.0) {
float2 source_size = GetResolution();
float2 window_size = GetWindowResolution();
return ceil(max(window_size.x / source_size.x, window_size.y / source_size.y));
} else {
return config_scale;
}
}
void main()
{
float2 source_size = GetResolution();
float2 texel = GetCoordinates() * source_size;
float2 texel_floored = floor(texel);
float2 s = fract(texel);
float config_scale = GetOption(PRESCALE_FACTOR);
float scale = CalculatePrescale(config_scale);
float region_range = 0.5 - 0.5 / scale;
// Figure out where in the texel to sample to get correct pre-scaled bilinear.
// Uses the hardware bilinear interpolator to avoid having to sample 4 times manually.
float2 center_dist = s - 0.5;
float2 f = (center_dist - clamp(center_dist, -region_range, region_range)) * scale + 0.5;
float2 mod_texel = texel_floored + f;
SetOutput(SampleLocation(mod_texel / source_size));
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.8 KiB

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