diff --git a/.github/workflows/impacto.yml b/.github/workflows/impacto.yml index 63a171086..4375ad71d 100644 --- a/.github/workflows/impacto.yml +++ b/.github/workflows/impacto.yml @@ -121,7 +121,6 @@ jobs: export MINSDKVERSION=28 echo "MINSDKVERSION=$MINSDKVERSION" >> $GITHUB_ENV echo "ABI=$ABI" >> $GITHUB_ENV - echo "CC=$ANDROID_NDK_HOME/toolchains/llvm/prebuilt/linux-x86_64/bin/clang --target=aarch64-linux-android$MINSDKVERSION -fPIC" >> $GITHUB_ENV echo "VULKAN_SDK=$ANDROID_NDK_HOME/toolchains/llvm/prebuilt/linux-x86_64/sysroot/usr" >> $GITHUB_ENV shell: bash diff --git a/CMakeLists.txt b/CMakeLists.txt index 1c02efeac..e28426fb6 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -65,8 +65,12 @@ set(Impacto_Src src/effects/chlcc/eyecatch.cpp src/renderer/renderer.cpp + src/renderer/textureref.cpp src/renderer/window.cpp + src/renderer/video/nv12frame.cpp + src/renderer/video/yuvframe.cpp + src/data/savesystem.cpp src/data/tipssystem.cpp src/data/achievementsystem.cpp @@ -439,10 +443,13 @@ set(Impacto_Header src/effects/chlcc/bubbleseffect.h src/effects/chlcc/eyecatch.h + src/renderer/positionedsprite.h src/renderer/renderer.h + src/renderer/textureref.h src/renderer/window.h - src/renderer/yuvframe.h - src/renderer/nv12frame.h + + src/renderer/video/nv12frame.h + src/renderer/video/yuvframe.h src/data/savesystem.h src/data/tipssystem.h @@ -820,14 +827,39 @@ set(Impacto_Lib_Targets ) if (NX OR EMSCRIPTEN) - set(IMPACTO_DISABLE_VULKAN ON) - set(IMPACTO_DISABLE_DX9 ON) set(IMPACTO_DISABLE_MMAP ON) set(BUILD_SHARED_LIBS OFF) endif () -if (UNIX AND NOT CYGWIN) - set(IMPACTO_DISABLE_DX9 ON) +if (LINUX) + set(IMPACTO_RENDERER_VULKAN ON) + set(IMPACTO_RENDERER_OPENGL ON) + set(IMPACTO_RENDERER_OPENGLES ON) +elseif (WIN32 OR CYGWIN) + set(IMPACTO_RENDERER_VULKAN ON) + set(IMPACTO_RENDERER_OPENGL ON) + set(IMPACTO_RENDERER_OPENGLES ON) + set(IMPACTO_RENDERER_DIRECT3D11 ON) + set(IMPACTO_RENDERER_DIRECT3D12 ON) +elseif (APPLE) + set(IMPACTO_RENDERER_VULKAN ON) + set(IMPACTO_RENDERER_METAL ON) +elseif (ANDROID) + set(IMPACTO_RENDERER_VULKAN ON) + set(IMPACTO_RENDERER_OPENGLES ON) +elseif (NX) + set(IMPACTO_RENDERER_OPENGLES ON) +else () + message(FATAL_ERROR "No renderer backends supplied for target platform") +endif () + +if (IMPACTO_RENDERER_VULKAN OR + IMPACTO_RENDERER_OPENGL OR + IMPACTO_RENDERER_OPENGLES OR + IMPACTO_RENDERER_DIRECT3D11 OR + IMPACTO_RENDERER_DIRECT3D12 OR + IMPACTO_RENDERER_METAL) + set(IMPACTO_RENDERER_BGFX ON) endif () if (IMPACTO_ASAN) @@ -915,33 +947,6 @@ endif () list(APPEND Impacto_Include_Dirs ${CMAKE_CURRENT_SOURCE_DIR}/vendor) list(APPEND Impacto_Include_Dirs ${CMAKE_CURRENT_SOURCE_DIR}/vendor/include) -if (NOT DEFINED IMPACTO_DISABLE_OPENGL) - list(APPEND Impacto_Include_Dirs ${CMAKE_CURRENT_SOURCE_DIR}/vendor/glad/include) - - if (ANDROID OR NX) - set(OpenGL_Libs - OpenGL::GLES3 - OpenGL::EGL - ) - set(OpenGL_Components - GLES3 - EGL - ) - else() - set(OpenGL_Libs - OpenGL::GL - ) - set(OpenGL_Components - OpenGL - ) - endif () - find_package(OpenGL COMPONENTS ${OpenGL_Components}) - list(APPEND Impacto_Libs - ${OpenGL_Libs} - ) -endif () - - if (NOT DEFINED IMPACTO_DISABLE_OPENAL) find_package(OpenAL CONFIG REQUIRED) @@ -982,7 +987,6 @@ if (EMSCRIPTEN) -g4 \ --preload-file ${CMAKE_CURRENT_SOURCE_DIR}/profiles@/profiles \ --preload-file ${CMAKE_CURRENT_SOURCE_DIR}/games@/games \ - --preload-file ${CMAKE_CURRENT_SOURCE_DIR}/src/shaders@/shaders \ ") if ("${CMAKE_BUILD_TYPE}" STREQUAL "Debug") set(IMPACTO_EMSCRIPTEN_BUILD_FLAGS "${IMPACTO_EMSCRIPTEN_BUILD_FLAGS} \ @@ -1041,7 +1045,7 @@ list(APPEND Impacto_Include_Dirs ${WebP_INCLUDE_DIRS}) find_package(fmt CONFIG REQUIRED) find_package(glm CONFIG REQUIRED) -find_package(Boost REQUIRED COMPONENTS circular_buffer) +find_package(Boost REQUIRED COMPONENTS circular_buffer pfr) find_package(pugixml CONFIG REQUIRED) find_package(unordered_dense CONFIG REQUIRED) find_package(readerwriterqueue CONFIG REQUIRED) @@ -1062,6 +1066,7 @@ list(APPEND Impacto_Libs concurrentqueue::concurrentqueue readerwriterqueue::readerwriterqueue Boost::circular_buffer + Boost::pfr toml11::toml11 Freetype::Freetype harfbuzz::harfbuzz @@ -1116,7 +1121,7 @@ if (NOT DEFINED IMPACTO_DISABLE_IMGUI) list(APPEND Impacto_Src src/overlay.cpp) list(APPEND Impacto_Header src/overlay.h) - if (NOT DEFINED IMPACTO_DISABLE_OPENGL) + if (IMPACTO_RENDERER_OPENGL OR IMPACTO_RENDERER_OPENGLES) list(APPEND imgui_src vendor/imgui_custom/backends/imgui_impl_opengl3.cpp ) @@ -1125,15 +1130,50 @@ if (NOT DEFINED IMPACTO_DISABLE_IMGUI) ) endif () - if (NOT DEFINED IMPACTO_DISABLE_VULKAN) + if (IMPACTO_RENDERER_VULKAN) list(APPEND imgui_src ${imgui_SOURCE_DIR}/backends/imgui_impl_vulkan.cpp ) endif () - if (NOT DEFINED IMPACTO_DISABLE_DX9) + if (IMPACTO_RENDERER_DIRECT3D11) + list(APPEND imgui_src + ${imgui_SOURCE_DIR}/backends/imgui_impl_dx11.cpp + ) + endif () + + if (IMPACTO_RENDERER_DIRECT3D12) + list(APPEND imgui_src + ${imgui_SOURCE_DIR}/backends/imgui_impl_dx12.cpp + ) + endif () + + if (IMPACTO_RENDERER_METAL) list(APPEND imgui_src - ${imgui_SOURCE_DIR}/backends/imgui_impl_dx9.cpp + ${imgui_SOURCE_DIR}/backends/imgui_impl_metal.mm + ) + endif () + + if (IMPACTO_RENDERER_BGFX) + FetchContent_Declare( + imgui_impl_bgfx + URL https://gist.github.com/Madman10K/0ffc9ba203333d3580d467d972bbf8b6/archive/9110d39e126dbd557ad1ff5147526ffeaeb7267c.zip + ) + FetchContent_MakeAvailable(imgui_impl_bgfx) + file(DOWNLOAD + https://raw.githubusercontent.com/pr0g/sdl-bgfx-imgui-starter/8cff6aef7d14a16b820254f646e2f22535925d8d/bgfx-imgui/fs_ocornut_imgui.bin.h + ${imgui_impl_bgfx_SOURCE_DIR}/fs_ocornut_imgui.bin.h + ) + file(DOWNLOAD + https://raw.githubusercontent.com/pr0g/sdl-bgfx-imgui-starter/8cff6aef7d14a16b820254f646e2f22535925d8d/bgfx-imgui/vs_ocornut_imgui.bin.h + ${imgui_impl_bgfx_SOURCE_DIR}/vs_ocornut_imgui.bin.h + ) + + list(APPEND imgui_src + ${imgui_impl_bgfx_SOURCE_DIR}/imgui_impl_bgfx.cpp + ) + list(APPEND imgui_Include_Dirs + ${imgui_impl_bgfx_SOURCE_DIR} ) endif () @@ -1148,36 +1188,145 @@ if (NOT DEFINED IMPACTO_DISABLE_IMGUI) target_compile_definitions(imgui PRIVATE IMGUI_DISABLE_DEFAULT_SHELL_FUNCTIONS=1) endif () - target_link_libraries(imgui PRIVATE ${SDL3_LIBRARIES} ${OpenGL_Libs}) + target_link_libraries(imgui PRIVATE ${SDL3_LIBRARIES}) + + if (IMPACTO_RENDERER_BGFX) + target_link_libraries(imgui PUBLIC bgfx::bgfx PRIVATE bgfx::bx) + endif () list(APPEND Impacto_Lib_Targets imgui) endif () -if (NOT DEFINED IMPACTO_DISABLE_OPENGL) +if (IMPACTO_RENDERER_BGFX) + find_package(bgfx CONFIG REQUIRED) + list(APPEND Impacto_Libs bgfx::bgfx) + + if (ANDROID AND IMPACTO_RENDERER_OPENGLES) + set(OpenGL_Libs + OpenGL::GLES3 + OpenGL::EGL + ) + set(OpenGL_Components + GLES3 + EGL + ) + + find_package(OpenGL COMPONENTS ${OpenGL_Components}) + list(APPEND Impacto_Libs ${OpenGL_Libs}) + endif () + list(APPEND Impacto_Src - src/renderer/opengl/window.cpp - src/renderer/opengl/renderer.cpp - src/renderer/opengl/shader.cpp - src/renderer/opengl/glc.cpp - src/renderer/opengl/yuvframe.cpp - src/renderer/opengl/nv12frame.cpp - src/renderer/opengl/3d/renderable3d.cpp - src/renderer/opengl/3d/scene.cpp - - vendor/glad/src/glad.c + src/renderer/bgfx/framebuffer.cpp + src/renderer/bgfx/renderer.cpp + src/renderer/bgfx/texture.cpp + src/renderer/bgfx/window.cpp ) list(APPEND Impacto_Header - src/renderer/opengl/window.h - src/renderer/opengl/renderer.h - src/renderer/opengl/shader.h - src/renderer/opengl/glc.h - src/renderer/opengl/yuvframe.h - src/renderer/opengl/nv12frame.h - src/renderer/opengl/3d/renderable3d.h - src/renderer/opengl/3d/scene.h + src/renderer/bgfx/framebuffer.h + src/renderer/bgfx/renderer.h + src/renderer/bgfx/shader.h + src/renderer/bgfx/texture.h + src/renderer/bgfx/window.h + + src/renderer/bgfx/shaders/vs_maskedsprite.h + src/renderer/bgfx/shaders/vs_sprite.h + src/renderer/bgfx/shaders/fs_additivemaskedsprite.h + src/renderer/bgfx/shaders/fs_ccmessageboxsprite.h + src/renderer/bgfx/shaders/fs_chlccmenubackground.h + src/renderer/bgfx/shaders/fs_colorburnmaskedsprite.h + src/renderer/bgfx/shaders/fs_colordodgemaskedsprite.h + src/renderer/bgfx/shaders/fs_colormaskedsprite.h + src/renderer/bgfx/shaders/fs_edgedetectedsinglesheetfont.h + src/renderer/bgfx/shaders/fs_gaussianblur.h + src/renderer/bgfx/shaders/fs_hardlightmaskedsprite.h + src/renderer/bgfx/shaders/fs_linearburnmaskedsprite.h + src/renderer/bgfx/shaders/fs_maskedsprite.h + src/renderer/bgfx/shaders/fs_maskedspritebinary.h + src/renderer/bgfx/shaders/fs_maskedspritenoalpha.h + src/renderer/bgfx/shaders/fs_mosaic.h + src/renderer/bgfx/shaders/fs_nv12frame.h + src/renderer/bgfx/shaders/fs_overlaymaskedsprite.h + src/renderer/bgfx/shaders/fs_screenmaskedsprite.h + src/renderer/bgfx/shaders/fs_silhouette.h + src/renderer/bgfx/shaders/fs_softlightmaskedsprite.h + src/renderer/bgfx/shaders/fs_sprite.h + src/renderer/bgfx/shaders/fs_spriteinverted.h + src/renderer/bgfx/shaders/fs_yuvframe.h ) -endif () + set(Bgfx_Vertex_Shaders + src/shaders/bgfx/vs_maskedsprite.sc + src/shaders/bgfx/vs_sprite.sc + ) + set(Bgfx_Fragment_Shaders + src/shaders/bgfx/fs_additivemaskedsprite.sc + src/shaders/bgfx/fs_ccmessageboxsprite.sc + src/shaders/bgfx/fs_chlccmenubackground.sc + src/shaders/bgfx/fs_colorburnmaskedsprite.sc + src/shaders/bgfx/fs_colordodgemaskedsprite.sc + src/shaders/bgfx/fs_colormaskedsprite.sc + src/shaders/bgfx/fs_edgedetectedsinglesheetfont.sc + src/shaders/bgfx/fs_gaussianblur.sc + src/shaders/bgfx/fs_hardlightmaskedsprite.sc + src/shaders/bgfx/fs_linearburnmaskedsprite.sc + src/shaders/bgfx/fs_maskedsprite.sc + src/shaders/bgfx/fs_maskedspritebinary.sc + src/shaders/bgfx/fs_maskedspritenoalpha.sc + src/shaders/bgfx/fs_mosaic.sc + src/shaders/bgfx/fs_nv12frame.sc + src/shaders/bgfx/fs_overlaymaskedsprite.sc + src/shaders/bgfx/fs_screenmaskedsprite.sc + src/shaders/bgfx/fs_silhouette.sc + src/shaders/bgfx/fs_softlightmaskedsprite.sc + src/shaders/bgfx/fs_sprite.sc + src/shaders/bgfx/fs_spriteinverted.sc + src/shaders/bgfx/fs_yuvframe.sc + ) + + set(Bgfx_Shaders ${Bgfx_Vertex_Shaders} ${Bgfx_Fragment_Shaders}) + + bgfx_compile_shaders( + TYPE VERTEX + SHADERS ${Bgfx_Vertex_Shaders} + VARYING_DEF ${CMAKE_SOURCE_DIR}/src/shaders/bgfx/varying.def.sc + OUTPUT_DIR "include/bgfx/shaders" + AS_HEADERS + ) + bgfx_compile_shaders( + TYPE FRAGMENT + SHADERS ${Bgfx_Fragment_Shaders} + VARYING_DEF ${CMAKE_SOURCE_DIR}/src/shaders/bgfx/varying.def.sc + OUTPUT_DIR "include/bgfx/shaders" + AS_HEADERS + ) + + add_library(bgfx_shaders INTERFACE ${Bgfx_Shaders}) + list(APPEND Impacto_Lib_Targets bgfx_shaders) + + # Automatically stamp out headers for including the shader source code. + # + # * /include/bgfx/shaders/ includes header files for each shader, + # containing the compiled shader binaries in an array. + # + # * /include/bgfx/shaders/.sc.h conditionally includes these compiled + # shader binaries based on which rendering backends are enabled, and stores them + # in an array of spans for easier access. + # These files are based on the /src/renderer/bgfx/shaders/shaders.h.in template file. + # + # * /include/bgfx/shader_contents.h includes all shader headers and should be included + # in the renderer implementation to access the shader source code. + set(shader_content_header "#pragma once\n") + foreach (shader IN LISTS Bgfx_Shaders) + string(REGEX MATCH "[^\\/]*$" SHADER_NAME ${shader}) + string(REGEX MATCH "^[^\.]*" SHADER_BASE_NAME ${SHADER_NAME}) + configure_file( + src/renderer/bgfx/shaders/shaders.h.in + "${CMAKE_BINARY_DIR}/include/bgfx/shaders/${SHADER_NAME}.h" + ) + string(APPEND shader_content_header "#include \"shaders/${SHADER_NAME}.h\"\n") + endforeach() + file(WRITE ${CMAKE_BINARY_DIR}/include/bgfx/shader_content.h ${shader_content_header}) +endif() if (NOT DEFINED IMPACTO_DISABLE_FFMPEG) list(APPEND Impacto_Src @@ -1225,63 +1374,6 @@ if (NOT DEFINED IMPACTO_DISABLE_MSPACK) list(APPEND Impacto_Header src/io/lzxstream.h) endif () -if (NOT DEFINED IMPACTO_DISABLE_VULKAN) - list(APPEND Impacto_Src - src/renderer/vulkan/window.cpp - src/renderer/vulkan/renderer.cpp - src/renderer/vulkan/pipeline.cpp - src/renderer/vulkan/utils.cpp - src/renderer/vulkan/yuvframe.cpp - src/renderer/vulkan/nv12frame.cpp - src/renderer/vulkan/3d/renderable3d.cpp - src/renderer/vulkan/3d/scene.cpp - ) - list(APPEND Impacto_Header - src/renderer/vulkan/window.h - src/renderer/vulkan/renderer.h - src/renderer/vulkan/pipeline.h - src/renderer/vulkan/utils.h - src/renderer/vulkan/yuvframe.h - src/renderer/vulkan/nv12frame.h - src/renderer/vulkan/3d/renderable3d.h - src/renderer/vulkan/3d/scene.h - ) - - find_package(Vulkan REQUIRED) - - list(APPEND Impacto_Libs - ${Vulkan_LIBRARIES} - ) - list(APPEND Impacto_Include_Dirs ${Vulkan_INCLUDE_DIRS}) -endif () - -if (NOT DEFINED IMPACTO_DISABLE_DX9) - list(APPEND Impacto_Src - src/renderer/dx9/renderer.cpp - src/renderer/dx9/window.cpp - src/renderer/dx9/shader.cpp - src/renderer/dx9/yuvframe.cpp - src/renderer/dx9/nv12frame.cpp - src/renderer/dx9/3d/scene.cpp - src/renderer/dx9/3d/renderable3d.cpp - ) - list(APPEND Impacto_Header - src/renderer/dx9/utils.h - src/renderer/dx9/renderer.h - src/renderer/dx9/window.h - src/renderer/dx9/shader.h - src/renderer/dx9/yuvframe.h - src/renderer/dx9/nv12frame.h - src/renderer/dx9/3d/scene.h - src/renderer/dx9/3d/renderable3d.h - ) - - list(APPEND Impacto_Libs - d3d9 - d3dcompiler - ) -endif () - configure_file(src/version.h.in ${PROJECT_BINARY_DIR}/include/version.h) if(ANDROID) @@ -1325,7 +1417,7 @@ list(APPEND Impacto_Libs ${Impacto_Lib_Targets}) target_link_libraries(impacto PRIVATE ${Impacto_Libs}) target_compile_options(impacto PRIVATE "$<$:/utf-8>") -target_compile_options(impacto PRIVATE "$<$:/utf-8>") +target_compile_options(impacto PRIVATE "$<$:/utf-8;/Zc:__cplusplus>") if (IMPACTO_WARNINGS) if (CMAKE_CXX_COMPILER_ID STREQUAL "Clang" OR CMAKE_CXX_COMPILER_ID STREQUAL "AppleClang") @@ -1384,7 +1476,7 @@ option(IMPACTO_ENABLE_SLOW_LOG "Compile log statements that get hit very frequently or are in a hot path" ${IMPACTO_ENABLE_SLOW_LOG_DEFAULT}) option(IMPACTO_GL_DEBUG -"Use an OpenGL debug context and log messages" +"Use a debug context and log renderer messages" ${IMPACTO_GL_DEBUG_DEFAULT}) option(IMPACTO_HAVE_THREADS "Multithreading support" ON) @@ -1447,9 +1539,6 @@ elseif(APPLE) RUNTIME DESTINATION . RESOURCE DESTINATION . ) - install(DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/src/shaders" - DESTINATION "Impacto.app/Contents/Resources/" - ) install(DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/resources" DESTINATION "Impacto.app/Contents/Resources/" ) @@ -1480,7 +1569,6 @@ endif () if (NOT ANDROID) if(NOT APPLE) - install(DIRECTORY src/shaders DESTINATION .) install(DIRECTORY resources DESTINATION .) endif() install(DIRECTORY profiles DESTINATION .) @@ -1492,10 +1580,7 @@ if (NOT ANDROID) install(FILES ${CMAKE_SOURCE_DIR}/basepaths.lua.sample DESTINATION . RENAME basepaths.lua) endif() else() - install(DIRECTORY src/shaders DESTINATION ${CMAKE_SOURCE_DIR}/android/app/src/main/assets) install(DIRECTORY profiles DESTINATION ${CMAKE_SOURCE_DIR}/android/app/src/main/assets) install(DIRECTORY resources DESTINATION ${CMAKE_SOURCE_DIR}/android/app/src/main/assets PATTERN "*/gamedata/*" EXCLUDE) install(FILES gamedefinitions.lua DESTINATION ${CMAKE_SOURCE_DIR}/android/app/src/main/assets) endif() - - diff --git a/HorizonNX.toolchain b/HorizonNX.toolchain index 65bc4e76d..60ae89e50 100644 --- a/HorizonNX.toolchain +++ b/HorizonNX.toolchain @@ -32,7 +32,7 @@ set(ENV{PKG_CONFIG_PATH} "") set(ENV{PKG_CONFIG_LIBDIR} "${DEVKITPRO}/portlibs/switch/lib/pkgconfig") set(ENV{PKG_CONFIG_SYSROOT_DIR} "${DEVKITPRO}/portlibs/switch") -set(CMAKE_C_FLAGS_INIT "${CPPFLAGS} -march=armv8-a -mtune=cortex-a57 -mtp=soft -fPIC -ffunction-sections -D__SWITCH__ -I${DEVKITPRO}/libnx/include -ftls-model=local-exec" CACHE STRING "C flags") +set(CMAKE_C_FLAGS_INIT "${CPPFLAGS} -march=armv8-a -mtune=cortex-a57 -mtp=soft -fPIC -ffunction-sections -D__NX__ -D__SWITCH__ -I${DEVKITPRO}/libnx/include -ftls-model=local-exec -D_DEFAULT_SOURCE" CACHE STRING "C flags") set(CMAKE_CXX_FLAGS_INIT "${CPPFLAGS} ${CMAKE_C_FLAGS_INIT}" CACHE STRING "C++ flags") if(WITH_PORTLIBS) diff --git a/README.md b/README.md index c1be329ba..ce6803c45 100644 --- a/README.md +++ b/README.md @@ -6,7 +6,7 @@ **impacto is in active development**. At current stage it should be possible to reach all endings in at least one supported game - "Memories Off 6 \~T-Wave\~." However, some functionality and architectural design are still missing and **no games are fully complete yet**. Refer to [#1](https://github.com/CommitteeOfZero/impacto/issues/1) for supported games and remaining work. -impacto is currently being developed for **64-bit Windows 10 and desktop Linux PCs** but we've successfully experimented on macOS, Android (ARM), Switch (homebrew and Linux) and HTML5/WebAssembly (via Emscripten) and full official Android support is planned. OpenGL is used for the graphics renderer with experimental Vulkan and DirectX 9 options available. +impacto is currently being developed for **64-bit Windows 10 and desktop Linux PCs** but we've successfully experimented on macOS, Android (ARM), Switch (homebrew and Linux) and HTML5/WebAssembly (via Emscripten) and full official Android support is planned. OpenGL, OpenGLES, Vulkan, Direct3D11, Direct3D12, and Metal graphics backends are supported. ## Building diff --git a/THIRDPARTY.md b/THIRDPARTY.md index 75b832e82..59ba55721 100644 --- a/THIRDPARTY.md +++ b/THIRDPARTY.md @@ -12,7 +12,6 @@ * `src/video/ffmpegplayer.cpp`: syncing code based on [FFplay](https://github.com/FFmpeg/FFmpeg/blob/master/fftools/ffplay.c) * `vendor/clHCA`: part of [vgmstream](https://github.com/losnoco/vgmstream) * `vendor/minilua`: [minilua](https://github.com/edubart/minilua) -* `vendor/glad`: output from [glad](https://github.com/Dav1dde/glad) generator, patched for Switch support * `vendor/include/stb_image.h`: [stb_image](https://github.com/nothings/stb) * `vendor/pcg`: [PCG Random Number Generation, Minimal C Edition](https://github.com/imneme/pcg-c-basic) * `vendor/squish`: [Squish](http://sjbrown.co.uk/?code=squish) @@ -664,15 +663,6 @@ https://github.com/martinus/unordered_dense Copyright (c) 2022 Martin Leitner-Ankerl See below for license text (MIT). -## glad - -Generated with https://github.com/Dav1dde/glad/tree/v0.1.27 - -> What's the license of glad generated code? #101 -> Any of Public Domain, WTFPL or CC0. - -See below for license text (CC0). - ## glm https://github.com/g-truc/glm/tree/0.9.9.3 or system version diff --git a/doc/switch_build.md b/doc/switch_build.md index a4731253d..fd1c832c1 100644 --- a/doc/switch_build.md +++ b/doc/switch_build.md @@ -19,6 +19,7 @@ the same `find_package(... CONFIG)` interface and imported targets on every plat (e.g. `/opt/devkitpro`). * A **vcpkg** checkout, with the `VCPKG_ROOT` environment variable pointing at it. * **CMake** ≥ 3.31 and **Ninja**. +* Additional host dependencies may be needed, see [`Switch Dockerfile`](../docker/impacto-switch/Dockerfile) for an always up-to-date version ## Building diff --git a/portfiles-switch/README.md b/portfiles-switch/README.md index 48723d972..3f6066bc5 100644 --- a/portfiles-switch/README.md +++ b/portfiles-switch/README.md @@ -23,7 +23,7 @@ nothing and CMake's existing lookup already finds the devkitPro copy: |---------------|--------------------------------------------------------------------------------------------------------| | `zlib` | `find_package(ZLIB)` (CMake module) → devkitPro | | `libass` | `pkg_check_modules(libass)` in impacto's CMakeLists | -| `vulkan` | unused on Switch (`IMPACTO_DISABLE_VULKAN`) | +| `vulkan` | unused on Switch | ## 2. Config-emitting overlays diff --git a/portfiles-switch/bgfx/fix-dependencies.patch b/portfiles-switch/bgfx/fix-dependencies.patch new file mode 100644 index 000000000..88d7b4758 --- /dev/null +++ b/portfiles-switch/bgfx/fix-dependencies.patch @@ -0,0 +1,420 @@ +diff --git a/bgfx/examples/common/bgfx_utils.cpp b/bgfx/examples/common/bgfx_utils.cpp +index baaeba3..f6bc854 100644 +--- a/bgfx/examples/common/bgfx_utils.cpp ++++ b/bgfx/examples/common/bgfx_utils.cpp +@@ -17,7 +17,7 @@ namespace stl = tinystl; + #include + #include + #include "entry/entry.h" +-#include ++#include + + #include "bgfx_utils.h" + +diff --git a/bgfx/examples/common/font/font_manager.cpp b/bgfx/examples/common/font/font_manager.cpp +index 92e497a..85d1495 100644 +--- a/bgfx/examples/common/font/font_manager.cpp ++++ b/bgfx/examples/common/font/font_manager.cpp +@@ -4,7 +4,7 @@ + */ + + #include +-#include ++#include + #include "../common.h" + #include + +diff --git a/bgfx/examples/common/imgui/imgui.cpp b/bgfx/examples/common/imgui/imgui.cpp +index 2fe8258..1006741 100644 +--- a/bgfx/examples/common/imgui/imgui.cpp ++++ b/bgfx/examples/common/imgui/imgui.cpp +@@ -8,10 +8,10 @@ + #include + #include + #include +-#include +-#include ++#include ++#include + +-#include "imgui.h" ++#include "imgui/imgui.h" + #include "../bgfx_utils.h" + + #ifndef USE_ENTRY +@@ -591,7 +591,7 @@ BX_PRAGMA_DIAGNOSTIC_IGNORED_CLANG_GCC("-Wtype-limits"); // warning: comparison + # define STBTT_free(_ptr, _userData) memFree(_ptr, _userData) + + # define STB_RECT_PACK_IMPLEMENTATION +-# include ++# include + # define STB_TRUETYPE_IMPLEMENTATION +-# include ++# include + #endif // USE_LOCAL_STB +diff --git a/bgfx/examples/common/imgui/imgui.h b/bgfx/examples/common/imgui/imgui.h +index 865879e..c6a3d84 100644 +--- a/bgfx/examples/common/imgui/imgui.h ++++ b/bgfx/examples/common/imgui/imgui.h +@@ -7,7 +7,7 @@ + #define IMGUI_H_HEADER_GUARD + + #include +-#include ++#include + #include + #include + +diff --git a/bgfx/examples/common/nanovg/fontstash.h b/bgfx/examples/common/nanovg/fontstash.h +index 39a48fb..ca0056d 100644 +--- a/bgfx/examples/common/nanovg/fontstash.h ++++ b/bgfx/examples/common/nanovg/fontstash.h +@@ -266,7 +266,7 @@ static void fons__tmpfree(void* ptr, void* up); + #endif // 0 + + #define STBTT_DEF extern +-#include ++#include + + struct FONSttFontImpl { + stbtt_fontinfo font; +diff --git a/bgfx/tools/geometryc/geometryc.cpp b/bgfx/tools/geometryc/geometryc.cpp +index d79a80e..7740272 100644 +--- a/bgfx/tools/geometryc/geometryc.cpp ++++ b/bgfx/tools/geometryc/geometryc.cpp +@@ -14,11 +14,11 @@ + #include + namespace stl = tinystl; + +-#include ++#include + + #define CGLTF_VALIDATE_ENABLE_ASSERTS BX_CONFIG_DEBUG + #define CGLTF_IMPLEMENTATION +-#include ++#include + + #define BGFX_GEOMETRYC_VERSION_MAJOR 1 + #define BGFX_GEOMETRYC_VERSION_MINOR 0 +diff --git a/bgfx/tools/shaderc/shaderc_metal.cpp b/bgfx/tools/shaderc/shaderc_metal.cpp +index 9f073b9..e8fd208 100644 +--- a/bgfx/tools/shaderc/shaderc_metal.cpp ++++ b/bgfx/tools/shaderc/shaderc_metal.cpp +@@ -20,11 +20,10 @@ BX_PRAGMA_DIAGNOSTIC_IGNORED_CLANG_GCC("-Wshadow") // warning: declaration of 'u + #include + + #define ENABLE_OPT 1 +-#include +-#include +-#include +-#include +-#include ++#include ++#include ++#include ++#include + #include + BX_PRAGMA_DIAGNOSTIC_POP() + +diff --git a/bgfx/tools/shaderc/shaderc_spirv.cpp b/bgfx/tools/shaderc/shaderc_spirv.cpp +index f7910de..a844cc0 100644 +--- a/bgfx/tools/shaderc/shaderc_spirv.cpp ++++ b/bgfx/tools/shaderc/shaderc_spirv.cpp +@@ -20,11 +20,10 @@ BX_PRAGMA_DIAGNOSTIC_IGNORED_CLANG_GCC("-Wshadow") // warning: declaration of 'u + #include + + #define ENABLE_OPT 1 +-#include +-#include +-#include +-#include +-#include ++#include ++#include ++#include ++#include + #include + BX_PRAGMA_DIAGNOSTIC_POP() + +diff --git a/bimg/src/image_decode.cpp b/bimg/src/image_decode.cpp +index 798eaba..a4cd3ef 100644 +--- a/bimg/src/image_decode.cpp ++++ b/bimg/src/image_decode.cpp +@@ -16,22 +16,14 @@ BX_PRAGMA_DIAGNOSTIC_IGNORED_MSVC(4018) // warning C4018: '<': signed/unsigned + BX_PRAGMA_DIAGNOSTIC_IGNORED_MSVC(4100) // error C4100: '' : unreferenced formal parameter + BX_PRAGMA_DIAGNOSTIC_IGNORED_MSVC(4389) // warning C4389 : '==' : signed / unsigned mismatch + BX_PRAGMA_DIAGNOSTIC_IGNORED_MSVC(4505) // warning C4505: 'tinyexr::miniz::def_realloc_func': unreferenced local function has been removed +-#define MINIZ_NO_ARCHIVE_APIS +-#define MINIZ_NO_STDIO +-#define TINYEXR_IMPLEMENTATION +-#include ++#include + BX_PRAGMA_DIAGNOSTIC_POP() + + BX_PRAGMA_DIAGNOSTIC_PUSH(); + BX_PRAGMA_DIAGNOSTIC_IGNORED_MSVC(4127) // warning C4127: conditional expression is constant + BX_PRAGMA_DIAGNOSTIC_IGNORED_MSVC(4267) // warning C4267: '=' : conversion from 'size_t' to 'unsigned short', possible loss of data + BX_PRAGMA_DIAGNOSTIC_IGNORED_MSVC(4334) // warning C4334: '<<' : result of 32 - bit shift implicitly converted to 64 bits(was 64 - bit shift intended ? ) +-#define LODEPNG_NO_COMPILE_ENCODER +-#define LODEPNG_NO_COMPILE_DISK +-#define LODEPNG_NO_COMPILE_ANCILLARY_CHUNKS +-#define LODEPNG_NO_COMPILE_ALLOCATORS +-#define LODEPNG_NO_COMPILE_CPP +-#include ++#include + BX_PRAGMA_DIAGNOSTIC_POP(); + + #if BIMG_DECODE_HEIF +@@ -72,7 +64,7 @@ BX_PRAGMA_DIAGNOSTIC_IGNORED_GCC("-Wimplicit-fallthrough"); + #define STBI_FREE(_ptr) lodepng_free(_ptr) + #define STB_IMAGE_IMPLEMENTATION + #define STB_IMAGE_STATIC +-#include ++#include + BX_PRAGMA_DIAGNOSTIC_POP(); + + namespace bimg +@@ -453,7 +445,7 @@ namespace bimg + case TINYEXR_ERROR_INVALID_HEADER: BX_ERROR_SET(_err, BIMG_ERROR, "EXR: Failed to parse image. Invalid header."); break; + case TINYEXR_ERROR_UNSUPPORTED_FEATURE: BX_ERROR_SET(_err, BIMG_ERROR, "EXR: Failed to parse image. Unsupported feature."); break; + case TINYEXR_ERROR_CANT_WRITE_FILE: BX_ERROR_SET(_err, BIMG_ERROR, "EXR: Failed to parse image. Can't write file."); break; +- case TINYEXR_ERROR_SERIALZATION_FAILED: BX_ERROR_SET(_err, BIMG_ERROR, "EXR: Failed to parse image. Serialization failed."); break; ++ case TINYEXR_ERROR_SERIALIZATION_FAILED: BX_ERROR_SET(_err, BIMG_ERROR, "EXR: Failed to parse image. Serialization failed."); break; + default: BX_ERROR_SET(_err, BIMG_ERROR, "EXR: Failed to parse image."); break; + } + } +diff --git a/bimg/src/image_encode.cpp b/bimg/src/image_encode.cpp +index 7c0cd76..530578f 100644 +--- a/bimg/src/image_encode.cpp ++++ b/bimg/src/image_encode.cpp +@@ -6,7 +6,7 @@ + #include + #include "bimg_p.h" + +-#include ++#include + #include + #include + #include +@@ -19,7 +19,7 @@ BX_PRAGMA_DIAGNOSTIC_IGNORED_MSVC(4100) // warning C4100: 'alloc_context': unref + BX_PRAGMA_DIAGNOSTIC_IGNORED_MSVC(4702) // warning C4702: unreachable code + BX_PRAGMA_DIAGNOSTIC_IGNORED_CLANG_GCC("-Wunused-parameter") // warning: unused parameter ‘alloc_context’ [-Wunused-parameter] + #define STB_IMAGE_RESIZE_IMPLEMENTATION +-#include ++#include + BX_PRAGMA_DIAGNOSTIC_POP(); + + extern "C" { +@@ -564,18 +564,16 @@ namespace bimg + const uint32_t srcDataStep = uint32_t(bx::floor(zz * _src->m_depth / float(_dst->m_depth) ) ); + const uint8_t* srcData = &srcMip.m_data[srcDataStep*srcSlice]; + +- int result = stbir_resize_float_generic( +- (const float*)srcData, _src->m_width, _src->m_height, srcPitch +- , ( float*)dstData, _dst->m_width, _dst->m_height, dstPitch +- , 4, 3 +- , STBIR_FLAG_ALPHA_PREMULTIPLIED ++ void* result = stbir_resize( ++ (const void *)srcData, _src->m_width, _src->m_height, srcPitch ++ , ( void *)dstData, _dst->m_width, _dst->m_height, dstPitch ++ , STBIR_RGBA_PM ++ , STBIR_TYPE_FLOAT + , STBIR_EDGE_CLAMP + , STBIR_FILTER_BOX +- , STBIR_COLORSPACE_LINEAR +- , NULL + ); + +- if (1 != result) ++ if (0 == result) + { + return false; + } +diff --git a/bx/src/settings.cpp b/bx/src/settings.cpp +index 907c74c..ffcc442 100644 +--- a/bx/src/settings.cpp ++++ b/bx/src/settings.cpp +@@ -19,7 +19,7 @@ BX_PRAGMA_DIAGNOSTIC_IGNORED_CLANG_GCC("-Wunused-function"); + + BX_PRAGMA_DIAGNOSTIC_PUSH(); + BX_PRAGMA_DIAGNOSTIC_IGNORED_CLANG_GCC("-Wsign-compare"); +-#include ++#include + BX_PRAGMA_DIAGNOSTIC_POP(); + } + +@@ -58,7 +58,7 @@ void Settings::load(const void* _data, uint32_t _len) + } + else + { +- m_ini = ini_load( (const char*)_data, _len, m_allocator); ++ m_ini = ini_load( (const char*)_data, m_allocator); + } + } + +diff --git a/cmake/Config.cmake.in b/cmake/Config.cmake.in +index 33a3943..8eddd3f 100644 +--- a/cmake/Config.cmake.in ++++ b/cmake/Config.cmake.in +@@ -1,5 +1,22 @@ + @PACKAGE_INIT@ + ++include(CMakeFindDependencyMacro) ++find_dependency(lodepng CONFIG) ++find_dependency(miniz CONFIG) ++find_dependency(tinyexr CONFIG) ++find_dependency(unofficial-libsquish CONFIG) ++if("@BGFX_BUILD_TOOLS_GEOMETRY@") ++ find_dependency(meshoptimizer CONFIG) ++endif() ++if("@BGFX_BUILD_TOOLS_SHADER@") ++ find_dependency(spirv_cross_core CONFIG) ++ find_dependency(spirv_cross_reflect CONFIG) ++ find_dependency(spirv_cross_glsl CONFIG) ++ find_dependency(spirv_cross_hlsl CONFIG) ++ find_dependency(spirv_cross_msl CONFIG) ++ find_dependency(glslang CONFIG REQUIRED) ++endif() ++ + if(@BGFX_CMAKE_USER_SCRIPT_PRESENT@) + include("${CMAKE_CURRENT_LIST_DIR}/@BGFX_CMAKE_USER_SCRIPT_INSTALL_NAME@") + endif() +diff --git a/cmake/bgfx/CMakeLists.txt b/cmake/bgfx/CMakeLists.txt +index 0125da3..9b10d09 100644 +--- a/cmake/bgfx/CMakeLists.txt ++++ b/cmake/bgfx/CMakeLists.txt +@@ -9,20 +9,22 @@ + # this software. If not, see . + + include(bgfx.cmake) +-include(3rdparty/meshoptimizer.cmake) +-include(3rdparty/dear-imgui.cmake) + + if(BGFX_BUILD_TOOLS_TEXTURE) +- include(texturev.cmake) + endif() + if(BGFX_BUILD_TOOLS_GEOMETRY) ++ find_package(meshoptimizer CONFIG REQUIRED) ++ set(MESHOPTIMIZER_LIBRARIES "meshoptimizer::meshoptimizer" CACHE INTERNAL "") + include(geometryc.cmake) +- include(geometryv.cmake) + endif() + if(BGFX_BUILD_TOOLS_SHADER) +- include(3rdparty/spirv-opt.cmake) +- include(3rdparty/spirv-cross.cmake) +- include(3rdparty/glslang.cmake) ++ find_package(spirv_cross_core CONFIG REQUIRED) ++ find_package(spirv_cross_reflect CONFIG REQUIRED) ++ find_package(spirv_cross_glsl CONFIG REQUIRED) ++ find_package(spirv_cross_hlsl CONFIG REQUIRED) ++ find_package(spirv_cross_msl CONFIG REQUIRED) ++ find_package(glslang CONFIG REQUIRED) ++ + include(3rdparty/glsl-optimizer.cmake) + include(3rdparty/fcpp.cmake) + include(3rdparty/webgpu.cmake) +diff --git a/cmake/bgfx/shaderc.cmake b/cmake/bgfx/shaderc.cmake +index 0f50eab..8b13b28 100644 +--- a/cmake/bgfx/shaderc.cmake ++++ b/cmake/bgfx/shaderc.cmake +@@ -24,21 +24,10 @@ target_link_libraries( + PRIVATE bx + bgfx-vertexlayout + fcpp +- glslang +- glsl-optimizer +- spirv-opt +- spirv-cross +-) +-target_link_libraries( +- shaderc +- PRIVATE bx + bimg +- bgfx-vertexlayout +- fcpp +- glslang ++ glslang::glslang glslang::glslang-default-resource-limits glslang::SPIRV + glsl-optimizer +- spirv-opt +- spirv-cross ++ spirv-cross-core spirv-cross-reflect spirv-cross-glsl spirv-cross-hlsl spirv-cross-msl + webgpu + ) + if(BGFX_AMALGAMATED) +diff --git a/cmake/bimg/CMakeLists.txt b/cmake/bimg/CMakeLists.txt +index 200b29b..1c857c0 100644 +--- a/cmake/bimg/CMakeLists.txt ++++ b/cmake/bimg/CMakeLists.txt +@@ -8,17 +8,24 @@ + # You should have received a copy of the CC0 Public Domain Dedication along with + # this software. If not, see . + +-include(3rdparty/loadpng.cmake) +-include(3rdparty/libsquish.cmake) ++find_package(lodepng CONFIG REQUIRED) ++set(LOADPNG_LIBRARIES "$;$>") ++find_package(unofficial-libsquish CONFIG REQUIRED) ++set(LIBSQUISH_LIBRARIES "$;$>") + include(3rdparty/astc_encoder.cmake) + include(3rdparty/edtaa3.cmake) + include(3rdparty/etc1.cmake) + include(3rdparty/etc2.cmake) + include(3rdparty/nvtt.cmake) + include(3rdparty/pvrtc.cmake) +-include(3rdparty/tinyexr.cmake) ++find_package(tinyexr CONFIG REQUIRED) ++set(TINYEXR_LIBRARIES "$;$>") + include(3rdparty/iqa.cmake) +-include(3rdparty/miniz.cmake) ++find_package(miniz CONFIG REQUIRED) ++set(MINIZ_LIBRARIES "$;$>") ++ ++find_package(Stb REQUIRED) ++ + include(bimg.cmake) + include(bimg_decode.cmake) + include(bimg_encode.cmake) +diff --git a/cmake/bimg/bimg_decode.cmake b/cmake/bimg/bimg_decode.cmake +index a511e8f..da98152 100644 +--- a/cmake/bimg/bimg_decode.cmake ++++ b/cmake/bimg/bimg_decode.cmake +@@ -34,6 +34,7 @@ target_include_directories( + PRIVATE ${LOADPNG_INCLUDE_DIR} # + ${MINIZ_INCLUDE_DIR} # + ${TINYEXR_INCLUDE_DIR} # ++ ${Stb_INCLUDE_DIR} + ) + + target_link_libraries( +diff --git a/cmake/bimg/bimg_encode.cmake b/cmake/bimg/bimg_encode.cmake +index 82d9fe0..a0ba5df 100644 +--- a/cmake/bimg/bimg_encode.cmake ++++ b/cmake/bimg/bimg_encode.cmake +@@ -32,6 +32,7 @@ target_include_directories( + ${TINYEXR_INCLUDE_DIR} # + ${IQA_INCLUDE_DIR} # + ${MINIZ_INCLUDE_DIR} # ++ ${Stb_INCLUDE_DIR} # + ) + + file( +diff --git a/cmake/bx/bx.cmake b/cmake/bx/bx.cmake +index d1a73c6..826c52b 100644 +--- a/cmake/bx/bx.cmake ++++ b/cmake/bx/bx.cmake +@@ -75,13 +75,14 @@ elseif(UNIX) + endif() + + # Add include directory of bx ++find_path(MGNLIBS_INCLUDE_DIR "mgnlibs/ini.h") + target_include_directories( + bx + PUBLIC $ # +- $ # + $ # + $ # + $ # ++ PRIVATE "${MGNLIBS_INCLUDE_DIR}" + ) + + # All configurations diff --git a/portfiles-switch/bgfx/portfile.cmake b/portfiles-switch/bgfx/portfile.cmake new file mode 100644 index 000000000..afb9b0212 --- /dev/null +++ b/portfiles-switch/bgfx/portfile.cmake @@ -0,0 +1,81 @@ +if(VCPKG_TARGET_IS_WINDOWS) + vcpkg_check_linkage(ONLY_STATIC_LIBRARY) +endif() + +vcpkg_download_distfile( + ARCHIVE_FILE + URLS https://github.com/bkaradzic/bgfx.cmake/releases/download/v${VERSION}/bgfx.cmake.v${VERSION}.tar.gz + FILENAME bgfx.cmake.v${VERSION}.tar.gz + SHA512 520c542b65e76e92eae818e32eeb62bb2347ac89a1e10fc07cd5059a3b8a9a543cadca87d451a3bc157c415f6183b1f0e5031248e38fae704b8efd54679d482b +) + +vcpkg_extract_source_archive( + SOURCE_PATH + ARCHIVE "${ARCHIVE_FILE}" + PATCHES + fix-dependencies.patch + switch.patch +) +file(REMOVE_RECURSE + "${SOURCE_PATH}/bgfx/3rdparty/dear-imgui" + "${SOURCE_PATH}/bgfx/3rdparty/glslang" + "${SOURCE_PATH}/bgfx/3rdparty/khronos/EGL" + "${SOURCE_PATH}/bgfx/3rdparty/khronos/GLES3" + "${SOURCE_PATH}/bgfx/3rdparty/khronos/GLES2" + "${SOURCE_PATH}/bgfx/3rdparty/meshoptimizer" + "${SOURCE_PATH}/bgfx/3rdparty/spirv-cross" + "${SOURCE_PATH}/bgfx/3rdparty/spirv-headers" + "${SOURCE_PATH}/bgfx/3rdparty/spirv-opt" + "${SOURCE_PATH}/bgfx/3rdparty/stb" + "${SOURCE_PATH}/bimg/3rdparty/libsquish" + "${SOURCE_PATH}/bimg/3rdparty/lodepng" + "${SOURCE_PATH}/bimg/3rdparty/stb" + "${SOURCE_PATH}/bimg/3rdparty/tinyexr" +) + +vcpkg_check_features( + OUT_FEATURE_OPTIONS FEATURE_OPTIONS + FEATURES + tools BGFX_BUILD_TOOLS + multithreaded BGFX_CONFIG_MULTITHREADED +) + +if(VCPKG_LIBRARY_LINKAGE STREQUAL dynamic) + set(BGFX_LIBRARY_TYPE "SHARED") +else () + set(BGFX_LIBRARY_TYPE "STATIC") +endif () + +vcpkg_cmake_configure( + SOURCE_PATH "${SOURCE_PATH}" + OPTIONS + -DBGFX_LIBRARY_TYPE=${BGFX_LIBRARY_TYPE} + -DBGFX_AMALGAMATED=ON + -DBGFX_BUILD_EXAMPLES=OFF + -DBGFX_OPENGLES_VERSION=30 + "-DBGFX_ADDITIONAL_TOOL_PATHS=${CURRENT_INSTALLED_DIR}/../${HOST_TRIPLET}/tools/bgfx" + ${FEATURE_OPTIONS} + OPTIONS_DEBUG + -DBGFX_BUILD_TOOLS=OFF +) + +vcpkg_cmake_install() +vcpkg_cmake_config_fixup(CONFIG_PATH "lib/cmake/${PORT}") +vcpkg_copy_pdbs() + +if ("tools" IN_LIST FEATURES) + vcpkg_copy_tools(TOOL_NAMES bin2c shaderc geometryc texturec AUTO_CLEAN) +endif () + +vcpkg_install_copyright( + FILE_LIST "${CURRENT_PACKAGES_DIR}/share/licences/${PORT}/LICENSE" + COMMENT [[ +bgfx includes third-party components which are subject to specific license +terms. Check the sources for details. +]]) + +file(REMOVE_RECURSE + "${CURRENT_PACKAGES_DIR}/share/licences" + "${CURRENT_PACKAGES_DIR}/debug/include" + "${CURRENT_PACKAGES_DIR}/debug/share" +) \ No newline at end of file diff --git a/portfiles-switch/bgfx/switch.patch b/portfiles-switch/bgfx/switch.patch new file mode 100644 index 000000000..9775a1e9a --- /dev/null +++ b/portfiles-switch/bgfx/switch.patch @@ -0,0 +1,224 @@ +--- b/cmake/bgfx/bgfx.cmake ++++ b/cmake/bgfx/bgfx.cmake +@@ -176,18 +176,25 @@ + ) + endif() + ++if (ANDROID OR NX OR EMSCRIPTEN) ++ find_package(OpenGL REQUIRED COMPONENTS GLES2 GLES3 EGL) ++ target_link_libraries(bgfx PUBLIC OpenGL::GLES2 OpenGL::GLES3 OpenGL::EGL) ++else() ++ find_package(OpenGL REQUIRED) ++ target_link_libraries(bgfx PUBLIC OpenGL::GL) ++endif() ++ + if(UNIX + AND NOT APPLE + AND NOT EMSCRIPTEN + AND NOT ANDROID + ) + find_package(X11 REQUIRED) +- find_package(OpenGL REQUIRED) + #The following commented libraries are linked by bx + #find_package(Threads REQUIRED) + #find_library(LIBRT_LIBRARIES rt) + #find_library(LIBDL_LIBRARIES dl) +- target_link_libraries(bgfx PUBLIC ${X11_LIBRARIES} ${OPENGL_LIBRARIES}) ++ target_link_libraries(bgfx PUBLIC ${X11_LIBRARIES}) + endif() + + # Exclude mm files if not on OS X +--- a/bgfx/src/config.h ++++ b/bgfx/src/config.h +@@ -67,10 +67,9 @@ + ? 1 : 0) + # endif // BGFX_CONFIG_RENDERER_METAL + ++ + # ifndef BGFX_CONFIG_RENDERER_NVN +-# define BGFX_CONFIG_RENDERER_NVN (0 \ +- || BX_PLATFORM_NX \ +- ? 1 : 0) ++# define BGFX_CONFIG_RENDERER_NVN (0) + # endif // BGFX_CONFIG_RENDERER_NVN + + # ifndef BGFX_CONFIG_RENDERER_OPENGL_MIN_VERSION +@@ -104,7 +103,6 @@ + || BX_PLATFORM_ANDROID \ + || BX_PLATFORM_LINUX \ + || BX_PLATFORM_WINDOWS \ +- || BX_PLATFORM_NX \ + || BX_PLATFORM_OSX \ + ? 1 : 0) + # endif // BGFX_CONFIG_RENDERER_VULKAN +--- a/cmake/Config.cmake.in ++++ b/cmake/Config.cmake.in +@@ -17,6 +17,13 @@ + find_dependency(glslang CONFIG REQUIRED) + endif() + ++if (ANDROID OR NX OR EMSCRIPTEN) ++ find_dependency(OpenGL COMPONENTS GLES2 GLES3 EGL) ++else() ++ find_dependency(OpenGL) ++endif() ++ ++ + if(@BGFX_CMAKE_USER_SCRIPT_PRESENT@) + include("${CMAKE_CURRENT_LIST_DIR}/@BGFX_CMAKE_USER_SCRIPT_INSTALL_NAME@") + endif() +--- a/cmake/bgfxToolUtils.cmake ++++ b/cmake/bgfxToolUtils.cmake +@@ -382,10 +382,10 @@ + function(_bgfx_shaderc_parse ARG_OUT) + cmake_parse_arguments( + ARG +- "DEPENDS;ANDROID;ASM_JS;IOS;LINUX;OSX;WINDOWS;ORBIS;PREPROCESS;RAW;FRAGMENT;VERTEX;COMPUTE;VERBOSE;DEBUG;DISASM;WERROR" +- "FILE;OUTPUT;VARYINGDEF;BIN2C;PROFILE;O" +- "INCLUDES;DEFINES" +- ${ARGN} ++ "DEPENDS;ANDROID;ASM_JS;IOS;LINUX;OSX;WINDOWS;ORBIS;NX;PREPROCESS;RAW;FRAGMENT;VERTEX;COMPUTE;VERBOSE;DEBUG;DISASM;WERROR" ++ "FILE;OUTPUT;VARYINGDEF;BIN2C;PROFILE;O" ++ "INCLUDES;DEFINES" ++ ${ARGN} + ) + set(CLI "") + +@@ -423,7 +423,7 @@ + + # --platform + set(PLATFORM "") +- set(PLATFORMS "ANDROID;ASM_JS;IOS;LINUX;OSX;WINDOWS;ORBIS") ++ set(PLATFORMS "ANDROID;ASM_JS;IOS;LINUX;OSX;WINDOWS;ORBIS;NX") + foreach(P ${PLATFORMS}) + if(ARG_${P}) + if(PLATFORM) +@@ -600,6 +600,9 @@ + elseif(ORBIS) # ORBIS should be defined by a PS4 CMake toolchain + set(PLATFORM ORBIS) + list(APPEND PROFILES pssl) ++ elseif(NX) ++ set(PLATFORM NX) ++ list(APPEND PROFILES 320_es) + else() + # pssl for Agc and Gnm renderers + # nvn for Nvn renderer +--- a/bx/include/bx/platform.h ++++ b/bx/include/bx/platform.h +@@ -150,6 +150,15 @@ + #endif // BX_CPU_PPC + + // http://sourceforge.net/apps/mediawiki/predef/index.php?title=Operating_Systems ++#if defined(__has_builtin) ++# if __has_builtin(__is_target_os) ++# if __is_target_os(xros) ++# undef BX_PLATFORM_VISIONOS ++# define BX_PLATFORM_VISIONOS 1 ++# endif ++# endif ++#endif ++ + #if defined(_DURANGO) || defined(_XBOX_ONE) + # undef BX_PLATFORM_XBOXONE + # define BX_PLATFORM_XBOXONE 1 +@@ -196,9 +205,7 @@ + || defined(__ENVIRONMENT_TV_OS_VERSION_MIN_REQUIRED__) + # undef BX_PLATFORM_IOS + # define BX_PLATFORM_IOS 1 +-#elif defined(__has_builtin) && __has_builtin(__is_target_os) && __is_target_os(xros) +-# undef BX_PLATFORM_VISIONOS +-# define BX_PLATFORM_VISIONOS 1 ++#elif BX_PLATFORM_VISIONOS + #elif defined(__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__) + # undef BX_PLATFORM_OSX + # define BX_PLATFORM_OSX __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ +--- a/bx/src/os.cpp ++++ b/bx/src/os.cpp +@@ -29,9 +29,9 @@ + # endif // BX_PLATFORM_* + + # include // nanosleep +-# if !BX_PLATFORM_PS4 ++# if !(BX_PLATFORM_PS4 || BX_PLATFORM_NX) + # include // dlopen, dlclose, dlsym +-# endif // !BX_PLATFORM_PS4 ++# endif // !BX_PLATFORM_* + + # if BX_PLATFORM_ANDROID + # include // mallinfo +--- a/bimg/3rdparty/nvtt/nvcore/nvcore.h ++++ b/bimg/3rdparty/nvtt/nvcore/nvcore.h +@@ -57,6 +57,8 @@ + # define NV_OS_WIN32 1 + #elif defined POSH_OS_XBOX + # define NV_OS_XBOX 1 ++#elif defined POSH_OS_NX ++# define NV_OS_NX 1 + #else + # error "Unsupported OS" + #endif +@@ -111,7 +113,7 @@ + + // Threading: + // some platforms don't implement __thread or similar for thread-local-storage +-#if NV_OS_UNIX || NV_OS_ORBIS || NV_OS_IOS //ACStodoIOS darwin instead of ios? ++#if NV_OS_UNIX || NV_OS_ORBIS || NV_OS_IOS || NV_OS_NX //ACStodoIOS darwin instead of ios? + # define NV_OS_USE_PTHREAD 1 + # if NV_OS_DARWIN || NV_OS_IOS + # define NV_OS_HAS_TLS_QUALIFIER 0 +@@ -181,6 +183,10 @@ + # define NV_CPU_EMSCRIPTEN 0 + #endif // NV_CPU_EMSCRIPTEN + ++#ifndef NV_OS_NX ++# define NV_OS_NX 0 ++#endif // NV_OS_NX ++ + // Compiler: + + #if defined POSH_COMPILER_CLANG +@@ -365,7 +371,7 @@ + # error "MSVC: Platform not supported" + # endif + #elif NV_CC_GNUC +-# if NV_OS_LINUX ++# if NV_OS_LINUX || NV_OS_NX + # include "defsgnuclinux.h" + # elif NV_OS_DARWIN || NV_OS_FREEBSD || NV_OS_OPENBSD + # include "defsgnucdarwin.h" +--- a/bimg/3rdparty/nvtt/nvcore/posh.h ++++ b/bimg/3rdparty/nvtt/nvcore/posh.h +@@ -435,6 +435,11 @@ + # define POSH_OS_STRING "MacOS" + #endif + ++#if defined __NX__ || defined __SWITCH__ ++# define POSH_OS_NX 1 ++# define POSH_OS_STRING "Switch" ++#endif ++ + /* + ** ----------------------------------------------------------------------------- + ** Determine target CPU +--- a/bimg/3rdparty/astc-encoder/source/astcenc_internal.h ++++ b/bimg/3rdparty/astc-encoder/source/astcenc_internal.h +@@ -30,6 +30,7 @@ + #endif + #include + #include ++#include + + #include "astcenc.h" + #include "astcenc_mathlib.h" +@@ -2197,8 +2197,10 @@ + + #if defined(_WIN32) + ptr = _aligned_malloc(size, real_align); ++#elif defined(HAVE_POSIX_MEMALIGN) ++ error = posix_memalign(&ptr, real_align, size); + #else +- error = posix_memalign(&ptr, real_align, size); ++ ptr = memalign(real_align, size); + #endif + + if (error || (!ptr)) diff --git a/portfiles-switch/bgfx/vcpkg.json b/portfiles-switch/bgfx/vcpkg.json new file mode 100644 index 000000000..1e01bb984 --- /dev/null +++ b/portfiles-switch/bgfx/vcpkg.json @@ -0,0 +1,55 @@ +{ + "name": "bgfx", + "version": "1.129.8940-496", + "port-version": 2, + "maintainers": "Sandy Carter ", + "description": "Cross-platform, graphics API agnostic, Bring Your Own Engine/Framework style rendering library.", + "homepage": "https://bkaradzic.github.io/bgfx/overview.html", + "documentation": "https://bkaradzic.github.io/bgfx", + "license": "BSD-2-Clause AND CC0-1.0", + "supports": "!bsd", + "dependencies": [ + "libsquish", + "lodepng", + "mgnlibs", + "miniz", + "stb", + "tinyexr", + { + "name": "vcpkg-cmake", + "host": true + }, + { + "name": "vcpkg-cmake-config", + "host": true + } + ], + "default-features": [ + { + "name": "multithreaded", + "platform": "!emscripten" + } + ], + "features": { + "multithreaded": { + "description": "Encode and render on different threads", + "supports": "!emscripten" + }, + "tools": { + "$comment": "Use '\"host\": true' in dependencies of vcpkg.json in manifest mode.", + "description": "Shader, Texture and Geometry compilers for bgfx.", + "dependencies": [ + "cgltf", + { + "name": "glslang", + "features": [ + "opt" + ] + }, + "meshoptimizer", + "spirv-cross", + "spirv-tools" + ] + } + } +} \ No newline at end of file diff --git a/portfiles-switch/vulkan/vcpkg.json b/portfiles-switch/vulkan/vcpkg.json index 0ea2df429..bb8f50c97 100644 --- a/portfiles-switch/vulkan/vcpkg.json +++ b/portfiles-switch/vulkan/vcpkg.json @@ -1,5 +1,5 @@ { "name": "vulkan", "version": "1.1.0", - "description": "Empty overlay for the Switch build: Vulkan is disabled on Switch (IMPACTO_DISABLE_VULKAN), so no Vulkan SDK is needed." + "description": "Empty overlay for the Switch build: Vulkan is disabled on Switch, so no Vulkan SDK is needed." } diff --git a/src/audio/openal/audiobackend.cpp b/src/audio/openal/audiobackend.cpp index 4fe38f06b..551bced86 100644 --- a/src/audio/openal/audiobackend.cpp +++ b/src/audio/openal/audiobackend.cpp @@ -25,7 +25,7 @@ void AL_APIENTRY DefaultDeviceChangedEventCallback( bool AudioBackend::Init() { AlcDevice = alcOpenDevice(NULL); if (!AlcDevice) { - ImpLog(LogLevel::Fatal, LogChannel::Audio, + ImpLog(LogLevel::Error, LogChannel::Audio, "Could not create OpenAL device\n"); return false; } diff --git a/src/background2d.cpp b/src/background2d.cpp index f48d8dfc5..0bc7c4585 100644 --- a/src/background2d.cpp +++ b/src/background2d.cpp @@ -3,6 +3,7 @@ #include #include #include +#include #include "mask2d.h" #include "mem.h" @@ -34,7 +35,6 @@ void Background2D::InitFrameBuffers() { Renderer->GetFramebufferTexture(i + 1); Framebuffers[i].Status = LoadStatus::Loaded; - Framebuffers[i].BgSprite.Sheet.IsScreenCap = true; } } @@ -45,7 +45,6 @@ void Background2D::Init() { const RectF viewport = Window->GetViewport(); const auto initCapture = [&viewport](Capture2D& capture) { - capture.BgSprite.Sheet.IsScreenCap = true; capture.LoadSolidColor(0xFF000000, static_cast(viewport.Width), static_cast(viewport.Height)); capture.BgSprite.Bounds.SetSize(viewport.GetSize()); @@ -57,7 +56,6 @@ void Background2D::Init() { for (Capture2D& capture : Screencaptures) initCapture(capture); initCapture(MaskCapture); - ShaderScreencapture.BgSprite.Sheet.IsScreenCap = true; InitFrameBuffers(); ShaderScreencapture.LoadSolidColor(0xFF000000, static_cast(viewport.Width), @@ -141,30 +139,26 @@ void Background2D::LoadSolidColor(uint32_t color, int width, int height) { } void Background2D::UnloadSync() { - Renderer->FreeTexture(BgSprite.Sheet.Texture); + BgSprite.Sheet.Texture = TextureRef{}; BgSprite.Sheet.DesignHeight = 0.0f; BgSprite.Sheet.DesignWidth = 0.0f; - BgSprite.Sheet.Texture = 0; - BgSprite.Sheet.IsScreenCap = false; if (BgFrameEffectType != BgEffTypeEnum::Disabled) { for (BgEff& bgEff : FrameBgEffs) { bgEff.Loaded = false; - Renderer->FreeTexture(bgEff.BgEffSprite.Sheet.Texture); + bgEff.BgEffSprite.Sheet.Texture = TextureRef{}; bgEff.BgEffSprite.Sheet.DesignHeight = 0.0f; bgEff.BgEffSprite.Sheet.DesignWidth = 0.0f; - bgEff.BgEffSprite.Sheet.Texture = 0; } } if (BgChaEffectType != BgEffTypeEnum::Disabled) { ChaBgEff.Loaded = false; - Renderer->FreeTexture(ChaBgEff.BgEffSprite.Sheet.Texture); + ChaBgEff.BgEffSprite.Sheet.Texture = TextureRef{}; ChaBgEff.BgEffSprite.Sheet.DesignHeight = 0.0f; ChaBgEff.BgEffSprite.Sheet.DesignWidth = 0.0f; - ChaBgEff.BgEffSprite.Sheet.Texture = 0; } Show = false; @@ -561,19 +555,6 @@ void Background2D::RenderBgEff(const int layer) { return; } - static Sprite frameSprite{}; - if (frameSprite.Sheet.Texture == 0) { - Texture frameTexture{}; - const RectF viewport = Window->GetViewport(); - frameTexture.LoadSolidColor(static_cast(viewport.Width), - static_cast(viewport.Height), 0x00000000); - frameSprite.Sheet.Texture = frameTexture.Submit(); - frameSprite.Bounds.SetSize(viewport.GetSize()); - frameSprite.BaseScale = {Profile::Game::DesignWidth / viewport.Width, - Profile::Game::DesignHeight / viewport.Height}; - // I am aware this leaks a texture at shutdown - } - using enum BgEffTypeEnum; const std::array vertices{ VertexBufferSprites{ @@ -607,9 +588,65 @@ void Background2D::RenderBgEff(const int layer) { bgEff++) { if (!bgEff->Loaded) continue; - Renderer->CaptureScreencap(frameSprite); - Renderer->DrawPrimitives(frameSprite.Sheet, &bgEff->BgEffSprite.Sheet, - bgEff->Shader, vertices, indices); + const static auto shaderTable = []() { + using enum ShaderProgramType; + magic_enum::containers::array< + ShaderProgramType, std::function> + table; + static_assert(table.size() == 11); + + table[AdditiveMaskedSprite] = + [](const PositionedMaskedSprite& spriteInfo) { + Renderer->DrawAdditiveMaskedSprite(spriteInfo); + }; + table[ColorBurnMaskedSprite] = + [](const PositionedMaskedSprite& spriteInfo) { + Renderer->DrawColorBurnMaskedSprite(spriteInfo); + }; + table[ColorDodgeMaskedSprite] = + [](const PositionedMaskedSprite& spriteInfo) { + Renderer->DrawColorDodgeMaskedSprite(spriteInfo); + }; + table[ColorMaskedSprite] = [](const PositionedMaskedSprite& spriteInfo) { + Renderer->DrawColorMaskedSprite(spriteInfo); + }; + table[HardLightMaskedSprite] = + [](const PositionedMaskedSprite& spriteInfo) { + Renderer->DrawHardLightMaskedSprite(spriteInfo); + }; + table[LinearBurnMaskedSprite] = + [](const PositionedMaskedSprite& spriteInfo) { + Renderer->DrawLinearBurnMaskedSprite(spriteInfo); + }; + table[MaskedSpriteNoAlpha] = + [](const PositionedMaskedSprite& spriteInfo) { + Renderer->DrawMaskedSpriteNoAlpha( + spriteInfo, {.Alpha = 1.0f, .FadeRange = 0.0f}); + }; + table[OverlayMaskedSprite] = + [](const PositionedMaskedSprite& spriteInfo) { + Renderer->DrawOverlayMaskedSprite(spriteInfo); + }; + table[ScreenMaskedSprite] = [](const PositionedMaskedSprite& spriteInfo) { + Renderer->DrawScreenMaskedSprite(spriteInfo); + }; + table[SoftLightMaskedSprite] = + [](const PositionedMaskedSprite& spriteInfo) { + Renderer->DrawSoftLightMaskedSprite(spriteInfo); + }; + table[Sprite] = [](const PositionedMaskedSprite& spriteInfo) { + Renderer->DrawSprite({spriteInfo.Texture, spriteInfo.GetVertices(), + spriteInfo.GetIndices(), + spriteInfo.GetTopologyMode(), + spriteInfo.Transformation}); + }; + + return table; + }(); + + MutableTextureRef frameTexture = Renderer->CaptureScreenCap(); + shaderTable[bgEff->Shader]({*frameTexture, bgEff->BgEffSprite.Sheet, + vertices, indices, TopologyMode::Triangles}); } LastRenderedBackground = nullptr; @@ -771,18 +808,19 @@ void BackgroundEffect2D::Render(const int layer) { } // Draw - Renderer->SetStencilMode(StencilBufferMode::Write); + using StencilModeType = BaseRenderer::StateConfig::StencilModeType; + Renderer->SetStencilMode(BaseRenderer::StateConfig::StencilModeType::Write); Renderer->ClearStencilBuffer(); Renderer->DrawConvexShape( std::span(Vertices.begin(), Vertices.begin() + VertexCount), StencilTransformation, glm::vec4(1.0f)); - Renderer->SetStencilMode(StencilBufferMode::Test); + Renderer->SetStencilMode(StencilModeType::Test); std::invoke(BackgroundRenderTable[RenderType], this); - Renderer->SetStencilMode(StencilBufferMode::Off); + Renderer->SetStencilMode(StencilModeType::Off); } template @@ -801,11 +839,11 @@ void Background2D::RenderBgWave() { PrimitiveData primitives = Effects::WaveBG.GetPrimitives(); - Renderer->DrawPrimitives( - RenderSprite.Sheet, &Masks2D[MaskNumber].MaskSprite.Sheet, - ShaderProgramType::MaskedSprite, primitives.Vertices, primitives.Indices, - TransformState.ToMatrix(), glm::mat4(1.0f), false, - TopologyMode::TriangleStrips); + Renderer->DrawMaskedSprite( + {RenderSprite.Sheet, Masks2D[MaskNumber].MaskSprite.Sheet, + primitives.Vertices, primitives.Indices, primitives.Topology, + TransformState.ToMatrix()}, + {.Alpha = 1.0f, .FadeRange = 0.0f}); } void Background2D::RenderRegular() { @@ -836,16 +874,19 @@ void Background2D::RenderMasked() { maskTransformState.Origin = -maskTransformState.Position; maskTransformState.Scale = newScale; - Renderer->DrawMaskedSprite(RenderSprite, Masks2D[MaskNumber].MaskSprite, - FadeCount, FadeRange, TransformState.ToMatrix(), - maskTransformState.ToMatrix(), Tint, false, false); + Renderer->DrawMaskedSprite( + {RenderSprite, Masks2D[MaskNumber].MaskSprite, TransformState.ToMatrix(), + maskTransformState.ToMatrix(), Tint}, + {.Alpha = static_cast(FadeCount), + .FadeRange = static_cast(FadeRange)}); // also can render Linked buffers, but IDK any examples to test } void Background2D::RenderCaptureMasked() { - Renderer->DrawMaskedBinarySprite(RenderSprite, MaskCapture.BgSprite, - TransformState.ToMatrix(), std::nullopt, - Tint, false); + Renderer->DrawMaskedBinarySprite( + {RenderSprite, MaskCapture.BgSprite, TransformState.ToMatrix(), + PositionedMaskedSprite::HaveFullscreenMask{}, Tint}, + {}); for (int i = 0; i < MaxLinkedBgBuffers; i++) { if (Links[i].Direction != LinkDirection::Off && Links[i].LinkedBuffer != nullptr) { @@ -853,9 +894,11 @@ void Background2D::RenderCaptureMasked() { TransformationMatrix(TransformState.Origin, TransformState.Scale, {TransformState.Origin, 0.0f}, TransformState.Rotation, Links[i].DisplayCoords); - Renderer->DrawMaskedBinarySprite(Links[i].LinkedBuffer->RenderSprite, - MaskCapture.BgSprite, linkTransformation, - std::nullopt, Tint, false); + Renderer->DrawMaskedBinarySprite( + {Links[i].LinkedBuffer->RenderSprite, MaskCapture.BgSprite, + linkTransformation, PositionedMaskedSprite::HaveFullscreenMask{}, + Tint}, + {}); } } } @@ -872,9 +915,12 @@ void Background2D::RenderMaskedInverted() { maskTransformState.Origin = -maskTransformState.Position; maskTransformState.Scale = newScale; - Renderer->DrawMaskedSprite(RenderSprite, Masks2D[MaskNumber].MaskSprite, - FadeCount, FadeRange, TransformState.ToMatrix(), - maskTransformState.ToMatrix(), Tint, true, false); + Renderer->DrawMaskedSprite( + {RenderSprite, Masks2D[MaskNumber].MaskSprite, TransformState.ToMatrix(), + maskTransformState.ToMatrix(), Tint}, + {.Alpha = static_cast(FadeCount), + .FadeRange = static_cast(FadeRange), + .IsInverted = true}); } void Background2D::RenderFade() { @@ -1062,8 +1108,8 @@ void Background2D::RenderExplode() { return tempIndices; }(); - Renderer->DrawPrimitives(RenderSprite.Sheet, ShaderProgramType::Sprite, - vertices, indices, glm::mat4(1.0f)); + Renderer->DrawSprite( + {RenderSprite.Sheet, vertices, indices, TopologyMode::Triangles}); } bool IsBgWaveEffectActive() { diff --git a/src/background2d.h b/src/background2d.h index c1a0fbc15..dcb977aa9 100644 --- a/src/background2d.h +++ b/src/background2d.h @@ -173,6 +173,8 @@ class Capture2D : public Background2D { public: void Render(int layer) override; void UpdateState(int capId) override; + + MutableTextureRef CaptureTexture; }; class BackgroundEffect2D : public Background2D { @@ -193,7 +195,7 @@ inline std::array Backgrounds; inline std::array Screencaptures; inline Capture2D MaskCapture; inline std::array Framebuffers; -inline Background2D ShaderScreencapture; +inline Capture2D ShaderScreencapture; inline ankerl::unordered_dense::map Backgrounds2D; diff --git a/src/character2d.cpp b/src/character2d.cpp index 70f734d47..021ace552 100644 --- a/src/character2d.cpp +++ b/src/character2d.cpp @@ -1,5 +1,7 @@ #include "character2d.h" +#include + #include "mem.h" #include "io/io.h" #include "io/vfs.h" @@ -161,10 +163,9 @@ bool Character2D::LoadSync(uint32_t charaId) { } void Character2D::UnloadSync() { - Renderer->FreeTexture(CharaSpriteSheet.Texture); + CharaSpriteSheet.Texture = TextureRef{}; CharaSpriteSheet.DesignHeight = 0.0f; CharaSpriteSheet.DesignWidth = 0.0f; - CharaSpriteSheet.Texture = 0; Show = false; std::fill(Layers.begin(), Layers.end(), -1); MvlVertices.clear(); @@ -430,8 +431,8 @@ void Character2D::Render(const int layer) { Background2D::LastRenderedBackground && Background2D::LastRenderedBackground->ChaBgEff.Loaded && UseBgEffect; if (!renderWithBgEffect) { - Renderer->DrawPrimitives(CharaSpriteSheet, ShaderProgramType::Sprite, - MvlVertices, MvlIndices, transformation); + Renderer->DrawSprite({CharaSpriteSheet, MvlVertices, MvlIndices, + TopologyMode::Triangles, transformation}); } else { const BgEff& bgEff = Background2D::LastRenderedBackground->ChaBgEff; @@ -455,9 +456,69 @@ void Character2D::Render(const int layer) { return glm::mat4(1.0f); }(); - Renderer->DrawPrimitives( - CharaSpriteSheet, &bgEff.BgEffSprite.Sheet, bgEff.Shader, MvlVertices, - MvlIndices, transformation, maskTransformation * transformation); + const static auto shaderTable = []() { + using enum ShaderProgramType; + magic_enum::containers::array< + ShaderProgramType, + std::function> + table; + static_assert(table.size() == 11); + + table[AdditiveMaskedSprite] = + [](const PositionedMaskedSprite& spriteInfo) { + Renderer->DrawAdditiveMaskedSprite(spriteInfo); + }; + table[ColorBurnMaskedSprite] = + [](const PositionedMaskedSprite& spriteInfo) { + Renderer->DrawColorBurnMaskedSprite(spriteInfo); + }; + table[ColorDodgeMaskedSprite] = + [](const PositionedMaskedSprite& spriteInfo) { + Renderer->DrawColorDodgeMaskedSprite(spriteInfo); + }; + table[ColorMaskedSprite] = + [](const PositionedMaskedSprite& spriteInfo) { + Renderer->DrawColorMaskedSprite(spriteInfo); + }; + table[HardLightMaskedSprite] = + [](const PositionedMaskedSprite& spriteInfo) { + Renderer->DrawHardLightMaskedSprite(spriteInfo); + }; + table[LinearBurnMaskedSprite] = + [](const PositionedMaskedSprite& spriteInfo) { + Renderer->DrawLinearBurnMaskedSprite(spriteInfo); + }; + table[MaskedSpriteNoAlpha] = + [](const PositionedMaskedSprite& spriteInfo) { + Renderer->DrawMaskedSpriteNoAlpha( + spriteInfo, {.Alpha = 1.0f, .FadeRange = 0.0f}); + }; + table[OverlayMaskedSprite] = + [](const PositionedMaskedSprite& spriteInfo) { + Renderer->DrawOverlayMaskedSprite(spriteInfo); + }; + table[ScreenMaskedSprite] = + [](const PositionedMaskedSprite& spriteInfo) { + Renderer->DrawScreenMaskedSprite(spriteInfo); + }; + table[SoftLightMaskedSprite] = + [](const PositionedMaskedSprite& spriteInfo) { + Renderer->DrawSoftLightMaskedSprite(spriteInfo); + }; + table[Sprite] = [](const PositionedMaskedSprite& spriteInfo) { + Renderer->DrawSprite({spriteInfo.Texture, spriteInfo.GetVertices(), + spriteInfo.GetIndices(), + spriteInfo.GetTopologyMode(), + spriteInfo.Transformation}); + }; + + return table; + }(); + + shaderTable[bgEff.Shader]({CharaSpriteSheet, bgEff.BgEffSprite.Sheet, + MvlVertices, MvlIndices, + TopologyMode::Triangles, transformation, + maskTransformation * transformation}); } } else { diff --git a/src/config.h.in b/src/config.h.in index 825790d24..c9c787a42 100644 --- a/src/config.h.in +++ b/src/config.h.in @@ -4,9 +4,16 @@ #cmakedefine01 IMPACTO_GL_DEBUG #cmakedefine01 IMPACTO_HAVE_THREADS #cmakedefine01 IMPACTO_USE_SDL_HIGHDPI -#cmakedefine IMPACTO_DISABLE_VULKAN -#cmakedefine IMPACTO_DISABLE_DX9 -#cmakedefine IMPACTO_DISABLE_OPENGL + +// Renderer backends +#cmakedefine IMPACTO_RENDERER_BGFX +#cmakedefine IMPACTO_RENDERER_VULKAN +#cmakedefine IMPACTO_RENDERER_OPENGL +#cmakedefine IMPACTO_RENDERER_OPENGLES +#cmakedefine IMPACTO_RENDERER_DIRECT3D11 +#cmakedefine IMPACTO_RENDERER_DIRECT3D12 +#cmakedefine IMPACTO_RENDERER_METAL + #cmakedefine IMPACTO_DISABLE_FFMPEG #cmakedefine IMPACTO_DISABLE_OPENAL #cmakedefine IMPACTO_DISABLE_MSPACK diff --git a/src/data/savesystem.cpp b/src/data/savesystem.cpp index 7aedf9caf..3614ff2e8 100644 --- a/src/data/savesystem.cpp +++ b/src/data/savesystem.cpp @@ -31,7 +31,7 @@ class SaveFileLoader : public Loadable { void MainThreadOnLoad(SaveError result) { // Texture submission has to happen on the main thread for (QueuedTexture& texture : QueuedTextures) { - texture.Id.get() = texture.Tex.Submit(); + texture.Reference = texture.Tex.Submit(); } QueuedTextures.clear(); @@ -368,13 +368,13 @@ Sprite& GetSaveThumbnail(SaveType type, int id) { return dummy; } -Sprite& GetWorkingSaveThumbnail() { +MutableTextureRef& GetWorkingSaveThumbnail() { if (Implementation) return Implementation->GetWorkingSaveThumbnail(); ImpLog(LogLevel::Warning, LogChannel::VMStub, "{:s}: save system not implemented, returning dummy sprite\n", __func__); - static Sprite dummy; - return dummy; + static MutableTextureRef nullTexture; + return nullTexture; } bool HasQSavedOnCurrentLine() { diff --git a/src/data/savesystem.h b/src/data/savesystem.h index 8de5b99c4..1ad6a9028 100644 --- a/src/data/savesystem.h +++ b/src/data/savesystem.h @@ -51,7 +51,7 @@ struct ScriptMessageDataPair { // A delayed Texture::Submit() operation to be executed on the main thread struct QueuedTexture { - std::reference_wrapper Id; + TextureRef Reference; Texture Tex{}; }; @@ -145,7 +145,7 @@ class SaveSystemBase { std::optional GetQuickSaveOpenSlot() const; int GetNewestSaveId(SaveType type) const; void UpdateQuickSaveRecentSortedId(int replacedSlot); - Sprite& GetWorkingSaveThumbnail() { return WorkingSaveThumbnail; } + MutableTextureRef& GetWorkingSaveThumbnail() { return WorkingSaveThumbnail; } int GetLockedQuickSaveCount() const; void SetLockedQuickSaveCount(int value); bool HasQSavedOnCurrentLine() const; @@ -174,7 +174,7 @@ class SaveSystemBase { std::iota(tmp.begin(), tmp.end(), 0); return tmp; }(); - Sprite WorkingSaveThumbnail; + MutableTextureRef WorkingSaveThumbnail; int LockedQuickSaveCount; bool QuickSavedOnCurrentLine; }; @@ -219,7 +219,7 @@ std::optional GetQuickSaveOpenSlot(); int GetNewestSaveId(SaveType type); void UpdateQuickSaveRecentSortedId(int replacedSlot); Sprite& GetSaveThumbnail(SaveType type, int id); -Sprite& GetWorkingSaveThumbnail(); +MutableTextureRef& GetWorkingSaveThumbnail(); bool HasQSavedOnCurrentLine(); void SetQSavedOnCurrentLine(bool value); diff --git a/src/debugmenu.cpp b/src/debugmenu.cpp index 16619311c..980fa3eb4 100644 --- a/src/debugmenu.cpp +++ b/src/debugmenu.cpp @@ -759,20 +759,18 @@ void ShowScriptDebugger() { ImGui::PopItemWidth(); } -static ankerl::unordered_dense::map> +static ankerl::unordered_dense::map> SpritesBySpriteSheet; static void ShowSprite(const Sprite* sprite) { - if (UserConfig::AdvancedSettings.ActiveRenderer == RendererType::OpenGL) { - float texWidth = sprite->Sheet.DesignWidth; - float texHeight = sprite->Sheet.DesignHeight; - ImGui::Image( - (ImTextureID)(intptr_t)sprite->Sheet.Texture, - ImVec2(sprite->Bounds.Width, sprite->Bounds.Height), - ImVec2(sprite->Bounds.X / texWidth, sprite->Bounds.Y / texHeight), - ImVec2((sprite->Bounds.X + sprite->Bounds.Width) / texWidth, - (sprite->Bounds.Y + sprite->Bounds.Height) / texHeight)); - } + float texWidth = sprite->Sheet.DesignWidth; + float texHeight = sprite->Sheet.DesignHeight; + ImGui::Image( + static_cast(sprite->Sheet.Texture->GetTextureId()), + ImVec2(sprite->Bounds.Width, sprite->Bounds.Height), + ImVec2(sprite->Bounds.X / texWidth, sprite->Bounds.Y / texHeight), + ImVec2((sprite->Bounds.X + sprite->Bounds.Width) / texWidth, + (sprite->Bounds.Y + sprite->Bounds.Height) / texHeight)); } void ShowObjects() { @@ -780,25 +778,26 @@ void ShowObjects() { if (SpritesBySpriteSheet.size() == 0) { for (const auto& sprite : Profile::Sprites) { - SpritesBySpriteSheet[sprite.second.Sheet.Texture].push_back(sprite.first); + SpritesBySpriteSheet[sprite.second.Sheet.Texture->GetTextureId()] + .push_back(sprite.first); } } if (ImGui::TreeNode("SpriteSheets")) { for (const auto& spriteSheet : Profile::SpriteSheets) { if (ImGui::TreeNode(spriteSheet.first.c_str())) { - ImGui::PushID(spriteSheet.second.Texture); + ImGui::PushID( + static_cast(spriteSheet.second.Texture->GetTextureId())); float texWidth = spriteSheet.second.DesignWidth * 0.4f; float texHeight = spriteSheet.second.DesignHeight * 0.4f; - // Only OpenGL for now - if (UserConfig::AdvancedSettings.ActiveRenderer == - RendererType::OpenGL) { - ImVec2 pos = ImGui::GetCursorScreenPos(); - ImGui::Image((ImTextureID)(intptr_t)spriteSheet.second.Texture, - ImVec2(texWidth, texHeight)); - ImageTooltip(pos, (ImTextureID)(intptr_t)spriteSheet.second.Texture, - texWidth, texHeight); - } + ImVec2 pos = ImGui::GetCursorScreenPos(); + ImGui::Image(static_cast( + spriteSheet.second.Texture->GetTextureId()), + ImVec2(texWidth, texHeight)); + ImageTooltip(pos, + static_cast( + spriteSheet.second.Texture->GetTextureId()), + texWidth, texHeight); ImGui::Spacing(); ImGui::BulletText("Texture: (width: %f, height: %f)", @@ -807,7 +806,8 @@ void ShowObjects() { if (ImGui::TreeNode("Sprites")) { for (const auto& spriteName : - SpritesBySpriteSheet[spriteSheet.second.Texture]) { + SpritesBySpriteSheet[spriteSheet.second.Texture + ->GetTextureId()]) { const auto& sprite = Profile::Sprites[spriteName]; if (ImGui::TreeNode(spriteName.c_str())) { ShowSprite(&sprite); @@ -840,18 +840,16 @@ void ShowObjects() { if (Backgrounds[i].Status == LoadStatus::Loaded) { float texWidth = Backgrounds[i].BgSprite.Sheet.DesignWidth * 0.4f; float texHeight = Backgrounds[i].BgSprite.Sheet.DesignHeight * 0.4f; - // Only OpenGL for now - if (UserConfig::AdvancedSettings.ActiveRenderer == - RendererType::OpenGL) { - ImVec2 pos = ImGui::GetCursorScreenPos(); - ImGui::Image( - (ImTextureID)(intptr_t)Backgrounds[i].BgSprite.Sheet.Texture, - ImVec2(texWidth, texHeight)); - ImageTooltip( - pos, - (ImTextureID)(intptr_t)Backgrounds[i].BgSprite.Sheet.Texture, - texWidth, texHeight); - } + ImVec2 pos = ImGui::GetCursorScreenPos(); + ImGui::Image( + static_cast( + Backgrounds[i].BgSprite.Sheet.Texture->GetTextureId()), + ImVec2(texWidth, texHeight)); + ImageTooltip( + pos, + static_cast( + Backgrounds[i].BgSprite.Sheet.Texture->GetTextureId()), + texWidth, texHeight); } ImGui::Spacing(); @@ -895,18 +893,16 @@ void ShowObjects() { float texWidth = Characters2D[i].CharaSprite.Sheet.DesignWidth * 0.4f; float texHeight = Characters2D[i].CharaSprite.Sheet.DesignHeight * 0.4f; - // Only OpenGL for now - if (UserConfig::AdvancedSettings.ActiveRenderer == - RendererType::OpenGL) { - ImVec2 pos = ImGui::GetCursorScreenPos(); - ImGui::Image((ImTextureID)(intptr_t)Characters2D[i] - .CharaSprite.Sheet.Texture, - ImVec2(texWidth, texHeight)); - ImageTooltip(pos, - (ImTextureID)(intptr_t)Characters2D[i] - .CharaSprite.Sheet.Texture, - texWidth, texHeight); - } + ImVec2 pos = ImGui::GetCursorScreenPos(); + ImGui::Image( + static_cast( + Characters2D[i].CharaSprite.Sheet.Texture->GetTextureId()), + ImVec2(texWidth, texHeight)); + ImageTooltip( + pos, + static_cast( + Characters2D[i].CharaSprite.Sheet.Texture->GetTextureId()), + texWidth, texHeight); } ImGui::Spacing(); diff --git a/src/effects/blur.cpp b/src/effects/blur.cpp index ffee05abb..2bdfcc257 100644 --- a/src/effects/blur.cpp +++ b/src/effects/blur.cpp @@ -11,28 +11,6 @@ namespace Effects { using namespace Impacto::Profile::ScriptVars; -BlurEffect::BlurEffect() - : BlurSprite( - SpriteSheet(Profile::Game::DesignWidth, Profile::Game::DesignHeight), - 0.0f, 0.0f, Profile::Game::DesignWidth, Profile::Game::DesignHeight) { - BlurSprite.Sheet.IsScreenCap = true; -} - -void BlurEffect::Init() { - if (BlurSprite.Sheet.Texture) { - Renderer->FreeTexture(BlurSprite.Sheet.Texture); - } - - Texture texture{}; - texture.LoadSolidColor(static_cast(Profile::Game::DesignWidth), - static_cast(Profile::Game::DesignHeight), 0); - BlurSprite.Sheet.Texture = texture.Submit(); -} - -BlurEffect::~BlurEffect() { - if (Renderer) Renderer->FreeTexture(BlurSprite.Sheet.Texture); -} - void BlurEffect::Render(int iterations) { if (Profile::Vm::GameInstructionSet == Vm::InstructionSet::CHLCC) { iterations = std::min(iterations / 2, 8); @@ -45,11 +23,11 @@ void BlurEffect::Render(int iterations) { ? RendererBlurDirection::Vertical : RendererBlurDirection::Horizontal; - Renderer->CaptureScreencap(BlurSprite); - Renderer->DrawBlurredSprite(BlurSprite, - RectF{0.0f, 0.0f, Profile::Game::DesignWidth, - Profile::Game::DesignHeight}, - glm::mat4(1.0f), direction, glm::vec4(1.0f)); + Renderer->CaptureScreenCap(BlurSprite); + Renderer->DrawBlurredSprite( + {*BlurSprite, RectF{0.0f, 0.0f, Profile::Game::DesignWidth, + Profile::Game::DesignHeight}}, + {.BlurDirection = direction}); } } diff --git a/src/effects/blur.h b/src/effects/blur.h index f506c7e62..4688f6779 100644 --- a/src/effects/blur.h +++ b/src/effects/blur.h @@ -6,13 +6,9 @@ namespace Effects { class BlurEffect { public: void Render(int iterations); - void Init(); - - BlurEffect(); - ~BlurEffect(); private: - Sprite BlurSprite; + MutableTextureRef BlurSprite; }; inline BlurEffect Blur; diff --git a/src/effects/chlcc/eyecatch.cpp b/src/effects/chlcc/eyecatch.cpp index 3fdd3790e..8cf9554f5 100644 --- a/src/effects/chlcc/eyecatch.cpp +++ b/src/effects/chlcc/eyecatch.cpp @@ -14,19 +14,6 @@ namespace Impacto { namespace UI { namespace CHLCC { -EyecatchEffect::EyecatchEffect() { - Texture textureStarsMask{}; - textureStarsMask.LoadSolidColor(static_cast(Profile::Game::DesignWidth), - static_cast(Profile::Game::DesignHeight), - 0); - SpriteSheet sheetStarsMask(Profile::Game::DesignWidth, - Profile::Game::DesignHeight); - sheetStarsMask.Texture = textureStarsMask.Submit(); - sheetStarsMask.IsScreenCap = true; - StarsMask = Sprite(sheetStarsMask, 0, 0, Profile::Game::DesignWidth, - Profile::Game::DesignHeight); -} - void EyecatchEffect::RenderMain() { if (!ScrWork[SW_EYECATCH_COUNT]) return; Renderer->Clear(glm::vec4(0.0f)); @@ -51,7 +38,7 @@ void EyecatchEffect::RenderMain() { scaleOffset += 2; } } - Renderer->CaptureScreencap(StarsMask); + Renderer->CaptureScreenCap(StarsMask); } void EyecatchEffect::RenderLayer(int layer) { @@ -61,9 +48,9 @@ void EyecatchEffect::RenderLayer(int layer) { if (ScrWork[SW_EYECATCH_COUNT] < 64) { Renderer->Clear(glm::vec4(0.0f)); Renderer->DrawMaskedSprite( - Backgrounds2D[ScrWork[SW_BG1SURF + childBufId]]->BgSprite, StarsMask, - 255, 256, glm::vec2{0.0f, 0.0f}, glm::vec2{0.0f, 0.0f}, - glm::vec4(1.0f), false, false); + {Backgrounds2D[ScrWork[SW_BG1SURF + childBufId]]->BgSprite, + *StarsMask, glm::vec2(0.0f)}, + {.Alpha = 255.0f, .FadeRange = 256.0f}); } else { Renderer->DrawSprite( diff --git a/src/effects/chlcc/eyecatch.h b/src/effects/chlcc/eyecatch.h index 4002d85cd..f57328a03 100644 --- a/src/effects/chlcc/eyecatch.h +++ b/src/effects/chlcc/eyecatch.h @@ -7,10 +7,8 @@ namespace UI { namespace CHLCC { class EyecatchEffect { - EyecatchEffect(); - public: - Sprite StarsMask; + MutableTextureRef StarsMask; void RenderMain(); void RenderLayer(int layer); diff --git a/src/effects/mosaic.cpp b/src/effects/mosaic.cpp index a16c7e5fd..0eaea830a 100644 --- a/src/effects/mosaic.cpp +++ b/src/effects/mosaic.cpp @@ -6,37 +6,17 @@ namespace Impacto { namespace Effects { -MosaicEffect::MosaicEffect() - : CaptureSprite( - SpriteSheet(Profile::Game::DesignWidth, Profile::Game::DesignHeight), - 0.0f, 0.0f, Profile::Game::DesignWidth, Profile::Game::DesignHeight) { - CaptureSprite.Sheet.IsScreenCap = true; -} - -MosaicEffect::~MosaicEffect() { - if (Renderer) Renderer->FreeTexture(CaptureSprite.Sheet.Texture); -} - -void MosaicEffect::Init() { - if (CaptureSprite.Sheet.Texture != 0) return; - - Texture texture{}; - texture.LoadSolidColor(static_cast(Profile::Game::DesignWidth), - static_cast(Profile::Game::DesignHeight), 0); - CaptureSprite.Sheet.Texture = texture.Submit(); -} - void MosaicEffect::Render(float tileSize) { if (tileSize <= 1.0f) return; tileSize = std::min(tileSize, 20.0f); - assert(CaptureSprite.Sheet.Texture != 0); - Renderer->CaptureScreencap(CaptureSprite); - Renderer->DrawMosaic(CaptureSprite, - RectF{0.0f, 0.0f, Profile::Game::DesignWidth, - Profile::Game::DesignHeight}, - tileSize, glm::mat4(1.0f), glm::vec4(1.0f)); + assert(CaptureTexture.IsValid()); + Renderer->CaptureScreenCap(CaptureTexture); + Renderer->DrawMosaic( + {*CaptureTexture, RectF{0.0f, 0.0f, Profile::Game::DesignWidth, + Profile::Game::DesignHeight}}, + {.TileSize = tileSize}); } } // namespace Effects diff --git a/src/effects/mosaic.h b/src/effects/mosaic.h index 07252dbff..929751f25 100644 --- a/src/effects/mosaic.h +++ b/src/effects/mosaic.h @@ -7,15 +7,10 @@ namespace Effects { class MosaicEffect { public: - MosaicEffect(); - ~MosaicEffect(); - - void Init(); - void Render(float tileSize); private: - Sprite CaptureSprite; + MutableTextureRef CaptureTexture; }; inline MosaicEffect Mosaic; diff --git a/src/effects/wave.cpp b/src/effects/wave.cpp index cd0da60f2..0e15e0291 100644 --- a/src/effects/wave.cpp +++ b/src/effects/wave.cpp @@ -163,12 +163,10 @@ void BGWave::CalcPos(int startPhase, std::optional alpha) { } } -void EFFWave::Render(const Sprite& mask) { +void EFFWave::Render(const TextureInterface& mask) { PrimitiveData primitives = GetPrimitives(); - Renderer->DrawPrimitives(mask.Sheet, nullptr, ShaderProgramType::Sprite, - primitives.Vertices, primitives.Indices, - glm::mat4(1.0f), glm::mat4(1.0f), false, - TopologyMode::TriangleStrips); + Renderer->DrawSprite( + {mask, primitives.Vertices, primitives.Indices, primitives.Topology}); } // TODO: Not implemented diff --git a/src/effects/wave.h b/src/effects/wave.h index 3db4c2986..7cd24b06c 100644 --- a/src/effects/wave.h +++ b/src/effects/wave.h @@ -39,7 +39,8 @@ class Wave { virtual void CalcPos(int startPhase, std::optional alpha = std::nullopt) = 0; PrimitiveData GetPrimitives() { - return {std::span(Vertices), std::span(Indices)}; + return {std::span(Vertices), std::span(Indices), + TopologyMode::TriangleStrips}; }; }; @@ -52,7 +53,7 @@ class BGWave : public Wave { class EFFWave : public BGWave { public: - void Render(const Sprite& sprite); + void Render(const TextureInterface& sprite); }; class CHAWave : public Wave { diff --git a/src/game.cpp b/src/game.cpp index 508b7ec9c..b9efc268d 100644 --- a/src/game.cpp +++ b/src/game.cpp @@ -7,7 +7,6 @@ #include "log.h" #include "inputsystem.h" #include "debugmenu.h" -#include "renderer/opengl/glc.h" #ifndef IMPACTO_DISABLE_IMGUI #include "overlay.h" @@ -40,6 +39,8 @@ #include "effects/blur.h" #include "effects/mosaic.h" +#include "userconfig.h" + #include "profile/profile.h" #include "profile/game.h" @@ -76,10 +77,9 @@ using namespace Profile::ScriptVars; namespace Game { -void Init() { - SDL_SetHint(SDL_HINT_MOUSE_TOUCH_EVENTS, "0"); - - WorkQueue::Init(); +static void InitRenderer() { + Renderer.reset(); + Window.reset(); #ifndef IMPACTO_DISABLE_IMGUI IMGUI_CHECKVERSION(); @@ -95,16 +95,30 @@ void Init() { io.ConfigFlags |= ImGuiConfigFlags_DockingEnable; } #endif + InitWindow(); CreateRenderer(); - InitCursors(); #ifndef IMPACTO_DISABLE_IMGUI Overlay::Init(); #endif } +void Init() { + SDL_SetHint(SDL_HINT_MOUSE_TOUCH_EVENTS, "0"); + + WorkQueue::Init(); + + InitRenderer(); + InitCursors(); +} + void InitGameProfile() { + if (UserConfig::AdvancedSettings.ActiveRenderer != Renderer->GetType()) { + // If the active renderer was changed in the launcher, re-init renderer + InitRenderer(); + } + Profile::ConfigureGameProfile(); Profile::Game::Configure(); Profile::Patch::Configure(); @@ -151,8 +165,6 @@ void InitGameProfile() { Profile::WaveEffects::Load(); Effects::Init(); } - - Effects::Blur.Init(); } SetWindowIcon(Window->SDLWindow); @@ -196,14 +208,12 @@ void InitGameProfile() { Vm::Interface::UpdatePADcustomType(0); SaveSystem::InitializeSystemData(); - - Effects::Mosaic.Init(); } Profile::ClearProfile(); } -void Shutdown() { +void Shutdown(const int exitCode) { if (+Profile::Game::GameFeatures & +GameFeature::Audio) { Audio::AudioShutdown(); } @@ -212,11 +222,12 @@ void Shutdown() { Video::VideoShutdown(); } - if (+Profile::Game::GameFeatures & +GameFeature::Renderer2D) { - Renderer->Shutdown(); - } WorkQueue::StopWorkQueue(); - Window->Shutdown(); + + Renderer.reset(); + Window.reset(); + + exit(exitCode); } void LauncherUpdate(float dt) { @@ -551,10 +562,10 @@ static void RenderMain() { if (isCC) { alpha = static_cast(ScrWork[SW_EFF_WAVE_ALPHA]) / 256.0f; } - Renderer->CaptureScreencap(Screencaptures[0].BgSprite); + Renderer->CaptureScreenCap(Screencaptures[0].CaptureTexture); Screencaptures[0].Status = LoadStatus::Loaded; Effects::WaveEFF.CalcPos(0, alpha); - Effects::WaveEFF.Render(Screencaptures[0].BgSprite); + Effects::WaveEFF.Render(*Screencaptures[0].CaptureTexture); } } } @@ -576,13 +587,13 @@ static void RenderMain() { continue; } - Renderer->CaptureScreencap(Screencaptures[capId].BgSprite); + Renderer->CaptureScreenCap(Screencaptures[capId].CaptureTexture); Screencaptures[capId].Status = LoadStatus::Loaded; } if (GetFlag(SF_MASK_CAPTURE) && ScrWork[SW_MASK_CAPTURE_PRI] == static_cast(layer)) { - Renderer->CaptureScreencap(MaskCapture.BgSprite); + Renderer->CaptureScreenCap(MaskCapture.CaptureTexture); MaskCapture.Status = LoadStatus::Loaded; } } @@ -591,7 +602,7 @@ static void RenderMain() { Renderer->SetFramebuffer(0); if (SaveSystem::Implementation) { - Renderer->CaptureScreencap(SaveSystem::GetWorkingSaveThumbnail()); + Renderer->CaptureScreenCap(SaveSystem::GetWorkingSaveThumbnail()); } DateDisplay::Render(); @@ -651,7 +662,7 @@ void Render() { Profile::Vm::GameInstructionSet == Vm::InstructionSet::LCCSwitch) && GetFlag(SF_SYSTEMMENUCAPTURE)) { - Renderer->CaptureScreencap( + Renderer->CaptureScreenCap( static_cast(UI::SystemMenuPtr) ->ScreenCap); SetFlag(SF_SYSTEMMENUCAPTURE, false); diff --git a/src/game.h b/src/game.h index 52e12fbf1..fc5086b12 100644 --- a/src/game.h +++ b/src/game.h @@ -57,7 +57,7 @@ enum class DrawComponentType : uint8_t { void Init(); void InitGameProfile(); -void Shutdown(); +[[noreturn]] void Shutdown(int exitCode = EXIT_SUCCESS); void Update(float dt); void Render(); diff --git a/src/games/cc/sysmesbox.cpp b/src/games/cc/sysmesbox.cpp index 74795c755..8c98637d5 100644 --- a/src/games/cc/sysmesbox.cpp +++ b/src/games/cc/sysmesbox.cpp @@ -31,9 +31,6 @@ void SysMesBox::Show() { MessageItems = std::make_unique(this); ChoiceItems = std::make_unique(this); - Sprite nullSprite = Sprite(); - nullSprite.Bounds = RectF(0.0f, 0.0f, 0.0f, 0.0f); - auto onClick = [this](auto* btn) { return ChoiceItemOnClick(btn); }; float textBeginY = (TextMiddleY - TextMarginY * MessageCount) / 2.0f; @@ -55,7 +52,7 @@ void SysMesBox::Show() { if (ChoiceCount == 1) { WidgetOK = - new Button(0, ButtonOK, ButtonOKHighlighted, nullSprite, + new Button(0, ButtonOK, ButtonOKHighlighted, std::nullopt, glm::vec2(ButtonOKCenterPosX - (ButtonOK.Bounds.Width / 2), ButtonOKCenterPosY - (ButtonOK.Bounds.Height / 2)), ButtonOkHoverBounds); @@ -64,14 +61,14 @@ void SysMesBox::Show() { } else if (ChoiceCount == 2) { WidgetYes = new Button( - 0, ButtonYes, ButtonYesHighlighted, nullSprite, + 0, ButtonYes, ButtonYesHighlighted, std::nullopt, glm::vec2(ButtonYesCenterPosX - (ButtonYes.Bounds.Width / 2), ButtonYesCenterPosY - (ButtonYes.Bounds.Height / 2)), ButtonYesHoverBounds); WidgetYes->OnClickHandler = onClick; ChoiceItems->Add(WidgetYes, FDIR_RIGHT); WidgetNo = - new Button(1, ButtonNo, ButtonNoHighlighted, nullSprite, + new Button(1, ButtonNo, ButtonNoHighlighted, std::nullopt, glm::vec2(ButtonNoCenterPosX - (ButtonNo.Bounds.Width / 2), ButtonNoCenterPosY - (ButtonNo.Bounds.Height / 2)), ButtonNoHoverBounds); @@ -146,12 +143,12 @@ void SysMesBox::Update(float dt) { ButtonYesAnimationProgressEnd); float scaleYes = ButtonScaleMax - (offsetProgress * ButtonYesNoScaleMultiplier); - WidgetYes->NormalSprite.BaseScale = glm::vec2(scaleYes); - WidgetYes->FocusedSprite.BaseScale = glm::vec2(scaleYes); + WidgetYes->NormalSprite->BaseScale = glm::vec2(scaleYes); + WidgetYes->FocusedSprite->BaseScale = glm::vec2(scaleYes); WidgetYes->MoveTo(glm::vec2( - ButtonYesCenterPosX - (WidgetYes->NormalSprite.ScaledWidth() * 0.5f), + ButtonYesCenterPosX - (WidgetYes->NormalSprite->ScaledWidth() * 0.5f), ButtonYesCenterPosY - - (WidgetYes->NormalSprite.ScaledHeight() * 0.5f))); + (WidgetYes->NormalSprite->ScaledHeight() * 0.5f))); WidgetYes->Tint = glm::vec4(1.0f, 1.0f, 1.0f, offsetProgress / ButtonYesNoAlphaDivider); @@ -160,12 +157,12 @@ void SysMesBox::Update(float dt) { offsetProgress = animationProgress - ButtonNoAnimationProgressOffset; float scaleNo = ButtonScaleMax - (offsetProgress * ButtonYesNoScaleMultiplier); - WidgetNo->NormalSprite.BaseScale = glm::vec2(scaleNo); - WidgetNo->FocusedSprite.BaseScale = glm::vec2(scaleNo); + WidgetNo->NormalSprite->BaseScale = glm::vec2(scaleNo); + WidgetNo->FocusedSprite->BaseScale = glm::vec2(scaleNo); WidgetNo->MoveTo(glm::vec2( - ButtonNoCenterPosX - (WidgetNo->NormalSprite.ScaledWidth() * 0.5f), + ButtonNoCenterPosX - (WidgetNo->NormalSprite->ScaledWidth() * 0.5f), ButtonNoCenterPosY - - (WidgetNo->NormalSprite.ScaledHeight() * 0.5f))); + (WidgetNo->NormalSprite->ScaledHeight() * 0.5f))); WidgetNo->Tint = glm::vec4(1.0f, 1.0f, 1.0f, offsetProgress / ButtonYesNoAlphaDivider); } else { @@ -176,11 +173,12 @@ void SysMesBox::Update(float dt) { (animationProgress - AnimationProgressWidgetsStartOffset); float scaleOk = ButtonScaleMax - (offsetProgress * ButtonOKScaleMultiplier); - WidgetOK->NormalSprite.BaseScale = glm::vec2(scaleOk); - WidgetOK->FocusedSprite.BaseScale = glm::vec2(scaleOk); + WidgetOK->NormalSprite->BaseScale = glm::vec2(scaleOk); + WidgetOK->FocusedSprite->BaseScale = glm::vec2(scaleOk); WidgetOK->MoveTo(glm::vec2( - ButtonOKCenterPosX - (WidgetOK->NormalSprite.ScaledWidth() * 0.5f), - ButtonOKCenterPosY - (WidgetOK->NormalSprite.ScaledHeight() * 0.5f))); + ButtonOKCenterPosX - (WidgetOK->NormalSprite->ScaledWidth() * 0.5f), + ButtonOKCenterPosY - + (WidgetOK->NormalSprite->ScaledHeight() * 0.5f))); WidgetOK->Tint = glm::vec4(1.0f, 1.0f, 1.0f, WidgetsAlphaMultiplier * offsetProgress); } diff --git a/src/games/cc/titlemenu.cpp b/src/games/cc/titlemenu.cpp index 838f28f97..019a6baec 100644 --- a/src/games/cc/titlemenu.cpp +++ b/src/games/cc/titlemenu.cpp @@ -65,9 +65,6 @@ TitleMenu::TitleMenu() { }; auto extraOnClick = [this](auto* btn) { return ExtraButtonOnClick(btn); }; - Sprite nullSprite = Sprite(); - nullSprite.Bounds = RectF(0.0f, 0.0f, 0.0f, 0.0f); - // NewGame menu button NewGame = new TitleButton( 0, MenuEntriesSprites[0], MenuEntriesHSprites[0], ItemHighlightSprite, @@ -109,7 +106,7 @@ TitleMenu::TitleMenu() { MainItems->Add(Help, FDIR_DOWN); // Load secondary Continue menu button - Load = new TitleButton(10, LoadSprite, LoadHighlightSprite, nullSprite, + Load = new TitleButton(10, LoadSprite, LoadHighlightSprite, std::nullopt, glm::vec2(((SecondaryFirstItemHighlightOffsetX)) + SecondaryFirstItemHighlightOffsetX, (ItemYBase + (2 * ItemPadding)))); @@ -118,17 +115,17 @@ TitleMenu::TitleMenu() { ContinueItems->Add(Load, FDIR_RIGHT); // QuickLoad secondary Continue menu button - QuickLoad = - new TitleButton(11, QuickLoadSprite, QuickLoadHighlightSprite, nullSprite, - glm::vec2(((SecondarySecondItemHighlightOffsetX)) + - SecondarySecondItemHighlightOffsetX, - (ItemYBase + (2 * ItemPadding)))); + QuickLoad = new TitleButton( + 11, QuickLoadSprite, QuickLoadHighlightSprite, std::nullopt, + glm::vec2(((SecondarySecondItemHighlightOffsetX)) + + SecondarySecondItemHighlightOffsetX, + (ItemYBase + (2 * ItemPadding)))); QuickLoad->OnClickHandler = onClick; QuickLoad->IsSubButton = true; ContinueItems->Add(QuickLoad, FDIR_RIGHT); // Tips secondary Extra menu button - Tips = new TitleButton(30, TipsSprite, TipsHighlightSprite, nullSprite, + Tips = new TitleButton(30, TipsSprite, TipsHighlightSprite, std::nullopt, glm::vec2(((SecondaryFirstItemHighlightOffsetX)) + SecondaryFirstItemHighlightOffsetX, (ItemYBase + (3 * ItemPadding)))); @@ -138,7 +135,7 @@ TitleMenu::TitleMenu() { // Library secondary Extra menu button Library = - new TitleButton(31, LibrarySprite, LibraryHighlightSprite, nullSprite, + new TitleButton(31, LibrarySprite, LibraryHighlightSprite, std::nullopt, glm::vec2(((SecondarySecondItemHighlightOffsetX)) + SecondarySecondItemHighlightOffsetX, (ItemYBase + (3 * ItemPadding)))); @@ -148,7 +145,7 @@ TitleMenu::TitleMenu() { // EndingList secondary Extra menu button EndingList = new TitleButton( - 32, EndingListSprite, EndingListHighlightSprite, nullSprite, + 32, EndingListSprite, EndingListHighlightSprite, std::nullopt, glm::vec2(((SecondaryThirdItemHighlightOffsetX)) + SecondaryThirdItemHighlightOffsetX, (ItemYBase + (3 * ItemPadding)))); diff --git a/src/games/cclcc/albummenu.cpp b/src/games/cclcc/albummenu.cpp index 31f0f6d02..6a6a07ef3 100644 --- a/src/games/cclcc/albummenu.cpp +++ b/src/games/cclcc/albummenu.cpp @@ -84,9 +84,8 @@ void AlbumMenu::SetThumbnailDirections() { case FDIR_RIGHT: return RIGHT; } - ImpLog(LogLevel::Fatal, LogChannel::General, - "Invalid FocusDirection value: {}", static_cast(dir)); - exit(1); + Panic(LogChannel::General, "Invalid FocusDirection value: {}", + static_cast(dir)); }; for (auto& page : ThumbnailPages) { diff --git a/src/games/cclcc/commonmenu.cpp b/src/games/cclcc/commonmenu.cpp index 64fbb1138..8dc5f0281 100644 --- a/src/games/cclcc/commonmenu.cpp +++ b/src/games/cclcc/commonmenu.cpp @@ -41,14 +41,6 @@ void CommonMenu::Init() { animation.LoopMode = AnimationLoopMode::Loop; animation.StartIn(); } - - const RectF viewport = Window->GetViewport(); - Texture captureTexture; - captureTexture.LoadSolidColor(static_cast(viewport.Width), - static_cast(viewport.Height), 0x00000000); - CaptureSprite.Sheet.Texture = captureTexture.Submit(); - CaptureSprite.Sheet.DesignWidth = viewport.Width; - CaptureSprite.Sheet.DesignHeight = viewport.Height; } void CommonMenu::InitSmokePos() { @@ -80,41 +72,10 @@ void CommonMenu::DrawSmoke(const float alpha) { } void CommonMenu::DrawOverlay(const float alpha) { - const glm::vec4 tint = {1.0f, 1.0f, 1.0f, alpha}; - - const RectF maskUvBounds = OverlaySprite.NormalizedBounds(); - std::array vertices{ - VertexBufferSprites{ - .Position = {0.0f, 0.0f}, - .UV = {0.0f, 0.0f}, - .Tint = tint, - .MaskUV = {maskUvBounds.Left(), 1.0f - maskUvBounds.Top()}, - }, - VertexBufferSprites{ - .Position = {Profile::Game::DesignWidth, 0.0f}, - .UV = {1.0f, 0.0f}, - .Tint = tint, - .MaskUV = {maskUvBounds.Right(), 1.0f - maskUvBounds.Top()}, - }, - VertexBufferSprites{ - .Position = {0.0f, Profile::Game::DesignHeight}, - .UV = {0.0f, 1.0f}, - .Tint = tint, - .MaskUV = {maskUvBounds.Left(), 1.0f - maskUvBounds.Bottom()}, - }, - VertexBufferSprites{ - .Position = {Profile::Game::DesignWidth, Profile::Game::DesignHeight}, - .UV = {1.0f, 1.0f}, - .Tint = tint, - .MaskUV = {maskUvBounds.Right(), 1.0f - maskUvBounds.Bottom()}, - }, - }; - constexpr static std::array indices{0, 1, 2, 1, 2, 3}; - - Renderer->CaptureScreencap(CaptureSprite); - Renderer->DrawPrimitives(CaptureSprite.Sheet, &OverlaySprite.Sheet, - ShaderProgramType::HardLightMaskedSprite, vertices, - indices, {0.0f, 0.0f}); + Renderer->CaptureScreenCap(CaptureTexture); + Renderer->DrawHardLightMaskedSprite({*CaptureTexture, OverlaySprite.Sheet, + glm::vec2(0.0f), + glm::vec4(1.0f, 1.0f, 1.0f, alpha)}); const float guideTransitionProgress = glm::smoothstep( 0.0f, 1.0f, @@ -207,7 +168,7 @@ void CommonMenu::TransformImage(CornersQuad const& sprCorners, template void CommonMenu::DrawBgSprite(MenuState state, const Animation& fadeAnimation, - std::optional screenCap) { + std::optional screenCap) { glm::vec3 tint = {1.0f, 1.0f, 1.0f}; // Alpha goes from 0 to 1 in half the time float alpha = glm::smoothstep(0.0f, 1.0f, fadeAnimation.Progress); @@ -273,10 +234,9 @@ void CommonMenu::DrawBgSprite(MenuState state, const Animation& fadeAnimation, return result; }(); - Renderer->DrawPrimitives(SystemMenuBG.Sheet, nullptr, - ShaderProgramType::Sprite, Vertices, indices, - glm::mat4(1.0f), glm::mat4(1.0f), false, - TopologyMode::TriangleStrips, true); + // TODO: Texturewraprepeat + Renderer->DrawSprite( + {SystemMenuBG.Sheet, Vertices, indices, TopologyMode::TriangleStrips}); if constexpr (IsSystem) { CornersQuad frameDisp = { @@ -301,7 +261,7 @@ void CommonMenu::DrawBgSprite(MenuState state, const Animation& fadeAnimation, return TransformImageVertex(corner, transformation, BGTranslationOffset); }); if (screenCap.has_value()) { - Renderer->DrawSprite(*screenCap, screenCapDisp, glm::vec4(1.0f), + Renderer->DrawSprite(**screenCap, screenCapDisp, glm::vec4(1.0f), glm::vec3(0.0f), false, true); } } diff --git a/src/games/cclcc/commonmenu.h b/src/games/cclcc/commonmenu.h index fa1f155e4..44aa34228 100644 --- a/src/games/cclcc/commonmenu.h +++ b/src/games/cclcc/commonmenu.h @@ -38,7 +38,7 @@ class CommonMenu { template void DrawBgSprite(MenuState state, const Animation& fadeAnimation, - std::optional ScreenCap = std::nullopt); + std::optional ScreenCap = std::nullopt); private: static glm::vec2 TransformImageVertex(const glm::vec2 vertex, @@ -57,7 +57,7 @@ class CommonMenu { static inline std::array SmokeAnimations; - static inline Sprite CaptureSprite; + static inline MutableTextureRef CaptureTexture; }; } // namespace CCLCC diff --git a/src/games/cclcc/delusiontrigger.cpp b/src/games/cclcc/delusiontrigger.cpp index ae59f6202..97d340d89 100644 --- a/src/games/cclcc/delusiontrigger.cpp +++ b/src/games/cclcc/delusiontrigger.cpp @@ -252,10 +252,10 @@ void DelusionTrigger::Update(float dt) { if (!GetFlag(SF_DELUSIONACTIVE)) { if ((GetFlag(SF_MOVIEPLAY) && GetFlag(SF_MOVIE_DRAWWAIT)) || ScrWork[SW_DELUSION_BG_COUNTER] == 0) { - if (BgOverlaySprite.Sheet.Texture) BgOverlaySprite = Sprite{}; - if (PositiveDelusionSprite.Sheet.Texture) + if (BgOverlaySprite.Sheet.Texture.IsValid()) BgOverlaySprite = Sprite{}; + if (PositiveDelusionSprite.Sheet.Texture.IsValid()) PositiveDelusionSprite.Sheet = SpriteSheet{}; - if (NegativeDelusionSprite.Sheet.Texture) + if (NegativeDelusionSprite.Sheet.Texture.IsValid()) NegativeDelusionSprite.Sheet = SpriteSheet{}; return; } @@ -268,7 +268,7 @@ void DelusionTrigger::Update(float dt) { MtrgAlphaCt = (MtrgAlphaCt + 1) & 0x1f; MtrgAng = (MtrgAng + 100) & 0xffff; - if (BgOverlaySprite.Sheet.Texture == 0) { + if (!BgOverlaySprite.Sheet.Texture.IsValid()) { int bgOverlayBGIdx = ScrWork[SW_BG1SURF + GetBufferId(ScrWork[SW_DELUSION_OVERLAY_BUF])]; BgOverlaySprite = Backgrounds2D[bgOverlayBGIdx]->BgSprite; @@ -276,11 +276,11 @@ void DelusionTrigger::Update(float dt) { int delusionCirclesBGIdx = ScrWork[SW_BG1SURF + GetBufferId(ScrWork[SW_DELUSION_CIRCLE_BUF])]; - if (PositiveDelusionSprite.Sheet.Texture == 0) { + if (!PositiveDelusionSprite.Sheet.Texture.IsValid()) { PositiveDelusionSprite.Sheet = Backgrounds2D[delusionCirclesBGIdx]->BgSprite.Sheet; } - if (NegativeDelusionSprite.Sheet.Texture == 0) { + if (!NegativeDelusionSprite.Sheet.Texture.IsValid()) { NegativeDelusionSprite.Sheet = Backgrounds2D[delusionCirclesBGIdx]->BgSprite.Sheet; } diff --git a/src/games/cclcc/moviemenu.cpp b/src/games/cclcc/moviemenu.cpp index 2913c3151..74e381395 100644 --- a/src/games/cclcc/moviemenu.cpp +++ b/src/games/cclcc/moviemenu.cpp @@ -43,7 +43,7 @@ MovieMenu::MovieMenu() : LibrarySubmenu() { Audio::Channels[Audio::AC_BGM0]->Stop(0.0f); }; auto disk = new Widgets::Button(static_cast(i), diskSprite, - diskHighlightSprite, Sprite(), + diskHighlightSprite, std::nullopt, MovieDiskDisplayPositions[i]); disk->OnClickHandler = movieOnclick; MainItems.Add(disk, FDIR_RIGHT); diff --git a/src/games/cclcc/musicmenu.cpp b/src/games/cclcc/musicmenu.cpp index fd08a8805..7bf485896 100644 --- a/src/games/cclcc/musicmenu.cpp +++ b/src/games/cclcc/musicmenu.cpp @@ -121,14 +121,14 @@ void MusicTrackButton::Render() { Renderer->DrawSprite( MusicButtonPlayingSprite, MusicButtonPlayingDispOffset + glm::vec2(Bounds.X, Bounds.Y), Tint); - Renderer->DrawSprite(FocusedSprite, glm::vec2(Bounds.X + 113, Bounds.Y), + Renderer->DrawSprite(*FocusedSprite, glm::vec2(Bounds.X + 113, Bounds.Y), Tint); } else { Profile::Dialogue::DialogueFont->DrawProcessedText(NumberText, Tint.a); } if (HasFocus) { - Renderer->DrawSprite(HighlightSprite, glm::vec2(Bounds.X + 113, Bounds.Y), - Tint); + Renderer->DrawSprite(*HighlightSprite, + glm::vec2(Bounds.X + 113, Bounds.Y), Tint); } if (IsLocked) { Profile::Dialogue::DialogueFont->DrawProcessedText(LockedText, Tint.a); diff --git a/src/games/cclcc/savesystem.cpp b/src/games/cclcc/savesystem.cpp index 418fdd120..8a3b7b73f 100644 --- a/src/games/cclcc/savesystem.cpp +++ b/src/games/cclcc/savesystem.cpp @@ -197,7 +197,7 @@ void SaveSystem::FlushWorkingSaveEntry(SaveType type, int id, int autoSaveType) { auto* entry = GetSaveEntry(type, id); if (entry != nullptr && !(entry->Flags & WriteProtect)) { - Renderer->FreeTexture(entry->SaveThumbnail.Sheet.Texture); + entry->SaveThumbnail.Sheet.Texture = TextureRef{}; uint8_t savedFlags = entry->Flags; UpdateWorkingSaveEntry(entry); entry->Flags = savedFlags; diff --git a/src/games/cclcc/savesystem_ps4.cpp b/src/games/cclcc/savesystem_ps4.cpp index 3850ca978..05bd23925 100644 --- a/src/games/cclcc/savesystem_ps4.cpp +++ b/src/games/cclcc/savesystem_ps4.cpp @@ -123,7 +123,7 @@ SaveError SaveSystem::MountSaveFile(std::vector& textures) { WorkingSaveThumbnail.Bounds.SetSize(viewport.GetSize()); QueuedTexture txt{ - .Id = std::ref(WorkingSaveThumbnail.Sheet.Texture), + .Reference = WorkingSaveThumbnail.Sheet.Texture, }; txt.Tex.LoadSolidColor((int)WorkingSaveThumbnail.Bounds.Width, (int)WorkingSaveThumbnail.Bounds.Height, 0x000000); @@ -153,7 +153,7 @@ SaveError SaveSystem::MountSaveFile(std::vector& textures) { entrySlotBuf.size(), false); QueuedTexture tex{ - .Id = std::ref(entryArray[i]->SaveThumbnail.Sheet.Texture), + .Reference = entryArray[i]->SaveThumbnail.Sheet.Texture, }; LoadEntryBuffer(saveEntryDataStream, static_cast(*entryArray[i]), saveType, diff --git a/src/games/cclcc/savesystem_switch.cpp b/src/games/cclcc/savesystem_switch.cpp index edfdc6b94..53b22d480 100644 --- a/src/games/cclcc/savesystem_switch.cpp +++ b/src/games/cclcc/savesystem_switch.cpp @@ -139,7 +139,7 @@ SaveError SaveSystem::MountSaveFile(std::vector& textures) { WorkingSaveThumbnail.Bounds.SetSize(viewport.GetSize()); QueuedTexture txt{ - .Id = std::ref(WorkingSaveThumbnail.Sheet.Texture), + .Reference = WorkingSaveThumbnail.Sheet.Texture, }; txt.Tex.LoadSolidColor((int)WorkingSaveThumbnail.Bounds.Width, (int)WorkingSaveThumbnail.Bounds.Height, 0x000000); @@ -168,7 +168,7 @@ SaveError SaveSystem::MountSaveFile(std::vector& textures) { entrySlotBuf.size(), false); QueuedTexture tex{ - .Id = std::ref(entries[i]->SaveThumbnail.Sheet.Texture), + .Reference = entries[i]->SaveThumbnail.Sheet.Texture, }; LoadEntryBuffer(saveEntryDataStream, static_cast(*entries[i]), saveType, diff --git a/src/games/cclcc/systemmenu.cpp b/src/games/cclcc/systemmenu.cpp index 67f43c6eb..6552a6a1f 100644 --- a/src/games/cclcc/systemmenu.cpp +++ b/src/games/cclcc/systemmenu.cpp @@ -66,17 +66,14 @@ SystemMenu::SystemMenu() : CommonMenu(FadeAnimation) { MainItems = new Widgets::Group(this); const RectF viewport = Window->GetViewport(); - ScreenCap.Sheet = SpriteSheet(viewport.Width, viewport.Height); Texture tex; tex.LoadSolidColor(static_cast(viewport.Width), static_cast(viewport.Height), 0x000000); - ScreenCap.Sheet.Texture = tex.Submit(); - ScreenCap.Bounds.SetSize(viewport.GetSize()); for (int i = 0; i < MenuEntriesNum; i++) { - SysMenuButton* menuButton = new SysMenuButton( - i, MenuEntriesSprites[i], Sprite(), MenuEntriesHSprites[i], - MenuEntriesPositions[i], MenuEntriesButtonBounds[i]); + SysMenuButton* menuButton = + new SysMenuButton(i, MenuEntriesSprites[i], MenuEntriesHSprites[i], + MenuEntriesPositions[i], MenuEntriesButtonBounds[i]); menuButton->OnClickHandler = onClick; MainItems->Add(menuButton, FDIR_DOWN); diff --git a/src/games/cclcc/systemmenu.h b/src/games/cclcc/systemmenu.h index 9f54135da..b27ae909b 100644 --- a/src/games/cclcc/systemmenu.h +++ b/src/games/cclcc/systemmenu.h @@ -24,7 +24,7 @@ class SystemMenu : public Menu, public CommonMenu { void Render() override; void MenuButtonOnClick(Widgets::Button* target); - Sprite ScreenCap; + MutableTextureRef ScreenCap; private: Widgets::Group* MainItems; diff --git a/src/games/cclcc/titlemenu.cpp b/src/games/cclcc/titlemenu.cpp index 73483d643..2e0dd9db7 100644 --- a/src/games/cclcc/titlemenu.cpp +++ b/src/games/cclcc/titlemenu.cpp @@ -165,9 +165,6 @@ TitleMenu::TitleMenu() { ExtraItems = new Widgets::Group(this); ExtraItems->WrapFocus = false; - Sprite nullSprite = Sprite(); - nullSprite.Bounds = RectF(0.0f, 0.0f, 0.0f, 0.0f); - MenuLabel = new Widgets::Label(MenuSprite, MenuPos); auto onClick = [this](Widgets::Button* target) { @@ -244,36 +241,36 @@ TitleMenu::TitleMenu() { } // Load secondary Continue menu button - Load = - new TitleButton(LoadButtonId, LoadSprite, LoadHighlightSprite, nullSprite, - glm::vec2(SecondaryFirstItemHighlightOffsetX, - (ItemYBase + (2 * ItemPadding)))); + Load = new TitleButton(LoadButtonId, LoadSprite, LoadHighlightSprite, + std::nullopt, + glm::vec2(SecondaryFirstItemHighlightOffsetX, + (ItemYBase + (2 * ItemPadding)))); setupBtn(Load, onClick, ContinueItems, FDIR_RIGHT); // QuickLoad secondary Continue menu button QuickLoad = new TitleButton(QLoadButtonId, QuickLoadSprite, - QuickLoadHighlightSprite, nullSprite, + QuickLoadHighlightSprite, std::nullopt, glm::vec2(SecondarySecondItemHighlightOffsetX, (ItemYBase + (2 * ItemPadding)))); setupBtn(QuickLoad, onClick, ContinueItems, FDIR_RIGHT); // Tips secondary Extra menu button - Tips = - new TitleButton(TipsButtonId, TipsSprite, TipsHighlightSprite, nullSprite, - glm::vec2(SecondaryFirstItemHighlightOffsetX, - (ItemYBase + (3 * ItemPadding)))); + Tips = new TitleButton(TipsButtonId, TipsSprite, TipsHighlightSprite, + std::nullopt, + glm::vec2(SecondaryFirstItemHighlightOffsetX, + (ItemYBase + (3 * ItemPadding)))); setupBtn(Tips, onClick, ExtraItems, FDIR_RIGHT); // Library secondary Extra menu button Library = new TitleButton(LibraryButtonId, LibrarySprite, - LibraryHighlightSprite, nullSprite, + LibraryHighlightSprite, std::nullopt, glm::vec2(SecondarySecondItemHighlightOffsetX, (ItemYBase + (3 * ItemPadding)))); setupBtn(Library, onClick, ExtraItems, FDIR_RIGHT); // EndingList secondary Extra menu button EndingList = new TitleButton(EndingListButtonId, EndingListSprite, - EndingListHighlightSprite, nullSprite, + EndingListHighlightSprite, std::nullopt, glm::vec2(SecondaryThirdItemHighlightOffsetX, (ItemYBase + (3 * ItemPadding)))); setupBtn(EndingList, onClick, ExtraItems, FDIR_RIGHT); @@ -292,15 +289,6 @@ TitleMenu::TitleMenu() { SecondaryFadeAnimation.DurationOut = SecondaryFadeOutDuration; SlideItemsAnimation.DurationIn = SlideItemsAnimationDurationIn; SlideItemsAnimation.DurationOut = SlideItemsAnimationDurationOut; - - const RectF viewport = Window->GetViewport(); - Texture pressToStartTransitionTexture; - pressToStartTransitionTexture.LoadSolidColor( - static_cast(viewport.Width), static_cast(viewport.Height), 0); - PressToStartTransitionCapture.Sheet.Texture = - pressToStartTransitionTexture.Submit(); - PressToStartTransitionCapture.Sheet.DesignWidth = viewport.Width; - PressToStartTransitionCapture.Sheet.DesignHeight = viewport.Height; } void TitleMenu::Show() { @@ -731,14 +719,14 @@ void TitleMenu::Render() { Renderer->DrawSprite(BackgroundSprite, {0.0f, 0.0f}); PressToStartTransitionCaptureSet = true; } else { - Renderer->DrawSprite(PressToStartTransitionCapture, {0.0f, 0.0f}); + Renderer->DrawSprite({*PressToStartTransitionCapture, {0.0f, 0.0f}}); } Renderer->DrawSprite(MainBackgroundSprite, {0.0f, 0.0f}, {1.0f, 1.0f, 1.0f, TitleAnimation.Progress}); TitleAnimationSprite.Render(-1); - Renderer->CaptureScreencap(PressToStartTransitionCapture); + Renderer->CaptureScreenCap(PressToStartTransitionCapture); if (renderOverlay) { CommonMenu::DrawOverlay(); diff --git a/src/games/cclcc/titlemenu.h b/src/games/cclcc/titlemenu.h index 9464e017b..74ffbb48b 100644 --- a/src/games/cclcc/titlemenu.h +++ b/src/games/cclcc/titlemenu.h @@ -15,9 +15,6 @@ namespace CCLCC { class TitleMenu : public Menu { public: TitleMenu(); - ~TitleMenu() { - Renderer->FreeTexture(PressToStartTransitionCapture.Sheet.Texture); - } void Show() override; void Hide() override; @@ -75,7 +72,7 @@ class TitleMenu : public Menu { bool InputLocked = false; bool PrevInputLocked = false; - Sprite PressToStartTransitionCapture; + MutableTextureRef PressToStartTransitionCapture; bool PressToStartTransitionCaptureSet = false; }; diff --git a/src/games/cclcc/yesnotrigger.cpp b/src/games/cclcc/yesnotrigger.cpp index 46b543335..f3c05b4d0 100644 --- a/src/games/cclcc/yesnotrigger.cpp +++ b/src/games/cclcc/yesnotrigger.cpp @@ -299,11 +299,9 @@ void YesNoTrigger::Render() { // Can't simply use ActiveBlur.Bounds due to some sprites having a // non-zero Y coordinate, so you don't want to additionally correct for it // via matrix - Renderer->DrawMaskedSpriteOverlay( - ActiveBlur, YesNoBlurMask, - RectF(0.0f, 0.0f, ActiveBlur.Bounds.Width, ActiveBlur.Bounds.Height), - YesNoBlurMask.Bounds, static_cast(alpha), 255, blurTransform, - maskTransform, glm::vec4(1.0f), true, true); + Renderer->DrawMaskedSprite( + {ActiveBlur, YesNoBlurMask, blurTransform, maskTransform}, + {.Alpha = alpha, .FadeRange = 255.0f, .IsInverted = true}); if (DispSel) { glm::vec2 yesChipPos = (DispPosArr[TargetArrIndex].ChipYesPos - diff --git a/src/games/chlcc/commonmenu.cpp b/src/games/chlcc/commonmenu.cpp index 2a1b60a51..e902c0f09 100644 --- a/src/games/chlcc/commonmenu.cpp +++ b/src/games/chlcc/commonmenu.cpp @@ -221,12 +221,14 @@ void CommonMenu::UpdateTitles(glm::vec2 rightTitlepos, glm::vec2 leftTitlePos, } void CommonMenu::DrawBackgroundFilter() { - Renderer->CaptureScreencap(ShaderScreencapture.BgSprite); + Renderer->CaptureScreenCap(ShaderScreencapture.CaptureTexture); Renderer->DrawCHLCCMenuBackground( - ShaderScreencapture.BgSprite, BackgroundFilter, - RectF(0.0f, 0.0f, Profile::Game::DesignWidth, - Profile::Game::DesignHeight), - std::clamp(MenuTransition.Progress * 2.0f, 0.0f, 1.0f)); + {*ShaderScreencapture.CaptureTexture, BackgroundFilter, + RectF(0.0f, 0.0f, Profile::Game::DesignWidth, + Profile::Game::DesignHeight), + glm::mat4(1.0f), glm::mat4(1.0f), + glm::vec4(1.0f, 1.0f, 1.0f, + std::clamp(MenuTransition.Progress * 2.0f, 0.0f, 1.0f))}); } } // namespace CHLCC diff --git a/src/games/chlcc/delusiontrigger.cpp b/src/games/chlcc/delusiontrigger.cpp index 14fcebf8c..83b9a3150 100644 --- a/src/games/chlcc/delusiontrigger.cpp +++ b/src/games/chlcc/delusiontrigger.cpp @@ -517,9 +517,11 @@ void DelusionTrigger::Render() { glm::vec4(1.0f, 1.0f, 1.0f, (BackgroundAlpha * 160) / 65536.0f)); TextSystem.Render(); - Renderer->DrawMaskedSpriteOverlay(BackgroundSprite, ScaledMask, spriteDest, - maskDest, (BackgroundAlpha * 160) >> 8, 20, - glm::mat4(1.0f), glm::vec4(1.0f), true); + Renderer->DrawMaskedSprite( + {BackgroundSprite, BackgroundSpriteMask, maskDest, spriteDest}, + {.Alpha = static_cast((BackgroundAlpha * 160) >> 8), + .FadeRange = 20.0f, + .IsInverted = true}); if (Profile::Patch::HasDelusionMouseSupport && UserConfig::EnhancementsSettings.CHLCC.DelusionMousePatch && HeartButtonFade.Progress > 0.0f) { diff --git a/src/games/chlcc/introsequence.cpp b/src/games/chlcc/introsequence.cpp index 5bab25f4b..14dc708d3 100644 --- a/src/games/chlcc/introsequence.cpp +++ b/src/games/chlcc/introsequence.cpp @@ -14,16 +14,6 @@ namespace Impacto { namespace CHLCC { IntroSequence::IntroSequence() { - const RectF viewport = Window->GetViewport(); - Texture fallingStarsMaskTexture{}; - fallingStarsMaskTexture.LoadSolidColor(static_cast(viewport.Width), - static_cast(viewport.Height), 0); - SpriteSheet fallingStarsMaskSheet(viewport.Width, viewport.Height); - fallingStarsMaskSheet.Texture = fallingStarsMaskTexture.Submit(); - fallingStarsMaskSheet.IsScreenCap = true; - FallingStarsMask = - Sprite(fallingStarsMaskSheet, 0, 0, viewport.Width, viewport.Height); - // Randomize falling stars for (size_t i = 0; i < FallingStarSeeds.size(); i++) { auto& [origin, angle] = FallingStarSeeds[i]; @@ -98,10 +88,6 @@ IntroSequence::IntroSequence() { IntroAnimation.AddAnimation(CopyrightAnimation); } -IntroSequence::~IntroSequence() { - Renderer->FreeTexture(FallingStarsMask.Sheet.Texture); -} - void IntroSequence::Reset() { IntroAnimation.Reset(); } void IntroSequence::Update(float dt) { @@ -127,24 +113,24 @@ void IntroSequence::Render() { } else if (FallingStarsAnimation.State == AnimationState::Playing) { // Make sure the mask is the only thing in the color buffer Renderer->Clear(glm::vec4(0.0f)); - Renderer->DrawSprite(FallingStarsMask, - RectF{0.0f, 0.0f, DesignWidth, DesignHeight}); + Renderer->DrawSprite( + {*FallingStarsMask, RectF{0.0f, 0.0f, DesignWidth, DesignHeight}}); // Draw the stars over the mask // effectively obtaining the union DrawFallingStars(); // Update the mask by rendering to the texture - Renderer->CaptureScreencap(FallingStarsMask); + Renderer->CaptureScreenCap(FallingStarsMask); // Draw the original background // this will be visible through the holes in the mask DrawBackground(); // Draw the new background with the mask - Renderer->DrawMaskedSprite(BackgroundSprite, FallingStarsMask, - RectF{0.0f, 0.0f, DesignWidth, DesignHeight}, - 255, 256); + Renderer->DrawMaskedSprite({BackgroundSprite, *FallingStarsMask, + RectF{0.0f, 0.0f, DesignWidth, DesignHeight}}, + {.Alpha = 255.0f, .FadeRange = 256.0f}); // Draw the stars again, not to the mask this time DrawFallingStars(); @@ -185,7 +171,8 @@ void IntroSequence::DrawBackground() const { glm::vec2 zoomFactor = designDimensions / 16.0f + designDimensions / 16.0f * 7.0f * progress; - Renderer->SetBlendMode(RendererBlendMode::Additive); + using BlendModeType = BaseRenderer::StateConfig::BlendModeType; + Renderer->SetBlendMode(BlendModeType::Additive); for (size_t i = 0; i < IntroHighlightCount; i++) { constexpr float scale = 1.5f; @@ -201,17 +188,18 @@ void IntroSequence::DrawBackground() const { Renderer->DrawSprite(sprite, dest, glm::vec4(1.0f)); } - Renderer->SetBlendMode(RendererBlendMode::Normal); + Renderer->SetBlendMode(BlendModeType::Normal); - Renderer->CaptureScreencap(ShaderScreencapture.BgSprite); + Renderer->CaptureScreenCap(ShaderScreencapture.CaptureTexture); // Cross-fade from black Renderer->DrawQuad(RectF{0.0f, 0.0f, DesignWidth, DesignHeight}, {0.0f, 0.0f, 0.0f, 1.0f}); const float scale = 4 / (progress * 3 + 1); - RectF dest = ShaderScreencapture.BgSprite.ScaledBounds().Scale( - glm::vec2(scale), glm::vec2(0.0f)); + const RectF dest = + RectF{0.0f, 0.0f, Profile::Game::DesignWidth, Profile::Game::DesignHeight} + .Scale(glm::vec2(scale), glm::vec2(0.0f)); Renderer->DrawSprite(ShaderScreencapture.BgSprite, dest, {1.0f, 1.0f, 1.0f, progress}); @@ -244,7 +232,8 @@ void IntroSequence::DrawBouncingStar() const { } void IntroSequence::DrawExplodingStars() const { - Renderer->SetBlendMode(RendererBlendMode::Additive); + using BlendModeType = BaseRenderer::StateConfig::BlendModeType; + Renderer->SetBlendMode(BlendModeType::Additive); glm::vec2 origin = glm::vec2(DesignWidth, DesignHeight) / 2.0f - IntroExplodingStarSprite.Bounds.GetSize() / 2.0f; @@ -272,7 +261,7 @@ void IntroSequence::DrawExplodingStars() const { {1.0f, 1.0f, 1.0f, opacity}); } - Renderer->SetBlendMode(RendererBlendMode::Normal); + Renderer->SetBlendMode(BlendModeType::Normal); } void IntroSequence::DrawFallingStars() const { diff --git a/src/games/chlcc/introsequence.h b/src/games/chlcc/introsequence.h index 2b9452127..d8d37f3bb 100644 --- a/src/games/chlcc/introsequence.h +++ b/src/games/chlcc/introsequence.h @@ -11,7 +11,6 @@ namespace CHLCC { class IntroSequence { public: IntroSequence(); - ~IntroSequence(); void Update(float dt); void Reset(); @@ -45,7 +44,7 @@ class IntroSequence { void DrawSeira() const; std::array, 20> FallingStarSeeds; - Sprite FallingStarsMask; + MutableTextureRef FallingStarsMask; }; } // namespace CHLCC diff --git a/src/games/chlcc/savesystem.cpp b/src/games/chlcc/savesystem.cpp index 5f85e30c4..758b0f89b 100644 --- a/src/games/chlcc/savesystem.cpp +++ b/src/games/chlcc/savesystem.cpp @@ -526,12 +526,14 @@ SaveError SaveSystem::MountSaveFile(std::vector& textures) { WorkingSaveThumbnail.Bounds = RectF(0.0f, 0.0f, viewport.Width, viewport.Height); - QueuedTexture txt{ - .Id = std::ref(WorkingSaveThumbnail.Sheet.Texture), - }; - txt.Tex.LoadSolidColor((int)WorkingSaveThumbnail.Bounds.Width, - (int)WorkingSaveThumbnail.Bounds.Height, 0x000000); - textures.push_back(txt); + { + QueuedTexture txt{ + .Reference = WorkingSaveThumbnail.Sheet.Texture, + }; + txt.Tex.LoadSolidColor((int)WorkingSaveThumbnail.Bounds.Width, + (int)WorkingSaveThumbnail.Bounds.Height, 0x000000); + textures.emplace_back(std::move(txt)); + } stream->Seek(0x0, SEEK_SET); const uint8_t readFileSystemChecksumSum = Io::ReadU8(stream); @@ -650,7 +652,7 @@ SaveError SaveSystem::MountSaveFile(std::vector& textures) { } QueuedTexture texture{ - .Id = std::ref(entry->SaveThumbnail.Sheet.Texture), + .Reference = entry->SaveThumbnail.Sheet.Texture, }; texture.Tex.Init(TexFmt_RGB, SaveThumbnailWidth, SaveThumbnailHeight); @@ -665,7 +667,7 @@ SaveError SaveSystem::MountSaveFile(std::vector& textures) { texture.Tex.Buffer.assign(entry->ThumbnailData.begin(), entry->ThumbnailData.end()); - textures.push_back(texture); + textures.emplace_back(std::move(texture)); std::tie(calcFileThumbnailsChecksumSum, calcFileThumbnailsChecksumXor) = CalculateFileChecksum(entry->ThumbnailData, diff --git a/src/games/chlcc/sysmesbox.cpp b/src/games/chlcc/sysmesbox.cpp index a24486784..c039cad92 100644 --- a/src/games/chlcc/sysmesbox.cpp +++ b/src/games/chlcc/sysmesbox.cpp @@ -32,9 +32,6 @@ void SysMesBox::Show() { MessageItems = std::make_unique(this); ChoiceItems = std::make_unique(this); - Sprite nullSprite = Sprite(); - nullSprite.Bounds = RectF(0.0f, 0.0f, 0.0f, 0.0f); - auto onClick = [this](auto* btn) { return ChoiceItemOnClick(btn); }; float diff = 0.0f; @@ -72,8 +69,7 @@ void SysMesBox::Show() { } Button* choice = new SystemMessageButton( - i, nullSprite, nullSprite, SelectionLeftPart, SelectionMiddlePart, - SelectionRightPart, + i, SelectionLeftPart, SelectionMiddlePart, SelectionRightPart, glm::vec2(Choices[i][0].DestRect.X, Choices[i][0].DestRect.Y)); choice->HighlightOffset = glm::vec2(HighlightXOffset, HighlightYOffset); diff --git a/src/games/chlcc/systemmenu.cpp b/src/games/chlcc/systemmenu.cpp index 539669c62..3f7f803ed 100644 --- a/src/games/chlcc/systemmenu.cpp +++ b/src/games/chlcc/systemmenu.cpp @@ -57,7 +57,7 @@ SystemMenu::SystemMenu() : CommonMenu(false) { for (int i = 0; i < MenuEntriesNum; i++) { SystemMenuEntryButton* menuButton = new SystemMenuEntryButton( i, MenuEntriesSprites[i], MenuEntriesSprites[i], - RgbIntToFloat(FocusTint), Sprite(), MenuEntriesPositions[i], + RgbIntToFloat(FocusTint), MenuEntriesPositions[i], RectF( MenuEntriesPositions[i].x - 30, (i + 1) * MenuSelectionDotMultiplier + MenuSelectionPosition.y - 14, diff --git a/src/games/darling/sysmesbox.cpp b/src/games/darling/sysmesbox.cpp index fe7a1465b..d4e195a51 100644 --- a/src/games/darling/sysmesbox.cpp +++ b/src/games/darling/sysmesbox.cpp @@ -25,9 +25,6 @@ void SysMesBox::Show() { MessageItems = std::make_unique(this); ChoiceItems = std::make_unique(this); - Sprite nullSprite = Sprite(); - nullSprite.Bounds = RectF(0.0f, 0.0f, 0.0f, 0.0f); - auto onClick = [this](auto* btn) { return ChoiceItemOnClick(btn); }; float diff = 0.0f; @@ -72,7 +69,7 @@ void SysMesBox::Show() { } Button* choice = new Button( - i, nullSprite, nullSprite, SelectionHighlight, + i, std::nullopt, std::nullopt, SelectionHighlight, glm::vec2(Choices[i][0].DestRect.X, Choices[i][0].DestRect.Y)); choice->SetText(Choices[i], ChoiceWidths[i], diff --git a/src/games/mo6tw/albummenu.cpp b/src/games/mo6tw/albummenu.cpp index a7c40ff53..96c8c11fb 100644 --- a/src/games/mo6tw/albummenu.cpp +++ b/src/games/mo6tw/albummenu.cpp @@ -104,16 +104,13 @@ AlbumMenu::AlbumMenu() { Arrows = new Group(this); Arrows->FocusLock = false; - Sprite nullSprite = Sprite(); - nullSprite.Bounds = RectF(0.0f, 0.0f, 0.0f, 0.0f); - ArrowUpButton = new Button(0, ArrowUp, ArrowUp, nullSprite, ArrowUpPosition); - ArrowUpButton->DisabledSprite = nullSprite; + ArrowUpButton = + new Button(0, ArrowUp, ArrowUp, std::nullopt, ArrowUpPosition); ArrowUpButton->OnClickHandler = [this](auto* btn) { return ArrowUpOnClick(btn); }; ArrowDownButton = - new Button(1, ArrowDown, ArrowDown, nullSprite, ArrowDownPosition); - ArrowDownButton->DisabledSprite = nullSprite; + new Button(1, ArrowDown, ArrowDown, std::nullopt, ArrowDownPosition); ArrowDownButton->OnClickHandler = [this](auto* btn) { return ArrowDownOnClick(btn); }; diff --git a/src/games/mo6tw/clearlistmenu.cpp b/src/games/mo6tw/clearlistmenu.cpp index 8f85c70ef..ab49352a5 100644 --- a/src/games/mo6tw/clearlistmenu.cpp +++ b/src/games/mo6tw/clearlistmenu.cpp @@ -51,15 +51,13 @@ ClearListMenu::ClearListMenu() { Arrows = new Group(this); Arrows->FocusLock = false; - Sprite nullSprite = Sprite(); - nullSprite.Bounds = RectF(0.0f, 0.0f, 0.0f, 0.0f); auto arrowLeft = - new Button(0, ArrowLeft, ArrowLeft, nullSprite, ArrowLeftPosition); + new Button(0, ArrowLeft, ArrowLeft, std::nullopt, ArrowLeftPosition); arrowLeft->OnClickHandler = [this](auto* btn) { return ArrowLeftOnClick(btn); }; auto arrowRight = - new Button(1, ArrowRight, ArrowRight, nullSprite, ArrowRightPosition); + new Button(1, ArrowRight, ArrowRight, std::nullopt, ArrowRightPosition); arrowRight->OnClickHandler = [this](auto* btn) { return ArrowRightOnClick(btn); }; diff --git a/src/games/mo6tw/moviemenu.cpp b/src/games/mo6tw/moviemenu.cpp index 002aa33dc..cd4fe8acf 100644 --- a/src/games/mo6tw/moviemenu.cpp +++ b/src/games/mo6tw/moviemenu.cpp @@ -35,10 +35,8 @@ MovieMenu::MovieMenu() { auto pos = InitialItemPosition; - Sprite nullSprite = Sprite(); - nullSprite.Bounds = RectF(0.0f, 0.0f, 0.0f, 0.0f); auto firstOp = new Widgets::MO6TW::ImageThumbnailButton( - 0, FirstOPTopPartSprite, FirstOPBottomPartSprite, nullSprite, + 0, FirstOPTopPartSprite, FirstOPBottomPartSprite, std::nullopt, SelectionHighlightTopLeft, SelectionHighlightTopRight, SelectionHighlightBottomLeft, SelectionHighlightBottomRight, pos); firstOp->OnClickHandler = onClick; @@ -47,7 +45,7 @@ MovieMenu::MovieMenu() { pos.x += ItemOffset.x; auto secondOp = new Widgets::MO6TW::ImageThumbnailButton( - 1, SecondOPTopPartSprite, SecondOPBottomPartSprite, nullSprite, + 1, SecondOPTopPartSprite, SecondOPBottomPartSprite, std::nullopt, SelectionHighlightTopLeft, SelectionHighlightTopRight, SelectionHighlightBottomLeft, SelectionHighlightBottomRight, pos); secondOp->OnClickHandler = onClick; diff --git a/src/games/mo6tw/musicmenu.cpp b/src/games/mo6tw/musicmenu.cpp index 4e7b29872..f58a2ea1a 100644 --- a/src/games/mo6tw/musicmenu.cpp +++ b/src/games/mo6tw/musicmenu.cpp @@ -43,11 +43,9 @@ MusicMenu::MusicMenu() { BackgroundItems->Add(new Label(ItemsWindow, ItemsWindowPosition)); BackgroundItems->Add(new Label(PlaybackWindow, PlaybackWindowPosition)); - NullSprite = Sprite(); - NullSprite.Bounds = RectF(0.0f, 0.0f, 0.0f, 0.0f); - Thumbnail = new Label(NullSprite, ThumbnailPosition); + Thumbnail = new Label(std::nullopt, ThumbnailPosition); BackgroundItems->Add(Thumbnail); - CurrentlyPlaying = new Label(NullSprite, CurrentlyPlayingLabelPosition); + CurrentlyPlaying = new Label(std::nullopt, CurrentlyPlayingLabelPosition); BackgroundItems->Add(CurrentlyPlaying); PlaybackModeLabel = new Label(PlaybackModeLabels[PlaybackMode], PlaybackModeLabelPosition); @@ -83,7 +81,7 @@ MusicMenu::MusicMenu() { pos = TimerInitialPosition; for (int i = 0; i < 8; i++) { - Timer->Add(new Label(NullSprite, pos)); + Timer->Add(new Label(std::nullopt, pos)); pos += TimerMargin; } } @@ -240,8 +238,8 @@ void MusicMenu::SwitchToTrack(int id) { CurrentlyPlayingTrackId = id; if (id == -1) { Audio::Channels[Audio::AC_BGM0]->Stop(0.5f); - Thumbnail->SetSprite(NullSprite); - CurrentlyPlaying->SetSprite(NullSprite); + Thumbnail->SetSprite(std::nullopt); + CurrentlyPlaying->SetSprite(std::nullopt); Timer->Hide(); return; } diff --git a/src/games/mo6tw/musicmenu.h b/src/games/mo6tw/musicmenu.h index f54aba358..399729662 100644 --- a/src/games/mo6tw/musicmenu.h +++ b/src/games/mo6tw/musicmenu.h @@ -41,7 +41,6 @@ class MusicMenu : public Menu { Widgets::Label* CurrentlyPlaying; Widgets::Label* PlaybackModeLabel; Animation FadeAnimation; - Sprite NullSprite; float MusicListY; MusicPlaybackMode PlaybackMode = MPM_One; diff --git a/src/games/mo6tw/savemenu.cpp b/src/games/mo6tw/savemenu.cpp index 60e75eb1e..3a327af3c 100644 --- a/src/games/mo6tw/savemenu.cpp +++ b/src/games/mo6tw/savemenu.cpp @@ -55,8 +55,6 @@ void SaveMenu::Show() { Sprite entrySprite; Sprite entryHSprite; - Sprite nullSprite = Sprite(); - nullSprite.Bounds = RectF(0.0f, 0.0f, 0.0f, 0.0f); switch (*ActiveMenuType) { case SaveMenuPageType::QuickLoad: @@ -76,7 +74,7 @@ void SaveMenu::Show() { for (int i = 0; i < RowsPerPage; i++) { for (int j = 0; j < EntriesPerRow; j++) { SaveEntryButton* saveEntryButton = - new SaveEntryButton(id, entrySprite, entryHSprite, nullSprite, + new SaveEntryButton(id, entrySprite, entryHSprite, glm::vec2(EntryStartX + (j * EntryXPadding), EntryStartY + (i * EntryYPadding))); diff --git a/src/games/mo6tw/savesystem.cpp b/src/games/mo6tw/savesystem.cpp index 9e25cc689..f633bcb48 100644 --- a/src/games/mo6tw/savesystem.cpp +++ b/src/games/mo6tw/savesystem.cpp @@ -92,12 +92,14 @@ SaveError SaveSystem::MountSaveFile(std::vector& textures) { WorkingSaveThumbnail.Bounds = RectF(0.0f, 0.0f, viewport.Width, viewport.Height); - QueuedTexture txt = { - .Id = std::ref(WorkingSaveThumbnail.Sheet.Texture), - }; - txt.Tex.LoadSolidColor((int)WorkingSaveThumbnail.Bounds.Width, - (int)WorkingSaveThumbnail.Bounds.Height, 0x000000); - textures.push_back(txt); + { + QueuedTexture txt = { + .Reference = WorkingSaveThumbnail.Sheet.Texture, + }; + txt.Tex.LoadSolidColor((int)WorkingSaveThumbnail.Bounds.Width, + (int)WorkingSaveThumbnail.Bounds.Height, 0x000000); + textures.push_back(std::move(txt)); + } Io::ReadArrayLE(SystemData.data(), stream, SystemData.size()); @@ -227,7 +229,7 @@ void SaveSystem::FlushWorkingSaveEntry(SaveType type, int id, if (WorkingSaveEntry != 0) { if (entry != 0 && !(entry->Flags & WriteProtect)) { - Renderer->FreeTexture(entry->SaveThumbnail.Sheet.Texture); + entry->SaveThumbnail.Sheet.Texture = TextureRef{}; if (type == SaveType::Quick) { entry->SaveType = autoSaveType; UpdateQuickSaveRecentSortedId(id); diff --git a/src/games/mo6tw/sysmesbox.cpp b/src/games/mo6tw/sysmesbox.cpp index 3bba0b996..d039dcb98 100644 --- a/src/games/mo6tw/sysmesbox.cpp +++ b/src/games/mo6tw/sysmesbox.cpp @@ -25,9 +25,6 @@ void SysMesBox::Show() { MessageItems = std::make_unique(this); ChoiceItems = std::make_unique(this); - Sprite nullSprite = Sprite(); - nullSprite.Bounds = RectF(0.0f, 0.0f, 0.0f, 0.0f); - auto onClick = [this](auto* btn) { return ChoiceItemOnClick(btn); }; float diff = 0.0f; @@ -72,7 +69,7 @@ void SysMesBox::Show() { } Button* choice = new Button( - i, nullSprite, nullSprite, SelectionHighlight, + i, std::nullopt, std::nullopt, SelectionHighlight, glm::vec2(Choices[i][0].DestRect.X, Choices[i][0].DestRect.Y)); choice->SetText(Choices[i], ChoiceWidths[i], diff --git a/src/games/mo6tw/titlemenu.cpp b/src/games/mo6tw/titlemenu.cpp index 5ca3b1292..8d155d82b 100644 --- a/src/games/mo6tw/titlemenu.cpp +++ b/src/games/mo6tw/titlemenu.cpp @@ -44,19 +44,16 @@ TitleMenu::TitleMenu() { return SecondaryButtonOnClick(btn); }; - Sprite nullSprite = Sprite(); - nullSprite.Bounds = RectF(0.0f, 0.0f, 0.0f, 0.0f); - // Initial Start menu button InitialStart = new TitleButton(0, MenuEntriesSprites[0], MenuEntriesHSprites[0], - nullSprite, glm::vec2(MenuEntriesX, MenuEntriesFirstY)); + glm::vec2(MenuEntriesX, MenuEntriesFirstY)); InitialStart->OnClickHandler = onClick; MainItems->Add(InitialStart, FDIR_DOWN); // Lockable Extra Story menu button ExtraStory = new TitleButton( - 1, MenuEntriesSprites[1], MenuEntriesHSprites[1], nullSprite, + 1, MenuEntriesSprites[1], MenuEntriesHSprites[1], glm::vec2(MenuEntriesX, MenuEntriesFirstY + (1 * MenuEntriesYPadding))); ExtraStory->Enabled = false; ExtraStory->OnClickHandler = onClick; @@ -65,14 +62,14 @@ TitleMenu::TitleMenu() { // Continue menu button Continue = new TitleButton( - 2, MenuEntriesSprites[2], MenuEntriesHSprites[2], nullSprite, + 2, MenuEntriesSprites[2], MenuEntriesHSprites[2], glm::vec2(MenuEntriesX, MenuEntriesFirstY + (2 * MenuEntriesYPadding))); Continue->OnClickHandler = onClick; MainItems->Add(Continue, FDIR_DOWN); // Lockable Memories menu button Memories = new TitleButton( - 3, MenuEntriesSprites[3], MenuEntriesHSprites[3], nullSprite, + 3, MenuEntriesSprites[3], MenuEntriesHSprites[3], glm::vec2(MenuEntriesX, MenuEntriesFirstY + (3 * MenuEntriesYPadding))); Memories->Enabled = false; Memories->OnClickHandler = onClick; @@ -81,114 +78,114 @@ TitleMenu::TitleMenu() { // Encyclopedia menu button Encyclopedia = new TitleButton( - 4, MenuEntriesSprites[4], MenuEntriesHSprites[4], nullSprite, + 4, MenuEntriesSprites[4], MenuEntriesHSprites[4], glm::vec2(MenuEntriesX, MenuEntriesFirstY + (4 * MenuEntriesYPadding))); Encyclopedia->OnClickHandler = onClick; MainItems->Add(Encyclopedia, FDIR_DOWN); // System menu button System = new TitleButton( - 5, MenuEntriesSprites[5], MenuEntriesHSprites[5], nullSprite, + 5, MenuEntriesSprites[5], MenuEntriesHSprites[5], glm::vec2(MenuEntriesX, MenuEntriesFirstY + (5 * MenuEntriesYPadding))); System->OnClickHandler = onClick; MainItems->Add(System, FDIR_DOWN); // Exit menu button Exit = new TitleButton( - 6, MenuEntriesSprites[6], MenuEntriesHSprites[6], nullSprite, + 6, MenuEntriesSprites[6], MenuEntriesHSprites[6], glm::vec2(MenuEntriesX, MenuEntriesFirstY + (6 * MenuEntriesYPadding))); Exit->OnClickHandler = onClick; MainItems->Add(Exit, FDIR_DOWN); // Load secondary Continue menu button Load = new TitleButton( - 0, MenuEntriesSprites[10], MenuEntriesHSprites[10], nullSprite, + 0, MenuEntriesSprites[10], MenuEntriesHSprites[10], glm::vec2(MenuEntriesX, MenuEntriesFirstY + (3 * MenuEntriesYPadding))); Load->OnClickHandler = secondaryOnClick; ContinueItems->Add(Load, FDIR_DOWN); // Quick Load secondary Continue menu button - QuickLoad = new TitleButton( - 1, MenuEntriesSprites[11], MenuEntriesHSprites[11], nullSprite, - glm::vec2(MenuEntriesX - 20.0f, - MenuEntriesFirstY + (4 * MenuEntriesYPadding))); + QuickLoad = + new TitleButton(1, MenuEntriesSprites[11], MenuEntriesHSprites[11], + glm::vec2(MenuEntriesX - 20.0f, + MenuEntriesFirstY + (4 * MenuEntriesYPadding))); QuickLoad->OnClickHandler = secondaryOnClick; ContinueItems->Add(QuickLoad, FDIR_DOWN); // Prologue secondary Extra Story menu button Prologue = new TitleButton( - 0, MenuEntriesSprites[7], MenuEntriesHSprites[7], nullSprite, + 0, MenuEntriesSprites[7], MenuEntriesHSprites[7], glm::vec2(MenuEntriesX, MenuEntriesFirstY + (2 * MenuEntriesYPadding))); Prologue->OnClickHandler = secondaryOnClick; ExtraStoryItems->Add(Prologue, FDIR_DOWN); // Otome Judge feat.Shin secondary Extra Story menu button - OtomeJudgeShin = new TitleButton( - 1, MenuEntriesSprites[8], MenuEntriesHSprites[8], nullSprite, - glm::vec2(MenuEntriesX - 20.0f, - MenuEntriesFirstY + (3 * MenuEntriesYPadding))); + OtomeJudgeShin = + new TitleButton(1, MenuEntriesSprites[8], MenuEntriesHSprites[8], + glm::vec2(MenuEntriesX - 20.0f, + MenuEntriesFirstY + (3 * MenuEntriesYPadding))); OtomeJudgeShin->OnClickHandler = secondaryOnClick; ExtraStoryItems->Add(OtomeJudgeShin, FDIR_DOWN); // Warning secondary Extra Story menu button - Warning = new TitleButton( - 2, MenuEntriesSprites[9], MenuEntriesHSprites[9], nullSprite, - glm::vec2(MenuEntriesX - 40.0f, - MenuEntriesFirstY + (4 * MenuEntriesYPadding))); + Warning = + new TitleButton(2, MenuEntriesSprites[9], MenuEntriesHSprites[9], + glm::vec2(MenuEntriesX - 40.0f, + MenuEntriesFirstY + (4 * MenuEntriesYPadding))); Warning->OnClickHandler = secondaryOnClick; ExtraStoryItems->Add(Warning, FDIR_DOWN); // Warning secondary Extra Story menu button ClearList = new TitleButton( - 0, MenuEntriesSprites[13], MenuEntriesHSprites[13], nullSprite, + 0, MenuEntriesSprites[13], MenuEntriesHSprites[13], glm::vec2(MenuEntriesX, MenuEntriesFirstY + (4 * MenuEntriesYPadding))); ClearList->OnClickHandler = secondaryOnClick; MemoriesItems->Add(ClearList, FDIR_DOWN); // Warning secondary Extra Story menu button - Album = new TitleButton( - 1, MenuEntriesSprites[14], MenuEntriesHSprites[14], nullSprite, - glm::vec2(MenuEntriesX - 20.0f, - MenuEntriesFirstY + (5 * MenuEntriesYPadding))); + Album = + new TitleButton(1, MenuEntriesSprites[14], MenuEntriesHSprites[14], + glm::vec2(MenuEntriesX - 20.0f, + MenuEntriesFirstY + (5 * MenuEntriesYPadding))); Album->OnClickHandler = secondaryOnClick; MemoriesItems->Add(Album, FDIR_DOWN); // Warning secondary Extra Story menu button - Music = new TitleButton( - 2, MenuEntriesSprites[15], MenuEntriesHSprites[15], nullSprite, - glm::vec2(MenuEntriesX - 40.0f, - MenuEntriesFirstY + (6 * MenuEntriesYPadding))); + Music = + new TitleButton(2, MenuEntriesSprites[15], MenuEntriesHSprites[15], + glm::vec2(MenuEntriesX - 40.0f, + MenuEntriesFirstY + (6 * MenuEntriesYPadding))); Music->OnClickHandler = secondaryOnClick; MemoriesItems->Add(Music, FDIR_DOWN); // Warning secondary Extra Story menu button - Movie = new TitleButton( - 3, MenuEntriesSprites[16], MenuEntriesHSprites[16], nullSprite, - glm::vec2(MenuEntriesX - 60.0f, - MenuEntriesFirstY + (7 * MenuEntriesYPadding))); + Movie = + new TitleButton(3, MenuEntriesSprites[16], MenuEntriesHSprites[16], + glm::vec2(MenuEntriesX - 60.0f, + MenuEntriesFirstY + (7 * MenuEntriesYPadding))); Movie->OnClickHandler = secondaryOnClick; MemoriesItems->Add(Movie, FDIR_DOWN); // Warning secondary Extra Story menu button - ActorsVoice = new TitleButton( - 4, MenuEntriesSprites[17], MenuEntriesHSprites[17], nullSprite, - glm::vec2(MenuEntriesX - 80.0f, - MenuEntriesFirstY + (8 * MenuEntriesYPadding))); + ActorsVoice = + new TitleButton(4, MenuEntriesSprites[17], MenuEntriesHSprites[17], + glm::vec2(MenuEntriesX - 80.0f, + MenuEntriesFirstY + (8 * MenuEntriesYPadding))); ActorsVoice->OnClickHandler = secondaryOnClick; MemoriesItems->Add(ActorsVoice, FDIR_DOWN); // Option secondary System menu button Option = new TitleButton( - 0, MenuEntriesSprites[18], MenuEntriesHSprites[18], nullSprite, + 0, MenuEntriesSprites[18], MenuEntriesHSprites[18], glm::vec2(MenuEntriesX, MenuEntriesFirstY + (6 * MenuEntriesYPadding))); Option->OnClickHandler = secondaryOnClick; SystemItems->Add(Option, FDIR_DOWN); // System Save secondary System menu button - SystemSave = new TitleButton( - 1, MenuEntriesSprites[20], MenuEntriesHSprites[20], nullSprite, - glm::vec2(MenuEntriesX - 20.0f, - MenuEntriesFirstY + (7 * MenuEntriesYPadding))); + SystemSave = + new TitleButton(1, MenuEntriesSprites[20], MenuEntriesHSprites[20], + glm::vec2(MenuEntriesX - 20.0f, + MenuEntriesFirstY + (7 * MenuEntriesYPadding))); SystemSave->OnClickHandler = secondaryOnClick; SystemItems->Add(SystemSave, FDIR_DOWN); } @@ -380,25 +377,27 @@ void TitleMenu::Render() { switch (ScrWork[SW_TITLEDISPCT]) { case 0: // Initial animation Renderer->DrawMaskedSprite( - BackgroundSprite, BackgroundSprite, - RectF(0.0f, 0.0f, BackgroundSprite.ScaledWidth(), - BackgroundSprite.ScaledHeight()), - (ScrWork[SW_TITLECT] * 287) / 48, 32, glm::mat4(1.0f), - glm::vec4(1.0f), false, true); + {BackgroundSprite, BackgroundSprite, + RectF(0.0f, 0.0f, BackgroundSprite.ScaledWidth(), + BackgroundSprite.ScaledHeight())}, + {.Alpha = static_cast((ScrWork[SW_TITLECT] * 287) / 48), + .FadeRange = 32.0f}); if (ScrWork[SW_TITLECT] > 48) { Renderer->DrawMaskedSprite( - LogoSprite, Masks2D[17].MaskSprite, - RectF(LogoX, LogoY, LogoSprite.ScaledWidth(), - LogoSprite.ScaledHeight()), - (ScrWork[SW_TITLECT] * 271 - 13008) / 32, 16); + {LogoSprite, Masks2D[17].MaskSprite, + RectF(LogoX, LogoY, LogoSprite.ScaledWidth(), + LogoSprite.ScaledHeight())}, + {.Alpha = static_cast( + (ScrWork[SW_TITLECT] * 271 - 13008) / 32), + .FadeRange = 16.0f}); } break; case 1: { // Press to start Renderer->DrawMaskedSprite( - BackgroundSprite, BackgroundSprite, - RectF(0.0f, 0.0f, BackgroundSprite.ScaledWidth(), - BackgroundSprite.ScaledHeight()), - 287, 32, glm::mat4(1.0f), glm::vec4(1.0f), false, true); + {BackgroundSprite, BackgroundSprite, + RectF(0.0f, 0.0f, BackgroundSprite.ScaledWidth(), + BackgroundSprite.ScaledHeight())}, + {.Alpha = 287.0f, .FadeRange = 32.0f}); Renderer->DrawSprite(LogoSprite, glm::vec2(LogoX, LogoY)); Renderer->DrawSprite(CopyrightSprite, glm::vec2(CopyrightX, CopyrightY)); @@ -408,10 +407,10 @@ void TitleMenu::Render() { } break; case 2: { Renderer->DrawMaskedSprite( - BackgroundSprite, BackgroundSprite, - RectF(0.0f, 0.0f, BackgroundSprite.ScaledWidth(), - BackgroundSprite.ScaledHeight()), - 287, 32, glm::mat4(1.0f), glm::vec4(1.0f), false, true); + {BackgroundSprite, BackgroundSprite, + RectF(0.0f, 0.0f, BackgroundSprite.ScaledWidth(), + BackgroundSprite.ScaledHeight())}, + {.Alpha = 287.0f, .FadeRange = 32.0f}); Renderer->DrawSprite(LogoSprite, glm::vec2(LogoX, LogoY)); Renderer->DrawSprite(CopyrightSprite, glm::vec2(CopyrightX, CopyrightY)); @@ -419,72 +418,72 @@ void TitleMenu::Render() { case 3: // Main Menu Fade In case 4: { // Main Menu Renderer->DrawMaskedSprite( - MenuBackgroundSprite, MenuBackgroundSprite, - RectF(0.0f, 0.0f, MenuBackgroundSprite.ScaledWidth(), - MenuBackgroundSprite.ScaledHeight()), - 287, 32, glm::mat4(1.0f), glm::vec4(1.0f), false, true); + {MenuBackgroundSprite, MenuBackgroundSprite, + RectF(0.0f, 0.0f, MenuBackgroundSprite.ScaledWidth(), + MenuBackgroundSprite.ScaledHeight())}, + {.Alpha = 287.0f, .FadeRange = 32.0f}); MainItems->Render(); } break; case 5: // Secondary menu Extra story Fade In case 6: { // Secondary menu Extra story Renderer->DrawMaskedSprite( - MenuBackgroundSprite, MenuBackgroundSprite, - RectF(0.0f, 0.0f, MenuBackgroundSprite.ScaledWidth(), - MenuBackgroundSprite.ScaledHeight()), - 287, 32, glm::mat4(1.0f), glm::vec4(1.0f), false, true); + {MenuBackgroundSprite, MenuBackgroundSprite, + RectF(0.0f, 0.0f, MenuBackgroundSprite.ScaledWidth(), + MenuBackgroundSprite.ScaledHeight())}, + {.Alpha = 287.0f, .FadeRange = 32.0f}); ExtraStoryItems->Render(); MainItems->Render(); } break; case 7: // Secondary menu Continue Fade In case 8: { // Secondary menu Continue Renderer->DrawMaskedSprite( - MenuBackgroundSprite, MenuBackgroundSprite, - RectF(0.0f, 0.0f, MenuBackgroundSprite.ScaledWidth(), - MenuBackgroundSprite.ScaledHeight()), - 287, 32, glm::mat4(1.0f), glm::vec4(1.0f), false, true); + {MenuBackgroundSprite, MenuBackgroundSprite, + RectF(0.0f, 0.0f, MenuBackgroundSprite.ScaledWidth(), + MenuBackgroundSprite.ScaledHeight())}, + {.Alpha = 287.0f, .FadeRange = 32.0f}); ContinueItems->Render(); MainItems->Render(); } break; case 9: // Secondary menu Memories Fade In case 10: { // Secondary menu Memories Renderer->DrawMaskedSprite( - MenuBackgroundSprite, MenuBackgroundSprite, - RectF(0.0f, 0.0f, MenuBackgroundSprite.ScaledWidth(), - MenuBackgroundSprite.ScaledHeight()), - 287, 32, glm::mat4(1.0f), glm::vec4(1.0f), false, true); + {MenuBackgroundSprite, MenuBackgroundSprite, + RectF(0.0f, 0.0f, MenuBackgroundSprite.ScaledWidth(), + MenuBackgroundSprite.ScaledHeight())}, + {.Alpha = 287.0f, .FadeRange = 32.0f}); MemoriesItems->Render(); MainItems->Render(); } break; case 11: // Secondary menu System Fade In case 12: { // Secondary menu System Renderer->DrawMaskedSprite( - MenuBackgroundSprite, MenuBackgroundSprite, - RectF(0.0f, 0.0f, MenuBackgroundSprite.ScaledWidth(), - MenuBackgroundSprite.ScaledHeight()), - 287, 32, glm::mat4(1.0f), glm::vec4(1.0f), false, true); + {MenuBackgroundSprite, MenuBackgroundSprite, + RectF(0.0f, 0.0f, MenuBackgroundSprite.ScaledWidth(), + MenuBackgroundSprite.ScaledHeight())}, + {.Alpha = 287.0f, .FadeRange = 32.0f}); SystemItems->Render(); MainItems->Render(); } break; case 20: case 21: { // Transition between Press to start and menus Renderer->DrawMaskedSprite( - BackgroundSprite, BackgroundSprite, - RectF(0.0f, 0.0f, BackgroundSprite.ScaledWidth(), - BackgroundSprite.ScaledHeight()), - 287, 32, glm::mat4(1.0f), glm::vec4(1.0f), false, true); + {BackgroundSprite, BackgroundSprite, + RectF(0.0f, 0.0f, BackgroundSprite.ScaledWidth(), + BackgroundSprite.ScaledHeight())}, + {.Alpha = 287.0f, .FadeRange = 32.0f}); Renderer->DrawMaskedSprite( - LogoSprite, Masks2D[17].MaskSprite, - RectF(LogoX, LogoY, LogoSprite.ScaledWidth(), - LogoSprite.ScaledHeight()), - 287, 16); + {LogoSprite, Masks2D[17].MaskSprite, + RectF(LogoX, LogoY, LogoSprite.ScaledWidth(), + LogoSprite.ScaledHeight())}, + {.Alpha = 287.0f, .FadeRange = 16.0f}); Renderer->DrawSprite(CopyrightSprite, glm::vec2(CopyrightX, CopyrightY)); Renderer->DrawMaskedSprite( - MenuBackgroundSprite, MenuBackgroundSprite, - RectF(0.0f, 0.0f, MenuBackgroundSprite.ScaledWidth(), - MenuBackgroundSprite.ScaledHeight()), - (ScrWork[SW_TITLECT] * 287) / 48, 32, glm::mat4(1.0f), - glm::vec4(1.0f), false, true); + {MenuBackgroundSprite, MenuBackgroundSprite, + RectF(0.0f, 0.0f, MenuBackgroundSprite.ScaledWidth(), + MenuBackgroundSprite.ScaledHeight())}, + {.Alpha = static_cast((ScrWork[SW_TITLECT] * 287) / 48), + .FadeRange = 32.0f}); } break; } } diff --git a/src/games/mo8/optionsmenu.cpp b/src/games/mo8/optionsmenu.cpp index 91ea9da85..966f6cd2e 100644 --- a/src/games/mo8/optionsmenu.cpp +++ b/src/games/mo8/optionsmenu.cpp @@ -71,13 +71,11 @@ OptionsMenu::OptionsMenu() : UI::OptionsMenu() { PageControls = new Group(this); PageControls->FocusLock = false; - Sprite nullSprite = Sprite(); - nullSprite.Bounds = RectF(0.0f, 0.0f, 0.0f, 0.0f); auto nextPage = new Button(0, NextButtonSprite, NextButtonHighlightedSprite, - nullSprite, NextButtonPosition); + std::nullopt, NextButtonPosition); nextPage->OnClickHandler = nextPageOnClick; auto previousPage = - new Button(0, BackButtonSprite, BackButtonHighlightedSprite, nullSprite, + new Button(0, BackButtonSprite, BackButtonHighlightedSprite, std::nullopt, BackButtonPosition); previousPage->OnClickHandler = previousPageOnClick; PageControls->Add(nextPage); @@ -101,7 +99,7 @@ OptionsMenu::OptionsMenu() : UI::OptionsMenu() { for (int i = 0; i < TextSpeedOptionsNum; i++) { auto toggle = new Toggle( i, &MessageSpeedValues[i], TextSpeedOptionsHSprites[i], - TextSpeedOptionsSprites[i], nullSprite, glm::vec2(0.0f), false); + TextSpeedOptionsSprites[i], std::nullopt, glm::vec2(0.0f), false); toggle->OnClickHandler = textSpeedOnClick; textSpeedOptions->AddOption(toggle); } @@ -118,7 +116,7 @@ OptionsMenu::OptionsMenu() : UI::OptionsMenu() { for (int i = 0; i < AutoModeOptionsNum; i++) { auto toggle = new Toggle( i, &AutoModeWaitTimeValues[i], AutoModeOptionsHSprites[i], - AutoModeOptionsSprites[i], nullSprite, glm::vec2(0.0f), false); + AutoModeOptionsSprites[i], std::nullopt, glm::vec2(0.0f), false); toggle->OnClickHandler = autoModeWaitTimeOnClick; autoModeOptions->AddOption(toggle); } @@ -132,7 +130,7 @@ OptionsMenu::OptionsMenu() : UI::OptionsMenu() { ButtonHighlight, currentPos, OptionGroupItemsOffset); for (int i = 0; i < SkipModeOptionsNum; i++) { auto toggle = new Toggle(i, &SkipModeValues[i], SkipModeOptionsHSprites[i], - SkipModeOptionsSprites[i], nullSprite, + SkipModeOptionsSprites[i], std::nullopt, glm::vec2(0.0f), false); toggle->OnClickHandler = skipModeOnClick; skipModeOptions->AddOption(toggle); @@ -153,7 +151,7 @@ OptionsMenu::OptionsMenu() : UI::OptionsMenu() { for (int i = 0; i < SoundModeOptionsNum; i++) { voiceSyncOptions->AddOption(new Toggle( i, &FalseValue, SoundModeOptionsHSprites[i], SoundModeOptionsSprites[i], - nullSprite, glm::vec2(0.0f), false)); + std::nullopt, glm::vec2(0.0f), false)); } soundPage1->Add(voiceSyncOptions, FDIR_DOWN); currentPos += ListPadding; @@ -165,7 +163,7 @@ OptionsMenu::OptionsMenu() : UI::OptionsMenu() { for (int i = 0; i < SoundModeOptionsNum; i++) { voiceSkipOptions->AddOption(new Toggle( i, &FalseValue, SoundModeOptionsHSprites[i], SoundModeOptionsSprites[i], - nullSprite, glm::vec2(0.0f), false)); + std::nullopt, glm::vec2(0.0f), false)); } soundPage1->Add(voiceSkipOptions, FDIR_DOWN); currentPos += ListPadding; @@ -177,7 +175,7 @@ OptionsMenu::OptionsMenu() : UI::OptionsMenu() { for (int i = 0; i < SoundModeOptionsNum; i++) { voiceHighlightOptions->AddOption(new Toggle( i, &FalseValue, SoundModeOptionsHSprites[i], SoundModeOptionsSprites[i], - nullSprite, glm::vec2(0.0f), false)); + std::nullopt, glm::vec2(0.0f), false)); } soundPage1->Add(voiceHighlightOptions, FDIR_DOWN); Pages.push_back(std::move(soundPage1)); @@ -190,11 +188,11 @@ OptionsMenu::OptionsMenu() : UI::OptionsMenu() { // BGM volume options auto bgmVolumeOptions = - new OptionGroup(this, BgmVolumeLabel, BgmVolumeLabelH, nullSprite, + new OptionGroup(this, BgmVolumeLabel, BgmVolumeLabelH, std::nullopt, currentPos, OptionGroupSliderOffset); auto bgmVolumeSlider = new Scrollbar( 0, glm::vec2(0.0f), 0.0f, 1.0f, &Audio::GroupVolumes[Audio::ACG_BGM], - SBDIR_HORIZONTAL, SliderTrackSprite, nullSprite, SliderFillSprite); + SBDIR_HORIZONTAL, SliderTrackSprite, Sprite(), SliderFillSprite); bgmVolumeOptions->AddOption(bgmVolumeSlider); bgmVolumeSlider->FillBeforeTrack = true; soundPage2->Add(bgmVolumeOptions, FDIR_DOWN); @@ -202,11 +200,11 @@ OptionsMenu::OptionsMenu() : UI::OptionsMenu() { // Voice volume options auto voiceVolumeOptions = - new OptionGroup(this, VoiceVolumeLabel, VoiceVolumeLabelH, nullSprite, + new OptionGroup(this, VoiceVolumeLabel, VoiceVolumeLabelH, std::nullopt, currentPos, OptionGroupSliderOffset); auto voiceVolumeSlider = new Scrollbar( 0, glm::vec2(0.0f), 0.0f, 1.0f, &Audio::GroupVolumes[Audio::ACG_Voice], - SBDIR_HORIZONTAL, SliderTrackSprite, nullSprite, SliderFillSprite); + SBDIR_HORIZONTAL, SliderTrackSprite, std::nullopt, SliderFillSprite); voiceVolumeOptions->AddOption(voiceVolumeSlider); voiceVolumeSlider->FillBeforeTrack = true; soundPage2->Add(voiceVolumeOptions, FDIR_DOWN); @@ -214,11 +212,11 @@ OptionsMenu::OptionsMenu() : UI::OptionsMenu() { // SE volume options auto seVolumeOptions = - new OptionGroup(this, SeVolumeLabel, SeVolumeLabelH, nullSprite, + new OptionGroup(this, SeVolumeLabel, SeVolumeLabelH, std::nullopt, currentPos, OptionGroupSliderOffset); auto seVolumeSlider = new Scrollbar( 0, glm::vec2(0.0f), 0.0f, 1.0f, &Audio::GroupVolumes[Audio::ACG_SE], - SBDIR_HORIZONTAL, SliderTrackSprite, nullSprite, SliderFillSprite); + SBDIR_HORIZONTAL, SliderTrackSprite, std::nullopt, SliderFillSprite); seVolumeOptions->AddOption(seVolumeSlider); seVolumeSlider->FillBeforeTrack = true; soundPage2->Add(seVolumeOptions, FDIR_DOWN); @@ -227,17 +225,17 @@ OptionsMenu::OptionsMenu() : UI::OptionsMenu() { // SYSSE volume options auto systemSeVolumeOptions = new OptionGroup(this, SystemSeVolumeLabel, SystemSeVolumeLabelH, - nullSprite, currentPos, OptionGroupSliderOffset); + std::nullopt, currentPos, OptionGroupSliderOffset); auto systemSeVolumeSlider = new Scrollbar( 0, glm::vec2(0.0f), 0.0f, 1.0f, &Audio::GroupVolumes[Audio::ACG_SE], - SBDIR_HORIZONTAL, SliderTrackSprite, nullSprite, SliderFillSprite); + SBDIR_HORIZONTAL, SliderTrackSprite, std::nullopt, SliderFillSprite); systemSeVolumeOptions->AddOption(systemSeVolumeSlider); systemSeVolumeSlider->FillBeforeTrack = true; soundPage2->Add(systemSeVolumeOptions, FDIR_DOWN); currentPos += ListPadding; auto characterVoiceButton = new Button(0, CharacterVoiceVolumeLabel, CharacterVoiceVolumeLabelH, - nullSprite, currentPos); + std::nullopt, currentPos); soundPage2->Add(characterVoiceButton, FDIR_DOWN); Pages.push_back(std::move(soundPage2)); currentPos = ListStartingPosition; @@ -254,7 +252,7 @@ OptionsMenu::OptionsMenu() : UI::OptionsMenu() { for (int i = 0; i < QuickSaveOptionsNum; i++) { quickSaveOptions->AddOption(new Toggle( i, &FalseValue, QuickSaveOptionsHSprites[i], QuickSaveOptionsSprites[i], - nullSprite, glm::vec2(0.0f), false)); + std::nullopt, glm::vec2(0.0f), false)); } otherPage->Add(quickSaveOptions, FDIR_DOWN); Pages.push_back(std::move(otherPage)); diff --git a/src/games/mo8/savemenu.cpp b/src/games/mo8/savemenu.cpp index 4de1dc857..9ed2fd12e 100644 --- a/src/games/mo8/savemenu.cpp +++ b/src/games/mo8/savemenu.cpp @@ -41,12 +41,10 @@ SaveMenu::SaveMenu() : UI::SaveMenu() { PageControls = new Group(this); PageControls->FocusLock = false; - Sprite nullSprite = Sprite(); - nullSprite.Bounds = RectF(0.0f, 0.0f, 0.0f, 0.0f); auto nextPage = new Button(0, NextButtonSprite, NextButtonHighlightedSprite, - nullSprite, NextButtonPosition); + std::nullopt, NextButtonPosition); auto previousPage = - new Button(0, BackButtonSprite, BackButtonHighlightedSprite, nullSprite, + new Button(0, BackButtonSprite, BackButtonHighlightedSprite, std::nullopt, BackButtonPosition); PageControls->Add(nextPage); PageControls->Add(previousPage); diff --git a/src/games/mo8/systemmenu.cpp b/src/games/mo8/systemmenu.cpp index 107aa04ff..26dcf4a5d 100644 --- a/src/games/mo8/systemmenu.cpp +++ b/src/games/mo8/systemmenu.cpp @@ -36,14 +36,11 @@ SystemMenu::SystemMenu() { auto onClick = [this](auto* btn) { return MenuButtonOnClick(btn); }; - Sprite nullSprite = Sprite(); - nullSprite.Bounds = RectF(0.0f, 0.0f, 0.0f, 0.0f); - for (int i = 0; i < MenuEntriesNum; i++) { - Button* menuButton = - new Button(i, MenuEntriesSprites[i], MenuEntriesHSprites[i], nullSprite, - glm::vec2(*MenuEntriesX, - *MenuEntriesFirstY + (*MenuEntriesYPadding * i))); + Button* menuButton = new Button( + i, MenuEntriesSprites[i], MenuEntriesHSprites[i], std::nullopt, + glm::vec2(*MenuEntriesX, + *MenuEntriesFirstY + (*MenuEntriesYPadding * i))); menuButton->LockedSprite = MenuEntriesLSprites[i]; menuButton->OnClickHandler = onClick; diff --git a/src/games/mo8/titlemenu.cpp b/src/games/mo8/titlemenu.cpp index 5e000743e..5990ef974 100644 --- a/src/games/mo8/titlemenu.cpp +++ b/src/games/mo8/titlemenu.cpp @@ -58,9 +58,6 @@ TitleMenu::TitleMenu() { }; auto galleryOnClick = [this](auto* btn) { return GalleryButtonOnClick(btn); }; - Sprite nullSprite = Sprite(); - nullSprite.Bounds = RectF(0.0f, 0.0f, 0.0f, 0.0f); - // New Game menu button NewGame = new Button(0, MenuEntriesSprites[NewGameSpriteIndex], MenuEntriesHSprites[NewGameSpriteIndex], diff --git a/src/games/rne/sysmesbox.cpp b/src/games/rne/sysmesbox.cpp index 433a90b5e..ef0023f30 100644 --- a/src/games/rne/sysmesbox.cpp +++ b/src/games/rne/sysmesbox.cpp @@ -29,9 +29,6 @@ void SysMesBox::Show() { MessageItems = std::make_unique(this); ChoiceItems = std::make_unique(this); - Sprite nullSprite = Sprite(); - nullSprite.Bounds = RectF(0.0f, 0.0f, 0.0f, 0.0f); - auto onClick = [this](auto* btn) { return ChoiceItemOnClick(btn); }; float textBeginY = TextMiddleY - (TextMarginY * (4 + MessageCount)); @@ -44,17 +41,17 @@ void SysMesBox::Show() { } if (ChoiceCount == 1) { - WidgetOK = new Button(0, ButtonOK, ButtonOKHighlighted, nullSprite, + WidgetOK = new Button(0, ButtonOK, ButtonOKHighlighted, std::nullopt, glm::vec2(ButtonRightX, 0.0f)); WidgetOK->OnClickHandler = onClick; ChoiceItems->Add(WidgetOK, FDIR_RIGHT); } else if (ChoiceCount == 2) { - WidgetYes = new Button(0, ButtonYes, ButtonYesHighlighted, nullSprite, + WidgetYes = new Button(0, ButtonYes, ButtonYesHighlighted, std::nullopt, glm::vec2(ButtonYesX, 0.0f)); WidgetYes->OnClickHandler = onClick; ChoiceItems->Add(WidgetYes, FDIR_RIGHT); - WidgetNo = new Button(1, ButtonNo, ButtonNoHighlighted, nullSprite, + WidgetNo = new Button(1, ButtonNo, ButtonNoHighlighted, std::nullopt, glm::vec2(ButtonRightX, 0.0f)); WidgetNo->OnClickHandler = onClick; ChoiceItems->Add(WidgetNo, FDIR_LEFT); @@ -157,12 +154,13 @@ void SysMesBox::Update(float dt) { float buttonYesSpriteWidth = ButtonYWidthBase + labelButtonSpriteOffsetX; if (buttonYesSpriteWidth > ButtonWidth) buttonYesSpriteWidth = ButtonWidth; - WidgetYes->NormalSprite.Bounds = RectF( - WidgetYes->NormalSprite.Bounds.X, WidgetYes->NormalSprite.Bounds.Y, - buttonYesSpriteWidth, WidgetYes->NormalSprite.Bounds.Height); - WidgetYes->FocusedSprite.Bounds = RectF( - WidgetYes->FocusedSprite.Bounds.X, WidgetYes->FocusedSprite.Bounds.Y, - buttonYesSpriteWidth, WidgetYes->FocusedSprite.Bounds.Height); + WidgetYes->NormalSprite->Bounds = RectF( + WidgetYes->NormalSprite->Bounds.X, WidgetYes->NormalSprite->Bounds.Y, + buttonYesSpriteWidth, WidgetYes->NormalSprite->Bounds.Height); + WidgetYes->FocusedSprite->Bounds = + RectF(WidgetYes->FocusedSprite->Bounds.X, + WidgetYes->FocusedSprite->Bounds.Y, buttonYesSpriteWidth, + WidgetYes->FocusedSprite->Bounds.Height); ButtonYesX = ButtonYesDisplayXBase - labelButtonSpriteOffsetX; WidgetYes->MoveTo(glm::vec2(ButtonYesX, BoxBottomY - ButtonYOffset)); } @@ -173,21 +171,23 @@ void SysMesBox::Update(float dt) { if (buttonRightSpriteWidth > ButtonWidth) buttonRightSpriteWidth = ButtonWidth; if (WidgetNo) { - WidgetNo->NormalSprite.Bounds = RectF( - WidgetNo->NormalSprite.Bounds.X, WidgetNo->NormalSprite.Bounds.Y, - buttonRightSpriteWidth, WidgetNo->NormalSprite.Bounds.Height); - WidgetNo->FocusedSprite.Bounds = RectF( - WidgetNo->FocusedSprite.Bounds.X, WidgetNo->FocusedSprite.Bounds.Y, - buttonRightSpriteWidth, WidgetNo->FocusedSprite.Bounds.Height); + WidgetNo->NormalSprite->Bounds = RectF( + WidgetNo->NormalSprite->Bounds.X, WidgetNo->NormalSprite->Bounds.Y, + buttonRightSpriteWidth, WidgetNo->NormalSprite->Bounds.Height); + WidgetNo->FocusedSprite->Bounds = + RectF(WidgetNo->FocusedSprite->Bounds.X, + WidgetNo->FocusedSprite->Bounds.Y, buttonRightSpriteWidth, + WidgetNo->FocusedSprite->Bounds.Height); WidgetNo->MoveTo(glm::vec2(ButtonRightX, BoxBottomY - ButtonYOffset)); } if (WidgetOK) { - WidgetOK->NormalSprite.Bounds = RectF( - WidgetOK->NormalSprite.Bounds.X, WidgetOK->NormalSprite.Bounds.Y, - buttonRightSpriteWidth, WidgetOK->NormalSprite.Bounds.Height); - WidgetOK->FocusedSprite.Bounds = RectF( - WidgetOK->FocusedSprite.Bounds.X, WidgetOK->FocusedSprite.Bounds.Y, - buttonRightSpriteWidth, WidgetOK->FocusedSprite.Bounds.Height); + WidgetOK->NormalSprite->Bounds = RectF( + WidgetOK->NormalSprite->Bounds.X, WidgetOK->NormalSprite->Bounds.Y, + buttonRightSpriteWidth, WidgetOK->NormalSprite->Bounds.Height); + WidgetOK->FocusedSprite->Bounds = + RectF(WidgetOK->FocusedSprite->Bounds.X, + WidgetOK->FocusedSprite->Bounds.Y, buttonRightSpriteWidth, + WidgetOK->FocusedSprite->Bounds.Height); WidgetOK->MoveTo(glm::vec2(ButtonRightX, BoxBottomY - ButtonYOffset)); } } diff --git a/src/games/rne/systemmenu.cpp b/src/games/rne/systemmenu.cpp index 471ae5f41..5b602a911 100644 --- a/src/games/rne/systemmenu.cpp +++ b/src/games/rne/systemmenu.cpp @@ -32,12 +32,9 @@ SystemMenu::SystemMenu() { auto onClick = [this](auto* btn) { return MenuButtonOnClick(btn); }; - Sprite nullSprite = Sprite(); - nullSprite.Bounds = RectF(0.0f, 0.0f, 0.0f, 0.0f); - for (int i = 0; i < MenuEntriesNum; i++) { SysMenuButton* menuButton = new SysMenuButton( - i, MenuEntriesSprites[i], nullSprite, MenuEntriesHSprites[i], + i, MenuEntriesSprites[i], MenuEntriesHSprites[i], glm::vec2(*MenuEntriesX, *MenuEntriesFirstY + (*MenuEntriesYPadding * i))); @@ -139,7 +136,7 @@ void SystemMenu::Update(float dt) { item->Tint.a = glm::smoothstep( 0.0f, 1.0f, 1.0f - (idx + 1) * (1.0f - EntriesMoveAnimation.Progress)); Button* button = (Button*)item; - button->HighlightSprite.Bounds.Width = + button->HighlightSprite->Bounds.Width = MenuEntriesTargetWidth * HighlightAnimation.Progress; idx++; } diff --git a/src/hud/cc/dialoguebox.cpp b/src/hud/cc/dialoguebox.cpp index a10034914..d3ff57494 100644 --- a/src/hud/cc/dialoguebox.cpp +++ b/src/hud/cc/dialoguebox.cpp @@ -33,9 +33,10 @@ void DialogueBox::Render(const DialoguePageMode mode, const NameInfo& nameInfo, const glm::vec4 tint) { switch (mode) { case DPM_ADV: { - Renderer->DrawCCMessageBox(ADVBoxSprite, ADVBoxMask, ADVBoxPos, - glm::vec4(1.0f), (int)(tint.a * 272.0f), 16, - TextBoxEffect.Progress); + Renderer->DrawCCMessageBox({ADVBoxSprite, ADVBoxMask, ADVBoxPos}, + {.Alpha = (int)(tint.a * 272.0f), + .FadeRange = 16, + .EffectCt = TextBoxEffect.Progress}); NametagDisplayInst->Render(nameInfo, tint); } break; diff --git a/src/hud/dialoguebox.cpp b/src/hud/dialoguebox.cpp index b99ee1416..fb9014888 100644 --- a/src/hud/dialoguebox.cpp +++ b/src/hud/dialoguebox.cpp @@ -55,28 +55,28 @@ PlainDialogueBox::PlainDialogueBox(const DialoguePage& page) : DialogueBox(page) { using namespace UI::Widgets; - Sprite nullSprite = Sprite(); - nullSprite.Bounds = RectF(0.0f, 0.0f, 0.0f, 0.0f); - if (HasAutoButton) { - ControlButtons.emplace_back(std::make_unique