Merge remote-tracking branch 'origin/develop' into develop->develop-rando

This commit is contained in:
Archez 2024-08-14 11:38:56 -04:00
commit 35b4da74cb
100 changed files with 1224 additions and 612 deletions

View File

@ -7,7 +7,7 @@ concurrency:
cancel-in-progress: true
jobs:
generate-soh-otr:
runs-on: ${{ (vars.LINUX_RUNNER && fromJSON(vars.LINUX_RUNNER)) || 'ubuntu-latest' }}
runs-on: ubuntu-22.04
steps:
- uses: actions/checkout@v3
with:
@ -20,7 +20,6 @@ jobs:
${{ runner.os }}-otr-ccache-${{ github.ref }}
${{ runner.os }}-otr-ccache-
- name: Install dependencies
if: ${{ !vars.LINUX_RUNNER }}
run: |
sudo apt-get update
sudo apt-get install -y $(cat .github/workflows/apt-deps.txt)
@ -35,7 +34,6 @@ jobs:
build-cmake
SDL2-2.28.5
- name: Install latest SDL
if: ${{ !vars.LINUX_RUNNER }}
run: |
export PATH="/usr/lib/ccache:/usr/local/opt/ccache/libexec:$PATH"
if [ ! -d "SDL2-2.28.5" ]; then
@ -73,47 +71,44 @@ jobs:
retention-days: 1
build-macos:
needs: generate-soh-otr
runs-on: ${{ (vars.MAC_RUNNER && fromJSON(vars.MAC_RUNNER)) || 'macos-12' }}
runs-on: macos-14
steps:
- uses: actions/checkout@v3
with:
submodules: true
- name: ccache
uses: hendrikmuhs/ccache-action@v1.2.11
uses: hendrikmuhs/ccache-action@v1.2.13
with:
key: ${{ runner.os }}-ccache-${{ github.ref }}-${{ github.sha }}
create-symlink: true
key: ${{ runner.os }}-14-ccache-${{ github.ref }}-${{ github.sha }}
restore-keys: |
${{ runner.os }}-ccache-${{ github.ref }}
${{ runner.os }}-ccache-
${{ runner.os }}-14-ccache-${{ github.ref }}
${{ runner.os }}-14-ccache-
- name: Install gtar wrapper
if: ${{ !vars.MAC_RUNNER }}
run: |
sudo mv /usr/local/bin/gtar /usr/local/bin/gtar.orig
sudo cp .github/workflows//gtar /usr/local/bin/gtar
sudo chmod +x /usr/local/bin/gtar
sudo mv /opt/homebrew/bin/gtar /opt/homebrew/bin/gtar.orig
sudo cp .github/workflows//gtar /opt/homebrew/bin/gtar
sudo chmod +x /opt/homebrew/bin/gtar
- name: Cache MacPorts
id: cache-macports
if: ${{ !vars.MAC_RUNNER }}
uses: actions/cache@v2
with:
path: /opt/local/
key: ${{ runner.os }}-macports-${{ hashFiles('.github/workflows/macports-deps.txt') }}
key: ${{ runner.os }}-14-macports-${{ hashFiles('.github/workflows/macports-deps.txt') }}
restore-keys: |
${{ runner.os }}-macports-
${{ runner.os }}-14-macports-
- name: Install MacPorts (if necessary)
if: ${{ !vars.MAC_RUNNER }}
run: |
if [ -d /opt/local/ ]; then
echo "MacPorts already installed"
else
wget https://github.com/macports/macports-base/releases/download/v2.9.3/MacPorts-2.9.3-12-Monterey.pkg
sudo installer -pkg ./MacPorts-2.9.3-12-Monterey.pkg -target /
wget https://github.com/macports/macports-base/releases/download/v2.9.3/MacPorts-2.9.3-14-Sonoma.pkg
sudo installer -pkg ./MacPorts-2.9.3-14-Sonoma.pkg -target /
fi
echo "/opt/local/bin:/opt/local/sbin" >> $GITHUB_PATH
- name: Install dependencies
if: ${{ !vars.MAC_RUNNER }}
run: |
brew uninstall --ignore-dependencies libpng libzip
brew uninstall --ignore-dependencies libpng
sudo port install $(cat .github/workflows/macports-deps.txt)
brew install ninja
- name: Download soh.otr
@ -122,7 +117,6 @@ jobs:
name: soh.otr
- name: Build SoH
run: |
export PATH="/usr/lib/ccache:/usr/local/opt/ccache/libexec:$PATH"
cmake --no-warn-unused-cli -H. -Bbuild-cmake -GNinja -DCMAKE_BUILD_TYPE:STRING=Release -DCMAKE_OSX_ARCHITECTURES="x86_64;arm64" -DBUILD_REMOTE_CONTROL=1
cmake --build build-cmake --config Release --parallel 10
mv soh.otr build-cmake/soh
@ -139,45 +133,33 @@ jobs:
readme.txt
build-linux:
needs: generate-soh-otr
strategy:
fail-fast: true
matrix:
include:
- os: ubuntu-20.04
gcc: 10
archive-suffix: compatibility
- os: ubuntu-22.04
gcc: 12
archive-suffix: performance
runs-on: ${{ (matrix.os == 'ubuntu-20.04' && ((vars.LINUX_COMPATIBILITY_RUNNER && fromJSON(vars.LINUX_COMPATIBILITY_RUNNER)) || matrix.os)) || (matrix.os == 'ubuntu-22.04' && ((vars.LINUX_PERFORMANCE_RUNNER && fromJSON(vars.LINUX_PERFORMANCE_RUNNER)) || matrix.os)) }}
runs-on: ubuntu-22.04
steps:
- uses: actions/checkout@v3
with:
submodules: true
- name: Install dependencies
if: ${{ (matrix.os == 'ubuntu-20.04' && !vars.LINUX_COMPATIBILITY_RUNNER) || (matrix.os == 'ubuntu-22.04' && !vars.LINUX_PERFORMANCE_RUNNER) }}
run: |
sudo apt-get update
sudo apt-get install -y $(cat .github/workflows/apt-deps.txt)
- name: ccache
uses: hendrikmuhs/ccache-action@v1.2.11
with:
key: ${{ matrix.os }}-ccache-${{ github.ref }}-${{ github.sha }}
key: linux-ccache-${{ github.ref }}-${{ github.sha }}
restore-keys: |
${{ matrix.os }}-ccache-${{ github.ref }}
${{ matrix.os }}-ccache-
linux-ccache-${{ github.ref }}
linux-ccache-
- name: Cache build folders
uses: actions/cache@v4
with:
key: ${{ matrix.os }}-build-${{ github.ref }}-${{ github.sha }}
key: linux-build-${{ github.ref }}-${{ github.sha }}
restore-keys: |
${{ matrix.os }}-build-${{ github.ref }}
${{ matrix.os }}-build-
linux-build-${{ github.ref }}
linux-build-
path: |
SDL2-2.28.5
SDL2_net-2.2.0
- name: Install latest SDL
if: ${{ (matrix.os == 'ubuntu-20.04' && !vars.LINUX_COMPATIBILITY_RUNNER) || (matrix.os == 'ubuntu-22.04' && !vars.LINUX_PERFORMANCE_RUNNER) }}
run: |
export PATH="/usr/lib/ccache:/usr/local/opt/ccache/libexec:$PATH"
if [ ! -d "SDL2-2.28.5" ]; then
@ -189,38 +171,7 @@ jobs:
make -j 10
sudo make install
sudo cp -av /usr/local/lib/libSDL* /lib/x86_64-linux-gnu/
- name: Install latest libzip
if: ${{ (matrix.os == 'ubuntu-20.04' && !vars.LINUX_COMPATIBILITY_RUNNER) }}
run: |
sudo apt-get remove libzip-dev zipcmp zipmerge ziptool
export PATH="/usr/lib/ccache:/usr/local/opt/ccache/libexec:$PATH"
if [ ! -d "libzip-1.10.1" ]; then
wget https://libzip.org/download/libzip-1.10.1.tar.gz
tar -xzvf libzip-1.10.1.tar.gz
fi
cd libzip-1.10.1
mkdir build
cd build
cmake ..
make
sudo make install
- name: Install latest nlohmann
if: ${{ (matrix.os == 'ubuntu-20.04' && !vars.LINUX_COMPATIBILITY_RUNNER) }}
run: |
sudo apt-get remove nlohmann-json3-dev
export PATH="/usr/lib/ccache:/usr/local/opt/ccache/libexec:$PATH"
if [ ! -d "json-3.11.3" ]; then
wget https://github.com/nlohmann/json/archive/refs/tags/v3.11.3.tar.gz
tar -xzvf v3.11.3.tar.gz
fi
cd json-3.11.3
mkdir build
cd build
cmake ..
make
sudo make install
- name: Install latest tinyxml2
if: ${{ (matrix.os == 'ubuntu-20.04' && !vars.LINUX_COMPATIBILITY_RUNNER) || (matrix.os == 'ubuntu-22.04' && !vars.LINUX_PERFORMANCE_RUNNER) }}
run: |
sudo apt-get remove libtinyxml2-dev
export PATH="/usr/lib/ccache:/usr/local/opt/ccache/libexec:$PATH"
@ -235,7 +186,6 @@ jobs:
make
sudo make install
- name: Install latest SDL_net
if: ${{ (matrix.os == 'ubuntu-20.04' && !vars.LINUX_COMPATIBILITY_RUNNER) || (matrix.os == 'ubuntu-22.04' && !vars.LINUX_PERFORMANCE_RUNNER) }}
run: |
export PATH="/usr/lib/ccache:/usr/local/opt/ccache/libexec:$PATH"
if [ ! -d "SDL2_net-2.2.0" ]; then
@ -261,12 +211,12 @@ jobs:
mv README.md readme.txt
mv build-cmake/*.appimage soh.appimage
env:
CC: gcc-${{ matrix.gcc }}
CXX: g++-${{ matrix.gcc }}
CC: gcc-12
CXX: g++-12
- name: Upload build
uses: actions/upload-artifact@v4
with:
name: soh-linux-${{ matrix.archive-suffix }}
name: soh-linux
path: |
soh.appimage
readme.txt

View File

@ -1,2 +1,2 @@
#!/bin/sh
exec sudo /usr/local/bin/gtar.orig "$@"
exec sudo /opt/homebrew/bin/gtar.orig "$@"

View File

@ -1,8 +1,3 @@
# todo:
# nlohmann
# tinyxml2
# spdlog
name: test-builds-on-distros
on:
workflow_dispatch: # by request
@ -28,31 +23,42 @@ jobs:
if: ${{ matrix.image == 'archlinux:base' }}
run: |
echo arch
echo pacman -S ${{ matrix.cc }} git cmake ninja lsb-release sdl2 libpng libzip sdl2_net boost
echo pacman -S ${{ matrix.cc }} git cmake ninja lsb-release sdl2 libpng libzip nlohmann-json tinyxml2 spdlog sdl2_net boost
pacman -Syu --noconfirm
pacman -S --noconfirm ${{ matrix.cc }} git cmake ninja lsb-release sdl2 libpng libzip sdl2_net boost
pacman -S --noconfirm ${{ matrix.cc }} git cmake ninja lsb-release sdl2 libpng libzip nlohmann-json tinyxml2 spdlog sdl2_net boost
- name: Install dependencies (dnf)
if: ${{ matrix.image == 'fedora:39' }}
run: |
echo fedora
echo dnf install ${{ matrix.cc }} ${{ (matrix.cxx == 'g++' && 'gcc-c++') || '' }} git cmake ninja-build lsb_release SDL2-devel libpng-devel libzip-devel libzip-tools boost-devel
echo dnf install ${{ matrix.cc }} ${{ (matrix.cxx == 'g++' && 'gcc-c++') || '' }} wget git cmake ninja-build lsb_release SDL2-devel libpng-devel libzip-devel libzip-tools tinyxml2-devel spdlog-devel boost-devel
dnf -y upgrade
dnf -y install ${{ matrix.cc }} ${{ (matrix.cxx == 'g++' && 'gcc-c++') || '' }} git cmake ninja-build lsb_release SDL2-devel libpng-devel libzip-devel libzip-tools boost-devel
dnf -y install ${{ matrix.cc }} ${{ (matrix.cxx == 'g++' && 'gcc-c++') || '' }} wget git cmake ninja-build lsb_release SDL2-devel libpng-devel libzip-devel libzip-tools tinyxml2-devel spdlog-devel boost-devel
- name: Install dependencies (apt)
if: ${{ matrix.image == 'ubuntu:mantic' || matrix.image == 'debian:bookworm' }}
run: |
echo debian based
echo apt-get install ${{ matrix.cc }} ${{ (matrix.cxx == 'g++' && 'g++') || '' }} git cmake ninja-build lsb-release libsdl2-dev libpng-dev libsdl2-net-dev libzip-dev zipcmp zipmerge ziptool libboost-dev libopengl-dev
echo apt-get install ${{ matrix.cc }} ${{ (matrix.cxx == 'g++' && 'g++') || '' }} git cmake ninja-build lsb-release libsdl2-dev libpng-dev libsdl2-net-dev libzip-dev zipcmp zipmerge ziptool nlohmann-json3-dev libtinyxml2-dev libspdlog-dev libboost-dev libopengl-dev
apt-get update
apt-get -y full-upgrade
apt-get -y install ${{ matrix.cc }} ${{ (matrix.cxx == 'g++' && 'g++') || '' }} git cmake ninja-build lsb-release libsdl2-dev libpng-dev libsdl2-net-dev libzip-dev zipcmp zipmerge ziptool libboost-dev libopengl-dev
apt-get -y install ${{ matrix.cc }} ${{ (matrix.cxx == 'g++' && 'g++') || '' }} git cmake ninja-build lsb-release libsdl2-dev libpng-dev libsdl2-net-dev libzip-dev zipcmp zipmerge ziptool nlohmann-json3-dev libtinyxml2-dev libspdlog-dev libboost-dev libopengl-dev
- name: Install dependencies (zypper)
if: ${{ matrix.image == 'opensuse/tumbleweed:latest' }}
run: |
echo openSUSE
echo zypper in ${{ matrix.cc }} ${{ (matrix.cxx == 'g++' && 'gcc-c++') || '' }} ${{ matrix.cc == 'clang' && 'libstdc++-devel' || '' }} git cmake ninja SDL2-devel libpng16-devel libzip-devel libzip-tools
echo zypper in ${{ matrix.cc }} ${{ (matrix.cxx == 'g++' && 'gcc-c++') || '' }} ${{ matrix.cc == 'clang' && 'libstdc++-devel' || '' }} git cmake ninja SDL2-devel libpng16-devel libzip-devel libzip-tools nlohmann_json-devel tinyxml2-devel spdlog-devel
zypper --non-interactive dup
zypper --non-interactive in ${{ matrix.cc }} ${{ (matrix.cxx == 'g++' && 'gcc-c++') || '' }} ${{ matrix.cc == 'clang' && 'libstdc++-devel' || '' }} git cmake ninja SDL2-devel libpng16-devel libzip-devel libzip-tools
zypper --non-interactive in ${{ matrix.cc }} ${{ (matrix.cxx == 'g++' && 'gcc-c++') || '' }} ${{ matrix.cc == 'clang' && 'libstdc++-devel' || '' }} git cmake ninja SDL2-devel libpng16-devel libzip-devel libzip-tools nlohmann_json-devel tinyxml2-devel spdlog-devel
- name: Install latest nlohmann
if: ${{ matrix.image == 'fedora:39' }}
run: |
wget https://github.com/nlohmann/json/archive/refs/tags/v3.11.3.tar.gz
tar -xzvf v3.11.3.tar.gz
cd json-3.11.3
mkdir build
cd build
cmake ..
make
sudo make install
- uses: actions/checkout@v3
with:
submodules: true

View File

@ -16,7 +16,6 @@ set(CVAR_STATS_WINDOW_OPEN "${CVAR_PREFIX_WINDOW}.Stats" CACHE STRING "")
set(CVAR_ENABLE_MULTI_VIEWPORTS "${CVAR_PREFIX_SETTING}.EnableMultiViewports" CACHE STRING "")
set(CVAR_LOW_RES_MODE "${CVAR_PREFIX_SETTING}.LowResMode" CACHE STRING "")
set(CVAR_SIMULATED_INPUT_LAG "${CVAR_PREFIX_SETTING}.SimulatedInputLag" CACHE STRING "")
set(CVAR_ALT_ASSETS "${CVAR_PREFIX_ENHANCEMENT}.AltAssets" CACHE STRING "")
set(CVAR_GAME_OVERLAY_FONT "${CVAR_PREFIX_SETTING}.OverlayFont" CACHE STRING "")
set(CVAR_MENU_BAR_OPEN "${CVAR_PREFIX_SETTING}.OpenMenuBar" CACHE STRING "")
set(CVAR_PREFIX_CONTROLLERS "${CVAR_PREFIX_SETTING}.Controllers" CACHE STRING "")

View File

@ -5,11 +5,11 @@ set(CMAKE_CXX_STANDARD 20 CACHE STRING "The C++ standard to use")
set(CMAKE_OSX_DEPLOYMENT_TARGET "10.15" CACHE STRING "Minimum OS X deployment version")
project(Ship VERSION 8.0.5 LANGUAGES C CXX)
project(Ship VERSION 8.0.6 LANGUAGES C CXX)
include(CMake/soh-cvars.cmake)
include(CMake/lus-cvars.cmake)
set(PROJECT_BUILD_NAME "MacReady Foxtrot" CACHE STRING "")
set(PROJECT_TEAM "github.com/harbourmasters" CACHE STRING "")
set(PROJECT_BUILD_NAME "MacReady Golf" CACHE STRING "" FORCE)
set(PROJECT_TEAM "github.com/harbourmasters" CACHE STRING "" FORCE)
set_property(DIRECTORY ${CMAKE_SOURCE_DIR} PROPERTY VS_STARTUP_PROJECT soh)
add_compile_options($<$<CXX_COMPILER_ID:MSVC>:/MP>)
@ -84,6 +84,12 @@ include(CMake/GlobalSettingsInclude.cmake OPTIONAL)
################################################################################
set_property(GLOBAL PROPERTY USE_FOLDERS ON)
################################################################################
# Set GBI version
################################################################################
set(GBI_UCODE F3DEX_GBI_2)
################################################################################
# Sub-projects
################################################################################

@ -1 +1 @@
Subproject commit 3cea9ee7c017d842aa4d9ceeb8d3ffbf29c6effb
Subproject commit 2cfdb3960900ba059f570b2ded2fed3494a96a9b

View File

@ -91,10 +91,7 @@ If you want to playtest a continuous integration build, you can find them at the
* [Windows](https://nightly.link/HarbourMasters/Shipwright/workflows/generate-builds/develop/soh-windows.zip)
* [macOS](https://nightly.link/HarbourMasters/Shipwright/workflows/generate-builds/develop/soh-mac.zip)
* [Linux (performance)](https://nightly.link/HarbourMasters/Shipwright/workflows/generate-builds/develop/soh-linux-performance.zip) _(requires `glibc 2.35` or newer, but will be more performant than the compatibility build.)_
* [Linux (compatibility)](https://nightly.link/HarbourMasters/Shipwright/workflows/generate-builds/develop/soh-linux-compatibility.zip) _(compatible with most Linux distributions, but may not be as performant as the performance build.)_
* [Switch](https://nightly.link/HarbourMasters/Shipwright/workflows/generate-builds/develop/soh-switch.zip)
* [Wii U](https://nightly.link/HarbourMasters/Shipwright/workflows/generate-builds/develop/soh-wiiu.zip)
* [Linux](https://nightly.link/HarbourMasters/Shipwright/workflows/generate-builds/develop/soh-linux.zip)
<a href="https://github.com/Kenix3/libultraship/">
<picture>

2
ZAPDTR

@ -1 +1 @@
Subproject commit f38a9c92eb99368c0607acf356d5651ebdc96f51
Subproject commit 04d42249d2c15c3b442a0282a90bc8b7bda25b03

View File

@ -88,34 +88,34 @@ cd "build/x64"
#### Debian/Ubuntu
```sh
# using gcc
apt-get install gcc g++ git cmake ninja-build lsb-release libsdl2-dev libpng-dev libsdl2-net-dev libzip-dev zipcmp zipmerge ziptool libboost-dev libopengl-dev
apt-get install gcc g++ git cmake ninja-build lsb-release libsdl2-dev libpng-dev libsdl2-net-dev libzip-dev zipcmp zipmerge ziptool nlohmann-json3-dev libtinyxml2-dev libspdlog-dev libboost-dev libopengl-dev
# or using clang
apt-get install clang git cmake ninja-build lsb-release libsdl2-dev libpng-dev libsdl2-net-dev libzip-dev zipcmp zipmerge ziptool libboost-dev libopengl-dev
apt-get install clang git cmake ninja-build lsb-release libsdl2-dev libpng-dev libsdl2-net-dev libzip-dev zipcmp zipmerge ziptool nlohmann-json3-dev libtinyxml2-dev libspdlog-dev libboost-dev libopengl-dev
```
#### Arch
```sh
# using gcc
pacman -S gcc git cmake ninja lsb-release sdl2 libpng libzip sdl2_net boost
pacman -S gcc git cmake ninja lsb-release sdl2 libpng libzip nlohmann-json tinyxml2 spdlog sdl2_net boost
# or using clang
pacman -S clang git cmake ninja lsb-release sdl2 libpng libzip sdl2_net boost
pacman -S clang git cmake ninja lsb-release sdl2 libpng libzip nlohmann-json tinyxml2 spdlog sdl2_net boost
```
#### Fedora
```sh
# using gcc
dnf install gcc gcc-c++ git cmake ninja-build lsb_release SDL2-devel libpng-devel libzip-devel libzip-tools boost-devel
dnf install gcc gcc-c++ git cmake ninja-build lsb_release SDL2-devel libpng-devel libzip-devel libzip-tools nlohmann-json-devel tinyxml2-devel spdlog-devel boost-devel
# or using clang
dnf install clang git cmake ninja-build lsb_release SDL2-devel libpng-devel libzip-devel libzip-tools boost-devel
dnf install clang git cmake ninja-build lsb_release SDL2-devel libpng-devel libzip-devel libzip-tools nlohmann-json-devel tinyxml2-devel spdlog-devel boost-devel
```
#### openSUSE
```sh
# using gcc
zypper in gcc gcc-c++ git cmake ninja SDL2-devel libpng16-devel libzip-devel libzip-tools
zypper in gcc gcc-c++ git cmake ninja SDL2-devel libpng16-devel libzip-devel libzip-tools nlohmann_json-devel tinyxml2-devel spdlog-devel
# or using clang
zypper in clang libstdc++-devel git cmake ninja SDL2-devel libpng16-devel libzip-devel libzip-tools
zypper in clang libstdc++-devel git cmake ninja SDL2-devel libpng16-devel libzip-devel libzip-tools nlohmann_json-devel tinyxml2-devel spdlog-devel
```
### Build

@ -1 +1 @@
Subproject commit 0da318c0f4e431313565cad546fc469b8e850388
Subproject commit 31e9b009f94e7074a847c7954926cba354cd7c72

View File

@ -407,6 +407,7 @@ if (CMAKE_SYSTEM_NAME STREQUAL "Windows")
">"
"$<$<BOOL:${BUILD_REMOTE_CONTROL}>:ENABLE_REMOTE_CONTROL>"
"INCLUDE_GAME_PRINTF;"
"F3DEX_GBI_2"
"UNICODE;"
"_UNICODE"
STORMLIB_NO_AUTO_LINK
@ -425,6 +426,7 @@ if (CMAKE_SYSTEM_NAME STREQUAL "Windows")
"NDEBUG;"
">"
"INCLUDE_GAME_PRINTF;"
"F3DEX_GBI_2"
"WIN32;"
"UNICODE;"
"_UNICODE"
@ -440,6 +442,7 @@ elseif (CMAKE_SYSTEM_NAME STREQUAL "CafeOS")
"$<$<CONFIG:Release>:"
"NDEBUG"
">"
"F3DEX_GBI_2"
"SPDLOG_ACTIVE_LEVEL=3;"
"SPDLOG_NO_THREAD_ID;"
"SPDLOG_NO_TLS;"
@ -453,6 +456,7 @@ elseif ("${CMAKE_CXX_COMPILER_ID}" MATCHES "GNU|Clang|AppleClang")
"$<$<CONFIG:Release>:"
"NDEBUG"
">"
"F3DEX_GBI_2"
"$<$<BOOL:${BUILD_REMOTE_CONTROL}>:ENABLE_REMOTE_CONTROL>"
"SPDLOG_ACTIVE_LEVEL=0;"
"_CONSOLE;"

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

View File

@ -0,0 +1,5 @@
<Root>
<File Name="code" OutName="sys_matrix" RangeStart="0x110CC0" RangeEnd="0x110D00">
<Mtx Name="gMtxClear" Offset="0x110CC0"/>
</File>
</Root>

View File

@ -1,4 +1,5 @@
<Root>
<ExternalFile XmlPath="code/sys_matrix.xml" OutPath="code/sys_matrix/"/>
<File Name="bdan_scene" Segment="2">
<Texture Name="bdan_sceneTex_013E00" OutName="bdan_sceneTex_013E00" Format="ci8" Width="32" Height="64" Offset="0x13E00" TlutOffset="0x13BF8" AddedByScript="true"/>
<Texture Name="bdan_sceneTex_014600" OutName="bdan_sceneTex_014600" Format="ci8" Width="32" Height="32" Offset="0x14600" TlutOffset="0x13BF8" AddedByScript="true"/>

View File

@ -1,4 +1,5 @@
<Root>
<ExternalFile XmlPath="code/sys_matrix.xml" OutPath="code/sys_matrix/"/>
<File Name="bdan_boss_scene" Segment="2">
<Scene Name="bdan_boss_scene" Offset="0x0"/>
</File>

View File

@ -0,0 +1,5 @@
<Root>
<File Name="code" OutName="sys_matrix" RangeStart="0xEAD00" RangeEnd="0xEAD40">
<Mtx Name="gMtxClear" Offset="0xEAD00"/>
</File>
</Root>

View File

@ -1,4 +1,5 @@
<Root>
<ExternalFile XmlPath="code/sys_matrix.xml" OutPath="code/sys_matrix/"/>
<File Name="bdan_scene" Segment="2">
<Texture Name="bdan_sceneTex_013E00" OutName="bdan_sceneTex_013E00" Format="ci8" Width="32" Height="64" Offset="0x13E00" TlutOffset="0x13BF8" AddedByScript="true"/>
<Texture Name="bdan_sceneTex_014600" OutName="bdan_sceneTex_014600" Format="ci8" Width="32" Height="32" Offset="0x14600" TlutOffset="0x13BF8" AddedByScript="true"/>

View File

@ -1,4 +1,5 @@
<Root>
<ExternalFile XmlPath="code/sys_matrix.xml" OutPath="code/sys_matrix/"/>
<File Name="bdan_boss_scene" Segment="2">
<Scene Name="bdan_boss_scene" Offset="0x0"/>
</File>

View File

@ -0,0 +1,5 @@
<Root>
<File Name="code" OutName="sys_matrix" RangeStart="0x110CE0" RangeEnd="0x110D20">
<Mtx Name="gMtxClear" Offset="0x110CE0"/>
</File>
</Root>

View File

@ -1,4 +1,5 @@
<Root>
<ExternalFile XmlPath="code/sys_matrix.xml" OutPath="code/sys_matrix/"/>
<File Name="bdan_scene" Segment="2">
<Texture Name="bdan_sceneTex_013E00" OutName="bdan_sceneTex_013E00" Format="ci8" Width="32" Height="64" Offset="0x13DE0" TlutOffset="0x13BD8" AddedByScript="true"/>
<Texture Name="bdan_sceneTex_014600" OutName="bdan_sceneTex_014600" Format="ci8" Width="32" Height="32" Offset="0x145E0" TlutOffset="0x13BD8" AddedByScript="true"/>

View File

@ -1,4 +1,5 @@
<Root>
<ExternalFile XmlPath="code/sys_matrix.xml" OutPath="code/sys_matrix/"/>
<File Name="bdan_boss_scene" Segment="2">
<Scene Name="bdan_boss_scene" Offset="0x0"/>
</File>

View File

@ -0,0 +1,5 @@
<Root>
<File Name="code" OutName="sys_matrix" RangeStart="0xEAD20" RangeEnd="0xEAD60">
<Mtx Name="gMtxClear" Offset="0xEAD20"/>
</File>
</Root>

View File

@ -1,4 +1,5 @@
<Root>
<ExternalFile XmlPath="code/sys_matrix.xml" OutPath="code/sys_matrix/"/>
<File Name="bdan_scene" Segment="2">
<Texture Name="bdan_sceneTex_013E00" OutName="bdan_sceneTex_013E00" Format="ci8" Width="32" Height="64" Offset="0x13DE0" TlutOffset="0x13BD8" AddedByScript="true"/>
<Texture Name="bdan_sceneTex_014600" OutName="bdan_sceneTex_014600" Format="ci8" Width="32" Height="32" Offset="0x145E0" TlutOffset="0x13BD8" AddedByScript="true"/>

View File

@ -1,4 +1,5 @@
<Root>
<ExternalFile XmlPath="code/sys_matrix.xml" OutPath="code/sys_matrix/"/>
<File Name="bdan_boss_scene" Segment="2">
<Scene Name="bdan_boss_scene" Offset="0x0"/>
</File>

View File

@ -0,0 +1,5 @@
<Root>
<File Name="code" OutName="sys_matrix" RangeStart="0xEB620" RangeEnd="0xEB660">
<Mtx Name="gMtxClear" Offset="0xEB620"/>
</File>
</Root>

View File

@ -1,4 +1,5 @@
<Root>
<ExternalFile XmlPath="code/sys_matrix.xml" OutPath="code/sys_matrix/"/>
<File Name="bdan_scene" Segment="2">
<Texture Name="bdan_sceneTex_013E00" OutName="bdan_sceneTex_013E00" Format="ci8" Width="32" Height="64" Offset="0x13DE0" TlutOffset="0x13BD8" AddedByScript="true"/>
<Texture Name="bdan_sceneTex_014600" OutName="bdan_sceneTex_014600" Format="ci8" Width="32" Height="32" Offset="0x145E0" TlutOffset="0x13BD8" AddedByScript="true"/>

View File

@ -1,4 +1,5 @@
<Root>
<ExternalFile XmlPath="code/sys_matrix.xml" OutPath="code/sys_matrix/"/>
<File Name="bdan_boss_scene" Segment="2">
<Scene Name="bdan_boss_scene" Offset="0x0"/>
</File>

View File

@ -0,0 +1,5 @@
<Root>
<File Name="code" OutName="sys_matrix" RangeStart="0xEB660" RangeEnd="0xEB6A0">
<Mtx Name="gMtxClear" Offset="0xEB660"/>
</File>
</Root>

View File

@ -1,4 +1,5 @@
<Root>
<ExternalFile XmlPath="code/sys_matrix.xml" OutPath="code/sys_matrix/"/>
<File Name="bdan_scene" Segment="2">
<Texture Name="bdan_sceneTex_013E00" OutName="bdan_sceneTex_013E00" Format="ci8" Width="32" Height="64" Offset="0x13DE0" TlutOffset="0x13BD8" AddedByScript="true"/>
<Texture Name="bdan_sceneTex_014600" OutName="bdan_sceneTex_014600" Format="ci8" Width="32" Height="32" Offset="0x145E0" TlutOffset="0x13BD8" AddedByScript="true"/>

View File

@ -1,4 +1,5 @@
<Root>
<ExternalFile XmlPath="code/sys_matrix.xml" OutPath="code/sys_matrix/"/>
<File Name="bdan_boss_scene" Segment="2">
<Scene Name="bdan_boss_scene" Offset="0x0"/>
</File>

View File

@ -22,12 +22,10 @@ extern "C"
void gSPSegment(void* value, int segNum, uintptr_t target);
void gSPSegmentLoadRes(void* value, int segNum, uintptr_t target);
void gDPSetTextureImage(Gfx* pkt, u32 f, u32 s, u32 w, uintptr_t i);
void gSPDisplayList(Gfx* pkt, Gfx* dl);
void gSPDisplayListOffset(Gfx* pkt, Gfx* dl, int offset);
void gSPVertex(Gfx* pkt, uintptr_t v, int n, int v0);
void gSPInvalidateTexCache(Gfx* pkt, uintptr_t texAddr);
void gDPSetTextureImageFB(Gfx* pkt, u32 format, u32 size, u32 width, int fb);
void cleararena(void);
@ -1261,6 +1259,8 @@ void SkelAnime_DrawFlexLod(PlayState* play, void** skeleton, Vec3s* jointTable,
s32 dListIndex);
void SkelAnime_DrawSkeletonOpa(PlayState* play, SkelAnime* skelAnime, OverrideLimbDrawOpa overrideLimbDraw,
PostLimbDrawOpa postLimbDraw, void* arg);
Gfx* SkelAnime_DrawSkeleton2(PlayState* play, SkelAnime* skelAnime, OverrideLimbDrawOpa overrideLimbDraw,
PostLimbDrawOpa postLimbDraw, void* arg, Gfx* gfx);
void SkelAnime_DrawOpa(PlayState* play, void** skeleton, Vec3s* jointTable,
OverrideLimbDrawOpa overrideLimbDraw, PostLimbDrawOpa postLimbDraw, void* arg);
void SkelAnime_DrawFlexOpa(PlayState* play, void** skeleton, Vec3s* jointTable, s32 dListCount,
@ -2466,6 +2466,8 @@ void Message_DrawText(PlayState* play, Gfx** gfxP);
void Interface_CreateQuadVertexGroup(Vtx* vtxList, s32 xStart, s32 yStart, s32 width, s32 height, u8 flippedH);
void Interface_RandoRestoreSwordless(void);
s32 Ship_CalcShouldDrawAndUpdate(PlayState* play, Actor* actor, Vec3f* projectedPos, f32 projectedW, bool* shouldDraw,
bool* shouldUpdate);
//Pause Warp
void PauseWarp_HandleSelection();

View File

@ -841,6 +841,9 @@ typedef enum {
#define PAUSE_CURSOR_PAGE_LEFT 10
#define PAUSE_CURSOR_PAGE_RIGHT 11
#define PAUSE_EQUIP_PLAYER_WIDTH 64
#define PAUSE_EQUIP_PLAYER_HEIGHT 112
typedef enum {
/* 0x00 */ PAUSE_ITEM,
/* 0x01 */ PAUSE_MAP,
@ -1481,6 +1484,8 @@ typedef struct PlayState {
/* 0x1242B */ u8 unk_1242B;
/* 0x1242C */ SceneTableEntry* loadedScene;
/* 0x12430 */ char unk_12430[0xE8];
// SOH [Custom Models] MTX tracker for flex based skeletons
Mtx** flexLimbOverrideMTX;
} PlayState; // size = 0x12518
typedef struct {

View File

@ -16,7 +16,7 @@ ActorDB* ActorDB::Instance;
#undef DEFINE_ACTOR_UNSET
struct AddPair {
std::string name;
const char* name;
ActorInit& init;
};
@ -24,7 +24,7 @@ struct AddPair {
#define DEFINE_ACTOR(name, _1, allocType) { #name, name##_InitVars },
#define DEFINE_ACTOR_UNSET(_0)
static const std::vector<AddPair> initialActorTable = {
static constexpr AddPair initialActorTable[] = {
#include "tables/actor_table.h"
};
@ -33,7 +33,7 @@ static const std::vector<AddPair> initialActorTable = {
#undef DEFINE_ACTOR
// https://wiki.cloudmodding.com/oot/Actor_List_(Variables)
static std::unordered_map<u16, const char*> actorDescriptions = {
static constexpr std::pair<u16, const char*> actorDescriptionData[] = {
{ ACTOR_PLAYER, "Link" },
{ ACTOR_EN_TEST, "Stalfos" },
{ ACTOR_EN_GIRLA, "Shop Items" },
@ -464,6 +464,7 @@ static std::unordered_map<u16, const char*> actorDescriptions = {
{ ACTOR_BG_JYA_BLOCK, "Silver Block (Child Era)" },
{ ACTOR_OBJ_WARP2BLOCK, "Navi Infospot (Green, Time Block)" }
};
static std::unordered_map<u16, const char*> actorDescriptions = std::unordered_map<u16, const char*>(std::begin(actorDescriptionData), std::end(actorDescriptionData));
ActorDB::ActorDB() {
db.reserve(ACTOR_NUMBER_MAX); // reserve size for all initial entries so we don't do it for each

View File

@ -20,6 +20,8 @@ static ImVec4 range2Color = ImVec4(0, 1.0f, 0, 1.0f);
static const char* buttonOutlineOptions[4] = { "Always Shown", "Shown Only While Not Pressed",
"Shown Only While Pressed", "Always Hidden" };
static const char* buttonOutlineOptionsVerbose[4] = { "Outline Always Shown", "Outline Shown Only While Not Pressed",
"Outline Shown Only While Pressed", "Outline Always Hidden" };
static const char* stickModeOptions[3] = { "Always", "While In Use", "Never" };
@ -85,6 +87,8 @@ void InputViewer::DrawElement() {
Ship::Context::GetInstance()->GetWindow()->GetGui()->LoadTextureFromRawImage("Dpad-Up", "textures/buttons/DPadUp.png");
Ship::Context::GetInstance()->GetWindow()->GetGui()->LoadTextureFromRawImage("Dpad-Down",
"textures/buttons/DPadDown.png");
Ship::Context::GetInstance()->GetWindow()->GetGui()->LoadTextureFromRawImage("Modifier-1", "textures/buttons/Mod1.png");
Ship::Context::GetInstance()->GetWindow()->GetGui()->LoadTextureFromRawImage("Modifier-2", "textures/buttons/Mod2.png");
Ship::Context::GetInstance()->GetWindow()->GetGui()->LoadTextureFromRawImage("Right-Stick",
"textures/buttons/RightStick.png");
Ship::Context::GetInstance()->GetWindow()->GetGui()->LoadTextureFromRawImage("A-Btn Outline",
@ -117,6 +121,10 @@ void InputViewer::DrawElement() {
"textures/buttons/DPadUpOutline.png");
Ship::Context::GetInstance()->GetWindow()->GetGui()->LoadTextureFromRawImage("Dpad-Down Outline",
"textures/buttons/DPadDownOutline.png");
Ship::Context::GetInstance()->GetWindow()->GetGui()->LoadTextureFromRawImage("Modifier-1 Outline",
"textures/buttons/Mod1Outline.png");
Ship::Context::GetInstance()->GetWindow()->GetGui()->LoadTextureFromRawImage("Modifier-2 Outline",
"textures/buttons/Mod2Outline.png");
Ship::Context::GetInstance()->GetWindow()->GetGui()->LoadTextureFromRawImage("Right-Stick Outline",
"textures/buttons/RightStickOutline.png");
sButtonTexturesLoaded = true;
@ -132,17 +140,19 @@ void InputViewer::DrawElement() {
#endif
const int showAnalogAngles = CVarGetInteger(CVAR_INPUT_VIEWER("AnalogAngles.Enabled"), 0);
const int buttonOutlineMode = CVarGetInteger(CVAR_INPUT_VIEWER("ButtonOutlineMode"), BUTTON_OUTLINE_NOT_PRESSED);
const bool useGlobalOutlineMode = CVarGetInteger(CVAR_INPUT_VIEWER("UseGlobalButtonOutlineMode"), 1);
ImVec2 bgSize = Ship::Context::GetInstance()->GetWindow()->GetGui()->GetTextureSize("Input-Viewer-Background");
ImVec2 scaledBGSize = ImVec2(bgSize.x * scale, bgSize.y * scale);
ImGui::SetNextWindowSize(ImVec2(
scaledBGSize.x + 20,
scaledBGSize.y +
(showAnalogAngles ? ImGui::CalcTextSize("X").y : 0) * scale * CVarGetFloat(CVAR_INPUT_VIEWER("AnalogAngles.Scale"), 1.0f) + 20));
ImGui::SetNextWindowSize(
ImVec2(scaledBGSize.x + 20, scaledBGSize.y +
(showAnalogAngles ? ImGui::CalcTextSize("X").y : 0) * scale *
CVarGetFloat(CVAR_INPUT_VIEWER("AnalogAngles.Scale"), 1.0f) +
20));
ImGui::SetNextWindowContentSize(
ImVec2(scaledBGSize.x, scaledBGSize.y + (showAnalogAngles ? 15 : 0) * scale *
CVarGetFloat(CVAR_INPUT_VIEWER("AnalogAngles.Scale"), 1.0f)));
CVarGetFloat(CVAR_INPUT_VIEWER("AnalogAngles.Scale"), 1.0f)));
ImGui::SetNextWindowPos(
ImVec2(mainPos.x + size.x - scaledBGSize.x - 30, mainPos.y + size.y - scaledBGSize.y - 30),
ImGuiCond_FirstUseEver);
@ -176,52 +186,78 @@ void InputViewer::DrawElement() {
if (CVarGetInteger(CVAR_INPUT_VIEWER("BBtn"), 1)) {
ImGui::SetNextItemAllowOverlap();
ImGui::SetCursorPos(aPos);
RenderButton("B-Btn", "B-Btn Outline", pads[0].button & BTN_B, scaledBGSize, buttonOutlineMode);
RenderButton("B-Btn", "B-Btn Outline", pads[0].button & BTN_B, scaledBGSize,
useGlobalOutlineMode
? buttonOutlineMode
: CVarGetInteger(CVAR_INPUT_VIEWER("BBtnOutlineMode"), BUTTON_OUTLINE_NOT_PRESSED));
}
if (CVarGetInteger(CVAR_INPUT_VIEWER("ABtn"), 1)) {
ImGui::SetNextItemAllowOverlap();
ImGui::SetCursorPos(aPos);
RenderButton("A-Btn", "A-Btn Outline", pads[0].button & BTN_A, scaledBGSize, buttonOutlineMode);
RenderButton("A-Btn", "A-Btn Outline", pads[0].button & BTN_A, scaledBGSize,
useGlobalOutlineMode
? buttonOutlineMode
: CVarGetInteger(CVAR_INPUT_VIEWER("ABtnOutlineMode"), BUTTON_OUTLINE_NOT_PRESSED));
}
// C buttons
if (CVarGetInteger(CVAR_INPUT_VIEWER("CUp"), 1)) {
ImGui::SetNextItemAllowOverlap();
ImGui::SetCursorPos(aPos);
RenderButton("C-Up", "C-Up Outline", pads[0].button & BTN_CUP, scaledBGSize, buttonOutlineMode);
RenderButton("C-Up", "C-Up Outline", pads[0].button & BTN_CUP, scaledBGSize,
useGlobalOutlineMode
? buttonOutlineMode
: CVarGetInteger(CVAR_INPUT_VIEWER("CUpOutlineMode"), BUTTON_OUTLINE_NOT_PRESSED));
}
if (CVarGetInteger(CVAR_INPUT_VIEWER("CLeft"), 1)) {
ImGui::SetNextItemAllowOverlap();
ImGui::SetCursorPos(aPos);
RenderButton("C-Left", "C-Left Outline", pads[0].button & BTN_CLEFT, scaledBGSize, buttonOutlineMode);
RenderButton("C-Left", "C-Left Outline", pads[0].button & BTN_CLEFT, scaledBGSize,
useGlobalOutlineMode
? buttonOutlineMode
: CVarGetInteger(CVAR_INPUT_VIEWER("CLeftOutlineMode"), BUTTON_OUTLINE_NOT_PRESSED));
}
if (CVarGetInteger(CVAR_INPUT_VIEWER("CRight"), 1)) {
ImGui::SetNextItemAllowOverlap();
ImGui::SetCursorPos(aPos);
RenderButton("C-Right", "C-Right Outline", pads[0].button & BTN_CRIGHT, scaledBGSize,
buttonOutlineMode);
useGlobalOutlineMode
? buttonOutlineMode
: CVarGetInteger(CVAR_INPUT_VIEWER("CRightOutlineMode"), BUTTON_OUTLINE_NOT_PRESSED));
}
if (CVarGetInteger(CVAR_INPUT_VIEWER("CDown"), 1)) {
ImGui::SetNextItemAllowOverlap();
ImGui::SetCursorPos(aPos);
RenderButton("C-Down", "C-Down Outline", pads[0].button & BTN_CDOWN, scaledBGSize, buttonOutlineMode);
RenderButton("C-Down", "C-Down Outline", pads[0].button & BTN_CDOWN, scaledBGSize,
useGlobalOutlineMode
? buttonOutlineMode
: CVarGetInteger(CVAR_INPUT_VIEWER("CDownOutlineMode"), BUTTON_OUTLINE_NOT_PRESSED));
}
// L/R/Z
if (CVarGetInteger(CVAR_INPUT_VIEWER("LBtn"), 1)) {
ImGui::SetNextItemAllowOverlap();
ImGui::SetCursorPos(aPos);
RenderButton("L-Btn", "L-Btn Outline", pads[0].button & BTN_L, scaledBGSize, buttonOutlineMode);
RenderButton("L-Btn", "L-Btn Outline", pads[0].button & BTN_L, scaledBGSize,
useGlobalOutlineMode
? buttonOutlineMode
: CVarGetInteger(CVAR_INPUT_VIEWER("LBtnOutlineMode"), BUTTON_OUTLINE_NOT_PRESSED));
}
if (CVarGetInteger(CVAR_INPUT_VIEWER("RBtn"), 1)) {
ImGui::SetNextItemAllowOverlap();
ImGui::SetCursorPos(aPos);
RenderButton("R-Btn", "R-Btn Outline", pads[0].button & BTN_R, scaledBGSize, buttonOutlineMode);
RenderButton("R-Btn", "R-Btn Outline", pads[0].button & BTN_R, scaledBGSize,
useGlobalOutlineMode
? buttonOutlineMode
: CVarGetInteger(CVAR_INPUT_VIEWER("RBtnOutlineMode"), BUTTON_OUTLINE_NOT_PRESSED));
}
if (CVarGetInteger(CVAR_INPUT_VIEWER("ZBtn"), 1)) {
ImGui::SetNextItemAllowOverlap();
ImGui::SetCursorPos(aPos);
RenderButton("Z-Btn", "Z-Btn Outline", pads[0].button & BTN_Z, scaledBGSize, buttonOutlineMode);
RenderButton("Z-Btn", "Z-Btn Outline", pads[0].button & BTN_Z, scaledBGSize,
useGlobalOutlineMode
? buttonOutlineMode
: CVarGetInteger(CVAR_INPUT_VIEWER("ZBtnOutlineMode"), BUTTON_OUTLINE_NOT_PRESSED));
}
// Start
@ -229,7 +265,9 @@ void InputViewer::DrawElement() {
ImGui::SetNextItemAllowOverlap();
ImGui::SetCursorPos(aPos);
RenderButton("Start-Btn", "Start-Btn Outline", pads[0].button & BTN_START, scaledBGSize,
buttonOutlineMode);
useGlobalOutlineMode
? buttonOutlineMode
: CVarGetInteger(CVAR_INPUT_VIEWER("StartBtnOutlineMode"), BUTTON_OUTLINE_NOT_PRESSED));
}
// Dpad
@ -237,18 +275,46 @@ void InputViewer::DrawElement() {
ImGui::SetNextItemAllowOverlap();
ImGui::SetCursorPos(aPos);
RenderButton("Dpad-Left", "Dpad-Left Outline", pads[0].button & BTN_DLEFT, scaledBGSize,
buttonOutlineMode);
useGlobalOutlineMode
? buttonOutlineMode
: CVarGetInteger(CVAR_INPUT_VIEWER("DpadOutlineMode"), BUTTON_OUTLINE_NOT_PRESSED));
ImGui::SetNextItemAllowOverlap();
ImGui::SetCursorPos(aPos);
RenderButton("Dpad-Right", "Dpad-Right Outline", pads[0].button & BTN_DRIGHT, scaledBGSize,
buttonOutlineMode);
useGlobalOutlineMode
? buttonOutlineMode
: CVarGetInteger(CVAR_INPUT_VIEWER("DpadOutlineMode"), BUTTON_OUTLINE_NOT_PRESSED));
ImGui::SetNextItemAllowOverlap();
ImGui::SetCursorPos(aPos);
RenderButton("Dpad-Up", "Dpad-Up Outline", pads[0].button & BTN_DUP, scaledBGSize, buttonOutlineMode);
RenderButton("Dpad-Up", "Dpad-Up Outline", pads[0].button & BTN_DUP, scaledBGSize,
useGlobalOutlineMode
? buttonOutlineMode
: CVarGetInteger(CVAR_INPUT_VIEWER("DpadOutlineMode"), BUTTON_OUTLINE_NOT_PRESSED));
ImGui::SetNextItemAllowOverlap();
ImGui::SetCursorPos(aPos);
RenderButton("Dpad-Down", "Dpad-Down Outline", pads[0].button & BTN_DDOWN, scaledBGSize,
buttonOutlineMode);
useGlobalOutlineMode
? buttonOutlineMode
: CVarGetInteger(CVAR_INPUT_VIEWER("DpadOutlineMode"), BUTTON_OUTLINE_NOT_PRESSED));
}
// Modifier 1
if (CVarGetInteger(CVAR_INPUT_VIEWER("Mod1"), 0)) {
ImGui::SetNextItemAllowOverlap();
ImGui::SetCursorPos(aPos);
RenderButton("Modifier-1", "Modifier-1 Outline", pads[0].button & BTN_MODIFIER1, scaledBGSize,
useGlobalOutlineMode
? buttonOutlineMode
: CVarGetInteger(CVAR_INPUT_VIEWER("Mod1OutlineMode"), BUTTON_OUTLINE_NOT_PRESSED));
}
// Modifier 2
if (CVarGetInteger(CVAR_INPUT_VIEWER("Mod2"), 0)) {
ImGui::SetNextItemAllowOverlap();
ImGui::SetCursorPos(aPos);
RenderButton("Modifier-2", "Modifier-2 Outline", pads[0].button & BTN_MODIFIER2, scaledBGSize,
useGlobalOutlineMode
? buttonOutlineMode
: CVarGetInteger(CVAR_INPUT_VIEWER("Mod2OutlineMode"), BUTTON_OUTLINE_NOT_PRESSED));
}
const bool analogStickIsInDeadzone = !pads[0].stick_x && !pads[0].stick_y;
@ -359,9 +425,9 @@ InputViewerSettingsWindow::~InputViewerSettingsWindow() {
}
void InputViewerSettingsWindow::DrawElement() {
ImGui::SetNextWindowSize(ImVec2(450, 525), ImGuiCond_FirstUseEver);
ImGui::SetNextWindowSize(ImVec2(500, 525), ImGuiCond_FirstUseEver);
if (ImGui::Begin("Input Viewer Settings", &mIsVisible)) {
if (ImGui::Begin("Input Viewer Settings", &mIsVisible, ImGuiWindowFlags_HorizontalScrollbar)) {
// gInputViewer.Scale
UIWidgets::EnhancementSliderFloat("Input Viewer Scale: %.2f", "##Input", CVAR_INPUT_VIEWER("Scale"), 0.1f, 5.0f, "",
@ -381,48 +447,143 @@ void InputViewerSettingsWindow::DrawElement() {
UIWidgets::PaddedSeparator(true, true);
if (ImGui::CollapsingHeader("Buttons")) {
// gInputViewer.ABtn
UIWidgets::EnhancementCheckbox("Show A-Button Layers", CVAR_INPUT_VIEWER("ABtn"), false, "",
UIWidgets::CheckboxGraphics::Checkmark, true);
// gInputViewer.BBtn
UIWidgets::EnhancementCheckbox("Show B-Button Layers", CVAR_INPUT_VIEWER("BBtn"), false, "",
UIWidgets::CheckboxGraphics::Checkmark, true);
// gInputViewer.CUp
UIWidgets::EnhancementCheckbox("Show C-Up Layers", CVAR_INPUT_VIEWER("CUp"), false, "",
UIWidgets::CheckboxGraphics::Checkmark, true);
// gInputViewer.CRight
UIWidgets::EnhancementCheckbox("Show C-Right Layers", CVAR_INPUT_VIEWER("CRight"), false, "",
UIWidgets::CheckboxGraphics::Checkmark, true);
// gInputViewer.CDown
UIWidgets::EnhancementCheckbox("Show C-Down Layers", CVAR_INPUT_VIEWER("CDown"), false, "",
UIWidgets::CheckboxGraphics::Checkmark, true);
// gInputViewer.CLeft
UIWidgets::EnhancementCheckbox("Show C-Left Layers", CVAR_INPUT_VIEWER("CLeft"), false, "",
UIWidgets::CheckboxGraphics::Checkmark, true);
// gInputViewer.LBtn
UIWidgets::EnhancementCheckbox("Show L-Button Layers", CVAR_INPUT_VIEWER("LBtn"), false, "",
UIWidgets::CheckboxGraphics::Checkmark, true);
// gInputViewer.RBtn
UIWidgets::EnhancementCheckbox("Show R-Button Layers", CVAR_INPUT_VIEWER("RBtn"), false, "",
UIWidgets::CheckboxGraphics::Checkmark, true);
// gInputViewer.ZBtn
UIWidgets::EnhancementCheckbox("Show Z-Button Layers", CVAR_INPUT_VIEWER("ZBtn"), false, "",
UIWidgets::CheckboxGraphics::Checkmark, true);
// gInputViewer.StartBtn
UIWidgets::EnhancementCheckbox("Show Start Button Layers", CVAR_INPUT_VIEWER("StartBtn"), false, "",
UIWidgets::CheckboxGraphics::Checkmark, true);
// gInputViewer.Dpad
UIWidgets::EnhancementCheckbox("Show D-Pad Layers", CVAR_INPUT_VIEWER("Dpad"), false, "",
UIWidgets::CheckboxGraphics::Checkmark, false);
// gInputViewer.ButtonOutlineMode
UIWidgets::PaddedText("Button Outlines/Backgrounds", true, false);
UIWidgets::EnhancementCombobox(CVAR_INPUT_VIEWER("ButtonOutlineMode"), buttonOutlineOptions,
BUTTON_OUTLINE_NOT_PRESSED);
UIWidgets::EnhancementCombobox(
CVAR_INPUT_VIEWER("ButtonOutlineMode"), buttonOutlineOptions, BUTTON_OUTLINE_NOT_PRESSED,
!CVarGetInteger(CVAR_INPUT_VIEWER("UseGlobalButtonOutlineMode"), 1), "",
CVarGetInteger(CVAR_INPUT_VIEWER("ButtonOutlineMode"), BUTTON_OUTLINE_NOT_PRESSED));
UIWidgets::Tooltip(
"Sets the desired visibility behavior for the button outline/background layers. Useful for "
"custom input viewers.");
// gInputViewer.UseGlobalButtonOutlineMode
UIWidgets::EnhancementCheckbox("Use for all buttons", CVAR_INPUT_VIEWER("UseGlobalButtonOutlineMode"), false, "",
UIWidgets::CheckboxGraphics::Checkmark, true);
UIWidgets::PaddedSeparator();
bool useIndividualOutlines = !CVarGetInteger(CVAR_INPUT_VIEWER("UseGlobalButtonOutlineMode"), 1);
// gInputViewer.ABtn
UIWidgets::EnhancementCheckbox("Show A-Button Layers", CVAR_INPUT_VIEWER("ABtn"), false, "",
UIWidgets::CheckboxGraphics::Checkmark, true);
if (useIndividualOutlines && CVarGetInteger(CVAR_INPUT_VIEWER("ABtn"), 1)) {
ImGui::Indent();
UIWidgets::EnhancementCombobox(CVAR_INPUT_VIEWER("ABtnOutlineMode"), buttonOutlineOptionsVerbose,
BUTTON_OUTLINE_NOT_PRESSED);
ImGui::Unindent();
}
// gInputViewer.BBtn
UIWidgets::EnhancementCheckbox("Show B-Button Layers", CVAR_INPUT_VIEWER("BBtn"), false, "",
UIWidgets::CheckboxGraphics::Checkmark, true);
if (useIndividualOutlines && CVarGetInteger(CVAR_INPUT_VIEWER("BBtn"), 1)) {
ImGui::Indent();
UIWidgets::EnhancementCombobox(CVAR_INPUT_VIEWER("BBtnOutlineMode"), buttonOutlineOptionsVerbose,
BUTTON_OUTLINE_NOT_PRESSED);
ImGui::Unindent();
}
// gInputViewer.CUp
UIWidgets::EnhancementCheckbox("Show C-Up Layers", CVAR_INPUT_VIEWER("CUp"), false, "",
UIWidgets::CheckboxGraphics::Checkmark, true);
if (useIndividualOutlines && CVarGetInteger(CVAR_INPUT_VIEWER("CUp"), 1)) {
ImGui::Indent();
UIWidgets::EnhancementCombobox(CVAR_INPUT_VIEWER("CUpOutlineMode"), buttonOutlineOptionsVerbose,
BUTTON_OUTLINE_NOT_PRESSED);
ImGui::Unindent();
}
// gInputViewer.CRight
UIWidgets::EnhancementCheckbox("Show C-Right Layers", CVAR_INPUT_VIEWER("CRight"), false, "",
UIWidgets::CheckboxGraphics::Checkmark, true);
if (useIndividualOutlines && CVarGetInteger(CVAR_INPUT_VIEWER("CRight"), 1)) {
ImGui::Indent();
UIWidgets::EnhancementCombobox(CVAR_INPUT_VIEWER("CRightOutlineMode"), buttonOutlineOptionsVerbose,
BUTTON_OUTLINE_NOT_PRESSED);
ImGui::Unindent();
}
// gInputViewer.CDown
UIWidgets::EnhancementCheckbox("Show C-Down Layers", CVAR_INPUT_VIEWER("CDown"), false, "",
UIWidgets::CheckboxGraphics::Checkmark, true);
if (useIndividualOutlines && CVarGetInteger(CVAR_INPUT_VIEWER("CDown"), 1)) {
ImGui::Indent();
UIWidgets::EnhancementCombobox(CVAR_INPUT_VIEWER("CDownOutlineMode"), buttonOutlineOptionsVerbose,
BUTTON_OUTLINE_NOT_PRESSED);
ImGui::Unindent();
}
// gInputViewer.CLeft
UIWidgets::EnhancementCheckbox("Show C-Left Layers", CVAR_INPUT_VIEWER("CLeft"), false, "",
UIWidgets::CheckboxGraphics::Checkmark, true);
if (useIndividualOutlines && CVarGetInteger(CVAR_INPUT_VIEWER("CLeft"), 1)) {
ImGui::Indent();
UIWidgets::EnhancementCombobox(CVAR_INPUT_VIEWER("CLeftOutlineMode"), buttonOutlineOptionsVerbose,
BUTTON_OUTLINE_NOT_PRESSED);
ImGui::Unindent();
}
// gInputViewer.LBtn
UIWidgets::EnhancementCheckbox("Show L-Button Layers", CVAR_INPUT_VIEWER("LBtn"), false, "",
UIWidgets::CheckboxGraphics::Checkmark, true);
if (useIndividualOutlines && CVarGetInteger(CVAR_INPUT_VIEWER("LBtn"), 1)) {
ImGui::Indent();
UIWidgets::EnhancementCombobox(CVAR_INPUT_VIEWER("LBtnOutlineMode"), buttonOutlineOptionsVerbose,
BUTTON_OUTLINE_NOT_PRESSED);
ImGui::Unindent();
}
// gInputViewer.RBtn
UIWidgets::EnhancementCheckbox("Show R-Button Layers", CVAR_INPUT_VIEWER("RBtn"), false, "",
UIWidgets::CheckboxGraphics::Checkmark, true);
if (useIndividualOutlines && CVarGetInteger(CVAR_INPUT_VIEWER("RBtn"), 1)) {
ImGui::Indent();
UIWidgets::EnhancementCombobox(CVAR_INPUT_VIEWER("RBtnOutlineMode"), buttonOutlineOptionsVerbose,
BUTTON_OUTLINE_NOT_PRESSED);
ImGui::Unindent();
}
// gInputViewer.ZBtn
UIWidgets::EnhancementCheckbox("Show Z-Button Layers", CVAR_INPUT_VIEWER("ZBtn"), false, "",
UIWidgets::CheckboxGraphics::Checkmark, true);
if (useIndividualOutlines && CVarGetInteger(CVAR_INPUT_VIEWER("ZBtn"), 1)) {
ImGui::Indent();
UIWidgets::EnhancementCombobox(CVAR_INPUT_VIEWER("ZBtnOutlineMode"), buttonOutlineOptionsVerbose,
BUTTON_OUTLINE_NOT_PRESSED);
ImGui::Unindent();
}
// gInputViewer.StartBtn
UIWidgets::EnhancementCheckbox("Show Start Button Layers", CVAR_INPUT_VIEWER("StartBtn"), false, "",
UIWidgets::CheckboxGraphics::Checkmark, true);
if (useIndividualOutlines && CVarGetInteger(CVAR_INPUT_VIEWER("StartBtn"), 1)) {
ImGui::Indent();
UIWidgets::EnhancementCombobox(CVAR_INPUT_VIEWER("StartBtnOutlineMode"), buttonOutlineOptionsVerbose,
BUTTON_OUTLINE_NOT_PRESSED);
ImGui::Unindent();
}
// gInputViewer.Dpad
UIWidgets::EnhancementCheckbox("Show D-Pad Layers", CVAR_INPUT_VIEWER("Dpad"), false, "",
UIWidgets::CheckboxGraphics::Checkmark, false);
if (useIndividualOutlines && CVarGetInteger(CVAR_INPUT_VIEWER("Dpad"), 0)) {
ImGui::Indent();
UIWidgets::EnhancementCombobox(CVAR_INPUT_VIEWER("DpadOutlineMode"), buttonOutlineOptionsVerbose,
BUTTON_OUTLINE_NOT_PRESSED);
ImGui::Unindent();
}
// gInputViewer.Mod1
UIWidgets::EnhancementCheckbox("Show Modifier Button 1 Layers", CVAR_INPUT_VIEWER("Mod1"), false, "",
UIWidgets::CheckboxGraphics::Checkmark, false);
if (useIndividualOutlines && CVarGetInteger(CVAR_INPUT_VIEWER("Mod1"), 0)) {
ImGui::Indent();
UIWidgets::EnhancementCombobox(CVAR_INPUT_VIEWER("Mod1OutlineMode"), buttonOutlineOptionsVerbose,
BUTTON_OUTLINE_NOT_PRESSED);
ImGui::Unindent();
}
// gInputViewer.Mod2
UIWidgets::EnhancementCheckbox("Show Modifier Button 2 Layers", CVAR_INPUT_VIEWER("Mod2"), false, "",
UIWidgets::CheckboxGraphics::Checkmark, false);
if (useIndividualOutlines && CVarGetInteger(CVAR_INPUT_VIEWER("Mod2"), 0)) {
ImGui::Indent();
UIWidgets::EnhancementCombobox(CVAR_INPUT_VIEWER("Mod2OutlineMode"), buttonOutlineOptionsVerbose,
BUTTON_OUTLINE_NOT_PRESSED);
ImGui::Unindent();
}
UIWidgets::PaddedSeparator(true, true);
}
@ -517,4 +678,4 @@ void InputViewerSettingsWindow::DrawElement() {
ImGui::End();
}
}
}

View File

@ -38,6 +38,13 @@ void SohInputEditorWindow::InitElement() {
addButtonName(BTN_DLEFT, "D-pad left");
addButtonName(BTN_DRIGHT, "D-pad right");
addButtonName(0, "None");
mDeviceIndexVisiblity.clear();
mDeviceIndexVisiblity[Ship::ShipDeviceIndex::Keyboard] = true;
mDeviceIndexVisiblity[Ship::ShipDeviceIndex::Blue] = true;
for (auto index = 1; index < Ship::ShipDeviceIndex::Max; index++) {
mDeviceIndexVisiblity[static_cast<Ship::ShipDeviceIndex>(index)] = false;
}
}
#define INPUT_EDITOR_WINDOW_GAME_INPUT_BLOCK_ID 95237929
@ -251,6 +258,9 @@ void SohInputEditorWindow::DrawButtonLineEditMappingButton(uint8_t port, uint16_
if (mapping == nullptr) {
return;
}
if (!mDeviceIndexVisiblity[mapping->GetShipDeviceIndex()]) {
return;
}
ImGui::PushStyleVar(ImGuiStyleVar_ButtonTextAlign, ImVec2(0.0f, 0.5f));
std::string icon = "";
@ -521,6 +531,9 @@ void SohInputEditorWindow::DrawStickDirectionLineEditMappingButton(uint8_t port,
if (mapping == nullptr) {
return;
}
if (!mDeviceIndexVisiblity[mapping->GetShipDeviceIndex()]) {
return;
}
ImGui::PushStyleVar(ImGuiStyleVar_ButtonTextAlign, ImVec2(0.0f, 0.5f));
std::string icon = "";
@ -1705,11 +1718,75 @@ void SohInputEditorWindow::DrawMiscControlPanel() {
Ship::GuiWindow::EndGroupPanel(0);
}
void SohInputEditorWindow::DrawDeviceVisibilityButtons() {
std::map<Ship::ShipDeviceIndex, std::pair<std::string, int32_t>> indexMappings;
for (auto [lusIndex, mapping] : Ship::Context::GetInstance()
->GetControlDeck()
->GetDeviceIndexMappingManager()
->GetAllDeviceIndexMappingsFromConfig()) {
auto sdlIndexMapping = std::static_pointer_cast<Ship::ShipDeviceIndexToSDLDeviceIndexMapping>(mapping);
if (sdlIndexMapping == nullptr) {
continue;
}
indexMappings[lusIndex] = { sdlIndexMapping->GetSDLControllerName(), -1 };
}
for (auto [lusIndex, mapping] : Ship::Context::GetInstance()
->GetControlDeck()
->GetDeviceIndexMappingManager()
->GetAllDeviceIndexMappings()) {
auto sdlIndexMapping = std::static_pointer_cast<Ship::ShipDeviceIndexToSDLDeviceIndexMapping>(mapping);
if (sdlIndexMapping == nullptr) {
continue;
}
indexMappings[lusIndex] = { sdlIndexMapping->GetSDLControllerName(), sdlIndexMapping->GetSDLDeviceIndex() };
}
auto keyboardButtonColor = ImGui::GetStyleColorVec4(ImGuiCol_Button);
auto keyboardButtonHoveredColor = ImGui::GetStyleColorVec4(ImGuiCol_ButtonHovered);
GetButtonColorsForLUSDeviceIndex(Ship::ShipDeviceIndex::Keyboard, keyboardButtonColor, keyboardButtonHoveredColor);
ImGui::PushStyleColor(ImGuiCol_Button, keyboardButtonColor);
ImGui::PushStyleColor(ImGuiCol_ButtonHovered, keyboardButtonHoveredColor);
bool keyboardVisible = mDeviceIndexVisiblity[Ship::ShipDeviceIndex::Keyboard];
if(ImGui::Button(
StringHelper::Sprintf("%s %s Keyboard", keyboardVisible ? ICON_FA_EYE : ICON_FA_EYE_SLASH, ICON_FA_KEYBOARD_O)
.c_str())) {
mDeviceIndexVisiblity[Ship::ShipDeviceIndex::Keyboard] = !keyboardVisible;
}
ImGui::PopStyleColor();
ImGui::PopStyleColor();
for (auto [lusIndex, info] : indexMappings) {
auto [name, sdlIndex] = info;
bool connected = sdlIndex != -1;
auto buttonColor = ImGui::GetStyleColorVec4(ImGuiCol_Button);
auto buttonHoveredColor = ImGui::GetStyleColorVec4(ImGuiCol_ButtonHovered);
GetButtonColorsForLUSDeviceIndex(lusIndex, buttonColor, buttonHoveredColor);
ImGui::PushStyleColor(ImGuiCol_Button, buttonColor);
ImGui::PushStyleColor(ImGuiCol_ButtonHovered, buttonHoveredColor);
bool visible = mDeviceIndexVisiblity[lusIndex];
if(ImGui::Button(
StringHelper::Sprintf("%s %s %s (%s)", visible ? ICON_FA_EYE : ICON_FA_EYE_SLASH, connected ? ICON_FA_GAMEPAD : ICON_FA_CHAIN_BROKEN, name.c_str(),
connected ? StringHelper::Sprintf("SDL %d", sdlIndex).c_str() : "Disconnected")
.c_str())) {
mDeviceIndexVisiblity[lusIndex] = !visible;
}
ImGui::PopStyleColor();
ImGui::PopStyleColor();
}
}
void SohInputEditorWindow::DrawLinkTab() {
uint8_t portIndex = 0;
if (ImGui::BeginTabItem(StringHelper::Sprintf("Link (P1)###port%d", portIndex).c_str())) {
DrawClearAllButton(portIndex);
DrawSetDefaultsButton(portIndex);
DrawDeviceVisibilityButtons();
UpdateBitmaskToMappingIds(portIndex);
UpdateStickDirectionToMappingIds(portIndex);
@ -1848,6 +1925,7 @@ void SohInputEditorWindow::DrawIvanTab() {
if (ImGui::BeginTabItem(StringHelper::Sprintf("Ivan (P2)###port%d", portIndex).c_str())) {
DrawClearAllButton(portIndex);
DrawSetDefaultsButton(portIndex);
DrawDeviceVisibilityButtons();
UpdateBitmaskToMappingIds(portIndex);
UpdateStickDirectionToMappingIds(portIndex);
@ -1903,6 +1981,7 @@ void SohInputEditorWindow::DrawDebugPortTab(uint8_t portIndex, std::string custo
: customName.c_str())) {
DrawClearAllButton(portIndex);
DrawSetDefaultsButton(portIndex);
DrawDeviceVisibilityButtons();
UpdateBitmaskToMappingIds(portIndex);
UpdateStickDirectionToMappingIds(portIndex);
@ -1972,133 +2051,6 @@ void SohInputEditorWindow::DrawClearAllButton(uint8_t portIndex) {
}
}
#ifdef __WIIU__
void SohInputEditorWindow::DrawSetDefaultsButton(uint8_t portIndex) {
ImGui::SameLine();
ImGui::PushStyleVar(ImGuiStyleVar_ButtonTextAlign, ImVec2(1.0f, 0.5f));
auto popupId = StringHelper::Sprintf("setDefaultsPopup##%d", portIndex);
if (ImGui::Button(StringHelper::Sprintf("Set defaults...##%d", portIndex).c_str())) {
ImGui::OpenPopup(popupId.c_str());
}
ImGui::PopStyleVar();
if (ImGui::BeginPopup(popupId.c_str())) {
std::map<Ship::ShipDeviceIndex, std::pair<std::string, int32_t>> indexMappings;
for (auto [lusIndex, mapping] : Ship::Context::GetInstance()
->GetControlDeck()
->GetDeviceIndexMappingManager()
->GetAllDeviceIndexMappings()) {
auto wiiuIndexMapping = std::static_pointer_cast<Ship::ShipDeviceIndexToWiiUDeviceIndexMapping>(mapping);
if (wiiuIndexMapping == nullptr) {
continue;
}
indexMappings[lusIndex] = { wiiuIndexMapping->GetWiiUControllerName(),
wiiuIndexMapping->IsWiiUGamepad() ? INT32_MAX
: wiiuIndexMapping->GetDeviceChannel() };
}
bool shouldClose = false;
for (auto [lusIndex, info] : indexMappings) {
auto [name, wiiuChannel] = info;
bool isGamepad = wiiuChannel == INT32_MAX;
auto buttonColor = ImGui::GetStyleColorVec4(ImGuiCol_Button);
auto buttonHoveredColor = ImGui::GetStyleColorVec4(ImGuiCol_ButtonHovered);
GetButtonColorsForLUSDeviceIndex(lusIndex, buttonColor, buttonHoveredColor);
ImGui::PushStyleColor(ImGuiCol_Button, buttonColor);
ImGui::PushStyleColor(ImGuiCol_ButtonHovered, buttonHoveredColor);
auto fancyName = StringHelper::Sprintf(
"%s%s", name.c_str(), isGamepad ? "" : StringHelper::Sprintf(" (%d)", wiiuChannel).c_str());
if (ImGui::Button(StringHelper::Sprintf("%s %s", ICON_FA_GAMEPAD, fancyName.c_str()).c_str())) {
ImGui::OpenPopup(StringHelper::Sprintf("Set Defaults for %s", name.c_str()).c_str());
}
ImGui::PopStyleColor();
ImGui::PopStyleColor();
if (ImGui::BeginPopupModal(StringHelper::Sprintf("Set Defaults for %s", name.c_str()).c_str(), NULL,
ImGuiWindowFlags_AlwaysAutoResize)) {
ImGui::Text("This will clear all existing mappings for\n%s on port %d.\n\nContinue?", fancyName.c_str(),
portIndex + 1);
if (ImGui::Button("Cancel")) {
shouldClose = true;
ImGui::CloseCurrentPopup();
}
if (ImGui::Button("Set defaults")) {
Ship::Context::GetInstance()
->GetControlDeck()
->GetControllerByPort(portIndex)
->ClearAllMappingsForDevice(lusIndex);
Ship::Context::GetInstance()->GetControlDeck()->GetControllerByPort(portIndex)->AddDefaultMappings(
lusIndex);
shouldClose = true;
ImGui::CloseCurrentPopup();
}
ImGui::EndPopup();
}
}
if (ImGui::Button("Cancel") || shouldClose) {
ImGui::CloseCurrentPopup();
}
ImGui::EndPopup();
}
}
void SohInputEditorWindow::DrawDevicesTab() {
if (ImGui::BeginTabItem("Devices")) {
std::map<Ship::ShipDeviceIndex, std::pair<std::string, int32_t>> indexMappings;
for (auto [lusIndex, mapping] : Ship::Context::GetInstance()
->GetControlDeck()
->GetDeviceIndexMappingManager()
->GetAllDeviceIndexMappingsFromConfig()) {
auto wiiuIndexMapping = std::static_pointer_cast<Ship::ShipDeviceIndexToWiiUDeviceIndexMapping>(mapping);
if (wiiuIndexMapping == nullptr) {
continue;
}
indexMappings[lusIndex] = { wiiuIndexMapping->GetWiiUControllerName(), -1 };
}
for (auto [lusIndex, mapping] : Ship::Context::GetInstance()
->GetControlDeck()
->GetDeviceIndexMappingManager()
->GetAllDeviceIndexMappings()) {
auto wiiuIndexMapping = std::static_pointer_cast<Ship::ShipDeviceIndexToWiiUDeviceIndexMapping>(mapping);
if (wiiuIndexMapping == nullptr) {
continue;
}
indexMappings[lusIndex] = { wiiuIndexMapping->GetWiiUControllerName(),
wiiuIndexMapping->IsWiiUGamepad() ? INT32_MAX
: wiiuIndexMapping->GetDeviceChannel() };
}
for (auto [lusIndex, info] : indexMappings) {
auto [name, wiiuChannel] = info;
bool connected = wiiuChannel != -1;
bool isGamepad = wiiuChannel == INT32_MAX;
auto buttonColor = ImGui::GetStyleColorVec4(ImGuiCol_Button);
auto buttonHoveredColor = ImGui::GetStyleColorVec4(ImGuiCol_ButtonHovered);
GetButtonColorsForLUSDeviceIndex(lusIndex, buttonColor, buttonHoveredColor);
ImGui::PushItemFlag(ImGuiItemFlags_Disabled, true);
ImGui::PushStyleColor(ImGuiCol_Button, buttonColor);
ImGui::Button(StringHelper::Sprintf("%s %s%s", connected ? ICON_FA_GAMEPAD : ICON_FA_CHAIN_BROKEN,
name.c_str(),
!connected ? " (Disconnected)"
: isGamepad ? ""
: StringHelper::Sprintf(" (%d)", wiiuChannel).c_str())
.c_str());
ImGui::PopStyleColor();
ImGui::PopItemFlag();
}
ImGui::EndTabItem();
}
}
#else
void SohInputEditorWindow::DrawSetDefaultsButton(uint8_t portIndex) {
ImGui::SameLine();
auto popupId = StringHelper::Sprintf("setDefaultsPopup##%d", portIndex);
@ -2192,55 +2144,6 @@ void SohInputEditorWindow::DrawSetDefaultsButton(uint8_t portIndex) {
}
}
void SohInputEditorWindow::DrawDevicesTab() {
if (ImGui::BeginTabItem("Devices")) {
std::map<Ship::ShipDeviceIndex, std::pair<std::string, int32_t>> indexMappings;
for (auto [lusIndex, mapping] : Ship::Context::GetInstance()
->GetControlDeck()
->GetDeviceIndexMappingManager()
->GetAllDeviceIndexMappingsFromConfig()) {
auto sdlIndexMapping = std::static_pointer_cast<Ship::ShipDeviceIndexToSDLDeviceIndexMapping>(mapping);
if (sdlIndexMapping == nullptr) {
continue;
}
indexMappings[lusIndex] = { sdlIndexMapping->GetSDLControllerName(), -1 };
}
for (auto [lusIndex, mapping] : Ship::Context::GetInstance()
->GetControlDeck()
->GetDeviceIndexMappingManager()
->GetAllDeviceIndexMappings()) {
auto sdlIndexMapping = std::static_pointer_cast<Ship::ShipDeviceIndexToSDLDeviceIndexMapping>(mapping);
if (sdlIndexMapping == nullptr) {
continue;
}
indexMappings[lusIndex] = { sdlIndexMapping->GetSDLControllerName(), sdlIndexMapping->GetSDLDeviceIndex() };
}
for (auto [lusIndex, info] : indexMappings) {
auto [name, sdlIndex] = info;
bool connected = sdlIndex != -1;
auto buttonColor = ImGui::GetStyleColorVec4(ImGuiCol_Button);
auto buttonHoveredColor = ImGui::GetStyleColorVec4(ImGuiCol_ButtonHovered);
GetButtonColorsForLUSDeviceIndex(lusIndex, buttonColor, buttonHoveredColor);
ImGui::PushItemFlag(ImGuiItemFlags_Disabled, true);
ImGui::PushStyleColor(ImGuiCol_Button, buttonColor);
ImGui::Button(
StringHelper::Sprintf("%s %s (%s)", connected ? ICON_FA_GAMEPAD : ICON_FA_CHAIN_BROKEN, name.c_str(),
connected ? StringHelper::Sprintf("SDL %d", sdlIndex).c_str() : "Disconnected")
.c_str());
ImGui::PopStyleColor();
ImGui::PopItemFlag();
}
ImGui::EndTabItem();
}
}
#endif
void SohInputEditorWindow::DrawElement() {
ImGui::Begin("Controller Configuration###sohControllerConfigWindowV1", &mIsVisible);
ImGui::BeginTabBar("##ControllerConfigPortTabs");
@ -2250,7 +2153,6 @@ void SohInputEditorWindow::DrawElement() {
DrawDebugPortTab(2);
DrawDebugPortTab(3);
}
DrawDevicesTab();
ImGui::EndTabBar();
ImGui::End();
}

View File

@ -92,7 +92,6 @@ class SohInputEditorWindow : public Ship::GuiWindow {
void DrawLinkTab();
void DrawIvanTab();
void DrawDebugPortTab(uint8_t portIndex, std::string customName = "");
void DrawDevicesTab();
std::set<uint16_t> mButtonsBitmasks;
std::set<uint16_t> mDpadBitmasks;
std::set<uint16_t> mModifierButtonsBitmasks;
@ -104,4 +103,7 @@ class SohInputEditorWindow : public Ship::GuiWindow {
bool mInputEditorPopupOpen;
void DrawSetDefaultsButton(uint8_t portIndex);
void DrawClearAllButton(uint8_t portIndex);
std::map<Ship::ShipDeviceIndex, bool> mDeviceIndexVisiblity;
void DrawDeviceVisibilityButtons();
};

View File

@ -9,7 +9,6 @@ extern "C" {
#include "objects/object_gi_soldout/object_gi_soldout.h"
#include "objects/object_ik/object_ik.h"
#include "objects/object_link_child/object_link_child.h"
#include "objects/object_ru2/object_ru2.h"
uint32_t ResourceMgr_GameHasMasterQuest();
uint32_t ResourceMgr_GameHasOriginal();
@ -189,25 +188,10 @@ void PatchIronKnuckleTextureOverflow() {
}
}
void PatchPrincessRutoEaring() {
// FAST3D: This is a hack for the issue of both TEXEL0 and TEXEL1 using the same texture with different settings.
// Ruto's earring uses both TEXEL0 and TEXEL1 to render. The issue is that it never loads anything into TEXEL1, so
// it reuses whatever happens to be there, which is the water temple brick texture. It just so happens that the
// earring texture loads into the same place in TMEM as the brick texture, so when it comes to rendering, TEXEL1
// uses the earring texture with different clamp settings, and it displays without noticeable error. However, both
// texel samplers are not intended to be used for the same texture with different settings, so this misuse confuses
// our texture cache, and we load the wrong settings for the earrings texture. This patch is a hack that replaces
// TEXEL1 with TEXEL0, which is most likely the original intention, and all is well.
ResourceMgr_PatchGfxByName(gAdultRutoHeadDL, "RutoEaringTileFix", 162,
gsDPSetCombineLERP(TEXEL0, 0, PRIMITIVE, 0, TEXEL0, 0, ENVIRONMENT, 0, 0, 0, 0, COMBINED,
TEXEL0, 0, PRIM_LOD_FRAC, COMBINED));
}
void ApplyAuthenticGfxPatches() {
PatchDekuStickTextureOverflow();
PatchFreezardTextureOverflow();
PatchIronKnuckleTextureOverflow();
PatchPrincessRutoEaring();
}
// Patches the Sold Out GI DL to render the texture in the mirror boundary

View File

@ -782,7 +782,7 @@ void DrawFlagTableArray16(const FlagTable& flagTable, uint16_t row, uint16_t& fl
ImGui::PopStyleColor();
if (ImGui::IsItemHovered() && hasDescription) {
ImGui::BeginTooltip();
ImGui::Text("%s", UIWidgets::WrappedText(flagTable.flagDescriptions.at(row * 16 + flagIndex), 60));
ImGui::Text("%s", UIWidgets::WrappedText(flagTable.flagDescriptions.at(row * 16 + flagIndex), 60).c_str());
ImGui::EndTooltip();
}
ImGui::PopID();

View File

@ -200,6 +200,10 @@ const std::vector<const char*> enhancementsCvars = {
CVAR_ENHANCEMENT("OcarinaGame.RoundOneNotes"),
CVAR_ENHANCEMENT("OcarinaGame.RoundTwoNotes"),
CVAR_ENHANCEMENT("OcarinaGame.RoundThreeNotes"),
CVAR_ENHANCEMENT("CustomizeFrogsOcarinaGame"),
CVAR_ENHANCEMENT("InstantFrogsGameWin"),
CVAR_ENHANCEMENT("FrogsUnlimitedFailTime"),
CVAR_ENHANCEMENT("FrogsModifyFailTime"),
CVAR_ENHANCEMENT("CreditsFix"),
CVAR_ENHANCEMENT("SilverRupeeJingleExtend"),
CVAR_ENHANCEMENT("StaticExplosionRadius"),
@ -222,6 +226,8 @@ const std::vector<const char*> enhancementsCvars = {
CVAR_ENHANCEMENT("DisableLOD"),
CVAR_ENHANCEMENT("DisableDrawDistance"),
CVAR_ENHANCEMENT("DisableKokiriDrawDistance"),
CVAR_ENHANCEMENT("WidescreenActorCulling"),
CVAR_ENHANCEMENT("ExtendedCullingExcludeGlitchActors"),
CVAR_LOW_RES_MODE,
CVAR_ENHANCEMENT("DrawLineupTick"),
CVAR_ENHANCEMENT("QuickBongoKill"),

View File

@ -6,7 +6,9 @@
#include <vector>
#include <map>
#define TWO_ACTOR_PARAMS(a, b) (abs(a) << 16) | abs(b)
// ABS macro to use since `std::abs` is not constexpr yet
#define ABS(x) ((x) < 0 ? -(x) : (x))
#define TWO_ACTOR_PARAMS(a, b) (ABS(a) << 16) | ABS(b)
namespace RandomizerCheckObjects {
bool AreaIsDungeon(RandomizerCheckArea area);

View File

@ -5,7 +5,6 @@
#include <cstdio> // std::sprintf
#include <spdlog/spdlog.h>
#include <spdlog/fmt/fmt.h>
#include <soh/OTRGlobals.h>
#include <soh/OTRAudio.h>
@ -25,19 +24,6 @@
extern "C" PlayState* gPlayState;
template <> struct fmt::formatter<RequestType> {
constexpr auto parse(format_parse_context& ctx) { return ctx.begin(); }
template <typename FormatContext>
auto format(const RequestType& type, FormatContext& ctx) {
switch (type) {
case RequestType::SAVE: return fmt::format_to(ctx.out(), "Save");
case RequestType::LOAD: return fmt::format_to(ctx.out(), "Load");
default: return fmt::format_to(ctx.out(), "Unknown");
}
}
};
// FROM z_lights.c
// I didn't feel like moving it into a header file.
#define LIGHTS_BUFFER_SIZE 32
@ -862,11 +848,11 @@ void SaveStateMgr::ProcessSaveStateRequests(void) {
this->states[request.slot]->Load();
Ship::Context::GetInstance()->GetWindow()->GetGui()->GetGameOverlay()->TextDrawNotification(1.0f, true, "loaded state %u", request.slot);
} else {
SPDLOG_ERROR("Invalid SaveState slot: {}", request.type);
SPDLOG_ERROR("Invalid SaveState slot: {}", request.slot);
}
break;
[[unlikely]] default:
SPDLOG_ERROR("Invalid SaveState request type: {}", request.type);
SPDLOG_ERROR("Invalid SaveState request type: Unknown ({})", static_cast<int>(request.type));
break;
}
this->requests.pop();
@ -889,12 +875,12 @@ SaveStateReturn SaveStateMgr::AddRequest(const SaveStateRequest request) {
requests.push(request);
return SaveStateReturn::SUCCESS;
} else {
SPDLOG_ERROR("Invalid SaveState slot: {}", request.type);
SPDLOG_ERROR("Invalid SaveState slot: {}", request.slot);
Ship::Context::GetInstance()->GetWindow()->GetGui()->GetGameOverlay()->TextDrawNotification(1.0f, true, "state slot %u empty", request.slot);
return SaveStateReturn::FAIL_INVALID_SLOT;
}
[[unlikely]] default:
SPDLOG_ERROR("Invalid SaveState request type: {}", request.type);
SPDLOG_ERROR("Invalid SaveState request type: Unknown ({})", static_cast<int>(request.type));
return SaveStateReturn::FAIL_BAD_REQUEST;
}
}

View File

@ -66,15 +66,6 @@ extern "C" void gSPSegmentLoadRes(void* value, int segNum, uintptr_t target) {
__gSPSegment(value, segNum, target);
}
extern "C" void gDPSetTextureImage(Gfx* pkt, u32 format, u32 size, u32 width, uintptr_t i) {
__gDPSetTextureImage(pkt, format, size, width, i);
}
extern "C" void gDPSetTextureImageFB(Gfx* pkt, u32 format, u32 size, u32 width, int fb)
{
__gDPSetTextureImageFB(pkt, format, size, width, fb);
}
extern "C" void gSPDisplayList(Gfx* pkt, Gfx* dl) {
char* imgData = (char*)dl;

View File

@ -22,7 +22,6 @@
#else
#include <time.h>
#endif
#include <Array.h>
#include <AudioPlayer.h>
#include "Enhancements/speechsynthesizer/SpeechSynthesizer.h"
#include "Enhancements/controls/SohInputEditorWindow.h"
@ -110,12 +109,12 @@ GameInteractorSail* GameInteractorSail::Instance;
#include "soh/resource/type/Skeleton.h"
#include "soh/resource/type/SkeletonLimb.h"
#include "soh/resource/type/Text.h"
#include "resource/factory/ArrayFactory.h"
#include "resource/factory/BlobFactory.h"
#include "resource/factory/DisplayListFactory.h"
#include "resource/factory/MatrixFactory.h"
#include "resource/factory/TextureFactory.h"
#include "resource/factory/VertexFactory.h"
#include "soh/resource/importer/ArrayFactory.h"
#include "soh/resource/importer/AnimationFactory.h"
#include "soh/resource/importer/AudioSampleFactory.h"
#include "soh/resource/importer/AudioSequenceFactory.h"
@ -155,6 +154,8 @@ Color_RGB8 zoraColor = { 0x00, 0xEC, 0x64 };
float previousImGuiScale;
bool prevAltAssets = false;
// Same as NaviColor type from OoT src (z_actor.c), but modified to be sans alpha channel for Controller LED.
typedef struct {
Color_RGB8 inner;
@ -326,6 +327,8 @@ OTRGlobals::OTRGlobals() {
// tell LUS to reserve 3 SoH specific threads (Game, Audio, Save)
context->InitResourceManager(OTRFiles, {}, 3);
prevAltAssets = CVarGetInteger(CVAR_ENHANCEMENT("AltAssets"), 0);
context->GetResourceManager()->SetAltAssetsEnabled(prevAltAssets);
context->InitControlDeck({BTN_MODIFIER1, BTN_MODIFIER2});
context->GetControlDeck()->SetSinglePlayerMappingMode(true);
@ -353,8 +356,8 @@ OTRGlobals::OTRGlobals() {
loader->RegisterResourceFactory(std::make_shared<LUS::ResourceFactoryBinaryDisplayListV0>(), RESOURCE_FORMAT_BINARY, "DisplayList", static_cast<uint32_t>(LUS::ResourceType::DisplayList), 0);
loader->RegisterResourceFactory(std::make_shared<LUS::ResourceFactoryXMLDisplayListV0>(), RESOURCE_FORMAT_XML, "DisplayList", static_cast<uint32_t>(LUS::ResourceType::DisplayList), 0);
loader->RegisterResourceFactory(std::make_shared<LUS::ResourceFactoryBinaryMatrixV0>(), RESOURCE_FORMAT_BINARY, "Matrix", static_cast<uint32_t>(LUS::ResourceType::Matrix), 0);
loader->RegisterResourceFactory(std::make_shared<LUS::ResourceFactoryBinaryArrayV0>(), RESOURCE_FORMAT_BINARY, "Array", static_cast<uint32_t>(LUS::ResourceType::Array), 0);
loader->RegisterResourceFactory(std::make_shared<LUS::ResourceFactoryBinaryBlobV0>(), RESOURCE_FORMAT_BINARY, "Blob", static_cast<uint32_t>(LUS::ResourceType::Blob), 0);
loader->RegisterResourceFactory(std::make_shared<SOH::ResourceFactoryBinaryArrayV0>(), RESOURCE_FORMAT_BINARY, "Array", static_cast<uint32_t>(SOH::ResourceType::SOH_Array), 0);
loader->RegisterResourceFactory(std::make_shared<SOH::ResourceFactoryBinaryAnimationV0>(), RESOURCE_FORMAT_BINARY, "Animation", static_cast<uint32_t>(SOH::ResourceType::SOH_Animation), 0);
loader->RegisterResourceFactory(std::make_shared<SOH::ResourceFactoryBinaryPlayerAnimationV0>(), RESOURCE_FORMAT_BINARY, "PlayerAnimation", static_cast<uint32_t>(SOH::ResourceType::SOH_PlayerAnimation), 0);
loader->RegisterResourceFactory(std::make_shared<SOH::ResourceFactoryBinarySceneV0>(), RESOURCE_FORMAT_BINARY, "Room", static_cast<uint32_t>(SOH::ResourceType::SOH_Room), 0); // Is room scene? maybe?
@ -479,7 +482,7 @@ bool OTRGlobals::HasOriginal() {
}
uint32_t OTRGlobals::GetInterpolationFPS() {
if (Ship::Context::GetInstance()->GetWindow()->GetWindowBackend() == Ship::WindowBackend::DX11) {
if (Ship::Context::GetInstance()->GetWindow()->GetWindowBackend() == Ship::WindowBackend::FAST3D_DXGI_DX11) {
return CVarGetInteger(CVAR_SETTING("InterpolationFPS"), 20);
}
@ -495,9 +498,6 @@ struct ExtensionEntry {
std::string ext;
};
extern uintptr_t clearMtx;
extern "C" Mtx gMtxClear;
extern "C" MtxF gMtxFClear;
extern "C" void OTRMessage_Init();
extern "C" void AudioMgr_CreateNextAudioBuffer(s16* samples, u32 num_samples);
extern "C" void AudioPlayer_Play(const uint8_t* buf, uint32_t len);
@ -1156,7 +1156,6 @@ extern "C" void InitOTR() {
GameInteractorSail::Instance = new GameInteractorSail();
#endif
clearMtx = (uintptr_t)&gMtxClear;
OTRMessage_Init();
OTRAudio_Init();
OTRExtScanner();
@ -1265,8 +1264,6 @@ extern "C" uint64_t GetUnixTimestamp() {
return (uint64_t)millis.count();
}
extern bool ToggleAltAssetsAtEndOfFrame;
extern "C" void Graph_StartFrame() {
#ifndef __WIIU__
using Ship::KbScancode;
@ -1348,7 +1345,7 @@ extern "C" void Graph_StartFrame() {
}
#endif
case KbScancode::LUS_KB_TAB: {
ToggleAltAssetsAtEndOfFrame = true;
CVarSetInteger(CVAR_ENHANCEMENT("AltAssets"), !CVarGetInteger(CVAR_ENHANCEMENT("AltAssets"), 0));
break;
}
}
@ -1431,11 +1428,10 @@ extern "C" void Graph_ProcessGfxCommands(Gfx* commands) {
}
}
if (ToggleAltAssetsAtEndOfFrame) {
ToggleAltAssetsAtEndOfFrame = false;
// Actually update the CVar now before runing the alt asset update listeners
CVarSetInteger(CVAR_ALT_ASSETS, !CVarGetInteger(CVAR_ALT_ASSETS, 0));
bool curAltAssets = CVarGetInteger(CVAR_ENHANCEMENT("AltAssets"), 0);
if (prevAltAssets != curAltAssets) {
prevAltAssets = curAltAssets;
Ship::Context::GetInstance()->GetResourceManager()->SetAltAssetsEnabled(curAltAssets);
gfx_texture_cache_clear();
SOH::SkeletonPatcher::UpdateSkeletons();
GameInteractor::Instance->ExecuteHooks<GameInteractor::OnAssetAltChange>();
@ -1622,10 +1618,14 @@ extern "C" uint8_t ResourceMgr_FileAltExists(const char* filePath) {
return ExtensionCache.contains(path);
}
extern "C" bool ResourceMgr_IsAltAssetsEnabled() {
return Ship::Context::GetInstance()->GetResourceManager()->IsAltAssetsEnabled();
}
// Unloads a resource if an alternate version exists when alt assets are enabled
// The resource is only removed from the internal cache to prevent it from used in the next resource lookup
extern "C" void ResourceMgr_UnloadOriginalWhenAltExists(const char* resName) {
if (CVarGetInteger(CVAR_ALT_ASSETS, 0) && ResourceMgr_FileAltExists((char*) resName)) {
if (ResourceMgr_IsAltAssetsEnabled() && ResourceMgr_FileAltExists((char*)resName)) {
ResourceMgr_UnloadResource((char*) resName);
}
}
@ -1708,8 +1708,8 @@ extern "C" char* ResourceMgr_LoadTexOrDListByName(const char* filePath) {
if (res->GetInitData()->Type == static_cast<uint32_t>(LUS::ResourceType::DisplayList))
return (char*)&((std::static_pointer_cast<LUS::DisplayList>(res))->Instructions[0]);
else if (res->GetInitData()->Type == static_cast<uint32_t>(LUS::ResourceType::Array))
return (char*)(std::static_pointer_cast<LUS::Array>(res))->Vertices.data();
else if (res->GetInitData()->Type == static_cast<uint32_t>(SOH::ResourceType::SOH_Array))
return (char*)(std::static_pointer_cast<SOH::Array>(res))->Vertices.data();
else {
return (char*)GetResourceDataByNameHandlingMQ(filePath);
}
@ -1844,13 +1844,14 @@ extern "C" void ResourceMgr_UnpatchGfxByName(const char* path, const char* patch
extern "C" char* ResourceMgr_LoadArrayByName(const char* path)
{
auto res = std::static_pointer_cast<LUS::Array>(GetResourceByNameHandlingMQ(path));
auto res = std::static_pointer_cast<SOH::Array>(GetResourceByNameHandlingMQ(path));
return (char*)res->Scalars.data();
}
// Return of LoadArrayByNameAsVec3s must be freed by the caller
extern "C" char* ResourceMgr_LoadArrayByNameAsVec3s(const char* path) {
auto res = std::static_pointer_cast<LUS::Array>(GetResourceByNameHandlingMQ(path));
auto res = std::static_pointer_cast<SOH::Array>(GetResourceByNameHandlingMQ(path));
// if (res->CachedGameAsset != nullptr)
// return (char*)res->CachedGameAsset;
@ -1981,7 +1982,7 @@ extern "C" SkeletonHeader* ResourceMgr_LoadSkeletonByName(const char* path, Skel
pathStr = pathStr.substr(sOtr.length());
}
bool isAlt = CVarGetInteger(CVAR_ALT_ASSETS, 0);
bool isAlt = ResourceMgr_IsAltAssetsEnabled();
if (isAlt) {
pathStr = Ship::IResource::gAltAssetPrefix + pathStr;

View File

@ -139,6 +139,7 @@ void Ctx_ReadSaveFile(uintptr_t addr, void* dramAddr, size_t size);
void Ctx_WriteSaveFile(uintptr_t addr, void* dramAddr, size_t size);
uint64_t GetPerfCounter();
bool ResourceMgr_IsAltAssetsEnabled();
struct SkeletonHeader* ResourceMgr_LoadSkeletonByName(const char* path, SkelAnime* skelAnime);
void ResourceMgr_UnregisterSkeleton(SkelAnime* skelAnime);
void ResourceMgr_ClearSkeletons();

View File

@ -43,7 +43,6 @@
#include "Enhancements/resolution-editor/ResolutionEditor.h"
#include "Enhancements/debugger/MessageViewer.h"
bool ToggleAltAssetsAtEndOfFrame = false;
bool isBetaQuestEnabled = false;
extern "C" {
@ -210,6 +209,9 @@ namespace SohGui {
}
void Destroy() {
auto gui = Ship::Context::GetInstance()->GetWindow()->GetGui();
gui->RemoveAllGuiWindows();
mModalWindow = nullptr;
mAdvancedResolutionSettingsWindow = nullptr;
mRandomizerSettingsWindow = nullptr;

View File

@ -42,7 +42,6 @@
// they don't work how I expect them to so I added that because it looked good when I eyeballed it
#define FA_ICON_BUTTON_FRAME_PADDING_X(icon) (((optionsButtonSize.x - ImGui::CalcTextSize(icon).x) / 2) + 2.0f)
extern bool ToggleAltAssetsAtEndOfFrame;
extern bool isBetaQuestEnabled;
extern "C" PlayState* gPlayState;
@ -57,6 +56,12 @@ std::string GetWindowButtonText(const char* text, bool menuOpen) {
return buttonText;
}
static std::unordered_map<Ship::WindowBackend, const char*> windowBackendNames = {
{ Ship::WindowBackend::FAST3D_DXGI_DX11, "DirectX" },
{ Ship::WindowBackend::FAST3D_SDL_OPENGL, "OpenGL" },
{ Ship::WindowBackend::FAST3D_SDL_METAL, "Metal" },
};
static const char* imguiScaleOptions[4] = { "Small", "Normal", "Large", "X-Large" };
static const char* filters[3] = {
@ -110,6 +115,24 @@ extern "C" SaveContext gSaveContext;
namespace SohGui {
std::unordered_map<Ship::WindowBackend, const char*> availableWindowBackendsMap;
Ship::WindowBackend configWindowBackend;
void UpdateWindowBackendObjects() {
Ship::WindowBackend runningWindowBackend = Ship::Context::GetInstance()->GetWindow()->GetWindowBackend();
int32_t configWindowBackendId = Ship::Context::GetInstance()->GetConfig()->GetInt("Window.Backend.Id", -1);
if (Ship::Context::GetInstance()->GetWindow()->IsAvailableWindowBackend(configWindowBackendId)) {
configWindowBackend = static_cast<Ship::WindowBackend>(configWindowBackendId);
} else {
configWindowBackend = runningWindowBackend;
}
auto availableWindowBackends = Ship::Context::GetInstance()->GetWindow()->GetAvailableWindowBackends();
for (auto& backend : *availableWindowBackends) {
availableWindowBackendsMap[backend] = windowBackendNames[backend];
}
}
void DrawMenuBarIcon() {
static bool gameIconLoaded = false;
if (!gameIconLoaded) {
@ -325,7 +348,7 @@ void DrawSettingsMenu() {
{ // FPS Slider
const int minFps = 20;
static int maxFps;
if (Ship::Context::GetInstance()->GetWindow()->GetWindowBackend() == Ship::WindowBackend::DX11) {
if (Ship::Context::GetInstance()->GetWindow()->GetWindowBackend() == Ship::WindowBackend::FAST3D_DXGI_DX11) {
maxFps = 360;
} else {
maxFps = Ship::Context::GetInstance()->GetWindow()->GetCurrentRefreshRate();
@ -393,12 +416,12 @@ void DrawSettingsMenu() {
Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesOnNextTick();
#else
bool matchingRefreshRate =
CVarGetInteger(CVAR_SETTING("MatchRefreshRate"), 0) && Ship::Context::GetInstance()->GetWindow()->GetWindowBackend() != Ship::WindowBackend::DX11;
CVarGetInteger(CVAR_SETTING("MatchRefreshRate"), 0) && Ship::Context::GetInstance()->GetWindow()->GetWindowBackend() != Ship::WindowBackend::FAST3D_DXGI_DX11;
UIWidgets::PaddedEnhancementSliderInt(
(currentFps == 20) ? "Frame Rate: Original (20 fps)" : "Frame Rate: %d fps",
"##FPSInterpolation", CVAR_SETTING("InterpolationFPS"), minFps, maxFps, "", 20, true, true, false, matchingRefreshRate);
#endif
if (Ship::Context::GetInstance()->GetWindow()->GetWindowBackend() == Ship::WindowBackend::DX11) {
if (Ship::Context::GetInstance()->GetWindow()->GetWindowBackend() == Ship::WindowBackend::FAST3D_DXGI_DX11) {
UIWidgets::Tooltip(
"Uses Matrix Interpolation to create extra frames, resulting in smoother graphics.\n"
"This is purely visual and does not impact game logic, execution of glitches etc.\n"
@ -413,7 +436,7 @@ void DrawSettingsMenu() {
}
} // END FPS Slider
if (Ship::Context::GetInstance()->GetWindow()->GetWindowBackend() == Ship::WindowBackend::DX11) {
if (Ship::Context::GetInstance()->GetWindow()->GetWindowBackend() == Ship::WindowBackend::FAST3D_DXGI_DX11) {
UIWidgets::Spacer(0);
if (ImGui::Button("Match Frame Rate to Refresh Rate")) {
int hz = Ship::Context::GetInstance()->GetWindow()->GetCurrentRefreshRate();
@ -427,7 +450,7 @@ void DrawSettingsMenu() {
}
UIWidgets::Tooltip("Matches interpolation value to the game window's current refresh rate.");
if (Ship::Context::GetInstance()->GetWindow()->GetWindowBackend() == Ship::WindowBackend::DX11) {
if (Ship::Context::GetInstance()->GetWindow()->GetWindowBackend() == Ship::WindowBackend::FAST3D_DXGI_DX11) {
UIWidgets::PaddedEnhancementSliderInt(CVarGetInteger(CVAR_SETTING("ExtraLatencyThreshold"), 80) == 0 ? "Jitter fix: Off" : "Jitter fix: >= %d FPS",
"##ExtraLatencyThreshold", CVAR_SETTING("ExtraLatencyThreshold"), 0, 360, "", 80, true, true, false);
UIWidgets::Tooltip(
@ -448,40 +471,24 @@ void DrawSettingsMenu() {
UIWidgets::Tooltip("Changes the scaling of the ImGui menu elements.");
UIWidgets::PaddedSeparator(true, true, 3.0f, 3.0f);
static std::unordered_map<Ship::WindowBackend, const char*> windowBackendNames = {
{ Ship::WindowBackend::DX11, "DirectX" },
{ Ship::WindowBackend::SDL_OPENGL, "OpenGL"},
{ Ship::WindowBackend::SDL_METAL, "Metal" },
{ Ship::WindowBackend::GX2, "GX2"}
};
ImGui::Text("Renderer API (Needs reload)");
Ship::WindowBackend runningWindowBackend = Ship::Context::GetInstance()->GetWindow()->GetWindowBackend();
Ship::WindowBackend configWindowBackend;
int configWindowBackendId = Ship::Context::GetInstance()->GetConfig()->GetInt("Window.Backend.Id", -1);
if (configWindowBackendId != -1 && configWindowBackendId < static_cast<int>(Ship::WindowBackend::BACKEND_COUNT)) {
configWindowBackend = static_cast<Ship::WindowBackend>(configWindowBackendId);
} else {
configWindowBackend = runningWindowBackend;
}
if (Ship::Context::GetInstance()->GetWindow()->GetAvailableWindowBackends()->size() <= 1) {
if (availableWindowBackendsMap.size() <= 1) {
UIWidgets::DisableComponent(ImGui::GetStyle().Alpha * 0.5f);
}
if (ImGui::BeginCombo("##RApi", windowBackendNames[configWindowBackend])) {
for (size_t i = 0; i < Ship::Context::GetInstance()->GetWindow()->GetAvailableWindowBackends()->size(); i++) {
auto backend = Ship::Context::GetInstance()->GetWindow()->GetAvailableWindowBackends()->data()[i];
if (ImGui::Selectable(windowBackendNames[backend], backend == configWindowBackend)) {
Ship::Context::GetInstance()->GetConfig()->SetInt("Window.Backend.Id", static_cast<int>(backend));
Ship::Context::GetInstance()->GetConfig()->SetString("Window.Backend.Name",
windowBackendNames[backend]);
if (ImGui::BeginCombo("##RApi", availableWindowBackendsMap[configWindowBackend])) {
for (auto backend : availableWindowBackendsMap) {
if (ImGui::Selectable(backend.second, backend.first == configWindowBackend)) {
Ship::Context::GetInstance()->GetConfig()->SetInt("Window.Backend.Id", static_cast<int>(backend.first));
Ship::Context::GetInstance()->GetConfig()->SetString("Window.Backend.Name", backend.second);
Ship::Context::GetInstance()->GetConfig()->Save();
UpdateWindowBackendObjects();
}
}
ImGui::EndCombo();
}
if (Ship::Context::GetInstance()->GetWindow()->GetAvailableWindowBackends()->size() <= 1) {
if (availableWindowBackendsMap.size() <= 1) {
UIWidgets::ReEnableComponent("");
}
@ -984,6 +991,32 @@ void DrawEnhancementsMenu() {
UIWidgets::Spacer(0);
if (ImGui::BeginMenu("Frogs Ocarina Game")) {
UIWidgets::EnhancementCheckbox("Customize Behavior", CVAR_ENHANCEMENT("CustomizeFrogsOcarinaGame"));
UIWidgets::Tooltip("Turn on/off changes to the frogs ocarina game behavior");
bool disabled = !CVarGetInteger(CVAR_ENHANCEMENT("CustomizeFrogsOcarinaGame"), 0);
static const char* disabledTooltip =
"This option is disabled because \"Customize Behavior\" is turned off";
UIWidgets::PaddedEnhancementCheckbox("Instant Win", CVAR_ENHANCEMENT("InstantFrogsGameWin"), true, false, disabled, disabledTooltip);
UIWidgets::Tooltip("Skips the frogs ocarina game");
UIWidgets::PaddedEnhancementCheckbox("Unlimited Playback Time", CVAR_ENHANCEMENT("FrogsUnlimitedFailTime"), true, false, disabled, disabledTooltip);
UIWidgets::Tooltip("Removes the timer to play back the song");
bool disabledFrog = 0;
static const char* disabledFrogTooltip =
"This option is disabled because \"Customize Behavior\" is turned off or \"Unlimited Playback Time\" is on";
if (!CVarGetInteger(CVAR_ENHANCEMENT("CustomizeFrogsOcarinaGame"), 0) || CVarGetInteger(CVAR_ENHANCEMENT("FrogsUnlimitedFailTime"), 0)) {
disabledFrog = 1;
} else {
disabledFrog = 0;
}
UIWidgets::PaddedEnhancementSliderInt("Modify note timer: %dx", "##FrogsFailTimer", CVAR_ENHANCEMENT("FrogsModifyFailTime"), 1, 5, "", 1, true, true, false,
disabledFrog, disabledFrogTooltip);
UIWidgets::Tooltip("Adjusts the time allowed for playback before failing");
ImGui::EndMenu();
}
UIWidgets::Spacer(0);
UIWidgets::PaddedEnhancementCheckbox("Delete File On Death", CVAR_ENHANCEMENT("DeleteFileOnDeath"), true, false);
ImGui::PushStyleColor(ImGuiCol_Text, ImVec4(1.0f, 0.0f, 0.0f, 1.0f));
UIWidgets::Tooltip("Dying will delete your file\n\n " ICON_FA_EXCLAMATION_TRIANGLE " WARNING " ICON_FA_EXCLAMATION_TRIANGLE "\nTHIS IS NOT REVERSABLE\nUSE AT YOUR OWN RISK!");
@ -1153,12 +1186,7 @@ void DrawEnhancementsMenu() {
if (ImGui::BeginMenu("Graphics"))
{
if (ImGui::BeginMenu("Mods")) {
if (UIWidgets::PaddedEnhancementCheckbox("Use Alternate Assets", CVAR_ALT_ASSETS, false, false)) {
// The checkbox will flip the alt asset CVar, but we instead want it to change at the end of the game frame
// We toggle it back while setting the flag to update the CVar later
CVarSetInteger(CVAR_ALT_ASSETS, !CVarGetInteger(CVAR_ALT_ASSETS, 0));
ToggleAltAssetsAtEndOfFrame = true;
}
UIWidgets::PaddedEnhancementCheckbox("Use Alternate Assets", CVAR_ENHANCEMENT("AltAssets"), false, false);
UIWidgets::Tooltip("Toggle between standard assets and alternate assets. Usually mods will indicate if this setting has to be used or not.");
UIWidgets::PaddedEnhancementCheckbox("Disable Bomb Billboarding", CVAR_ENHANCEMENT("DisableBombBillboarding"), true, false);
UIWidgets::Tooltip("Disables bombs always rotating to face the camera. To be used in conjunction with mods that want to replace bombs with 3D objects.");
@ -1221,26 +1249,42 @@ void DrawEnhancementsMenu() {
UIWidgets::Spacer(0);
UIWidgets::PaddedEnhancementCheckbox("Disable LOD", CVAR_ENHANCEMENT("DisableLOD"), true, false);
UIWidgets::Tooltip("Turns off the Level of Detail setting, making models use their higher-poly variants at any distance");
if (UIWidgets::PaddedEnhancementCheckbox("Disable Draw Distance", CVAR_ENHANCEMENT("DisableDrawDistance"), true, false)) {
if (CVarGetInteger(CVAR_ENHANCEMENT("DisableDrawDistance"), 0) == 0) {
UIWidgets::Tooltip(
"Turns off the Level of Detail setting, making models use their higher-poly variants at any distance");
if (UIWidgets::EnhancementSliderInt("Increase Actor Draw Distance: %dx", "##IncreaseActorDrawDistance",
CVAR_ENHANCEMENT("DisableDrawDistance"), 1, 5, "", 1, true, false)) {
if (CVarGetInteger(CVAR_ENHANCEMENT("DisableDrawDistance"), 1) <= 1) {
CVarSetInteger(CVAR_ENHANCEMENT("DisableKokiriDrawDistance"), 0);
}
}
UIWidgets::Tooltip("Turns off the objects draw distance, making objects being visible from a longer range");
if (CVarGetInteger(CVAR_ENHANCEMENT("DisableDrawDistance"), 0) == 1) {
UIWidgets::PaddedEnhancementCheckbox("Kokiri Draw Distance", CVAR_ENHANCEMENT("DisableKokiriDrawDistance"), true, false);
UIWidgets::Tooltip("The Kokiri are mystical beings that fade into view when approached\nEnabling this will remove their draw distance");
UIWidgets::Tooltip("Increases the range in which actors/objects are drawn");
if (CVarGetInteger(CVAR_ENHANCEMENT("DisableDrawDistance"), 1) > 1) {
UIWidgets::PaddedEnhancementCheckbox("Kokiri Draw Distance",
CVAR_ENHANCEMENT("DisableKokiriDrawDistance"), true, false);
UIWidgets::Tooltip("The Kokiri are mystical beings that fade into view when approached\nEnabling this "
"will remove their draw distance");
}
if (UIWidgets::PaddedEnhancementCheckbox("Show Age-Dependent Equipment", CVAR_ENHANCEMENT("EquimentAlwaysVisible"), true,
false)) {
UpdatePatchHand();
}
UIWidgets::Tooltip("Makes all equipment visible, regardless of Age.");
if (CVarGetInteger(CVAR_ENHANCEMENT("EquimentAlwaysVisible"), 0) == 1) {
UIWidgets::PaddedEnhancementCheckbox("Scale Adult Equipment as Child", CVAR_ENHANCEMENT("ScaleAdultEquimentAsChild"), true, false);
UIWidgets::Tooltip("Scales all of the Adult Equipment, as well and moving some a bit, to fit on Child Link Better. May not work properly with some mods.");
}
UIWidgets::PaddedEnhancementCheckbox("Widescreen Actor Culling", CVAR_ENHANCEMENT("WidescreenActorCulling"),
true, false);
UIWidgets::Tooltip("Adjusts the horizontal culling plane to account for widescreen resolutions");
UIWidgets::PaddedEnhancementCheckbox(
"Cull Glitch Useful Actors", CVAR_ENHANCEMENT("ExtendedCullingExcludeGlitchActors"), true, false,
!CVarGetInteger(CVAR_ENHANCEMENT("WidescreenActorCulling"), 0) &&
CVarGetInteger(CVAR_ENHANCEMENT("DisableDrawDistance"), 1) <= 1,
"Requires Actor Draw Distance to be increased or Widescreen Actor Culling enabled");
UIWidgets::Tooltip(
"Exclude actors that are useful for glitches from the extended culling ranges.\n"
"Some actors may still draw in the extended ranges, but will not \"update\" so that certain "
"glitches that leverage the original culling requirements will still work.\n"
"\n"
"The following actors are excluded:\n"
"- White clothed Gerudos\n"
"- King Zora\n"
"- Gossip Stones\n"
"- Boulders\n"
"- Blue Warps\n"
"- Darunia\n"
"- Gold Skulltulas");
UIWidgets::PaddedEnhancementCheckbox("N64 Mode", CVAR_LOW_RES_MODE, true, false);
UIWidgets::Tooltip("Sets aspect ratio to 4:3 and lowers resolution to 240p, the N64's native resolution");
UIWidgets::PaddedEnhancementCheckbox("Glitch line-up tick", CVAR_ENHANCEMENT("DrawLineupTick"), true, false);
@ -2141,6 +2185,10 @@ void DrawRandomizerMenu() {
}
}
void SohMenuBar::InitElement() {
UpdateWindowBackendObjects();
}
void SohMenuBar::DrawElement() {
if (ImGui::BeginMenuBar()) {
DrawMenuBarIcon();

View File

@ -10,7 +10,7 @@ class SohMenuBar : public Ship::GuiMenuBar {
using Ship::GuiMenuBar::GuiMenuBar;
protected:
void DrawElement() override;
void InitElement() override {};
void InitElement() override;
void UpdateElement() override {};
};
} // namespace SohGui

View File

@ -24,7 +24,7 @@ namespace UIWidgets {
// Automatically adds newlines to break up text longer than a specified number of characters
// Manually included newlines will still be respected and reset the line length
// If line is midword when it hits the limit, text should break at the last encountered space
char* WrappedText(const char* text, unsigned int charactersPerLine) {
std::string WrappedText(const char* text, unsigned int charactersPerLine) {
std::string newText(text);
const size_t tipLength = newText.length();
int lastSpace = -1;
@ -46,17 +46,17 @@ namespace UIWidgets {
currentLineLength++;
}
return strdup(newText.c_str());
return newText;
}
char* WrappedText(const std::string& text, unsigned int charactersPerLine) {
std::string WrappedText(const std::string& text, unsigned int charactersPerLine) {
return WrappedText(text.c_str(), charactersPerLine);
}
void SetLastItemHoverText(const std::string& text) {
if (ImGui::IsItemHovered()) {
ImGui::BeginTooltip();
ImGui::Text("%s", WrappedText(text, 60));
ImGui::Text("%s", WrappedText(text, 60).c_str());
ImGui::EndTooltip();
}
}
@ -64,7 +64,7 @@ namespace UIWidgets {
void SetLastItemHoverText(const char* text) {
if (ImGui::IsItemHovered()) {
ImGui::BeginTooltip();
ImGui::Text("%s", WrappedText(text, 60));
ImGui::Text("%s", WrappedText(text, 60).c_str());
ImGui::EndTooltip();
}
}
@ -75,7 +75,7 @@ namespace UIWidgets {
ImGui::TextColored(ImVec4(0.7f, 0.7f, 0.7f, 1.0f), "?");
if (ImGui::IsItemHovered()) {
ImGui::BeginTooltip();
ImGui::Text("%s", WrappedText(text, 60));
ImGui::Text("%s", WrappedText(text, 60).c_str());
ImGui::EndTooltip();
}
}
@ -85,7 +85,7 @@ namespace UIWidgets {
ImGui::TextColored(ImVec4(0.7f, 0.7f, 0.7f, 1.0f), "?");
if (ImGui::IsItemHovered()) {
ImGui::BeginTooltip();
ImGui::Text("%s", WrappedText(text, 60));
ImGui::Text("%s", WrappedText(text, 60).c_str());
ImGui::EndTooltip();
}
}
@ -95,7 +95,7 @@ namespace UIWidgets {
void Tooltip(const char* text) {
if (ImGui::IsItemHovered()) {
ImGui::SetTooltip("%s", WrappedText(text));
ImGui::SetTooltip("%s", WrappedText(text).c_str());
}
}

View File

@ -54,8 +54,8 @@ namespace UIWidgets {
constexpr float sliderButtonWidth = 30.0f;
#endif
char* WrappedText(const char* text, unsigned int charactersPerLine = 60);
char* WrappedText(const std::string& text, unsigned int charactersPerLine);
std::string WrappedText(const char* text, unsigned int charactersPerLine = 60);
std::string WrappedText(const std::string& text, unsigned int charactersPerLine);
void SetLastItemHoverText(const std::string& text);
void SetLastItemHoverText(const char* text);

View File

@ -99,8 +99,14 @@ void aClearBufferImpl(uint16_t addr, int nbytes) {
memset(BUF_U8(addr), 0, nbytes);
}
void aLoadBufferImpl(const void *source_addr, uint16_t dest_addr, uint16_t nbytes) {
void aLoadBufferImpl(const void* source_addr, uint16_t dest_addr, uint16_t nbytes) {
#if __SANITIZE_ADDRESS__
for (size_t i = 0; i < ROUND_DOWN_16(nbytes); i++) {
BUF_U8(dest_addr)[i] = ((const unsigned char*)source_addr)[i];
}
#else
memcpy(BUF_U8(dest_addr), source_addr, ROUND_DOWN_16(nbytes));
#endif
}
void aSaveBufferImpl(uint16_t source_addr, int16_t *dest_addr, uint16_t nbytes) {

View File

@ -0,0 +1,64 @@
#include "soh/resource/importer/ArrayFactory.h"
#include "soh/resource/type/Array.h"
#include "spdlog/spdlog.h"
#include "graphic/Fast3D/lus_gbi.h"
namespace SOH {
std::shared_ptr<Ship::IResource> ResourceFactoryBinaryArrayV0::ReadResource(std::shared_ptr<Ship::File> file) {
if (!FileHasValidFormatAndReader(file)) {
return nullptr;
}
auto array = std::make_shared<Array>(file->InitData);
auto reader = std::get<std::shared_ptr<Ship::BinaryReader>>(file->Reader);
array->ArrayType = (ArrayResourceType)reader->ReadUInt32();
array->ArrayCount = reader->ReadUInt32();
for (uint32_t i = 0; i < array->ArrayCount; i++) {
if (array->ArrayType == ArrayResourceType::Vertex) {
// OTRTODO: Implement Vertex arrays as just a vertex resource.
F3DVtx data;
data.v.ob[0] = reader->ReadInt16();
data.v.ob[1] = reader->ReadInt16();
data.v.ob[2] = reader->ReadInt16();
data.v.flag = reader->ReadUInt16();
data.v.tc[0] = reader->ReadInt16();
data.v.tc[1] = reader->ReadInt16();
data.v.cn[0] = reader->ReadUByte();
data.v.cn[1] = reader->ReadUByte();
data.v.cn[2] = reader->ReadUByte();
data.v.cn[3] = reader->ReadUByte();
array->Vertices.push_back(data);
} else {
array->ArrayScalarType = (ScalarType)reader->ReadUInt32();
int iter = 1;
if (array->ArrayType == ArrayResourceType::Vector) {
iter = reader->ReadUInt32();
}
for (int k = 0; k < iter; k++) {
ScalarData data;
switch (array->ArrayScalarType) {
case ScalarType::ZSCALAR_S16:
data.s16 = reader->ReadInt16();
break;
case ScalarType::ZSCALAR_U16:
data.u16 = reader->ReadUInt16();
break;
default:
// OTRTODO: IMPLEMENT OTHER TYPES!
break;
}
array->Scalars.push_back(data);
}
}
}
return array;
}
} // namespace LUS

View File

@ -0,0 +1,11 @@
#pragma once
#include "resource/Resource.h"
#include "resource/ResourceFactoryBinary.h"
namespace SOH {
class ResourceFactoryBinaryArrayV0 : public Ship::ResourceFactoryBinary {
public:
std::shared_ptr<Ship::IResource> ReadResource(std::shared_ptr<Ship::File> file) override;
};
} // namespace LUS

View File

@ -1,5 +1,6 @@
#include "soh/resource/importer/PathFactory.h"
#include "soh/resource/type/Path.h"
#include "soh/resource/logging/PathLogger.h"
#include "spdlog/spdlog.h"
namespace SOH {
@ -35,6 +36,60 @@ std::shared_ptr<Ship::IResource> ResourceFactoryBinaryPathV0::ReadResource(std::
path->pathData.push_back(pathDataEntry);
}
if (CVarGetInteger(CVAR_DEVELOPER_TOOLS("ResourceLogging"), 0)) {
LogPathAsXML(path);
}
return path;
}
std::shared_ptr<Ship::IResource> ResourceFactoryXMLPathV0::ReadResource(std::shared_ptr<Ship::File> file) {
if (!FileHasValidFormatAndReader(file)) {
return nullptr;
}
auto path = std::make_shared<Path>(file->InitData);
auto reader = std::get<std::shared_ptr<tinyxml2::XMLDocument>>(file->Reader);
auto pathElement = reader->RootElement();
//path->numPaths = pathElement->IntAttribute("NumPaths");
//path->paths.reserve(path->numPaths);
auto pathDataElement = pathElement->FirstChildElement();
while (pathDataElement != nullptr) {
std::vector<Vec3s> points;
//uint32_t pointCount = pathDataElement->IntAttribute("NumPoints");
//points.reserve(pointCount);
auto pointElement = pathDataElement->FirstChildElement();
while (pointElement != nullptr) {
Vec3s point;
point.x = pointElement->IntAttribute("X");
point.y = pointElement->IntAttribute("Y");
point.z = pointElement->IntAttribute("Z");
points.push_back(point);
pointElement = pointElement->NextSiblingElement();
}
PathData pathDataEntry;
//pathDataEntry.count = pointCount;
pathDataEntry.count = points.size();
path->paths.push_back(points);
pathDataEntry.points = path->paths.back().data();
path->pathData.push_back(pathDataEntry);
pathDataElement = pathDataElement->NextSiblingElement();
}
path->numPaths = path->paths.size();
return path;
};
} // namespace SOH

View File

@ -2,10 +2,16 @@
#include "Resource.h"
#include "ResourceFactoryBinary.h"
#include "ResourceFactoryXML.h"
namespace SOH {
class ResourceFactoryBinaryPathV0 : public Ship::ResourceFactoryBinary {
public:
std::shared_ptr<Ship::IResource> ReadResource(std::shared_ptr<Ship::File> file) override;
};
class ResourceFactoryXMLPathV0 : public Ship::ResourceFactoryXML {
public:
std::shared_ptr<Ship::IResource> ReadResource(std::shared_ptr<Ship::File> file) override;
};
} // namespace SOH

View File

@ -17,6 +17,7 @@ std::shared_ptr<Ship::IResource> SetAlternateHeadersFactory::ReadResource(std::s
auto headerName = reader->ReadString();
if (!headerName.empty()) {
setAlternateHeaders->headers.push_back(std::static_pointer_cast<Scene>(Ship::Context::GetInstance()->GetResourceManager()->LoadResourceProcess(headerName.c_str())));
setAlternateHeaders->headerFileNames.push_back(headerName);
} else {
setAlternateHeaders->headers.push_back(nullptr);
}
@ -41,7 +42,7 @@ std::shared_ptr<Ship::IResource> SetAlternateHeadersFactoryXML::ReadResource(std
std::string childName = child->Name();
if (childName == "AlternateHeader") {
for (uint32_t i = 0; i < setAlternateHeaders->numHeaders; i++) {
auto headerName = std::string(child->Attribute("HeaderName"));
auto headerName = std::string(child->Attribute("Path"));
if (!headerName.empty()) {
setAlternateHeaders->headers.push_back(std::static_pointer_cast<Scene>(Ship::Context::GetInstance()->GetResourceManager()->LoadResourceProcess(headerName.c_str())));
} else {

View File

@ -17,6 +17,7 @@ SetPathwaysFactory::ReadResource(std::shared_ptr<Ship::ResourceInitData> initDat
std::string pathFileName = reader->ReadString();
auto path = std::static_pointer_cast<Path>(Ship::Context::GetInstance()->GetResourceManager()->LoadResourceProcess(pathFileName.c_str()));
setPathways->paths.push_back(path->GetPointer());
setPathways->pathFileNames.push_back(pathFileName);
}
if (CVarGetInteger(CVAR_DEVELOPER_TOOLS("ResourceLogging"), 0)) {

View File

@ -0,0 +1,33 @@
#include "soh/resource/type/Path.h"
#include "spdlog/spdlog.h"
namespace SOH {
void LogPathAsXML(std::shared_ptr<Ship::IResource> resource) {
std::shared_ptr<Path> path = std::static_pointer_cast<Path>(resource);
tinyxml2::XMLDocument doc;
tinyxml2::XMLElement* root = doc.NewElement("Path");
doc.InsertFirstChild(root);
for (size_t i = 0; i < path->paths.size(); i += 1) {
tinyxml2::XMLElement* pathData = doc.NewElement("PathData");
for (size_t j = 0; j < path->paths[i].size(); j += 1) {
tinyxml2::XMLElement* pathPoint = doc.NewElement("PathPoint");
pathPoint->SetAttribute("X", path->paths[i][j].x);
pathPoint->SetAttribute("Y", path->paths[i][j].y);
pathPoint->SetAttribute("Z", path->paths[i][j].z);
pathData->InsertEndChild(pathPoint);
}
root->InsertEndChild(pathData);
}
tinyxml2::XMLPrinter printer;
doc.Accept(&printer);
SPDLOG_INFO("{}: {}", resource->GetInitData()->Path, printer.CStr());
}
}

View File

@ -0,0 +1,6 @@
#include "Resource.h"
#include "soh/OTRGlobals.h"
namespace SOH {
void LogPathAsXML(std::shared_ptr<Ship::IResource> resource);
}

View File

@ -73,6 +73,12 @@ void LogAlternateHeadersAsXML(std::shared_ptr<Ship::IResource> resource) {
tinyxml2::XMLElement* root = doc.NewElement("SetAlternateHeaders");
doc.InsertFirstChild(root);
for (size_t i = 0; i < setAlternateHeaders->headerFileNames.size(); i++) {
tinyxml2::XMLElement* entry = doc.NewElement("Header");
entry->SetAttribute("Path", setAlternateHeaders->headerFileNames[i].c_str());
root->InsertEndChild(entry);
}
tinyxml2::XMLPrinter printer;
doc.Accept(&printer);

View File

@ -0,0 +1,45 @@
#include "Array.h"
#include "graphic/Fast3D/lus_gbi.h"
namespace SOH {
Array::Array() : Resource(std::shared_ptr<Ship::ResourceInitData>()) {
}
void* Array::GetPointer() {
void* dataPointer = nullptr;
switch (ArrayType) {
case ArrayResourceType::Vertex:
dataPointer = Vertices.data();
break;
case ArrayResourceType::Scalar:
default:
dataPointer = Scalars.data();
break;
}
return dataPointer;
}
size_t Array::GetPointerSize() {
size_t typeSize = 0;
switch (ArrayType) {
case ArrayResourceType::Vertex:
typeSize = sizeof(F3DVtx);
break;
case ArrayResourceType::Scalar:
default:
switch (ArrayScalarType) {
case ScalarType::ZSCALAR_S16:
typeSize = sizeof(int16_t);
break;
case ScalarType::ZSCALAR_U16:
typeSize = sizeof(uint16_t);
break;
default:
// OTRTODO: IMPLEMENT OTHER TYPES!
break;
}
break;
}
return ArrayCount * typeSize;
}
} // namespace LUS

View File

@ -0,0 +1,85 @@
#pragma once
#include "resource/Resource.h"
union F3DVtx;
namespace SOH {
typedef union ScalarData {
uint8_t u8;
int8_t s8;
uint16_t u16;
int16_t s16;
uint32_t u32;
int32_t s32;
uint64_t u64;
int64_t s64;
float f32;
double f64;
} ScalarData;
enum class ScalarType {
ZSCALAR_NONE,
ZSCALAR_S8,
ZSCALAR_U8,
ZSCALAR_X8,
ZSCALAR_S16,
ZSCALAR_U16,
ZSCALAR_X16,
ZSCALAR_S32,
ZSCALAR_U32,
ZSCALAR_X32,
ZSCALAR_S64,
ZSCALAR_U64,
ZSCALAR_X64,
ZSCALAR_F32,
ZSCALAR_F64
};
// OTRTODO: Replace this with something that can be shared between the exporter and importer...
enum class ArrayResourceType {
Error,
Animation,
Array,
AltHeader,
Background,
Blob,
CollisionHeader,
Cutscene,
DisplayList,
Limb,
LimbTable,
Mtx,
Path,
PlayerAnimationData,
Room,
RoomCommand,
Scalar,
Scene,
Skeleton,
String,
Symbol,
Texture,
TextureAnimation,
TextureAnimationParams,
Vector,
Vertex,
Audio
};
class Array : public Ship::Resource<void> {
public:
using Resource::Resource;
Array();
void* GetPointer() override;
size_t GetPointerSize() override;
ArrayResourceType ArrayType;
ScalarType ArrayScalarType;
size_t ArrayCount;
// OTRTODO: Should be a vector of resource pointers...
std::vector<ScalarData> Scalars;
std::vector<F3DVtx> Vertices;
};
} // namespace LUS

View File

@ -65,12 +65,11 @@ void SkeletonPatcher::ClearSkeletons()
}
void SkeletonPatcher::UpdateSkeletons() {
bool isHD = CVarGetInteger(CVAR_ALT_ASSETS, 0);
auto resourceMgr = Ship::Context::GetInstance()->GetResourceManager();
bool isHD = resourceMgr->IsAltAssetsEnabled();
for (auto skel : skeletons) {
Skeleton* newSkel =
(Skeleton*)Ship::Context::GetInstance()->GetResourceManager()
->LoadResource((isHD ? Ship::IResource::gAltAssetPrefix : "") + skel.vanillaSkeletonPath, true)
.get();
(Skeleton*)resourceMgr->LoadResource((isHD ? Ship::IResource::gAltAssetPrefix : "") + skel.vanillaSkeletonPath, true).get();
if (newSkel != nullptr) {
skel.skelAnime->skeleton = newSkel->skeletonData.skeletonHeader.segment;

View File

@ -2,6 +2,7 @@
namespace SOH {
enum class ResourceType {
SOH_Array = 0x4F415252, // OARR
SOH_Animation = 0x4F414E4D, // OANM
SOH_PlayerAnimation = 0x4F50414D, // OPAM
SOH_Room = 0x4F524F4D, // OROM

View File

@ -21,6 +21,7 @@ class SetAlternateHeaders : public SceneCommand<void> {
size_t GetPointerSize();
uint32_t numHeaders;
std::vector<std::string> headerFileNames;
std::vector<std::shared_ptr<Scene>> headers;
};
}; // namespace LUS

View File

@ -239,16 +239,15 @@ void GameState_ReqPadData(GameState* gameState) {
PadMgr_RequestPadData(&gPadMgr, &gameState->input[0], 1);
}
// OTRTODO
int fbTest = -1;
// Framebuffer for the Link preview on the pause menu equipment sub-screen
int gPauseLinkFrameBuffer = -1;
void GameState_Update(GameState* gameState) {
GraphicsContext* gfxCtx = gameState->gfxCtx;
if (fbTest == -1)
{
fbTest = gfx_create_framebuffer(64, 112, SCREEN_WIDTH, SCREEN_HEIGHT, true);
//fbTest = gfx_create_framebuffer(256, 512);
if (gPauseLinkFrameBuffer == -1) {
gPauseLinkFrameBuffer = gfx_create_framebuffer(PAUSE_EQUIP_PLAYER_WIDTH, PAUSE_EQUIP_PLAYER_HEIGHT,
PAUSE_EQUIP_PLAYER_WIDTH, PAUSE_EQUIP_PLAYER_HEIGHT, true);
}
GameState_SetFrameBuffer(gfxCtx);
@ -467,7 +466,7 @@ void GameState_Destroy(GameState* gameState) {
// Performing clear skeletons before unload resources fixes an actor heap corruption crash due to the skeleton patching system.
ResourceMgr_ClearSkeletons();
if (CVarGetInteger(CVAR_ALT_ASSETS, 0)) {
if (ResourceMgr_IsAltAssetsEnabled()) {
ResourceUnloadDirectory("alt/*");
gfx_texture_cache_clear();
}

View File

@ -141,7 +141,7 @@ static const ALIGN_ASSET(2) char rGfxPrintFontDataAlt[] = drGfxPrintFontDataAlt;
// https://github.com/HarbourMasters/Shipwright/issues/2762
typedef enum {hardcoded, otrDefault, otrAlt} font_texture_t;
font_texture_t GfxPrint_TextureToUse() {
if (CVarGetInteger(CVAR_ALT_ASSETS, 0) && ResourceMgr_FileExists(rGfxPrintFontDataAlt)) {
if (ResourceMgr_IsAltAssetsEnabled() && ResourceMgr_FileExists(rGfxPrintFontDataAlt)) {
// If we have alt assets enabled, and we have alt prefixed font texture, use that
return otrAlt;
} else if (ResourceMgr_FileExists(rGfxPrintFontData)) {

View File

@ -1228,14 +1228,6 @@ void Actor_Init(Actor* actor, PlayState* play) {
actor->uncullZoneForward = 1000.0f;
actor->uncullZoneScale = 350.0f;
actor->uncullZoneDownward = 700.0f;
if (CVarGetInteger(CVAR_ENHANCEMENT("DisableDrawDistance"), 0) != 0 && actor->id != ACTOR_EN_TORCH2 && actor->id != ACTOR_EN_BLKOBJ // Extra check for Dark Link and his room
&& actor->id != ACTOR_EN_HORSE // Check for Epona, else if we call her she will spawn at the other side of the map + we can hear her during the title screen sequence
&& actor->id != ACTOR_EN_HORSE_GANON && actor->id != ACTOR_EN_HORSE_ZELDA // check for Zelda's and Ganondorf's horses that will always be scene during cinematic whith camera paning
&& (play->sceneNum != SCENE_DODONGOS_CAVERN && actor->id != ACTOR_EN_ZF)) { // Check for DC and Lizalfos for the case where the miniboss music would still play under certains conditions and changing room
actor->uncullZoneForward = 32767.0f;
actor->uncullZoneScale = 32767.0f;
actor->uncullZoneDownward = 32767.0f;
}
CollisionCheck_InitInfo(&actor->colChkInfo);
actor->floorBgId = BGCHECK_SCENE;
ActorShape_Init(&actor->shape, 0.0f, NULL, 0.0f);
@ -2897,34 +2889,93 @@ s32 func_800314B0(PlayState* play, Actor* actor) {
s32 func_800314D4(PlayState* play, Actor* actor, Vec3f* arg2, f32 arg3) {
f32 var;
if (CVarGetInteger(CVAR_ENHANCEMENT("DisableDrawDistance"), 0) != 0 && actor->id != ACTOR_EN_TORCH2 && actor->id != ACTOR_EN_BLKOBJ // Extra check for Dark Link and his room
&& actor->id != ACTOR_EN_HORSE // Check for Epona, else if we call her she will spawn at the other side of the map + we can hear her during the title screen sequence
&& actor->id != ACTOR_EN_HORSE_GANON && actor->id != ACTOR_EN_HORSE_ZELDA // check for Zelda's and Ganondorf's horses that will always be scene during cinematic whith camera paning
&& (play->sceneNum != SCENE_DODONGOS_CAVERN && actor->id != ACTOR_EN_ZF)) { // Check for DC and Lizalfos for the case where the miniboss music would still play under certains conditions and changing room
return true;
}
if ((arg2->z > -actor->uncullZoneScale) && (arg2->z < (actor->uncullZoneForward + actor->uncullZoneScale))) {
var = (arg3 < 1.0f) ? 1.0f : 1.0f / arg3;
// #region SoH [Widescreen support]
// Doors will cull quite noticeably on wider screens. For these actors the zone is increased
f32 limit = 1.0f;
if (((actor->id == ACTOR_EN_DOOR) || (actor->id == ACTOR_DOOR_SHUTTER)) && CVarGetInteger(CVAR_GENERAL("IncreaseDoorUncullZones"), 1)) {
limit = 2.0f;
}
if ((((fabsf(arg2->x) - actor->uncullZoneScale) * var) < limit) &&
(((arg2->y + actor->uncullZoneDownward) * var) > -limit) &&
(((arg2->y - actor->uncullZoneScale) * var) < limit)) {
if ((((fabsf(arg2->x) - actor->uncullZoneScale) * var) < 1.0f) &&
(((arg2->y + actor->uncullZoneDownward) * var) > -1.0f) &&
(((arg2->y - actor->uncullZoneScale) * var) < 1.0f)) {
return true;
}
// #endregion
}
return false;
}
// #region SOH [Enhancements] Allows us to increase the draw and update distance independently,
// mostly a modified version of the function above and additional tweaks for some specfic actors
s32 Ship_CalcShouldDrawAndUpdate(PlayState* play, Actor* actor, Vec3f* projectedPos, f32 projectedW, bool* shouldDraw,
bool* shouldUpdate) {
f32 clampedProjectedW;
// Check if the actor passes its original/vanilla culling requirements
if (func_800314D4(play, actor, projectedPos, projectedW)) {
*shouldUpdate = true;
*shouldDraw = true;
return true;
}
// Skip cutscne actors that depend on culling to hide from camera pans
if (actor->id == ACTOR_EN_VIEWER) {
return false;
}
s32 multiplier = CVarGetInteger(CVAR_ENHANCEMENT("DisableDrawDistance"), 1);
multiplier = MAX(multiplier, 1);
// Some actors have a really short forward value, so we need to add to it before the multiplier to increase the
// final strength of the forward culling
f32 adder = (actor->uncullZoneForward < 500) ? 1000.0f : 0.0f;
if ((projectedPos->z > -actor->uncullZoneScale) &&
(projectedPos->z < (((actor->uncullZoneForward + adder) * multiplier) + actor->uncullZoneScale))) {
clampedProjectedW = (projectedW < 1.0f) ? 1.0f : 1.0f / projectedW;
f32 ratioAdjusted = 1.0f;
if (CVarGetInteger(CVAR_ENHANCEMENT("WidescreenActorCulling"), 0)) {
f32 originalAspectRatio = 4.0f / 3.0f;
f32 currentAspectRatio = OTRGetAspectRatio();
ratioAdjusted = MAX(currentAspectRatio / originalAspectRatio, 1.0f);
}
if ((((fabsf(projectedPos->x) - actor->uncullZoneScale) * (clampedProjectedW / ratioAdjusted)) < 1.0f) &&
(((projectedPos->y + actor->uncullZoneDownward) * clampedProjectedW) > -1.0f) &&
(((projectedPos->y - actor->uncullZoneScale) * clampedProjectedW) < 1.0f)) {
if (CVarGetInteger(CVAR_ENHANCEMENT("ExtendedCullingExcludeGlitchActors"), 0)) {
// These actors are safe to draw without impacting glitches
if ((actor->id == ACTOR_OBJ_BOMBIWA || actor->id == ACTOR_OBJ_HAMISHI ||
actor->id == ACTOR_EN_ISHI) || // Boulders (hookshot through collision)
actor->id == ACTOR_EN_GS || // Gossip stones (text delay)
actor->id == ACTOR_EN_GE1 || // White gerudos (gate clip/archery room transition)
actor->id == ACTOR_EN_KZ || // King Zora (unfreeze glitch)
actor->id == ACTOR_EN_DU || // Darunia (Fire temple BK skip)
actor->id == ACTOR_DOOR_WARP1 // Blue warps (wrong warps)
) {
*shouldDraw = true;
return true;
}
// Skip these actors entirely as their draw funcs impacts glitches
if ((actor->id == ACTOR_EN_SW &&
(((actor->params & 0xE000) >> 0xD) == 1 ||
((actor->params & 0xE000) >> 0xD) == 2)) // Gold Skulltulas (hitbox at 0,0)
) {
return false;
}
}
*shouldDraw = true;
*shouldUpdate = true;
return true;
}
}
return false;
}
// #endregion
void func_800315AC(PlayState* play, ActorContext* actorCtx) {
s32 invisibleActorCounter;
Actor* invisibleActors[INVISIBLE_ACTOR_MAX];
@ -2960,18 +3011,35 @@ void func_800315AC(PlayState* play, ActorContext* actorCtx) {
}
}
// #region SOH [Enhancement] Extended culling updates
bool shipShouldDraw = false;
bool shipShouldUpdate = false;
if ((HREG(64) != 1) || ((HREG(65) != -1) && (HREG(65) != HREG(66))) || (HREG(70) == 0)) {
if (func_800314B0(play, actor)) {
actor->flags |= ACTOR_FLAG_ACTIVE;
if (CVarGetInteger(CVAR_ENHANCEMENT("DisableDrawDistance"), 1) > 1 ||
CVarGetInteger(CVAR_ENHANCEMENT("WidescreenActorCulling"), 0)) {
Ship_CalcShouldDrawAndUpdate(play, actor, &actor->projectedPos, actor->projectedW, &shipShouldDraw,
&shipShouldUpdate);
if (shipShouldUpdate) {
actor->flags |= ACTOR_FLAG_ACTIVE;
} else {
actor->flags &= ~ACTOR_FLAG_ACTIVE;
}
} else {
actor->flags &= ~ACTOR_FLAG_ACTIVE;
if (func_800314B0(play, actor)) {
actor->flags |= ACTOR_FLAG_ACTIVE;
} else {
actor->flags &= ~ACTOR_FLAG_ACTIVE;
}
}
}
actor->isDrawn = false;
if ((HREG(64) != 1) || ((HREG(65) != -1) && (HREG(65) != HREG(66))) || (HREG(71) == 0)) {
if ((actor->init == NULL) && (actor->draw != NULL) && (actor->flags & (ACTOR_FLAG_DRAW_WHILE_CULLED | ACTOR_FLAG_ACTIVE))) {
if ((actor->init == NULL) && (actor->draw != NULL) &&
((actor->flags & (ACTOR_FLAG_DRAW_WHILE_CULLED | ACTOR_FLAG_ACTIVE)) || shipShouldDraw)) {
// #endregion
if ((actor->flags & ACTOR_FLAG_LENS) &&
((play->roomCtx.curRoom.lensMode == LENS_MODE_HIDE_ACTORS) ||
play->actorCtx.lensActive || (actor->room != play->roomCtx.curRoom.num))) {

View File

@ -131,10 +131,6 @@ void SkelCurve_DrawLimb(PlayState* play, s32 limbIndex, SkelAnimeCurve* skelCurv
Matrix_TranslateRotateZYX(&pos, &rot);
Matrix_Scale(scale.x, scale.y, scale.z, MTXMODE_APPLY);
if (CVarGetInteger(CVAR_ENHANCEMENT("DisableLOD"), 0)) {
lod = 0;
}
if (lod == 0) {
s32 pad1;

View File

@ -1116,7 +1116,7 @@ void Message_DrawText(PlayState* play, Gfx** gfxP) {
}
}
if (msgCtx->textDelayTimer == 0) {
msgCtx->textDrawPos = i + CVarGetInteger(CVAR_ENHANCEMENT("TextSpeed"), 2);
msgCtx->textDrawPos = i + CVarGetInteger(CVAR_ENHANCEMENT("TextSpeed"), 1);
msgCtx->textDelayTimer = msgCtx->textDelay;
} else {
msgCtx->textDelayTimer--;

View File

@ -2079,10 +2079,12 @@ void Pause_DrawTriforceSpot(PlayState* play, s32 showLightColumn) {
rotation += 0x03E8;
}
void Player_DrawPauseImpl(PlayState* play, void* seg04, void* seg06, SkelAnime* skelAnime, Vec3f* pos, Vec3s* rot,
f32 scale, s32 sword, s32 tunic, s32 shield, s32 boots, s32 width, s32 height, Vec3f* eye, Vec3f* at,
f32 fovy, void* img1, void* img2) {
static Vp viewport = { 128, 224, 511, 0, 128, 224, 511, 0 };
void Player_DrawPauseImpl(PlayState* play, void* gameplayKeep, void* linkObject, SkelAnime* skelAnime, Vec3f* pos,
Vec3s* rot, f32 scale, s32 sword, s32 tunic, s32 shield, s32 boots, s32 width, s32 height,
Vec3f* eye, Vec3f* at, f32 fovy, void* colorFrameBuffer, void* depthFrameBuffer) {
// Note: the viewport x and y values are overwritten below, before usage
static Vp viewport = { (PAUSE_EQUIP_PLAYER_WIDTH / 2) << 2, (PAUSE_EQUIP_PLAYER_HEIGHT / 2) << 2, G_MAXZ / 2, 0,
(PAUSE_EQUIP_PLAYER_WIDTH / 2) << 2, (PAUSE_EQUIP_PLAYER_HEIGHT / 2) << 2, G_MAXZ / 2, 0 };
static Lights1 lights1 = gdSPDefLights1(80, 80, 80, 255, 255, 255, 84, 84, 172);
static Vec3f lightDir = { 89.8f, 0.0f, 89.8f };
u8 playerSwordAndShield[2];
@ -2110,6 +2112,24 @@ void Player_DrawPauseImpl(PlayState* play, void* seg04, void* seg06, SkelAnime*
gDPSetScissor(POLY_OPA_DISP++, G_SC_NON_INTERLACE, 0, 0, width, height);
gSPClipRatio(POLY_OPA_DISP++, FRUSTRATIO_1);
gDPSetColorImage(POLY_OPA_DISP++, G_IM_FMT_RGBA, G_IM_SIZ_16b, width, depthFrameBuffer);
gDPSetCycleType(POLY_OPA_DISP++, G_CYC_FILL);
gDPSetRenderMode(POLY_OPA_DISP++, G_RM_NOOP, G_RM_NOOP2);
gDPSetFillColor(POLY_OPA_DISP++, (GPACK_ZDZ(G_MAXFBZ, 0) << 16) | GPACK_ZDZ(G_MAXFBZ, 0));
gDPFillRectangle(POLY_OPA_DISP++, 0, 0, width - 1, height - 1);
gDPPipeSync(POLY_OPA_DISP++);
gDPSetColorImage(POLY_OPA_DISP++, G_IM_FMT_RGBA, G_IM_SIZ_16b, width, colorFrameBuffer);
gDPSetCycleType(POLY_OPA_DISP++, G_CYC_FILL);
gDPSetRenderMode(POLY_OPA_DISP++, G_RM_NOOP, G_RM_NOOP2);
gDPSetFillColor(POLY_OPA_DISP++, (GPACK_RGBA5551(0, 0, 0, 1) << 16) | GPACK_RGBA5551(0, 0, 0, 1));
gDPFillRectangle(POLY_OPA_DISP++, 0, 0, width - 1, height - 1);
gDPPipeSync(POLY_OPA_DISP++);
gDPSetDepthImage(POLY_OPA_DISP++, depthFrameBuffer);
viewport.vp.vscale[0] = viewport.vp.vtrans[0] = width * 2;
viewport.vp.vscale[1] = viewport.vp.vtrans[1] = height * 2;
gSPViewport(POLY_OPA_DISP++, &viewport);
@ -2130,8 +2150,8 @@ void Player_DrawPauseImpl(PlayState* play, void* seg04, void* seg06, SkelAnime*
pos->y - (CVarGetInteger(CVAR_GENERAL("PauseTriforce"), 0) ? 16 : 0), pos->z, rot);
Matrix_Scale(scale * (CVarGetInteger(CVAR_ENHANCEMENT("MirroredWorld"), 0) ? -1 : 1), scale, scale, MTXMODE_APPLY);
gSPSegment(POLY_OPA_DISP++, 0x04, seg04);
gSPSegment(POLY_OPA_DISP++, 0x06, seg06);
gSPSegment(POLY_OPA_DISP++, 0x04, gameplayKeep);
gSPSegment(POLY_OPA_DISP++, 0x06, linkObject);
gSPSetLights1(POLY_OPA_DISP++, lights1);
@ -2399,14 +2419,16 @@ void Player_DrawPause(PlayState* play, u8* segment, SkelAnime* skelAnime, Vec3f*
}
srcTable = ResourceMgr_LoadArrayByNameAsVec3s(srcTable);
Vec3s* ogSrcTable = srcTable;
destTable = skelAnime->jointTable;
for (i = 0; i < skelAnime->limbCount; i++) {
*destTable++ = *srcTable++;
}
free(ogSrcTable);
}
Player_DrawPauseImpl(play, segment + 0x3800, segment + 0x8800, skelAnime, pos, rot, scale, sword, tunic, shield,
boots, 64, 112, &eye, &at, 60.0f, play->state.gfxCtx->curFrameBuffer,
play->state.gfxCtx->curFrameBuffer + 0x1C00);
boots, PAUSE_EQUIP_PLAYER_WIDTH, PAUSE_EQUIP_PLAYER_HEIGHT, &eye, &at, 60.0f,
play->state.gfxCtx->curFrameBuffer,
play->state.gfxCtx->curFrameBuffer + (PAUSE_EQUIP_PLAYER_WIDTH * PAUSE_EQUIP_PLAYER_HEIGHT));
}

View File

@ -1539,7 +1539,7 @@ void Gfx_SetupFrame(GraphicsContext* gfxCtx, u8 r, u8 g, u8 b) {
gDPSetCycleType(POLY_OPA_DISP++, G_CYC_FILL);
gDPSetRenderMode(POLY_OPA_DISP++, G_RM_NOOP, G_RM_NOOP2);
gDPSetFillColor(POLY_OPA_DISP++, (GPACK_ZDZ(G_MAXFBZ, 0) << 16) | GPACK_ZDZ(G_MAXFBZ, 0));
gDPFillRectangle(POLY_OPA_DISP++, 0, letterboxSize, gScreenWidth - 1, gScreenHeight - letterboxSize - 1);
gDPFillWideRectangle(POLY_OPA_DISP++, OTRGetRectDimensionFromLeftEdge(0), letterboxSize, OTRGetRectDimensionFromRightEdge(gScreenWidth - 1), gScreenHeight - letterboxSize - 1);
gDPPipeSync(POLY_OPA_DISP++);
// Fill the whole screen with the base color
@ -1548,7 +1548,7 @@ void Gfx_SetupFrame(GraphicsContext* gfxCtx, u8 r, u8 g, u8 b) {
gDPSetCycleType(POLY_OPA_DISP++, G_CYC_FILL);
gDPSetRenderMode(POLY_OPA_DISP++, G_RM_NOOP, G_RM_NOOP2);
gDPSetFillColor(POLY_OPA_DISP++, (GPACK_RGBA5551(r, g, b, 1) << 16) | GPACK_RGBA5551(r, g, b, 1));
gDPFillRectangle(POLY_OPA_DISP++, 0, letterboxSize, gScreenWidth - 1, gScreenHeight - letterboxSize - 1);
gDPFillWideRectangle(POLY_OPA_DISP++, OTRGetRectDimensionFromLeftEdge(0), letterboxSize, OTRGetRectDimensionFromRightEdge(gScreenWidth - 1), gScreenHeight - letterboxSize - 1);
gDPPipeSync(POLY_OPA_DISP++);
// Draw the letterbox if applicable (uses the same color as the screen base)
@ -1557,8 +1557,8 @@ void Gfx_SetupFrame(GraphicsContext* gfxCtx, u8 r, u8 g, u8 b) {
gDPSetCycleType(OVERLAY_DISP++, G_CYC_FILL);
gDPSetRenderMode(OVERLAY_DISP++, G_RM_NOOP, G_RM_NOOP2);
gDPSetFillColor(OVERLAY_DISP++, (GPACK_RGBA5551(r, g, b, 1) << 16) | GPACK_RGBA5551(r, g, b, 1));
gDPFillRectangle(OVERLAY_DISP++, 0, 0, gScreenWidth - 1, letterboxSize - 1);
gDPFillRectangle(OVERLAY_DISP++, 0, gScreenHeight - letterboxSize, gScreenWidth - 1, gScreenHeight - 1);
gDPFillWideRectangle(OVERLAY_DISP++, OTRGetRectDimensionFromLeftEdge(0), 0, OTRGetRectDimensionFromRightEdge(gScreenWidth - 1), letterboxSize - 1);
gDPFillWideRectangle(OVERLAY_DISP++, OTRGetRectDimensionFromLeftEdge(0), gScreenHeight - letterboxSize, OTRGetRectDimensionFromRightEdge(gScreenWidth - 1), gScreenHeight - 1);
gDPPipeSync(OVERLAY_DISP++);
}
}

View File

@ -148,6 +148,8 @@ void SkelAnime_DrawFlexLimbLod(PlayState* play, s32 limbIndex, void** skeleton,
newDList = limbDList = limb->dLists[lod];
play->flexLimbOverrideMTX = mtx;
if ((overrideLimbDraw == NULL) || !overrideLimbDraw(play, limbIndex, &newDList, &pos, &rot, arg)) {
Matrix_TranslateRotateZYX(&pos, &rot);
if (newDList != NULL) {
@ -220,6 +222,8 @@ void SkelAnime_DrawFlexLod(PlayState* play, void** skeleton, Vec3s* jointTable,
newDList = limbDList = rootLimb->dLists[lod];
play->flexLimbOverrideMTX = &mtx;
if ((overrideLimbDraw == 0) || !overrideLimbDraw(play, 1, &newDList, &pos, &rot, arg)) {
Matrix_TranslateRotateZYX(&pos, &rot);
if (newDList != NULL) {
@ -306,6 +310,20 @@ void SkelAnime_DrawSkeletonOpa(PlayState* play, SkelAnime* skelAnime, OverrideLi
}
}
Gfx* SkelAnime_DrawSkeleton2(PlayState* play, SkelAnime* skelAnime, OverrideLimbDrawOpa overrideLimbDraw,
PostLimbDrawOpa postLimbDraw, void* arg, Gfx* gfx)
{
if (skelAnime->skeletonHeader->skeletonType == SKELANIME_TYPE_NORMAL) {
return SkelAnime_Draw(play, skelAnime->skeleton, skelAnime->jointTable, overrideLimbDraw, postLimbDraw, arg, gfx);
} else if (skelAnime->skeletonHeader->skeletonType == SKELANIME_TYPE_FLEX) {
FlexSkeletonHeader* flexHeader = (FlexSkeletonHeader*)skelAnime->skeletonHeader;
return SkelAnime_DrawFlex(play, skelAnime->skeleton, skelAnime->jointTable, flexHeader->dListCount,
overrideLimbDraw, postLimbDraw, arg, gfx);
}
return gfx;
}
/**
* Draw all limbs of type `StandardLimb` in a given skeleton to the polyOpa buffer
*/
@ -383,6 +401,8 @@ void SkelAnime_DrawFlexLimbOpa(PlayState* play, s32 limbIndex, void** skeleton,
newDList = limbDList = limb->dList;
play->flexLimbOverrideMTX = limbMatricies;
if ((overrideLimbDraw == NULL) || !overrideLimbDraw(play, limbIndex, &newDList, &pos, &rot, arg)) {
Matrix_TranslateRotateZYX(&pos, &rot);
if (newDList != NULL) {

View File

@ -1288,6 +1288,10 @@ block_1:
if (*dList != NULL) {
OPEN_DISPS(play->state.gfxCtx);
if (this->skelAnime.skeletonHeader->skeletonType == SKELANIME_TYPE_FLEX) {
MATRIX_TOMTX(*play->flexLimbOverrideMTX);
}
mtxScaleZ = 1.0f;
mtxScaleY = 1.0f;
@ -1308,11 +1312,20 @@ block_1:
Matrix_RotateX(-(this->unk_25C[limbIndex] * 0.115f), MTXMODE_APPLY);
}
gSPMatrix(POLY_OPA_DISP++, MATRIX_NEWMTX(play->state.gfxCtx),
G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
if (this->skelAnime.skeletonHeader->skeletonType == SKELANIME_TYPE_FLEX) {
gSPMatrix(POLY_OPA_DISP++, *play->flexLimbOverrideMTX, G_MTX_LOAD);
} else {
gSPMatrix(POLY_OPA_DISP++, MATRIX_NEWMTX(play->state.gfxCtx),
G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
}
gSPDisplayList(POLY_OPA_DISP++, *dList);
Matrix_Pop();
if (this->skelAnime.skeletonHeader->skeletonType == SKELANIME_TYPE_FLEX) {
(*play->flexLimbOverrideMTX)++;
}
CLOSE_DISPS(play->state.gfxCtx);
}
{ s32 pad; } // Required to match

View File

@ -2015,12 +2015,26 @@ s32 BossGoma_OverrideLimbDraw(PlayState* play, s32 limbIndex, Gfx** dList, Vec3f
Matrix_TranslateRotateZYX(pos, rot);
if (*dList != NULL) {
if (this->skelanime.skeletonHeader->skeletonType == SKELANIME_TYPE_FLEX) {
MATRIX_TOMTX(*play->flexLimbOverrideMTX);
}
Matrix_Push();
Matrix_Scale(this->eyeIrisScaleX, this->eyeIrisScaleY, 1.0f, MTXMODE_APPLY);
gSPMatrix(POLY_OPA_DISP++, MATRIX_NEWMTX(play->state.gfxCtx),
G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
if (this->skelanime.skeletonHeader->skeletonType == SKELANIME_TYPE_FLEX) {
gSPMatrix(POLY_OPA_DISP++, *play->flexLimbOverrideMTX, G_MTX_LOAD);
} else {
gSPMatrix(POLY_OPA_DISP++, MATRIX_NEWMTX(play->state.gfxCtx),
G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
}
gSPDisplayList(POLY_OPA_DISP++, *dList);
Matrix_Pop();
if (this->skelanime.skeletonHeader->skeletonType == SKELANIME_TYPE_FLEX) {
(*play->flexLimbOverrideMTX)++;
}
}
doNotDrawLimb = true;
@ -2034,14 +2048,28 @@ s32 BossGoma_OverrideLimbDraw(PlayState* play, s32 limbIndex, Gfx** dList, Vec3f
Matrix_TranslateRotateZYX(pos, rot);
if (*dList != NULL) {
if (this->skelanime.skeletonHeader->skeletonType == SKELANIME_TYPE_FLEX) {
MATRIX_TOMTX(*play->flexLimbOverrideMTX);
}
Matrix_Push();
Matrix_Scale(this->tailLimbsScale[limbIndex - BOSSGOMA_LIMB_TAIL4],
this->tailLimbsScale[limbIndex - BOSSGOMA_LIMB_TAIL4],
this->tailLimbsScale[limbIndex - BOSSGOMA_LIMB_TAIL4], MTXMODE_APPLY);
gSPMatrix(POLY_OPA_DISP++, MATRIX_NEWMTX(play->state.gfxCtx),
G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
if (this->skelanime.skeletonHeader->skeletonType == SKELANIME_TYPE_FLEX) {
gSPMatrix(POLY_OPA_DISP++, *play->flexLimbOverrideMTX, G_MTX_LOAD);
} else {
gSPMatrix(POLY_OPA_DISP++, MATRIX_NEWMTX(play->state.gfxCtx),
G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
}
gSPDisplayList(POLY_OPA_DISP++, *dList);
Matrix_Pop();
if (this->skelanime.skeletonHeader->skeletonType == SKELANIME_TYPE_FLEX) {
(*play->flexLimbOverrideMTX)++;
}
}
doNotDrawLimb = true;

View File

@ -961,7 +961,7 @@ void DoorWarp1_DrawBlueCrystal(DoorWarp1* this, PlayState* play) {
gDPSetPrimColor(POLY_XLU_DISP++, 0xFF, 0xFF, 200, 255, 255, (u8)this->crystalAlpha);
gDPSetEnvColor(POLY_XLU_DISP++, 0, 100, 255, (u8)this->crystalAlpha);
POLY_XLU_DISP = SkelAnime_Draw(play, this->skelAnime.skeleton, this->skelAnime.jointTable, NULL, NULL,
POLY_XLU_DISP = SkelAnime_DrawSkeleton2(play, &this->skelAnime, NULL, NULL,
&this->actor, POLY_XLU_DISP);
CLOSE_DISPS(play->state.gfxCtx);
@ -985,7 +985,7 @@ void DoorWarp1_DrawPurpleCrystal(DoorWarp1* this, PlayState* play) {
gDPSetPrimColor(POLY_XLU_DISP++, 0, 0, 255, 255, 255, (u8)this->crystalAlpha);
gDPSetEnvColor(POLY_XLU_DISP++, 150, 0, 100, (u8)this->crystalAlpha);
POLY_XLU_DISP = SkelAnime_Draw(play, this->skelAnime.skeleton, this->skelAnime.jointTable, NULL, NULL,
POLY_XLU_DISP = SkelAnime_DrawSkeleton2(play, &this->skelAnime, NULL, NULL,
&this->actor, POLY_XLU_DISP);
CLOSE_DISPS(play->state.gfxCtx);

View File

@ -768,7 +768,7 @@ void EnBili_Draw(Actor* thisx, PlayState* play) {
gSPSegment(POLY_XLU_DISP++, 0x09, D_809C1700);
}
POLY_XLU_DISP = SkelAnime_Draw(play, this->skelAnime.skeleton, this->skelAnime.jointTable,
POLY_XLU_DISP = SkelAnime_DrawSkeleton2(play, &this->skelAnime,
EnBili_OverrideLimbDraw, NULL, this, POLY_XLU_DISP);
CLOSE_DISPS(play->state.gfxCtx);
}

View File

@ -895,7 +895,7 @@ void EnBox_Draw(Actor* thisx, PlayState* play) {
gDPSetEnvColor(POLY_OPA_DISP++, 0, 0, 0, 255);
gSPSegment(POLY_OPA_DISP++, 0x08, EnBox_EmptyDList(play->state.gfxCtx));
Gfx_SetupDL_25Opa(play->state.gfxCtx);
POLY_OPA_DISP = SkelAnime_Draw(play, this->skelanime.skeleton, this->skelanime.jointTable, NULL,
POLY_OPA_DISP = SkelAnime_DrawSkeleton2(play, &this->skelanime, NULL,
EnBox_PostLimbDraw, this, POLY_OPA_DISP);
} else if (this->alpha != 0) {
gDPPipeSync(POLY_XLU_DISP++);
@ -906,7 +906,7 @@ void EnBox_Draw(Actor* thisx, PlayState* play) {
} else {
gSPSegment(POLY_XLU_DISP++, 0x08, func_809CA4A0(play->state.gfxCtx));
}
POLY_XLU_DISP = SkelAnime_Draw(play, this->skelanime.skeleton, this->skelanime.jointTable, NULL,
POLY_XLU_DISP = SkelAnime_DrawSkeleton2(play, &this->skelanime, NULL,
EnBox_PostLimbDraw, this, POLY_XLU_DISP);
}

View File

@ -856,7 +856,7 @@ void EnBw_Draw(Actor* thisx, PlayState* play2) {
Gfx_SetupDL_25Opa(play->state.gfxCtx);
gDPSetEnvColor(POLY_OPA_DISP++, this->color1.r, this->color1.g, this->color1.b, this->color1.a);
gSPSegment(POLY_OPA_DISP++, 0x08, &D_80116280[2]);
POLY_OPA_DISP = SkelAnime_Draw(play, this->skelAnime.skeleton, this->skelAnime.jointTable,
POLY_OPA_DISP = SkelAnime_DrawSkeleton2(play, &this->skelAnime,
EnBw_OverrideLimbDraw, NULL, this, POLY_OPA_DISP);
} else {
Gfx_SetupDL_25Xlu(play->state.gfxCtx);
@ -864,7 +864,7 @@ void EnBw_Draw(Actor* thisx, PlayState* play2) {
gDPSetPrimColor(POLY_XLU_DISP++, 0x80, 0x80, 0, 0, 0, this->color1.a);
gDPSetEnvColor(POLY_XLU_DISP++, this->color1.r, this->color1.g, this->color1.b, this->color1.a);
gSPSegment(POLY_XLU_DISP++, 0x08, &D_80116280[0]);
POLY_XLU_DISP = SkelAnime_Draw(play, this->skelAnime.skeleton, this->skelAnime.jointTable,
POLY_XLU_DISP = SkelAnime_DrawSkeleton2(play, &this->skelAnime,
EnBw_OverrideLimbDraw, NULL, this, POLY_XLU_DISP);
}

View File

@ -708,14 +708,14 @@ void EnEiyer_Draw(Actor* thisx, PlayState* play) {
gSPSegment(POLY_OPA_DISP++, 0x08, &D_80116280[2]);
gDPSetEnvColor(POLY_OPA_DISP++, 255, 255, 255, 255);
POLY_OPA_DISP = SkelAnime_Draw(play, this->skelanime.skeleton, this->skelanime.jointTable,
POLY_OPA_DISP = SkelAnime_DrawSkeleton2(play, &this->skelanime,
EnEiyer_OverrideLimbDraw, NULL, this, POLY_OPA_DISP);
} else {
Gfx_SetupDL_25Xlu(play->state.gfxCtx);
gSPSegment(POLY_XLU_DISP++, 0x08, D_80116280);
gDPSetEnvColor(POLY_XLU_DISP++, 255, 255, 255, this->actor.shape.shadowAlpha);
POLY_XLU_DISP = SkelAnime_Draw(play, this->skelanime.skeleton, this->skelanime.jointTable,
POLY_XLU_DISP = SkelAnime_DrawSkeleton2(play, &this->skelanime,
EnEiyer_OverrideLimbDraw, NULL, this, POLY_XLU_DISP);
}
CLOSE_DISPS(play->state.gfxCtx);

View File

@ -1540,7 +1540,7 @@ void EnElf_Draw(Actor* thisx, PlayState* play) {
gSPEndDisplayList(dListHead++);
gDPSetEnvColor(POLY_XLU_DISP++, (u8)this->outerColor.r, (u8)this->outerColor.g, (u8)this->outerColor.b,
(u8)(envAlpha * alphaScale));
POLY_XLU_DISP = SkelAnime_Draw(play, this->skelAnime.skeleton, this->skelAnime.jointTable,
POLY_XLU_DISP = SkelAnime_DrawSkeleton2(play, &this->skelAnime,
EnElf_OverrideLimbDraw, NULL, this, POLY_XLU_DISP);
CLOSE_DISPS(play->state.gfxCtx);

View File

@ -839,8 +839,9 @@ void EnFirefly_Draw(Actor* thisx, PlayState* play) {
gDPSetEnvColor(POLY_OPA_DISP++, 0, 0, 0, 255);
}
POLY_OPA_DISP = SkelAnime_Draw(play, this->skelAnime.skeleton, this->skelAnime.jointTable,
EnFirefly_OverrideLimbDraw, EnFirefly_PostLimbDraw, &this->actor, POLY_OPA_DISP);
POLY_OPA_DISP = SkelAnime_DrawSkeleton2(play, &this->skelAnime, EnFirefly_OverrideLimbDraw, EnFirefly_PostLimbDraw,
&this->actor, POLY_OPA_DISP);
CLOSE_DISPS(play->state.gfxCtx);
}
@ -856,7 +857,7 @@ void EnFirefly_DrawInvisible(Actor* thisx, PlayState* play) {
gDPSetEnvColor(POLY_XLU_DISP++, 0, 0, 0, 255);
}
POLY_XLU_DISP = SkelAnime_Draw(play, this->skelAnime.skeleton, this->skelAnime.jointTable,
POLY_XLU_DISP = SkelAnime_DrawSkeleton2(play, &this->skelAnime,
EnFirefly_OverrideLimbDraw, EnFirefly_PostLimbDraw, this, POLY_XLU_DISP);
CLOSE_DISPS(play->state.gfxCtx);
}

View File

@ -817,12 +817,28 @@ void EnFr_SetupFrogSong(EnFr* this, PlayState* play) {
if (this->frogSongTimer != 0) {
this->frogSongTimer--;
} else {
this->frogSongTimer = 40;
this->ocarinaNoteIndex = 0;
func_8010BD58(play, OCARINA_ACTION_FROGS);
this->ocarinaNote = EnFr_GetNextNoteFrogSong(this->ocarinaNoteIndex);
EnFr_CheckOcarinaInputFrogSong(this->ocarinaNote);
this->actionFunc = EnFr_ContinueFrogSong;
// #region SOH [Enhancement]
if (CVarGetInteger(CVAR_ENHANCEMENT("CustomizeFrogsOcarinaGame"), 0)) {
this->frogSongTimer = 40 * CVarGetInteger(CVAR_ENHANCEMENT("FrogsModifyFailTime"), 1);
if (CVarGetInteger(CVAR_ENHANCEMENT("InstantFrogsGameWin"), 0)) {
this->actor.textId = 0x40AC;
EnFr_SetupReward(this, play, false);
} else {
this->ocarinaNoteIndex = 0;
func_8010BD58(play, OCARINA_ACTION_FROGS);
this->ocarinaNote = EnFr_GetNextNoteFrogSong(this->ocarinaNoteIndex);
EnFr_CheckOcarinaInputFrogSong(this->ocarinaNote);
this->actionFunc = EnFr_ContinueFrogSong;
}
// #endregion
} else {
this->frogSongTimer = 40;
this->ocarinaNoteIndex = 0;
func_8010BD58(play, OCARINA_ACTION_FROGS);
this->ocarinaNote = EnFr_GetNextNoteFrogSong(this->ocarinaNoteIndex);
EnFr_CheckOcarinaInputFrogSong(this->ocarinaNote);
this->actionFunc = EnFr_ContinueFrogSong;
}
}
}
@ -844,7 +860,13 @@ s32 EnFr_IsFrogSongComplete(EnFr* this, PlayState* play) {
ocarinaNote = EnFr_GetNextNoteFrogSong(ocarinaNoteIndex);
this->ocarinaNote = ocarinaNote;
EnFr_CheckOcarinaInputFrogSong(ocarinaNote);
this->frogSongTimer = sTimerFrogSong[index];
// #region SOH [Enhancement]
if (CVarGetInteger(CVAR_ENHANCEMENT("CustomizeFrogsOcarinaGame"), 0)) {
this->frogSongTimer = sTimerFrogSong[index] * CVarGetInteger(CVAR_ENHANCEMENT("FrogsModifyFailTime"), 1);
// #endregion
} else {
this->frogSongTimer = sTimerFrogSong[index];
}
}
return false;
}
@ -867,7 +889,12 @@ void EnFr_ContinueFrogSong(EnFr* this, PlayState* play) {
if (this->frogSongTimer == 0) {
EnFr_OcarinaMistake(this, play);
} else {
this->frogSongTimer--;
// #region SOH [Enhancement] - Don't decrement timer
if (!CVarGetInteger(CVAR_ENHANCEMENT("CustomizeFrogsOcarinaGame"), 0) ||
!CVarGetInteger(CVAR_ENHANCEMENT("FrogsUnlimitedFailTime"), 0)) {
// #endregion
this->frogSongTimer--;
}
if (play->msgCtx.msgMode == MSGMODE_FROGS_PLAYING) {
counter = 0;
for (i = 0; i < ARRAY_COUNT(sEnFrPointers.frogs); i++) {

View File

@ -880,7 +880,7 @@ void EnPartner_Draw(Actor* thisx, PlayState* play) {
gSPEndDisplayList(dListHead++);
gDPSetEnvColor(POLY_XLU_DISP++, (u8)this->outerColor.r, (u8)this->outerColor.g, (u8)this->outerColor.b,
(u8)(envAlpha * alphaScale));
POLY_XLU_DISP = SkelAnime_Draw(play, this->skelAnime.skeleton, this->skelAnime.jointTable,
POLY_XLU_DISP = SkelAnime_DrawSkeleton2(play, &this->skelAnime,
EnPartner_OverrideLimbDraw, NULL, this, POLY_XLU_DISP);
CLOSE_DISPS(play->state.gfxCtx);

View File

@ -267,7 +267,7 @@ void EnPoDesert_Draw(Actor* thisx, PlayState* play) {
} else {
gSPSegment(POLY_XLU_DISP++, 0x0C, D_80116280 + 2);
}
POLY_XLU_DISP = SkelAnime_Draw(play, this->skelAnime.skeleton, this->skelAnime.jointTable,
POLY_XLU_DISP = SkelAnime_DrawSkeleton2(play, &this->skelAnime,
EnPoDesert_OverrideLimbDraw, EnPoDesert_PostLimbDraw, &this->actor, POLY_XLU_DISP);
CLOSE_DISPS(play->state.gfxCtx);
}

View File

@ -944,15 +944,14 @@ void EnPoField_Draw(Actor* thisx, PlayState* play) {
this->lightColor.a));
gSPSegment(POLY_OPA_DISP++, 0x0C, D_80116280 + 2);
POLY_OPA_DISP =
SkelAnime_Draw(play, this->skelAnime.skeleton, this->skelAnime.jointTable,
SkelAnime_DrawSkeleton2(play, &this->skelAnime,
EnPoField_OverrideLimbDraw2, EnPoField_PostLimDraw2, &this->actor, POLY_OPA_DISP);
} else {
gSPSegment(POLY_XLU_DISP++, 0x08,
Gfx_EnvColor(play->state.gfxCtx, this->lightColor.r, this->lightColor.g, this->lightColor.b,
this->lightColor.a));
gSPSegment(POLY_XLU_DISP++, 0x0C, D_80116280);
POLY_XLU_DISP =
SkelAnime_Draw(play, this->skelAnime.skeleton, this->skelAnime.jointTable,
POLY_XLU_DISP = SkelAnime_DrawSkeleton2(play, &this->skelAnime,
EnPoField_OverrideLimbDraw2, EnPoField_PostLimDraw2, &this->actor, POLY_XLU_DISP);
}
gDPPipeSync(POLY_OPA_DISP++);

View File

@ -1362,14 +1362,12 @@ void EnPoSisters_Draw(Actor* thisx, PlayState* play) {
if (this->unk_22E.a == 255 || this->unk_22E.a == 0) {
gDPSetEnvColor(POLY_OPA_DISP++, this->unk_22E.r, this->unk_22E.g, this->unk_22E.b, this->unk_22E.a);
gSPSegment(POLY_OPA_DISP++, 0x09, D_80116280 + 2);
POLY_OPA_DISP =
SkelAnime_Draw(play, this->skelAnime.skeleton, this->skelAnime.jointTable,
EnPoSisters_OverrideLimbDraw, EnPoSisters_PostLimbDraw, &this->actor, POLY_OPA_DISP);
POLY_OPA_DISP = SkelAnime_DrawSkeleton2(play, &this->skelAnime, EnPoSisters_OverrideLimbDraw,
EnPoSisters_PostLimbDraw, &this->actor, POLY_OPA_DISP);
} else {
gDPSetEnvColor(POLY_XLU_DISP++, 255, 255, 255, this->unk_22E.a);
gSPSegment(POLY_XLU_DISP++, 0x09, D_80116280);
POLY_XLU_DISP =
SkelAnime_Draw(play, this->skelAnime.skeleton, this->skelAnime.jointTable,
POLY_XLU_DISP = SkelAnime_DrawSkeleton2(play, &this->skelAnime,
EnPoSisters_OverrideLimbDraw, EnPoSisters_PostLimbDraw, &this->actor, POLY_XLU_DISP);
}
if (!(this->unk_199 & 0x80)) {

View File

@ -1085,12 +1085,12 @@ void EnPoh_DrawRegular(Actor* thisx, PlayState* play) {
if (this->lightColor.a == 255 || this->lightColor.a == 0) {
gDPSetEnvColor(POLY_OPA_DISP++, this->lightColor.r, this->lightColor.g, this->lightColor.b, this->lightColor.a);
gSPSegment(POLY_OPA_DISP++, 0x08, D_80116280 + 2);
POLY_OPA_DISP = SkelAnime_Draw(play, this->skelAnime.skeleton, this->skelAnime.jointTable,
POLY_OPA_DISP = SkelAnime_DrawSkeleton2(play, &this->skelAnime,
EnPoh_OverrideLimbDraw, EnPoh_PostLimbDraw, &this->actor, POLY_OPA_DISP);
} else {
gDPSetEnvColor(POLY_XLU_DISP++, 255, 255, 255, this->lightColor.a);
gSPSegment(POLY_XLU_DISP++, 0x08, D_80116280);
POLY_XLU_DISP = SkelAnime_Draw(play, this->skelAnime.skeleton, this->skelAnime.jointTable,
POLY_XLU_DISP = SkelAnime_DrawSkeleton2(play, &this->skelAnime,
EnPoh_OverrideLimbDraw, EnPoh_PostLimbDraw, &this->actor, POLY_XLU_DISP);
}
gDPPipeSync(POLY_OPA_DISP++);

View File

@ -814,7 +814,7 @@ void EnVali_Draw(Actor* thisx, PlayState* play) {
EnVali_DrawBody(this, play);
POLY_XLU_DISP = SkelAnime_Draw(play, this->skelAnime.skeleton, this->skelAnime.jointTable,
POLY_XLU_DISP = SkelAnime_DrawSkeleton2(play, &this->skelAnime,
EnVali_OverrideLimbDraw, EnVali_PostLimbDraw, this, POLY_XLU_DISP);
CLOSE_DISPS(play->state.gfxCtx);

View File

@ -640,13 +640,13 @@ void EnWeiyer_Draw(Actor* thisx, PlayState* play) {
Gfx_SetupDL_25Opa(play->state.gfxCtx);
gSPSegment(POLY_OPA_DISP++, 0x08, &D_80116280[2]);
gDPSetEnvColor(POLY_OPA_DISP++, 255, 255, 255, 255);
POLY_OPA_DISP = SkelAnime_Draw(play, this->skelAnime.skeleton, this->skelAnime.jointTable,
EnWeiyer_OverrideLimbDraw, NULL, &this->actor, POLY_OPA_DISP);
POLY_OPA_DISP = SkelAnime_DrawSkeleton2(play, &this->skelAnime, EnWeiyer_OverrideLimbDraw, NULL, &this->actor,
POLY_OPA_DISP);
} else {
Gfx_SetupDL_25Xlu(play->state.gfxCtx);
gSPSegment(POLY_XLU_DISP++, 0x08, &D_80116280[0]);
gDPSetEnvColor(POLY_XLU_DISP++, 255, 255, 255, this->actor.shape.shadowAlpha);
POLY_XLU_DISP = SkelAnime_Draw(play, this->skelAnime.skeleton, this->skelAnime.jointTable,
POLY_XLU_DISP = SkelAnime_DrawSkeleton2(play, &this->skelAnime,
EnWeiyer_OverrideLimbDraw, NULL, &this->actor, POLY_XLU_DISP);
}

View File

@ -101,13 +101,19 @@ static f32 sSpawnSin;
s32 EnWood02_SpawnZoneCheck(EnWood02* this, PlayState* play, Vec3f* pos) {
f32 phi_f12;
if (CVarGetInteger(CVAR_ENHANCEMENT("DisableDrawDistance"), 0) != 0) {
return true;
}
SkinMatrix_Vec3fMtxFMultXYZW(&play->viewProjectionMtxF, pos, &this->actor.projectedPos,
&this->actor.projectedW);
// #region SOH [Enhancement] Use the extended culling calculation
if (CVarGetInteger(CVAR_ENHANCEMENT("DisableDrawDistance"), 1) > 1 ||
CVarGetInteger(CVAR_ENHANCEMENT("WidescreenActorCulling"), 0)) {
bool shipShouldDraw = false;
bool shipShouldUpdate = false;
return Ship_CalcShouldDrawAndUpdate(play, &this->actor, &this->actor.projectedPos, this->actor.projectedW,
&shipShouldDraw, &shipShouldUpdate);
}
// #endregion
phi_f12 = ((this->actor.projectedW == 0.0f) ? 1000.0f : fabsf(1.0f / this->actor.projectedW));
if ((-this->actor.uncullZoneScale < this->actor.projectedPos.z) &&

View File

@ -2252,7 +2252,7 @@ void EnZf_Draw(Actor* thisx, PlayState* play) {
gDPSetEnvColor(POLY_OPA_DISP++, 0, 0, 0, this->alpha);
gSPSegment(POLY_OPA_DISP++, 0x09, &D_80116280[2]);
POLY_OPA_DISP = SkelAnime_Draw(play, this->skelAnime.skeleton, this->skelAnime.jointTable,
POLY_OPA_DISP = SkelAnime_DrawSkeleton2(play, &this->skelAnime,
EnZf_OverrideLimbDraw, EnZf_PostLimbDraw, this, POLY_OPA_DISP);
if (this->iceTimer != 0) {
@ -2271,7 +2271,7 @@ void EnZf_Draw(Actor* thisx, PlayState* play) {
gDPPipeSync(POLY_XLU_DISP++);
gDPSetEnvColor(POLY_XLU_DISP++, 0, 0, 0, this->alpha);
gSPSegment(POLY_XLU_DISP++, 0x09, &D_80116280[0]);
POLY_XLU_DISP = SkelAnime_Draw(play, this->skelAnime.skeleton, this->skelAnime.jointTable,
POLY_XLU_DISP = SkelAnime_DrawSkeleton2(play, &this->skelAnime,
EnZf_OverrideLimbDraw, EnZf_PostLimbDraw, this, POLY_XLU_DISP);
}
CLOSE_DISPS(play->state.gfxCtx);

View File

@ -275,7 +275,12 @@ void ObjMure_InitialAction(ObjMure* this, PlayState* play) {
}
void ObjMure_CulledState(ObjMure* this, PlayState* play) {
if (fabsf(this->actor.projectedPos.z) < sZClip[this->type] || CVarGetInteger(CVAR_ENHANCEMENT("DisableDrawDistance"), 0) != 0) {
// #region SOH [Enhancements] Extended draw distance
s32 distanceMultiplier = CVarGetInteger(CVAR_ENHANCEMENT("DisableDrawDistance"), 1);
distanceMultiplier = MAX(distanceMultiplier, 1);
if (fabsf(this->actor.projectedPos.z) < sZClip[this->type] * distanceMultiplier) {
// #endregion
this->actionFunc = ObjMure_ActiveState;
this->actor.flags |= ACTOR_FLAG_UPDATE_WHILE_CULLED;
ObjMure_SpawnActors(this, play);
@ -398,8 +403,13 @@ static ObjMureActionFunc sTypeGroupBehaviorFunc[] = {
void ObjMure_ActiveState(ObjMure* this, PlayState* play) {
ObjMure_CheckChildren(this, play);
if (sZClip[this->type] + 40.0f <= fabsf(this->actor.projectedPos.z) &&
CVarGetInteger(CVAR_ENHANCEMENT("DisableDrawDistance"), 1) != 0) {
// #region SOH [Enhancements] Extended draw distance
s32 distanceMultiplier = CVarGetInteger(CVAR_ENHANCEMENT("DisableDrawDistance"), 1);
distanceMultiplier = MAX(distanceMultiplier, 1);
if ((sZClip[this->type] + 40.0f) * distanceMultiplier <= fabsf(this->actor.projectedPos.z)) {
// #endregion
this->actionFunc = ObjMure_CulledState;
this->actor.flags &= ~ACTOR_FLAG_UPDATE_WHILE_CULLED;
ObjMure_KillActors(this, play);

View File

@ -190,8 +190,7 @@ void func_80B9A658(ObjMure2* this) {
void func_80B9A668(ObjMure2* this, PlayState* play) {
if (Math3D_Dist1DSq(this->actor.projectedPos.x, this->actor.projectedPos.z) <
(sDistSquared1[this->actor.params & 3] * this->unk_184) ||
CVarGetInteger(CVAR_ENHANCEMENT("DisableDrawDistance"), 0) != 0) {
(sDistSquared1[this->actor.params & 3] * this->unk_184)) {
this->actor.flags |= ACTOR_FLAG_UPDATE_WHILE_CULLED;
ObjMure2_SpawnActors(this, play);
func_80B9A6E8(this);
@ -205,12 +204,8 @@ void func_80B9A6E8(ObjMure2* this) {
void func_80B9A6F8(ObjMure2* this, PlayState* play) {
func_80B9A534(this);
if (CVarGetInteger(CVAR_ENHANCEMENT("DisableDrawDistance"), 0) != 0) {
return;
}
if ((sDistSquared2[this->actor.params & 3] * this->unk_184) <=
Math3D_Dist1DSq(this->actor.projectedPos.x, this->actor.projectedPos.z)) {
Math3D_Dist1DSq(this->actor.projectedPos.x, this->actor.projectedPos.z)) {
this->actor.flags &= ~ACTOR_FLAG_UPDATE_WHILE_CULLED;
ObjMure2_CleanupAndDie(this, play);
func_80B9A658(this);
@ -225,5 +220,20 @@ void ObjMure2_Update(Actor* thisx, PlayState* play) {
} else {
this->unk_184 = 4.0f;
}
// SOH [Enhancements] Extended draw distance
s32 distanceMultiplier = CVarGetInteger(CVAR_ENHANCEMENT("DisableDrawDistance"), 1);
if (CVarGetInteger(CVAR_ENHANCEMENT("WidescreenActorCulling"), 0) || distanceMultiplier > 1) {
f32 originalAspectRatio = 4.0f / 3.0f;
f32 currentAspectRatio = OTRGetAspectRatio();
// Adjust ratio difference based on field of view testing
f32 ratioAdjusted = 1.0f + (MAX(currentAspectRatio / originalAspectRatio, 1.0f) / 1.5f);
// Distance multiplier is squared due to the checks above for squared distances
distanceMultiplier = SQ(MAX(distanceMultiplier, 1));
// Prefer the largest of the three values
this->unk_184 = MAX(MAX((f32)distanceMultiplier, ratioAdjusted), this->unk_184);
}
this->actionFunc(this, play);
}

View File

@ -11895,10 +11895,6 @@ void Player_Draw(Actor* thisx, PlayState* play2) {
lod = 1;
}
if (CVarGetInteger(CVAR_ENHANCEMENT("DisableLOD"), 0)) {
lod = 0;
}
func_80093C80(play);
Gfx_SetupDL_25Xlu(play->state.gfxCtx);
@ -12119,7 +12115,8 @@ void func_8084AEEC(Player* this, f32* arg1, f32 arg2, s16 arg3) {
} else if (gWalkSpeedToggle2) {
swimMod *= CVarGetFloat(CVAR_SETTING("WalkModifier.SwimMapping2"), 1.0f);
}
} else {
// sControlInput is NULL to prevent inputs while surfacing after obtaining an underwater item so we want to ignore it for that case
} else if (sControlInput != NULL) {
if (CHECK_BTN_ALL(sControlInput->cur.button, BTN_MODIFIER1)) {
swimMod *= CVarGetFloat(CVAR_SETTING("WalkModifier.SwimMapping1"), 1.0f);
} else if (CHECK_BTN_ALL(sControlInput->cur.button, BTN_MODIFIER2)) {

View File

@ -27,6 +27,8 @@ static Vtx sStrengthAButtonVtx[] = {
static s16 sEquipTimer = 0;
extern int gPauseLinkFrameBuffer;
void KaleidoScope_DrawEquipmentImage(PlayState* play, void* source, u32 width, u32 height) {
PauseContext* pauseCtx = &play->pauseCtx;
u8* curTexture;
@ -70,13 +72,12 @@ void KaleidoScope_DrawEquipmentImage(PlayState* play, void* source, u32 width, u
for (i = 0; i < textureCount; i++) {
gSPVertex(POLY_KAL_DISP++, &pauseCtx->equipVtx[vtxIndex], 4, 0);
extern int fbTest;
gDPSetTextureImage(POLY_KAL_DISP++, G_IM_FMT_RGBA, G_IM_SIZ_16b, width, curTexture);
gDPLoadSync(POLY_KAL_DISP++);
gDPLoadTile(POLY_KAL_DISP++, G_TX_LOADTILE, 0, 0, (width - 1) << 2, (textureHeight - 1) << 2);
gDPSetTextureImageFB(POLY_KAL_DISP++, G_IM_FMT_RGBA, G_IM_SIZ_16b, width, fbTest);
gDPSetTextureImageFB(POLY_KAL_DISP++, G_IM_FMT_RGBA, G_IM_SIZ_16b, width, gPauseLinkFrameBuffer);
gSP1Quadrangle(POLY_KAL_DISP++, 0, 2, 3, 1, 0);
curTexture += textureSize;
@ -185,8 +186,7 @@ void KaleidoScope_DrawPlayerWork(PlayState* play) {
link_kaleido_rot.x = 0;
extern int fbTest;
gsSPSetFB(play->state.gfxCtx->polyOpa.p++, fbTest);
gsSPSetFB(play->state.gfxCtx->polyOpa.p++, gPauseLinkFrameBuffer);
Player_DrawPause(play, pauseCtx->playerSegment, &pauseCtx->playerSkelAnime, &pos, &link_kaleido_rot, scale,
SWORD_EQUIP_TO_PLAYER(CUR_EQUIP_VALUE(EQUIP_TYPE_SWORD)),
TUNIC_EQUIP_TO_PLAYER(CUR_EQUIP_VALUE(EQUIP_TYPE_TUNIC)),
@ -852,7 +852,7 @@ void KaleidoScope_DrawEquipment(PlayState* play) {
//gSPSegment(POLY_KAL_DISP++, 0x0C, pauseCtx->iconItemAltSegment);
Gfx_SetupDL_42Kal(play->state.gfxCtx);
KaleidoScope_DrawEquipmentImage(play, pauseCtx->playerSegment, 64, 112);
KaleidoScope_DrawEquipmentImage(play, pauseCtx->playerSegment, PAUSE_EQUIP_PLAYER_WIDTH, PAUSE_EQUIP_PLAYER_HEIGHT);
if (gUpgradeMasks[0]) {}

View File

@ -929,7 +929,6 @@ static void* sPromptChoiceTexs[][2] = {
static u8 sButtonStatusSave[ARRAY_COUNT(gSaveContext.buttonStatus)];
static PreRender sPlayerPreRender;
static void* sPreRenderCvg;
extern int fbTest;
void KaleidoScope_ProcessPlayerPreRender(void) {
PreRender_Calc(&sPlayerPreRender);
@ -3725,7 +3724,8 @@ void KaleidoScope_Update(PlayState* play)
sPreRenderCvg = (void*)(((uintptr_t)pauseCtx->nameSegment + 0x400 + 0xA00 + 0xF) & ~0xF);
PreRender_Init(&sPlayerPreRender);
PreRender_SetValuesSave(&sPlayerPreRender, 64, 112, pauseCtx->playerSegment, NULL, sPreRenderCvg);
PreRender_SetValuesSave(&sPlayerPreRender, PAUSE_EQUIP_PLAYER_WIDTH, PAUSE_EQUIP_PLAYER_HEIGHT,
pauseCtx->playerSegment, NULL, sPreRenderCvg);
KaleidoScope_DrawPlayerWork(play);
//KaleidoScope_SetupPlayerPreRender(play);