Merge remote-tracking branch 'origin/develop' into merge-macready-may6
2
.github/workflows/apt-deps.txt
vendored
@ -1 +1 @@
|
|||||||
libsdl2-dev libsdl2-net-dev libpng-dev libglew-dev ninja-build
|
libusb-dev libusb-1.0-0-dev libsdl2-dev libsdl2-net-dev libpng-dev libglew-dev libzip-dev zipcmp zipmerge ziptool nlohmann-json3-dev libtinyxml2-dev libspdlog-dev ninja-build
|
||||||
|
258
.github/workflows/generate-builds.yml
vendored
@ -13,42 +13,60 @@ jobs:
|
|||||||
with:
|
with:
|
||||||
submodules: true
|
submodules: true
|
||||||
- name: ccache
|
- name: ccache
|
||||||
uses: hendrikmuhs/ccache-action@v1.2
|
uses: hendrikmuhs/ccache-action@v1.2.11
|
||||||
with:
|
with:
|
||||||
key: ${{ runner.os }}-soh-otr-ccache
|
key: ${{ runner.os }}-otr-ccache-${{ github.ref }}-${{ github.sha }}
|
||||||
|
restore-keys: |
|
||||||
|
${{ runner.os }}-otr-ccache-${{ github.ref }}
|
||||||
|
${{ runner.os }}-otr-ccache-
|
||||||
- name: Install dependencies
|
- name: Install dependencies
|
||||||
if: ${{ !vars.LINUX_RUNNER }}
|
if: ${{ !vars.LINUX_RUNNER }}
|
||||||
run: |
|
run: |
|
||||||
sudo apt-get update
|
sudo apt-get update
|
||||||
sudo apt-get install -y $(cat .github/workflows/apt-deps.txt)
|
sudo apt-get install -y $(cat .github/workflows/apt-deps.txt)
|
||||||
|
- name: Cache build folders
|
||||||
|
uses: actions/cache@v4
|
||||||
|
with:
|
||||||
|
key: ${{ runner.os }}-otr-build-${{ github.ref }}-${{ github.sha }}
|
||||||
|
restore-keys: |
|
||||||
|
${{ runner.os }}-otr-build-${{ github.ref }}
|
||||||
|
${{ runner.os }}-otr-build-
|
||||||
|
path: |
|
||||||
|
build-cmake
|
||||||
|
SDL2-2.28.5
|
||||||
- name: Install latest SDL
|
- name: Install latest SDL
|
||||||
if: ${{ !vars.LINUX_RUNNER }}
|
if: ${{ !vars.LINUX_RUNNER }}
|
||||||
run: |
|
run: |
|
||||||
export PATH="/usr/lib/ccache:/usr/local/opt/ccache/libexec:$PATH"
|
export PATH="/usr/lib/ccache:/usr/local/opt/ccache/libexec:$PATH"
|
||||||
wget https://www.libsdl.org/release/SDL2-2.26.1.tar.gz
|
if [ ! -d "SDL2-2.28.5" ]; then
|
||||||
tar -xzf SDL2-2.26.1.tar.gz
|
wget https://www.libsdl.org/release/SDL2-2.28.5.tar.gz
|
||||||
cd SDL2-2.26.1
|
tar -xzf SDL2-2.28.5.tar.gz
|
||||||
./configure
|
fi
|
||||||
|
cd SDL2-2.28.5
|
||||||
|
./configure --enable-hidapi-libusb
|
||||||
make -j 10
|
make -j 10
|
||||||
sudo make install
|
sudo make install
|
||||||
sudo cp -av /usr/local/lib/libSDL* /lib/x86_64-linux-gnu/
|
sudo cp -av /usr/local/lib/libSDL* /lib/x86_64-linux-gnu/
|
||||||
- name: Install latest SDL_net
|
- name: Install latest tinyxml2
|
||||||
if: ${{ !vars.LINUX_RUNNER }}
|
|
||||||
run: |
|
run: |
|
||||||
|
sudo apt-get remove libtinyxml2-dev
|
||||||
export PATH="/usr/lib/ccache:/usr/local/opt/ccache/libexec:$PATH"
|
export PATH="/usr/lib/ccache:/usr/local/opt/ccache/libexec:$PATH"
|
||||||
wget https://www.libsdl.org/projects/SDL_net/release/SDL2_net-2.2.0.tar.gz
|
if [ ! -d "tinyxml2-10.0.0" ]; then
|
||||||
tar -xzf SDL2_net-2.2.0.tar.gz
|
wget https://github.com/leethomason/tinyxml2/archive/refs/tags/10.0.0.tar.gz
|
||||||
cd SDL2_net-2.2.0
|
tar -xzf 10.0.0.tar.gz
|
||||||
./configure
|
fi
|
||||||
make -j 10
|
cd tinyxml2-10.0.0
|
||||||
|
mkdir build
|
||||||
|
cd build
|
||||||
|
cmake ..
|
||||||
|
make
|
||||||
sudo make install
|
sudo make install
|
||||||
sudo cp -av /usr/local/lib/libSDL* /lib/x86_64-linux-gnu/
|
|
||||||
- name: Generate soh.otr
|
- name: Generate soh.otr
|
||||||
run: |
|
run: |
|
||||||
export PATH="/usr/lib/ccache:/usr/local/opt/ccache/libexec:$PATH"
|
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
|
cmake --no-warn-unused-cli -H. -Bbuild-cmake -GNinja -DCMAKE_BUILD_TYPE:STRING=Release
|
||||||
cmake --build build-cmake --config Release --target GenerateSohOtr
|
cmake --build build-cmake --config Release --target GenerateSohOtr
|
||||||
- uses: actions/upload-artifact@v3
|
- uses: actions/upload-artifact@v4
|
||||||
with:
|
with:
|
||||||
name: soh.otr
|
name: soh.otr
|
||||||
path: soh.otr
|
path: soh.otr
|
||||||
@ -61,9 +79,12 @@ jobs:
|
|||||||
with:
|
with:
|
||||||
submodules: true
|
submodules: true
|
||||||
- name: ccache
|
- name: ccache
|
||||||
uses: hendrikmuhs/ccache-action@v1.2
|
uses: hendrikmuhs/ccache-action@v1.2.11
|
||||||
with:
|
with:
|
||||||
key: ${{ runner.os }}-ccache
|
key: ${{ runner.os }}-ccache-${{ github.ref }}-${{ github.sha }}
|
||||||
|
restore-keys: |
|
||||||
|
${{ runner.os }}-ccache-${{ github.ref }}
|
||||||
|
${{ runner.os }}-ccache-
|
||||||
- name: Install gtar wrapper
|
- name: Install gtar wrapper
|
||||||
if: ${{ !vars.MAC_RUNNER }}
|
if: ${{ !vars.MAC_RUNNER }}
|
||||||
run: |
|
run: |
|
||||||
@ -85,24 +106,24 @@ jobs:
|
|||||||
if [ -d /opt/local/ ]; then
|
if [ -d /opt/local/ ]; then
|
||||||
echo "MacPorts already installed"
|
echo "MacPorts already installed"
|
||||||
else
|
else
|
||||||
wget https://github.com/macports/macports-base/releases/download/v2.7.2/MacPorts-2.7.2-12-Monterey.pkg
|
wget https://github.com/macports/macports-base/releases/download/v2.9.3/MacPorts-2.9.3-12-Monterey.pkg
|
||||||
sudo installer -pkg ./MacPorts-2.7.2-12-Monterey.pkg -target /
|
sudo installer -pkg ./MacPorts-2.9.3-12-Monterey.pkg -target /
|
||||||
fi
|
fi
|
||||||
echo "/opt/local/bin:/opt/local/sbin" >> $GITHUB_PATH
|
echo "/opt/local/bin:/opt/local/sbin" >> $GITHUB_PATH
|
||||||
- name: Install dependencies
|
- name: Install dependencies
|
||||||
if: ${{ !vars.MAC_RUNNER }}
|
if: ${{ !vars.MAC_RUNNER }}
|
||||||
run: |
|
run: |
|
||||||
brew uninstall --ignore-dependencies libpng
|
brew uninstall --ignore-dependencies libpng libzip
|
||||||
sudo port install $(cat .github/workflows/macports-deps.txt)
|
sudo port install $(cat .github/workflows/macports-deps.txt)
|
||||||
brew install ninja
|
brew install ninja
|
||||||
- name: Download soh.otr
|
- name: Download soh.otr
|
||||||
uses: actions/download-artifact@v3
|
uses: actions/download-artifact@v4
|
||||||
with:
|
with:
|
||||||
name: soh.otr
|
name: soh.otr
|
||||||
- name: Build SoH
|
- name: Build SoH
|
||||||
run: |
|
run: |
|
||||||
export PATH="/usr/lib/ccache:/usr/local/opt/ccache/libexec:$PATH"
|
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"
|
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
|
cmake --build build-cmake --config Release --parallel 10
|
||||||
mv soh.otr build-cmake/soh
|
mv soh.otr build-cmake/soh
|
||||||
(cd build-cmake && cpack)
|
(cd build-cmake && cpack)
|
||||||
@ -110,7 +131,7 @@ jobs:
|
|||||||
mv _packages/*.dmg SoH.dmg
|
mv _packages/*.dmg SoH.dmg
|
||||||
mv README.md readme.txt
|
mv README.md readme.txt
|
||||||
- name: Upload build
|
- name: Upload build
|
||||||
uses: actions/upload-artifact@v3
|
uses: actions/upload-artifact@v4
|
||||||
with:
|
with:
|
||||||
name: soh-mac
|
name: soh-mac
|
||||||
path: |
|
path: |
|
||||||
@ -139,39 +160,101 @@ jobs:
|
|||||||
sudo apt-get update
|
sudo apt-get update
|
||||||
sudo apt-get install -y $(cat .github/workflows/apt-deps.txt)
|
sudo apt-get install -y $(cat .github/workflows/apt-deps.txt)
|
||||||
- name: ccache
|
- name: ccache
|
||||||
uses: hendrikmuhs/ccache-action@v1.2
|
uses: hendrikmuhs/ccache-action@v1.2.11
|
||||||
with:
|
with:
|
||||||
key: ${{ matrix.os }}-ccache
|
key: ${{ matrix.os }}-ccache-${{ github.ref }}-${{ github.sha }}
|
||||||
|
restore-keys: |
|
||||||
|
${{ matrix.os }}-ccache-${{ github.ref }}
|
||||||
|
${{ matrix.os }}-ccache-
|
||||||
|
- name: Cache build folders
|
||||||
|
uses: actions/cache@v4
|
||||||
|
with:
|
||||||
|
key: ${{ matrix.os }}-build-${{ github.ref }}-${{ github.sha }}
|
||||||
|
restore-keys: |
|
||||||
|
${{ matrix.os }}-build-${{ github.ref }}
|
||||||
|
${{ matrix.os }}-build-
|
||||||
|
path: |
|
||||||
|
SDL2-2.28.5
|
||||||
|
SDL2_net-2.2.0
|
||||||
- name: Install latest SDL
|
- name: Install latest SDL
|
||||||
if: ${{ (matrix.os == 'ubuntu-20.04' && !vars.LINUX_COMPATIBILITY_RUNNER) || (matrix.os == 'ubuntu-22.04' && !vars.LINUX_PERFORMANCE_RUNNER) }}
|
if: ${{ (matrix.os == 'ubuntu-20.04' && !vars.LINUX_COMPATIBILITY_RUNNER) || (matrix.os == 'ubuntu-22.04' && !vars.LINUX_PERFORMANCE_RUNNER) }}
|
||||||
run: |
|
run: |
|
||||||
export PATH="/usr/lib/ccache:/usr/local/opt/ccache/libexec:$PATH"
|
export PATH="/usr/lib/ccache:/usr/local/opt/ccache/libexec:$PATH"
|
||||||
wget https://www.libsdl.org/release/SDL2-2.26.1.tar.gz
|
if [ ! -d "SDL2-2.28.5" ]; then
|
||||||
tar -xzf SDL2-2.26.1.tar.gz
|
wget https://www.libsdl.org/release/SDL2-2.28.5.tar.gz
|
||||||
cd SDL2-2.26.1
|
tar -xzf SDL2-2.28.5.tar.gz
|
||||||
./configure
|
fi
|
||||||
|
cd SDL2-2.28.5
|
||||||
|
./configure --enable-hidapi-libusb
|
||||||
make -j 10
|
make -j 10
|
||||||
sudo make install
|
sudo make install
|
||||||
sudo cp -av /usr/local/lib/libSDL* /lib/x86_64-linux-gnu/
|
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"
|
||||||
|
if [ ! -d "tinyxml2-10.0.0" ]; then
|
||||||
|
wget https://github.com/leethomason/tinyxml2/archive/refs/tags/10.0.0.tar.gz
|
||||||
|
tar -xzf 10.0.0.tar.gz
|
||||||
|
fi
|
||||||
|
cd tinyxml2-10.0.0
|
||||||
|
mkdir build
|
||||||
|
cd build
|
||||||
|
cmake ..
|
||||||
|
make
|
||||||
|
sudo make install
|
||||||
- name: Install latest SDL_net
|
- name: Install latest SDL_net
|
||||||
if: ${{ (matrix.os == 'ubuntu-20.04' && !vars.LINUX_COMPATIBILITY_RUNNER) || (matrix.os == 'ubuntu-22.04' && !vars.LINUX_PERFORMANCE_RUNNER) }}
|
if: ${{ (matrix.os == 'ubuntu-20.04' && !vars.LINUX_COMPATIBILITY_RUNNER) || (matrix.os == 'ubuntu-22.04' && !vars.LINUX_PERFORMANCE_RUNNER) }}
|
||||||
run: |
|
run: |
|
||||||
export PATH="/usr/lib/ccache:/usr/local/opt/ccache/libexec:$PATH"
|
export PATH="/usr/lib/ccache:/usr/local/opt/ccache/libexec:$PATH"
|
||||||
|
if [ ! -d "SDL2_net-2.2.0" ]; then
|
||||||
wget https://www.libsdl.org/projects/SDL_net/release/SDL2_net-2.2.0.tar.gz
|
wget https://www.libsdl.org/projects/SDL_net/release/SDL2_net-2.2.0.tar.gz
|
||||||
tar -xzf SDL2_net-2.2.0.tar.gz
|
tar -xzf SDL2_net-2.2.0.tar.gz
|
||||||
|
fi
|
||||||
cd SDL2_net-2.2.0
|
cd SDL2_net-2.2.0
|
||||||
./configure
|
./configure
|
||||||
make -j 10
|
make -j 10
|
||||||
sudo make install
|
sudo make install
|
||||||
sudo cp -av /usr/local/lib/libSDL* /lib/x86_64-linux-gnu/
|
sudo cp -av /usr/local/lib/libSDL* /lib/x86_64-linux-gnu/
|
||||||
- name: Download soh.otr
|
- name: Download soh.otr
|
||||||
uses: actions/download-artifact@v3
|
uses: actions/download-artifact@v4
|
||||||
with:
|
with:
|
||||||
name: soh.otr
|
name: soh.otr
|
||||||
- name: Build SoH
|
- name: Build SoH
|
||||||
run: |
|
run: |
|
||||||
export PATH="/usr/lib/ccache:/usr/local/opt/ccache/libexec:$PATH"
|
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
|
cmake --no-warn-unused-cli -H. -Bbuild-cmake -GNinja -DCMAKE_BUILD_TYPE:STRING=Release -DBUILD_REMOTE_CONTROL=1
|
||||||
cmake --build build-cmake --config Release -j3
|
cmake --build build-cmake --config Release -j3
|
||||||
(cd build-cmake && cpack -G External)
|
(cd build-cmake && cpack -G External)
|
||||||
|
|
||||||
@ -181,92 +264,12 @@ jobs:
|
|||||||
CC: gcc-${{ matrix.gcc }}
|
CC: gcc-${{ matrix.gcc }}
|
||||||
CXX: g++-${{ matrix.gcc }}
|
CXX: g++-${{ matrix.gcc }}
|
||||||
- name: Upload build
|
- name: Upload build
|
||||||
uses: actions/upload-artifact@v3
|
uses: actions/upload-artifact@v4
|
||||||
with:
|
with:
|
||||||
name: soh-linux-${{ matrix.archive-suffix }}
|
name: soh-linux-${{ matrix.archive-suffix }}
|
||||||
path: |
|
path: |
|
||||||
soh.appimage
|
soh.appimage
|
||||||
readme.txt
|
readme.txt
|
||||||
build-switch:
|
|
||||||
needs: generate-soh-otr
|
|
||||||
runs-on: ${{ (vars.LINUX_RUNNER && fromJSON(vars.LINUX_RUNNER)) || 'ubuntu-latest' }}
|
|
||||||
container:
|
|
||||||
image: devkitpro/devkita64:20240120
|
|
||||||
steps:
|
|
||||||
- name: Install dependencies
|
|
||||||
run: |
|
|
||||||
sudo apt-get update
|
|
||||||
sudo apt-get install -y ninja-build
|
|
||||||
- name: Fix dubious ownership error
|
|
||||||
if: ${{ vars.LINUX_RUNNER }}
|
|
||||||
run: git config --global --add safe.directory '*'
|
|
||||||
- uses: actions/checkout@v3
|
|
||||||
with:
|
|
||||||
submodules: true
|
|
||||||
- name: ccache
|
|
||||||
uses: hendrikmuhs/ccache-action@v1.2
|
|
||||||
with:
|
|
||||||
key: ${{ runner.os }}-switch-ccache
|
|
||||||
- name: Build SoH
|
|
||||||
run: |
|
|
||||||
cmake -H. -Bbuild-switch -GNinja -DCMAKE_TOOLCHAIN_FILE=/opt/devkitpro/cmake/Switch.cmake -DCMAKE_BUILD_TYPE:STRING=Release -DCMAKE_CXX_COMPILER_LAUNCHER=ccache -DCMAKE_C_COMPILER_LAUNCHER=ccache
|
|
||||||
cmake --build build-switch --target soh_nro -j3
|
|
||||||
|
|
||||||
mv build-switch/soh/*.nro soh.nro
|
|
||||||
mv README.md readme.txt
|
|
||||||
- name: Download soh.otr
|
|
||||||
uses: actions/download-artifact@v3
|
|
||||||
with:
|
|
||||||
name: soh.otr
|
|
||||||
- name: Upload build
|
|
||||||
uses: actions/upload-artifact@v3
|
|
||||||
with:
|
|
||||||
name: soh-switch
|
|
||||||
path: |
|
|
||||||
soh.nro
|
|
||||||
soh.otr
|
|
||||||
readme.txt
|
|
||||||
build-wiiu:
|
|
||||||
needs: generate-soh-otr
|
|
||||||
runs-on: ${{ (vars.LINUX_RUNNER && fromJSON(vars.LINUX_RUNNER)) || 'ubuntu-latest' }}
|
|
||||||
container:
|
|
||||||
image: devkitpro/devkitppc:20230110
|
|
||||||
steps:
|
|
||||||
- name: Install dependencies
|
|
||||||
if: ${{ !vars.LINUX_RUNNER }}
|
|
||||||
run: |
|
|
||||||
sudo apt-get install -y ninja-build
|
|
||||||
- uses: actions/checkout@v3
|
|
||||||
with:
|
|
||||||
submodules: true
|
|
||||||
- name: ccache
|
|
||||||
uses: hendrikmuhs/ccache-action@v1.2
|
|
||||||
with:
|
|
||||||
key: ${{ runner.os }}-wiiu-ccache
|
|
||||||
- name: Build SoH
|
|
||||||
run: |
|
|
||||||
cmake -H. -Bbuild-wiiu -GNinja -DCMAKE_TOOLCHAIN_FILE=/opt/devkitpro/cmake/WiiU.cmake -DCMAKE_BUILD_TYPE:STRING=Release -DCMAKE_BUILD_TYPE:STRING=Release -DCMAKE_CXX_COMPILER_LAUNCHER=ccache -DCMAKE_C_COMPILER_LAUNCHER=ccache
|
|
||||||
cmake --build build-wiiu --target soh_wuhb --config Release -j3
|
|
||||||
|
|
||||||
mv build-wiiu/soh/*.rpx soh.rpx
|
|
||||||
mv build-wiiu/soh/*.wuhb soh.wuhb
|
|
||||||
mv README.md readme.txt
|
|
||||||
env:
|
|
||||||
DEVKITPRO: /opt/devkitpro
|
|
||||||
DEVKITPPC: /opt/devkitpro/devkitPPC
|
|
||||||
- name: Download soh.otr
|
|
||||||
uses: actions/download-artifact@v3
|
|
||||||
with:
|
|
||||||
name: soh.otr
|
|
||||||
- name: Upload build
|
|
||||||
uses: actions/upload-artifact@v3
|
|
||||||
with:
|
|
||||||
name: soh-wiiu
|
|
||||||
path: |
|
|
||||||
soh.rpx
|
|
||||||
soh.wuhb
|
|
||||||
soh.otr
|
|
||||||
readme.txt
|
|
||||||
build-windows:
|
build-windows:
|
||||||
needs: generate-soh-otr
|
needs: generate-soh-otr
|
||||||
runs-on: ${{ (vars.WINDOWS_RUNNER && fromJSON(vars.WINDOWS_RUNNER)) || 'windows-latest' }}
|
runs-on: ${{ (vars.WINDOWS_RUNNER && fromJSON(vars.WINDOWS_RUNNER)) || 'windows-latest' }}
|
||||||
@ -280,16 +283,33 @@ jobs:
|
|||||||
with:
|
with:
|
||||||
submodules: true
|
submodules: true
|
||||||
- name: ccache
|
- name: ccache
|
||||||
uses: dcvz/ccache-action@27b9f33213c0079872f064f6b6ba0233dfa16ba2
|
uses: hendrikmuhs/ccache-action@v1.2.11
|
||||||
with:
|
with:
|
||||||
key: ${{ runner.os }}-ccache
|
variant: sccache
|
||||||
- uses: ilammy/msvc-dev-cmd@v1
|
max-size: "1G"
|
||||||
|
key: ${{ runner.os }}-ccache-${{ github.ref }}-${{ github.sha }}
|
||||||
|
restore-keys: |
|
||||||
|
${{ runner.os }}-ccache-${{ github.ref }}
|
||||||
|
${{ runner.os }}-ccache-
|
||||||
|
- name: Cache build folder
|
||||||
|
uses: actions/cache@v4
|
||||||
|
with:
|
||||||
|
save-always: true
|
||||||
|
key: ${{ runner.os }}-build-${{ github.ref }}-${{ github.sha }}
|
||||||
|
restore-keys: |
|
||||||
|
${{ runner.os }}-build-${{ github.ref }}
|
||||||
|
${{ runner.os }}-build-
|
||||||
|
path: |
|
||||||
|
build-windows
|
||||||
|
vcpkg
|
||||||
|
- name: Configure Developer Command Prompt
|
||||||
|
uses: ilammy/msvc-dev-cmd@v1
|
||||||
- name: Build SoH
|
- name: Build SoH
|
||||||
env:
|
env:
|
||||||
VCPKG_ROOT: D:/a/vcpkg
|
VCPKG_ROOT: ${{github.workspace}}/vcpkg
|
||||||
run: |
|
run: |
|
||||||
set $env:PATH="$env:USERPROFILE/.cargo/bin;$env:PATH"
|
set $env:PATH="$env:USERPROFILE/.cargo/bin;$env:PATH"
|
||||||
cmake -S . -B build-windows -G Ninja -DCMAKE_MAKE_PROGRAM=ninja -DCMAKE_BUILD_TYPE:STRING=Release -DCMAKE_C_COMPILER_LAUNCHER=ccache -DCMAKE_CXX_COMPILER_LAUNCHER=ccache
|
cmake -S . -B build-windows -G Ninja -DCMAKE_MAKE_PROGRAM=ninja -DCMAKE_BUILD_TYPE:STRING=Release -DCMAKE_C_COMPILER_LAUNCHER=sccache -DCMAKE_CXX_COMPILER_LAUNCHER=sccache -DBUILD_REMOTE_CONTROL=1
|
||||||
cmake --build build-windows --config Release --parallel 10
|
cmake --build build-windows --config Release --parallel 10
|
||||||
|
|
||||||
mkdir soh-windows
|
mkdir soh-windows
|
||||||
@ -302,12 +322,12 @@ jobs:
|
|||||||
mv ./build-windows/gamecontrollerdb.txt ./soh-windows/gamecontrollerdb.txt
|
mv ./build-windows/gamecontrollerdb.txt ./soh-windows/gamecontrollerdb.txt
|
||||||
mv ./x64/Release/assets ./soh-windows
|
mv ./x64/Release/assets ./soh-windows
|
||||||
- name: Download soh.otr
|
- name: Download soh.otr
|
||||||
uses: actions/download-artifact@v3
|
uses: actions/download-artifact@v4
|
||||||
with:
|
with:
|
||||||
name: soh.otr
|
name: soh.otr
|
||||||
path: soh-windows
|
path: soh-windows
|
||||||
- name: Upload build
|
- name: Upload build
|
||||||
uses: actions/upload-artifact@v3
|
uses: actions/upload-artifact@v4
|
||||||
with:
|
with:
|
||||||
name: soh-windows
|
name: soh-windows
|
||||||
path: soh-windows
|
path: soh-windows
|
||||||
|
2
.github/workflows/macports-deps.txt
vendored
@ -1 +1 @@
|
|||||||
libsdl2 +universal libpng +universal glew +universal
|
libsdl2 +universal libsdl2_net +universal libpng +universal glew +universal libzip +universal nlohmann-json +universal tinyxml2 +universal
|
66
.github/workflows/test-builds-on-distros.yml
vendored
Normal file
@ -0,0 +1,66 @@
|
|||||||
|
# todo:
|
||||||
|
# nlohmann
|
||||||
|
# tinyxml2
|
||||||
|
# spdlog
|
||||||
|
|
||||||
|
name: test-builds-on-distros
|
||||||
|
on:
|
||||||
|
workflow_dispatch: # by request
|
||||||
|
concurrency:
|
||||||
|
group: ${{ github.workflow }}-${{ github.ref }}
|
||||||
|
cancel-in-progress: true
|
||||||
|
jobs:
|
||||||
|
build:
|
||||||
|
strategy:
|
||||||
|
matrix:
|
||||||
|
image: ["archlinux:base", "opensuse/tumbleweed:latest", "ubuntu:mantic", "debian:bookworm", "fedora:39"]
|
||||||
|
cc: ["gcc", "clang"]
|
||||||
|
include:
|
||||||
|
- cxx: g++
|
||||||
|
cc: gcc
|
||||||
|
- cxx: clang++
|
||||||
|
cc: clang
|
||||||
|
runs-on: ${{ (vars.LINUX_RUNNER && fromJSON(vars.LINUX_RUNNER)) || 'ubuntu-latest' }}
|
||||||
|
container:
|
||||||
|
image: ${{ matrix.image }}
|
||||||
|
steps:
|
||||||
|
- name: Install dependencies (pacman)
|
||||||
|
if: ${{ matrix.image == 'archlinux:base' }}
|
||||||
|
run: |
|
||||||
|
echo arch
|
||||||
|
echo pacman -S ${{ matrix.cc }} git cmake ninja lsb-release sdl2 libpng libzip sdl2_net boost
|
||||||
|
pacman -Syu --noconfirm
|
||||||
|
pacman -S --noconfirm ${{ matrix.cc }} git cmake ninja lsb-release sdl2 libpng libzip 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
|
||||||
|
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
|
||||||
|
- 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
|
||||||
|
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
|
||||||
|
- 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
|
||||||
|
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
|
||||||
|
- uses: actions/checkout@v3
|
||||||
|
with:
|
||||||
|
submodules: true
|
||||||
|
- 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 -DBUILD_REMOTE_CONTROL=1
|
||||||
|
cmake --build build-cmake --config Release -j3
|
||||||
|
env:
|
||||||
|
CC: ${{ matrix.cc }}
|
||||||
|
CXX: ${{ matrix.cxx }}
|
2
.gitignore
vendored
@ -448,5 +448,5 @@ _packages
|
|||||||
*/extract_assets_cmake*
|
*/extract_assets_cmake*
|
||||||
/build*
|
/build*
|
||||||
|
|
||||||
soh/build.c
|
soh/src/boot/build.c
|
||||||
soh/properties.h
|
soh/properties.h
|
||||||
|
@ -8,5 +8,9 @@ if(MSVC)
|
|||||||
|
|
||||||
set_target_properties("${PROPS_TARGET}" PROPERTIES MSVC_RUNTIME_LIBRARY "MultiThreaded$<$<CONFIG:Debug>:Debug>DLL")
|
set_target_properties("${PROPS_TARGET}" PROPERTIES MSVC_RUNTIME_LIBRARY "MultiThreaded$<$<CONFIG:Debug>:Debug>DLL")
|
||||||
set_config_specific_property("DEFAULT_CXX_EXCEPTION_HANDLING" "/EHsc")
|
set_config_specific_property("DEFAULT_CXX_EXCEPTION_HANDLING" "/EHsc")
|
||||||
|
if (CMAKE_C_COMPILER_LAUNCHER MATCHES "ccache|sccache")
|
||||||
|
set_config_specific_property("DEFAULT_CXX_DEBUG_INFORMATION_FORMAT" "/Z7")
|
||||||
|
else()
|
||||||
set_config_specific_property("DEFAULT_CXX_DEBUG_INFORMATION_FORMAT" "/Zi")
|
set_config_specific_property("DEFAULT_CXX_DEBUG_INFORMATION_FORMAT" "/Zi")
|
||||||
|
endif()
|
||||||
endif()
|
endif()
|
24
CMake/lus-cvars.cmake
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
set(CVAR_VSYNC_ENABLED "${CVAR_PREFIX_SETTING}.VsyncEnabled" CACHE STRING "")
|
||||||
|
set(CVAR_Z_FIGHTING_MODE "${CVAR_PREFIX_SETTING}.ZFightingMode" CACHE STRING "")
|
||||||
|
set(CVAR_NEW_FILE_DROPPED "${CVAR_PREFIX_GENERAL}.NewFileDropped" CACHE STRING "")
|
||||||
|
set(CVAR_DROPPED_FILE "${CVAR_PREFIX_GENERAL}.DroppedFile" CACHE STRING "")
|
||||||
|
set(CVAR_INTERNAL_RESOLUTION "${CVAR_PREFIX_SETTING}.InternalResolution" CACHE STRING "")
|
||||||
|
set(CVAR_MSAA_VALUE "${CVAR_PREFIX_SETTING}.MSAAValue" CACHE STRING "")
|
||||||
|
set(CVAR_SDL_WINDOWED_FULLSCREEN "${CVAR_PREFIX_SETTING}.SdlWindowedFullscreen" CACHE STRING "")
|
||||||
|
set(CVAR_TEXTURE_FILTER "${CVAR_PREFIX_SETTING}.TextureFilter" CACHE STRING "")
|
||||||
|
set(CVAR_IMGUI_CONTROLLER_NAV "${CVAR_PREFIX_SETTING}.ControlNav" CACHE STRING "")
|
||||||
|
set(CVAR_CONSOLE_WINDOW_OPEN "${CVAR_PREFIX_WINDOW}.Console" CACHE STRING "")
|
||||||
|
set(CVAR_CONTROLLER_CONFIGURATION_WINDOW_OPEN "${CVAR_PREFIX_WINDOW}.ControllerConfiguration" CACHE STRING "")
|
||||||
|
set(CVAR_CONTROLLER_DISCONNECTED_WINDOW_OPEN "${CVAR_PREFIX_WINDOW}.ControllerDisconnected" CACHE STRING "")
|
||||||
|
set(CVAR_CONTROLLER_REORDERING_WINDOW_OPEN "${CVAR_PREFIX_WINDOW}.ControllerReordering" CACHE STRING "")
|
||||||
|
set(CVAR_GFX_DEBUGGER_WINDOW_OPEN "${CVAR_PREFIX_WINDOW}.GfxDebugger" CACHE STRING "")
|
||||||
|
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 "")
|
||||||
|
set(CVAR_PREFIX_ADVANCED_RESOLUTION "${CVAR_PREFIX_SETTING}.AdvancedResolution" CACHE STRING "")
|
||||||
|
include("libultraship/cmake/cvars.cmake")
|
26
CMake/soh-cvars.cmake
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
set(CVAR_PREFIX_RANDOMIZER_ENHANCEMENT "gRandoEnhancements")
|
||||||
|
set(CVAR_PREFIX_RANDOMIZER_SETTING "gRandoSettings")
|
||||||
|
set(CVAR_PREFIX_COSMETIC "gCosmetics")
|
||||||
|
set(CVAR_PREFIX_AUDIO "gAudioEditor")
|
||||||
|
set(CVAR_PREFIX_CHEAT "gCheats")
|
||||||
|
set(CVAR_PREFIX_ENHANCEMENT "gEnhancements")
|
||||||
|
set(CVAR_PREFIX_SETTING "gSettings")
|
||||||
|
set(CVAR_PREFIX_WINDOW "gOpenWindows")
|
||||||
|
set(CVAR_PREFIX_TRACKER "gTrackers")
|
||||||
|
set(CVAR_PREFIX_DEVELOPER_TOOLS "gDeveloperTools")
|
||||||
|
set(CVAR_PREFIX_GENERAL "gGeneral")
|
||||||
|
set(CVAR_PREFIX_REMOTE "gRemote")
|
||||||
|
add_compile_definitions(
|
||||||
|
CVAR_PREFIX_RANDOMIZER_ENHANCEMENT="${CVAR_PREFIX_RANDOMIZER_ENHANCEMENT}"
|
||||||
|
CVAR_PREFIX_RANDOMIZER_SETTING="${CVAR_PREFIX_RANDOMIZER_SETTING}"
|
||||||
|
CVAR_PREFIX_COSMETIC="${CVAR_PREFIX_COSMETIC}"
|
||||||
|
CVAR_PREFIX_AUDIO="${CVAR_PREFIX_AUDIO}"
|
||||||
|
CVAR_PREFIX_CHEAT="${CVAR_PREFIX_CHEAT}"
|
||||||
|
CVAR_PREFIX_ENHANCEMENT="${CVAR_PREFIX_ENHANCEMENT}"
|
||||||
|
CVAR_PREFIX_SETTING="${CVAR_PREFIX_SETTING}"
|
||||||
|
CVAR_PREFIX_WINDOW="${CVAR_PREFIX_WINDOW}"
|
||||||
|
CVAR_PREFIX_TRACKER="${CVAR_PREFIX_TRACKER}"
|
||||||
|
CVAR_PREFIX_DEVELOPER_TOOLS="${CVAR_PREFIX_DEVELOPER_TOOLS}"
|
||||||
|
CVAR_PREFIX_GENERAL="${CVAR_PREFIX_GENERAL}"
|
||||||
|
CVAR_PREFIX_REMOTE="${CVAR_PREFIX_REMOTE}"
|
||||||
|
)
|
@ -6,6 +6,8 @@ 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")
|
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.5 LANGUAGES C CXX)
|
||||||
|
include(CMake/soh-cvars.cmake)
|
||||||
|
include(CMake/lus-cvars.cmake)
|
||||||
set(PROJECT_BUILD_NAME "MacReady Foxtrot" CACHE STRING "")
|
set(PROJECT_BUILD_NAME "MacReady Foxtrot" CACHE STRING "")
|
||||||
set(PROJECT_TEAM "github.com/harbourmasters" CACHE STRING "")
|
set(PROJECT_TEAM "github.com/harbourmasters" CACHE STRING "")
|
||||||
|
|
||||||
@ -13,20 +15,18 @@ set_property(DIRECTORY ${CMAKE_SOURCE_DIR} PROPERTY VS_STARTUP_PROJECT soh)
|
|||||||
add_compile_options($<$<CXX_COMPILER_ID:MSVC>:/MP>)
|
add_compile_options($<$<CXX_COMPILER_ID:MSVC>:/MP>)
|
||||||
add_compile_options($<$<CXX_COMPILER_ID:MSVC>:/utf-8>)
|
add_compile_options($<$<CXX_COMPILER_ID:MSVC>:/utf-8>)
|
||||||
|
|
||||||
if (CMAKE_SYSTEM_NAME MATCHES "Windows|Linux")
|
|
||||||
if(NOT DEFINED BUILD_CROWD_CONTROL)
|
|
||||||
set(BUILD_CROWD_CONTROL ON)
|
|
||||||
endif()
|
|
||||||
endif()
|
|
||||||
|
|
||||||
if (CMAKE_SYSTEM_NAME STREQUAL "Windows")
|
if (CMAKE_SYSTEM_NAME STREQUAL "Windows")
|
||||||
include(CMake/automate-vcpkg.cmake)
|
include(CMake/automate-vcpkg.cmake)
|
||||||
|
|
||||||
set(VCPKG_TRIPLET x64-windows-static)
|
set(VCPKG_TRIPLET x64-windows-static)
|
||||||
set(VCPKG_TARGET_TRIPLET x64-windows-static)
|
set(VCPKG_TARGET_TRIPLET x64-windows-static)
|
||||||
|
|
||||||
vcpkg_bootstrap()
|
vcpkg_bootstrap()
|
||||||
vcpkg_install_packages(zlib bzip2 libpng sdl2 sdl2-net glew glfw3)
|
vcpkg_install_packages(zlib bzip2 libzip libpng sdl2 sdl2-net glew glfw3 nlohmann-json tinyxml2 spdlog)
|
||||||
|
|
||||||
|
if (CMAKE_C_COMPILER_LAUNCHER MATCHES "ccache|sccache")
|
||||||
|
set(CMAKE_MSVC_DEBUG_INFORMATION_FORMAT Embedded)
|
||||||
|
endif()
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
################################################################################
|
################################################################################
|
||||||
|
@ -1 +1 @@
|
|||||||
Subproject commit 04b85b95fab07a394b62dcd28a502a3040f08e0c
|
Subproject commit 3cea9ee7c017d842aa4d9ceeb8d3ffbf29c6effb
|
@ -92,7 +92,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)
|
* [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)
|
* [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 (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-compatiblity.zip) _(compatible with most Linux distributions, but may not be as performant as the performance 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)
|
* [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)
|
* [Wii U](https://nightly.link/HarbourMasters/Shipwright/workflows/generate-builds/develop/soh-wiiu.zip)
|
||||||
|
|
||||||
|
2
ZAPDTR
@ -1 +1 @@
|
|||||||
Subproject commit eff29036118349e142ee8efca80fd975a2a2b6ff
|
Subproject commit f38a9c92eb99368c0607acf356d5651ebdc96f51
|
@ -84,41 +84,66 @@ cd "build/x64"
|
|||||||
```
|
```
|
||||||
|
|
||||||
## Linux
|
## Linux
|
||||||
Requires `gcc >= 10, x11, curl, python3, sdl2 >= 2.0.22, libpng, glew >= 2.2, ninja, cmake, lld, pulseaudio-libs`
|
### Install dependencies
|
||||||
|
#### 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
|
||||||
|
|
||||||
**Important: For maximum performance make sure you have ninja build tools installed!**
|
# 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
|
||||||
|
```
|
||||||
|
#### Arch
|
||||||
|
```sh
|
||||||
|
# using gcc
|
||||||
|
pacman -S gcc git cmake ninja lsb-release sdl2 libpng libzip sdl2_net boost
|
||||||
|
|
||||||
_Note: If you're using Visual Studio Code, the [cpack plugin](https://marketplace.visualstudio.com/items?itemName=ms-vscode.cmake-tools) makes it very easy to just press run and debug._
|
# or using clang
|
||||||
|
pacman -S clang git cmake ninja lsb-release sdl2 libpng libzip 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
|
||||||
|
|
||||||
|
# or using clang
|
||||||
|
dnf install clang git cmake ninja-build lsb_release SDL2-devel libpng-devel libzip-devel libzip-tools boost-devel
|
||||||
|
```
|
||||||
|
#### openSUSE
|
||||||
|
```sh
|
||||||
|
# using gcc
|
||||||
|
zypper in gcc gcc-c++ git cmake ninja SDL2-devel libpng16-devel libzip-devel libzip-tools
|
||||||
|
|
||||||
|
# or using clang
|
||||||
|
zypper in clang libstdc++-devel git cmake ninja SDL2-devel libpng16-devel libzip-devel libzip-tools
|
||||||
|
```
|
||||||
|
|
||||||
|
### Build
|
||||||
|
|
||||||
|
_Note: If you're using Visual Studio Code, the [CMake Tools plugin](https://marketplace.visualstudio.com/items?itemName=ms-vscode.cmake-tools) makes it very easy to just press run and debug._
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
# Clone the repo
|
# Clone the repo and enter the directory
|
||||||
git clone https://github.com/HarbourMasters/Shipwright.git
|
git clone https://github.com/HarbourMasters/Shipwright.git
|
||||||
cd Shipwright
|
cd Shipwright
|
||||||
# Clone the submodule libultraship
|
|
||||||
|
# Clone the submodules
|
||||||
git submodule update --init
|
git submodule update --init
|
||||||
# Copy the baserom to the OTRExporter folder
|
|
||||||
cp <path to your ROM> OTRExporter
|
|
||||||
# Generate Ninja project
|
# Generate Ninja project
|
||||||
cmake -H. -Bbuild-cmake -GNinja # -DCMAKE_BUILD_TYPE:STRING=Release (if you're packaging) -DPython3_EXECUTABLE=$(which python3) (if you are using non-standard Python installations such as PyEnv)
|
cmake -H. -Bbuild-cmake -GNinja # -DCMAKE_BUILD_TYPE:STRING=Release (if you're packaging) -DPython3_EXECUTABLE=$(which python3) (if you are using non-standard Python installations such as PyEnv)
|
||||||
# Extract assets & generate OTR (run this anytime you need to regenerate OTR)
|
|
||||||
cmake --build build-cmake --target ExtractAssets
|
# Generate soh.otr
|
||||||
|
cmake --build build-cmake --target GenerateSohOtr
|
||||||
|
|
||||||
# Compile the project
|
# Compile the project
|
||||||
cmake --build build-cmake # --config Release (if you're packaging)
|
cmake --build build-cmake # --config Release (if you're packaging)
|
||||||
|
|
||||||
# Now you can run the executable in ./build-cmake/soh/soh.elf
|
# Now you can run the executable in ./build-cmake/soh/soh.elf
|
||||||
# To develop the project open the repository in VSCode (or your preferred editor)
|
# To develop the project open the repository in VSCode (or your preferred editor)
|
||||||
|
|
||||||
# If you need to clean the project you can run
|
|
||||||
cmake --build build-cmake --target clean
|
|
||||||
|
|
||||||
# If you need to regenerate the asset headers to check them into source
|
|
||||||
cmake --build build-cmake --target ExtractAssetHeaders
|
|
||||||
|
|
||||||
# If you need a newer soh.otr only
|
|
||||||
cmake --build build-cmake --target GenerateSohOtr
|
|
||||||
```
|
```
|
||||||
|
|
||||||
### Generating a distributable
|
### Generate a distributable
|
||||||
After compiling the project you can generate a distributable by running of the following:
|
After compiling the project you can generate a distributable by running of the following:
|
||||||
```bash
|
```bash
|
||||||
# Go to build folder
|
# Go to build folder
|
||||||
@ -129,6 +154,20 @@ cpack -G ZIP
|
|||||||
cpack -G External (creates appimage)
|
cpack -G External (creates appimage)
|
||||||
```
|
```
|
||||||
|
|
||||||
|
### Additional CMake Targets
|
||||||
|
#### Clean
|
||||||
|
```bash
|
||||||
|
# If you need to clean the project you can run
|
||||||
|
cmake --build build-cmake --target clean
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Regenerate Asset Headers
|
||||||
|
```bash
|
||||||
|
# If you need to regenerate the asset headers to check them into source
|
||||||
|
cp <path to your ROM> OTRExporter
|
||||||
|
cmake --build build-cmake --target ExtractAssetHeaders
|
||||||
|
```
|
||||||
|
|
||||||
## macOS
|
## macOS
|
||||||
Requires Xcode (or xcode-tools) && `sdl2, libpng, glew, ninja, cmake` (can be installed via homebrew, macports, etc)
|
Requires Xcode (or xcode-tools) && `sdl2, libpng, glew, ninja, cmake` (can be installed via homebrew, macports, etc)
|
||||||
|
|
||||||
|
@ -1 +1 @@
|
|||||||
Subproject commit 96c8a8929c18c1bffd7d92a35a589f74cf16fc59
|
Subproject commit 7d71a290657a2d3b09a83e8b33025e807f4fb38e
|
@ -21,12 +21,17 @@ fi
|
|||||||
while [[ (! -e "$SHIP_HOME"/oot.otr) || (! -e "$SHIP_HOME"/oot-mq.otr) ]]; do
|
while [[ (! -e "$SHIP_HOME"/oot.otr) || (! -e "$SHIP_HOME"/oot-mq.otr) ]]; do
|
||||||
for romfile in "$SHIP_HOME"/*.*64
|
for romfile in "$SHIP_HOME"/*.*64
|
||||||
do
|
do
|
||||||
if [[ -e $romfile ]]; then
|
if [[ -e "$romfile" ]] || [[ -L "$romfile" ]]; then
|
||||||
export ASSETDIR="$(mktemp -d /tmp/assets-XXXXX)"
|
export ASSETDIR="$(mktemp -d /tmp/assets-XXXXX)"
|
||||||
ln -s "$HERE"/usr/bin/{assets,soh.elf,ZAPD} "$ASSETDIR"
|
ln -s "$SHIP_BIN_DIR"/{assets,soh.elf,ZAPD} "$ASSETDIR"
|
||||||
export OLDPWD="$PWD"
|
export OLDPWD="$PWD"
|
||||||
mkdir -p "$ASSETDIR"/tmp
|
mkdir -p "$ASSETDIR"/tmp
|
||||||
|
if [[ -e "$romfile" ]]; then
|
||||||
ln -s "$romfile" "$ASSETDIR"/tmp/rom.z64
|
ln -s "$romfile" "$ASSETDIR"/tmp/rom.z64
|
||||||
|
else
|
||||||
|
ORIG_ROM_PATH=$(readlink "$romfile")
|
||||||
|
ln -s "$ORIG_ROM_PATH" "$ASSETDIR"/tmp/rom.z64
|
||||||
|
fi
|
||||||
cd "$ASSETDIR"
|
cd "$ASSETDIR"
|
||||||
ROMHASH=$(sha1sum -b "$ASSETDIR"/tmp/rom.z64 | awk '{ print $1 }')
|
ROMHASH=$(sha1sum -b "$ASSETDIR"/tmp/rom.z64 | awk '{ print $1 }')
|
||||||
|
|
||||||
|
@ -8,5 +8,9 @@ if(MSVC)
|
|||||||
|
|
||||||
set_target_properties("${PROPS_TARGET}" PROPERTIES MSVC_RUNTIME_LIBRARY "MultiThreaded$<$<CONFIG:Debug>:Debug>DLL")
|
set_target_properties("${PROPS_TARGET}" PROPERTIES MSVC_RUNTIME_LIBRARY "MultiThreaded$<$<CONFIG:Debug>:Debug>DLL")
|
||||||
set_config_specific_property("DEFAULT_CXX_EXCEPTION_HANDLING" "/EHsc")
|
set_config_specific_property("DEFAULT_CXX_EXCEPTION_HANDLING" "/EHsc")
|
||||||
|
if (CMAKE_C_COMPILER_LAUNCHER MATCHES "ccache|sccache")
|
||||||
|
set_config_specific_property("DEFAULT_CXX_DEBUG_INFORMATION_FORMAT" "/Z7")
|
||||||
|
else()
|
||||||
set_config_specific_property("DEFAULT_CXX_DEBUG_INFORMATION_FORMAT" "/Zi")
|
set_config_specific_property("DEFAULT_CXX_DEBUG_INFORMATION_FORMAT" "/Zi")
|
||||||
|
endif()
|
||||||
endif()
|
endif()
|
@ -92,10 +92,6 @@ if (NOT TARGET libultraship)
|
|||||||
add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/../libultraship ${CMAKE_BINARY_DIR}/libultraship)
|
add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/../libultraship ${CMAKE_BINARY_DIR}/libultraship)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if (NOT TARGET ZAPDUtils)
|
|
||||||
add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/../ZAPDTR/ZAPDUtils ${CMAKE_BINARY_DIR}/ZAPDUtils)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
if (NOT TARGET ZAPDLib)
|
if (NOT TARGET ZAPDLib)
|
||||||
add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/../ZAPDTR/ZAPD ${CMAKE_BINARY_DIR}/ZAPD)
|
add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/../ZAPDTR/ZAPD ${CMAKE_BINARY_DIR}/ZAPD)
|
||||||
endif()
|
endif()
|
||||||
@ -105,8 +101,8 @@ set(PROJECT_NAME soh)
|
|||||||
################################################################################
|
################################################################################
|
||||||
# Sources
|
# Sources
|
||||||
################################################################################
|
################################################################################
|
||||||
configure_file( ${CMAKE_CURRENT_SOURCE_DIR}/src/boot/build.c.in ${CMAKE_BINARY_DIR}/build.c @ONLY)
|
configure_file( ${CMAKE_CURRENT_SOURCE_DIR}/src/boot/build.c.in ${CMAKE_CURRENT_SOURCE_DIR}/src/boot/build.c @ONLY)
|
||||||
configure_file( ${CMAKE_CURRENT_SOURCE_DIR}/src/boot/properties.h.in ${CMAKE_CURRENT_SOURCE_DIR}/properties.h @ONLY)
|
configure_file( ${CMAKE_CURRENT_SOURCE_DIR}/properties.h.in ${CMAKE_CURRENT_SOURCE_DIR}/properties.h @ONLY)
|
||||||
|
|
||||||
set(Header_Files "resource.h")
|
set(Header_Files "resource.h")
|
||||||
source_group("headers" FILES ${Header_Files})
|
source_group("headers" FILES ${Header_Files})
|
||||||
@ -154,7 +150,7 @@ list(FILTER soh__Enhancements EXCLUDE REGEX "soh/Enhancements/gfx.*")
|
|||||||
# handle crowd control removals
|
# handle crowd control removals
|
||||||
list(REMOVE_ITEM soh__Enhancements "soh/Enhancements/crowd-control/soh.cs")
|
list(REMOVE_ITEM soh__Enhancements "soh/Enhancements/crowd-control/soh.cs")
|
||||||
list(REMOVE_ITEM soh__Enhancements "soh/Enhancements/crowd-control/soh.ccpak")
|
list(REMOVE_ITEM soh__Enhancements "soh/Enhancements/crowd-control/soh.ccpak")
|
||||||
if (!BUILD_CROWD_CONTROL)
|
if (!BUILD_REMOTE_CONTROL)
|
||||||
list(FILTER soh__Enhancements EXCLUDE REGEX "soh/Enhancements/crowd-control/*")
|
list(FILTER soh__Enhancements EXCLUDE REGEX "soh/Enhancements/crowd-control/*")
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
@ -217,8 +213,6 @@ source_group("soh\\resource\\importer\\scenecommand" REGULAR_EXPRESSION "soh/res
|
|||||||
# src (decomp) {{{
|
# src (decomp) {{{
|
||||||
file(GLOB_RECURSE src__ RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} "src/*.c" "src/*.h")
|
file(GLOB_RECURSE src__ RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} "src/*.c" "src/*.h")
|
||||||
|
|
||||||
list(APPEND src__ ${CMAKE_BINARY_DIR}/build.c)
|
|
||||||
list(APPEND src__ ${CMAKE_CURRENT_SOURCE_DIR}/properties.h)
|
|
||||||
list(APPEND src__ ${CMAKE_CURRENT_SOURCE_DIR}/Resource.rc)
|
list(APPEND src__ ${CMAKE_CURRENT_SOURCE_DIR}/Resource.rc)
|
||||||
list(FILTER src__ EXCLUDE REGEX "src/dmadata/*")
|
list(FILTER src__ EXCLUDE REGEX "src/dmadata/*")
|
||||||
list(FILTER src__ EXCLUDE REGEX "src/elf_message/*")
|
list(FILTER src__ EXCLUDE REGEX "src/elf_message/*")
|
||||||
@ -238,7 +232,6 @@ list(REMOVE_ITEM src__ "src/libultra/gu/sqrtf.c")
|
|||||||
list(REMOVE_ITEM src__ "src/libultra/gu/us2dex.c")
|
list(REMOVE_ITEM src__ "src/libultra/gu/us2dex.c")
|
||||||
|
|
||||||
source_group("src" REGULAR_EXPRESSION "src/*")
|
source_group("src" REGULAR_EXPRESSION "src/*")
|
||||||
source_group("src\\build" FILES ${CMAKE_BINARY_DIR}/build.c ${CMAKE_CURRENT_SOURCE_DIR}/properties.h ${CMAKE_CURRENT_SOURCE_DIR}/Resource.rc)
|
|
||||||
source_group("src\\boot" REGULAR_EXPRESSION "src/boot/*")
|
source_group("src\\boot" REGULAR_EXPRESSION "src/boot/*")
|
||||||
source_group("src\\buffers" REGULAR_EXPRESSION "src/buffers/*")
|
source_group("src\\buffers" REGULAR_EXPRESSION "src/buffers/*")
|
||||||
source_group("src\\code" REGULAR_EXPRESSION "src/code/*")
|
source_group("src\\code" REGULAR_EXPRESSION "src/code/*")
|
||||||
@ -354,9 +347,15 @@ endif()
|
|||||||
find_package(SDL2)
|
find_package(SDL2)
|
||||||
set(SDL2-INCLUDE ${SDL2_INCLUDE_DIRS})
|
set(SDL2-INCLUDE ${SDL2_INCLUDE_DIRS})
|
||||||
|
|
||||||
if (BUILD_CROWD_CONTROL)
|
if (BUILD_REMOTE_CONTROL)
|
||||||
find_package(SDL2_net)
|
find_package(SDL2_net)
|
||||||
|
|
||||||
|
if(NOT SDL2_net_FOUND)
|
||||||
|
message(STATUS "SDL2_net not found (it's possible the version installed is too old). Disabling BUILD_REMOTE_CONTROL.")
|
||||||
|
set(BUILD_REMOTE_CONTROL 0)
|
||||||
|
else()
|
||||||
set(SDL2-NET-INCLUDE ${SDL_NET_INCLUDE_DIRS})
|
set(SDL2-NET-INCLUDE ${SDL_NET_INCLUDE_DIRS})
|
||||||
|
endif()
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
target_include_directories(${PROJECT_NAME} PRIVATE assets
|
target_include_directories(${PROJECT_NAME} PRIVATE assets
|
||||||
@ -385,10 +384,8 @@ target_include_directories(${PROJECT_NAME} PRIVATE assets
|
|||||||
${CMAKE_CURRENT_SOURCE_DIR}/../libultraship/extern/tinyxml2
|
${CMAKE_CURRENT_SOURCE_DIR}/../libultraship/extern/tinyxml2
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/../libultraship/libultraship/Lib/
|
${CMAKE_CURRENT_SOURCE_DIR}/../libultraship/libultraship/Lib/
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/../libultraship/libultraship/Lib/libjpeg/include/
|
${CMAKE_CURRENT_SOURCE_DIR}/../libultraship/libultraship/Lib/libjpeg/include/
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/../libultraship/libultraship/Lib/spdlog/include/
|
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/../libultraship/src/graphic/Fast3D/U64/PR
|
${CMAKE_CURRENT_SOURCE_DIR}/../libultraship/src/graphic/Fast3D/U64/PR
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/../libultraship/src/graphic
|
${CMAKE_CURRENT_SOURCE_DIR}/../libultraship/src/graphic
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/../ZAPDTR/ZAPDUtils
|
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/../ZAPDTR/ZAPD/resource/type
|
${CMAKE_CURRENT_SOURCE_DIR}/../ZAPDTR/ZAPD/resource/type
|
||||||
${SDL2-INCLUDE}
|
${SDL2-INCLUDE}
|
||||||
${SDL2-NET-INCLUDE}
|
${SDL2-NET-INCLUDE}
|
||||||
@ -408,13 +405,13 @@ if (CMAKE_SYSTEM_NAME STREQUAL "Windows")
|
|||||||
"$<$<CONFIG:Release>:"
|
"$<$<CONFIG:Release>:"
|
||||||
"NDEBUG"
|
"NDEBUG"
|
||||||
">"
|
">"
|
||||||
"$<$<BOOL:${BUILD_CROWD_CONTROL}>:ENABLE_CROWD_CONTROL>"
|
"$<$<BOOL:${BUILD_REMOTE_CONTROL}>:ENABLE_REMOTE_CONTROL>"
|
||||||
"INCLUDE_GAME_PRINTF;"
|
"INCLUDE_GAME_PRINTF;"
|
||||||
"ENABLE_CROWD_CONTROL;"
|
|
||||||
"UNICODE;"
|
"UNICODE;"
|
||||||
"_UNICODE"
|
"_UNICODE"
|
||||||
STORMLIB_NO_AUTO_LINK
|
STORMLIB_NO_AUTO_LINK
|
||||||
"_CRT_SECURE_NO_WARNINGS;"
|
"_CRT_SECURE_NO_WARNINGS;"
|
||||||
|
NOMINMAX
|
||||||
)
|
)
|
||||||
elseif("${CMAKE_VS_PLATFORM_NAME}" STREQUAL "Win32")
|
elseif("${CMAKE_VS_PLATFORM_NAME}" STREQUAL "Win32")
|
||||||
target_compile_definitions(${PROJECT_NAME} PRIVATE
|
target_compile_definitions(${PROJECT_NAME} PRIVATE
|
||||||
@ -432,6 +429,7 @@ if (CMAKE_SYSTEM_NAME STREQUAL "Windows")
|
|||||||
"UNICODE;"
|
"UNICODE;"
|
||||||
"_UNICODE"
|
"_UNICODE"
|
||||||
STORMLIB_NO_AUTO_LINK
|
STORMLIB_NO_AUTO_LINK
|
||||||
|
NOMINMAX
|
||||||
)
|
)
|
||||||
endif()
|
endif()
|
||||||
elseif (CMAKE_SYSTEM_NAME STREQUAL "CafeOS")
|
elseif (CMAKE_SYSTEM_NAME STREQUAL "CafeOS")
|
||||||
@ -455,7 +453,7 @@ elseif ("${CMAKE_CXX_COMPILER_ID}" MATCHES "GNU|Clang|AppleClang")
|
|||||||
"$<$<CONFIG:Release>:"
|
"$<$<CONFIG:Release>:"
|
||||||
"NDEBUG"
|
"NDEBUG"
|
||||||
">"
|
">"
|
||||||
"$<$<BOOL:${BUILD_CROWD_CONTROL}>:ENABLE_CROWD_CONTROL>"
|
"$<$<BOOL:${BUILD_REMOTE_CONTROL}>:ENABLE_REMOTE_CONTROL>"
|
||||||
"SPDLOG_ACTIVE_LEVEL=0;"
|
"SPDLOG_ACTIVE_LEVEL=0;"
|
||||||
"_CONSOLE;"
|
"_CONSOLE;"
|
||||||
"_CRT_SECURE_NO_WARNINGS;"
|
"_CRT_SECURE_NO_WARNINGS;"
|
||||||
@ -624,6 +622,8 @@ if (CMAKE_CXX_COMPILER_ID MATCHES "GNU|Clang|AppleClang")
|
|||||||
-Wno-parentheses
|
-Wno-parentheses
|
||||||
-Wno-narrowing
|
-Wno-narrowing
|
||||||
-Wno-missing-braces
|
-Wno-missing-braces
|
||||||
|
-Wno-int-conversion
|
||||||
|
-Wno-implicit-int
|
||||||
$<$<COMPILE_LANGUAGE:C>:
|
$<$<COMPILE_LANGUAGE:C>:
|
||||||
-Werror-implicit-function-declaration
|
-Werror-implicit-function-declaration
|
||||||
-Wno-incompatible-pointer-types
|
-Wno-incompatible-pointer-types
|
||||||
@ -643,15 +643,6 @@ endif()
|
|||||||
################################################################################
|
################################################################################
|
||||||
# Pre build events
|
# Pre build events
|
||||||
################################################################################
|
################################################################################
|
||||||
if (CMAKE_SYSTEM_NAME STREQUAL "Windows")
|
|
||||||
add_custom_command_if(
|
|
||||||
TARGET ${PROJECT_NAME}
|
|
||||||
PRE_BUILD
|
|
||||||
COMMANDS
|
|
||||||
COMMAND $<CONFIG:Debug> copy /b $<SHELL_PATH:${CMAKE_BINARY_DIR}/>build.c +,,
|
|
||||||
)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
if(NOT CMAKE_SYSTEM_NAME MATCHES "NintendoSwitch|CafeOS")
|
if(NOT CMAKE_SYSTEM_NAME MATCHES "NintendoSwitch|CafeOS")
|
||||||
add_custom_command(
|
add_custom_command(
|
||||||
TARGET ${PROJECT_NAME}
|
TARGET ${PROJECT_NAME}
|
||||||
@ -670,7 +661,6 @@ endif()
|
|||||||
# Dependencies
|
# Dependencies
|
||||||
################################################################################
|
################################################################################
|
||||||
add_dependencies(${PROJECT_NAME}
|
add_dependencies(${PROJECT_NAME}
|
||||||
ZAPDUtils
|
|
||||||
libultraship
|
libultraship
|
||||||
)
|
)
|
||||||
if(NOT CMAKE_SYSTEM_NAME MATCHES "NintendoSwitch|CafeOS")
|
if(NOT CMAKE_SYSTEM_NAME MATCHES "NintendoSwitch|CafeOS")
|
||||||
@ -684,12 +674,11 @@ if (CMAKE_SYSTEM_NAME STREQUAL "Windows")
|
|||||||
if("${CMAKE_VS_PLATFORM_NAME}" STREQUAL "x64")
|
if("${CMAKE_VS_PLATFORM_NAME}" STREQUAL "x64")
|
||||||
set(ADDITIONAL_LIBRARY_DEPENDENCIES
|
set(ADDITIONAL_LIBRARY_DEPENDENCIES
|
||||||
"libultraship;"
|
"libultraship;"
|
||||||
"ZAPDUtils;"
|
|
||||||
"ZAPDLib;"
|
"ZAPDLib;"
|
||||||
"glu32;"
|
"glu32;"
|
||||||
"SDL2::SDL2;"
|
"SDL2::SDL2;"
|
||||||
"SDL2::SDL2main;"
|
"SDL2::SDL2main;"
|
||||||
"$<$<BOOL:${BUILD_CROWD_CONTROL}>:SDL2_net::SDL2_net-static>"
|
"$<$<BOOL:${BUILD_REMOTE_CONTROL}>:SDL2_net::SDL2_net-static>"
|
||||||
"glfw;"
|
"glfw;"
|
||||||
"winmm;"
|
"winmm;"
|
||||||
"imm32;"
|
"imm32;"
|
||||||
@ -699,7 +688,6 @@ if (CMAKE_SYSTEM_NAME STREQUAL "Windows")
|
|||||||
elseif("${CMAKE_VS_PLATFORM_NAME}" STREQUAL "Win32")
|
elseif("${CMAKE_VS_PLATFORM_NAME}" STREQUAL "Win32")
|
||||||
set(ADDITIONAL_LIBRARY_DEPENDENCIES
|
set(ADDITIONAL_LIBRARY_DEPENDENCIES
|
||||||
"libultraship;"
|
"libultraship;"
|
||||||
"ZAPDUtils;"
|
|
||||||
"ZAPDLib;"
|
"ZAPDLib;"
|
||||||
"glu32;"
|
"glu32;"
|
||||||
"SDL2::SDL2;"
|
"SDL2::SDL2;"
|
||||||
@ -717,7 +705,6 @@ elseif(CMAKE_SYSTEM_NAME STREQUAL "NintendoSwitch")
|
|||||||
find_package(Threads REQUIRED)
|
find_package(Threads REQUIRED)
|
||||||
set(ADDITIONAL_LIBRARY_DEPENDENCIES
|
set(ADDITIONAL_LIBRARY_DEPENDENCIES
|
||||||
"libultraship;"
|
"libultraship;"
|
||||||
"ZAPDUtils;"
|
|
||||||
SDL2::SDL2
|
SDL2::SDL2
|
||||||
-lglad
|
-lglad
|
||||||
Threads::Threads
|
Threads::Threads
|
||||||
@ -739,10 +726,9 @@ else()
|
|||||||
find_package(Threads REQUIRED)
|
find_package(Threads REQUIRED)
|
||||||
set(ADDITIONAL_LIBRARY_DEPENDENCIES
|
set(ADDITIONAL_LIBRARY_DEPENDENCIES
|
||||||
"libultraship;"
|
"libultraship;"
|
||||||
"ZAPDUtils;"
|
|
||||||
"ZAPDLib;"
|
"ZAPDLib;"
|
||||||
SDL2::SDL2
|
SDL2::SDL2
|
||||||
"$<$<BOOL:${BUILD_CROWD_CONTROL}>:SDL2_net::SDL2_net>"
|
"$<$<BOOL:${BUILD_REMOTE_CONTROL}>:SDL2_net::SDL2_net>"
|
||||||
${CMAKE_DL_LIBS}
|
${CMAKE_DL_LIBS}
|
||||||
Threads::Threads
|
Threads::Threads
|
||||||
)
|
)
|
||||||
|
@ -28,4 +28,10 @@
|
|||||||
<supportedOS Id="{8e0f7a12-bfb3-4fe8-b9a5-48fd50a15a9a}" />
|
<supportedOS Id="{8e0f7a12-bfb3-4fe8-b9a5-48fd50a15a9a}" />
|
||||||
</application>
|
</application>
|
||||||
</compatibility>
|
</compatibility>
|
||||||
|
<asmv3:application xmlns:asmv3="urn:schemas-microsoft-com:asm.v3">
|
||||||
|
<asmv3:windowsSettings>
|
||||||
|
<dpiAware xmlns="http://schemas.microsoft.com/SMI/2005/WindowsSettings">true/pm</dpiAware> <!-- legacy -->
|
||||||
|
<dpiAwareness xmlns="http://schemas.microsoft.com/SMI/2016/WindowsSettings">permonitorv2,permonitor</dpiAwareness> <!-- falls back to pm if pmv2 is not available -->
|
||||||
|
</asmv3:windowsSettings>
|
||||||
|
</asmv3:application>
|
||||||
</assembly>
|
</assembly>
|
||||||
|
2
soh/assets/.gitignore
vendored
@ -4,4 +4,4 @@
|
|||||||
*.cfg
|
*.cfg
|
||||||
*.vtx.inc
|
*.vtx.inc
|
||||||
*.dlist.inc
|
*.dlist.inc
|
||||||
*.txt
|
!*.png
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
{
|
{
|
||||||
"0": "Abre Mojo",
|
"0": "Arbre Mojo",
|
||||||
"1": "Caverne Dodongo",
|
"1": "Caverne Dodongo",
|
||||||
"2": "Ventre de Jabu-Jabu",
|
"2": "Ventre de Jabu-Jabu",
|
||||||
"3": "Temple de la Forêt",
|
"3": "Temple de la Forêt",
|
||||||
@ -58,9 +58,9 @@
|
|||||||
"56": "Laboratoire du Lac",
|
"56": "Laboratoire du Lac",
|
||||||
"57": "", // Tente du Marathonien (No title card)
|
"57": "", // Tente du Marathonien (No title card)
|
||||||
"58": "Cabane du fossoyeur",
|
"58": "Cabane du fossoyeur",
|
||||||
"59": "Fountaine Royale des Fées",
|
"59": "Fontaine Royale des Fées",
|
||||||
"60": "Fountaine des Fées",
|
"60": "Fontaine des Fées",
|
||||||
"61": "Fountaine Royale des Fées",
|
"61": "Fontaine Royale des Fées",
|
||||||
"62": "", // Grottes (No title card)
|
"62": "", // Grottes (No title card)
|
||||||
"63": "", // Tombe 1 (No title card)
|
"63": "", // Tombe 1 (No title card)
|
||||||
"64": "", // Tombe 2 (No title card)
|
"64": "", // Tombe 2 (No title card)
|
||||||
|
Before Width: | Height: | Size: 11 KiB After Width: | Height: | Size: 1.5 KiB |
BIN
soh/assets/custom/textures/buttons/ABtnOutline.png
Normal file
After Width: | Height: | Size: 1.8 KiB |
BIN
soh/assets/custom/textures/buttons/AnalogStick.png
Normal file
After Width: | Height: | Size: 2.2 KiB |
BIN
soh/assets/custom/textures/buttons/AnalogStickOutline.png
Normal file
After Width: | Height: | Size: 3.6 KiB |
Before Width: | Height: | Size: 1.3 KiB After Width: | Height: | Size: 1.5 KiB |
BIN
soh/assets/custom/textures/buttons/BBtnOutline.png
Normal file
After Width: | Height: | Size: 1.8 KiB |
Before Width: | Height: | Size: 11 KiB After Width: | Height: | Size: 1.3 KiB |
BIN
soh/assets/custom/textures/buttons/CDownOutline.png
Normal file
After Width: | Height: | Size: 1.5 KiB |
Before Width: | Height: | Size: 11 KiB After Width: | Height: | Size: 1.3 KiB |
BIN
soh/assets/custom/textures/buttons/CLeftOutline.png
Normal file
After Width: | Height: | Size: 1.5 KiB |
Before Width: | Height: | Size: 11 KiB After Width: | Height: | Size: 1.3 KiB |
BIN
soh/assets/custom/textures/buttons/CRightOutline.png
Normal file
After Width: | Height: | Size: 1.5 KiB |
Before Width: | Height: | Size: 11 KiB After Width: | Height: | Size: 1.3 KiB |
BIN
soh/assets/custom/textures/buttons/CUpOutline.png
Normal file
After Width: | Height: | Size: 1.5 KiB |
BIN
soh/assets/custom/textures/buttons/DPadDown.png
Normal file
After Width: | Height: | Size: 946 B |
BIN
soh/assets/custom/textures/buttons/DPadDownOutline.png
Normal file
After Width: | Height: | Size: 984 B |
BIN
soh/assets/custom/textures/buttons/DPadLeft.png
Normal file
After Width: | Height: | Size: 929 B |
BIN
soh/assets/custom/textures/buttons/DPadLeftOutline.png
Normal file
After Width: | Height: | Size: 953 B |
BIN
soh/assets/custom/textures/buttons/DPadRight.png
Normal file
After Width: | Height: | Size: 922 B |
BIN
soh/assets/custom/textures/buttons/DPadRightOutline.png
Normal file
After Width: | Height: | Size: 954 B |
BIN
soh/assets/custom/textures/buttons/DPadUp.png
Normal file
After Width: | Height: | Size: 968 B |
BIN
soh/assets/custom/textures/buttons/DPadUpOutline.png
Normal file
After Width: | Height: | Size: 993 B |
BIN
soh/assets/custom/textures/buttons/InputViewerBackground.png
Normal file
After Width: | Height: | Size: 941 B |
Before Width: | Height: | Size: 355 B After Width: | Height: | Size: 1.0 KiB |
BIN
soh/assets/custom/textures/buttons/LBtnOutline.png
Normal file
After Width: | Height: | Size: 1.1 KiB |
Before Width: | Height: | Size: 379 B After Width: | Height: | Size: 992 B |
BIN
soh/assets/custom/textures/buttons/RBtnOutline.png
Normal file
After Width: | Height: | Size: 1.0 KiB |
BIN
soh/assets/custom/textures/buttons/RightStick.png
Normal file
After Width: | Height: | Size: 2.1 KiB |
BIN
soh/assets/custom/textures/buttons/RightStickOutline.png
Normal file
After Width: | Height: | Size: 2.4 KiB |
Before Width: | Height: | Size: 12 KiB After Width: | Height: | Size: 973 B |
BIN
soh/assets/custom/textures/buttons/StartBtnOutline.png
Normal file
After Width: | Height: | Size: 1.0 KiB |
Before Width: | Height: | Size: 1.2 KiB After Width: | Height: | Size: 1005 B |
BIN
soh/assets/custom/textures/buttons/ZBtnOutline.png
Normal file
After Width: | Height: | Size: 1.0 KiB |
15
soh/assets/sources/triforce-hunt/paths.txt
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
Complete triforce:
|
||||||
|
DL name: gTriforcePieceCompletedDL
|
||||||
|
Export Path: objects/object_triforce_completed
|
||||||
|
|
||||||
|
Shard 0:
|
||||||
|
DL name: gTriforcePiece0DL
|
||||||
|
Export Path: objects/object_triforce_piece_0
|
||||||
|
|
||||||
|
Shard 1:
|
||||||
|
DL name: gTriforcePiece1DL
|
||||||
|
Export Path: objects/object_triforce_piece_1
|
||||||
|
|
||||||
|
Shard 2:
|
||||||
|
DL name: gTriforcePiece2DL
|
||||||
|
Export Path: objects/object_triforce_piece_2
|
BIN
soh/assets/sources/triforce-hunt/textures/noise_tex.png
Normal file
After Width: | Height: | Size: 660 B |
BIN
soh/assets/sources/triforce-hunt/triforce_complete.blend
Normal file
BIN
soh/assets/sources/triforce-hunt/triforce_shard_0.blend
Normal file
BIN
soh/assets/sources/triforce-hunt/triforce_shard_1.blend
Normal file
BIN
soh/assets/sources/triforce-hunt/triforce_shard_2.blend
Normal file
@ -1230,8 +1230,8 @@ Gfx* Gfx_EnvColor(GraphicsContext* gfxCtx, s32 r, s32 g, s32 b, s32 a);
|
|||||||
void Gfx_SetupFrame(GraphicsContext* gfxCtx, u8 r, u8 g, u8 b);
|
void Gfx_SetupFrame(GraphicsContext* gfxCtx, u8 r, u8 g, u8 b);
|
||||||
void func_80095974(GraphicsContext* gfxCtx);
|
void func_80095974(GraphicsContext* gfxCtx);
|
||||||
void func_80095AA0(PlayState* play, Room* room, Input* arg2, UNK_TYPE arg3);
|
void func_80095AA0(PlayState* play, Room* room, Input* arg2, UNK_TYPE arg3);
|
||||||
void func_8009638C(Gfx** displayList, void* source, void* tlut, u16 width, u16 height, u8 fmt, u8 siz, u16 mode0,
|
void Room_DrawBackground2D(Gfx** gfxP, void* tex, void* tlut, u16 width, u16 height, u8 fmt, u8 siz, u16 tlutMode,
|
||||||
u16 tlutCount, f32 frameX, f32 frameY);
|
u16 tlutCount, f32 offsetX, f32 offsetY);
|
||||||
void func_80096FD4(PlayState* play, Room* room);
|
void func_80096FD4(PlayState* play, Room* room);
|
||||||
u32 func_80096FE8(PlayState* play, RoomContext* roomCtx);
|
u32 func_80096FE8(PlayState* play, RoomContext* roomCtx);
|
||||||
s32 func_8009728C(PlayState* play, RoomContext* roomCtx, s32 roomNum);
|
s32 func_8009728C(PlayState* play, RoomContext* roomCtx, s32 roomNum);
|
||||||
@ -1250,7 +1250,7 @@ s32 Object_IsLoaded(ObjectContext* objectCtx, s32 bankIndex);
|
|||||||
void func_800981B8(ObjectContext* objectCtx);
|
void func_800981B8(ObjectContext* objectCtx);
|
||||||
s32 Scene_ExecuteCommands(PlayState* play, SceneCmd* sceneCmd);
|
s32 Scene_ExecuteCommands(PlayState* play, SceneCmd* sceneCmd);
|
||||||
void TransitionActor_InitContext(GameState* state, TransitionActorContext* transiActorCtx);
|
void TransitionActor_InitContext(GameState* state, TransitionActorContext* transiActorCtx);
|
||||||
void func_800994A0(PlayState* play);
|
void Scene_SetTransitionForNextEntrance(PlayState* play);
|
||||||
void Scene_Draw(PlayState* play);
|
void Scene_Draw(PlayState* play);
|
||||||
void SkelAnime_DrawLod(PlayState* play, void** skeleton, Vec3s* jointTable,
|
void SkelAnime_DrawLod(PlayState* play, void** skeleton, Vec3s* jointTable,
|
||||||
OverrideLimbDrawOpa overrideLimbDraw, PostLimbDrawOpa postLimbDraw, void* arg, s32 dListIndex);
|
OverrideLimbDrawOpa overrideLimbDraw, PostLimbDrawOpa postLimbDraw, void* arg, s32 dListIndex);
|
||||||
@ -1537,7 +1537,7 @@ void KaleidoScopeCall_Draw(PlayState* play);
|
|||||||
void func_800BC490(PlayState* play, s16 point);
|
void func_800BC490(PlayState* play, s16 point);
|
||||||
s32 func_800BC56C(PlayState* play, s16 arg1);
|
s32 func_800BC56C(PlayState* play, s16 arg1);
|
||||||
void func_800BC590(PlayState* play);
|
void func_800BC590(PlayState* play);
|
||||||
void func_800BC5E0(PlayState* play, s32 arg1);
|
void Gameplay_SetupTransition(PlayState* play, s32 arg1);
|
||||||
Gfx* Play_SetFog(PlayState* play, Gfx* gfx);
|
Gfx* Play_SetFog(PlayState* play, Gfx* gfx);
|
||||||
void Play_Destroy(GameState* thisx);
|
void Play_Destroy(GameState* thisx);
|
||||||
void Play_Init(GameState* thisx);
|
void Play_Init(GameState* thisx);
|
||||||
@ -1828,8 +1828,8 @@ MtxF* Matrix_CheckFloats(MtxF* mf, char* file, s32 line);
|
|||||||
void Matrix_SetTranslateScaleMtx2(Mtx* mtx, f32 scaleX, f32 scaleY, f32 scaleZ, f32 translateX, f32 translateY,
|
void Matrix_SetTranslateScaleMtx2(Mtx* mtx, f32 scaleX, f32 scaleY, f32 scaleZ, f32 translateX, f32 translateY,
|
||||||
f32 translateZ);
|
f32 translateZ);
|
||||||
uintptr_t SysUcode_GetUCodeBoot(void);
|
uintptr_t SysUcode_GetUCodeBoot(void);
|
||||||
uintptr_t SysUcode_GetUCodeBootSize(void);
|
size_t SysUcode_GetUCodeBootSize(void);
|
||||||
uintptr_t SysUcode_GetUCode(void);
|
uint32_t SysUcode_GetUCode(void);
|
||||||
uintptr_t SysUcode_GetUCodeData(void);
|
uintptr_t SysUcode_GetUCodeData(void);
|
||||||
void func_800D2E30(UnkRumbleStruct* arg0);
|
void func_800D2E30(UnkRumbleStruct* arg0);
|
||||||
void func_800D3140(UnkRumbleStruct* arg0);
|
void func_800D3140(UnkRumbleStruct* arg0);
|
||||||
@ -2171,7 +2171,7 @@ void func_800FA18C(u8, u8);
|
|||||||
void Audio_SetVolScale(u8 playerIdx, u8 scaleIdx, u8 targetVol, u8 volFadeTimer);
|
void Audio_SetVolScale(u8 playerIdx, u8 scaleIdx, u8 targetVol, u8 volFadeTimer);
|
||||||
void func_800FA3DC(void);
|
void func_800FA3DC(void);
|
||||||
u8 func_800FAD34(void);
|
u8 func_800FAD34(void);
|
||||||
void func_800FADF8(void);
|
void Audio_ResetActiveSequences(void);
|
||||||
void func_800FAEB4(void);
|
void func_800FAEB4(void);
|
||||||
void GfxPrint_SetColor(GfxPrint* this, u32 r, u32 g, u32 b, u32 a);
|
void GfxPrint_SetColor(GfxPrint* this, u32 r, u32 g, u32 b, u32 a);
|
||||||
void GfxPrint_SetPosPx(GfxPrint* this, s32 x, s32 y);
|
void GfxPrint_SetPosPx(GfxPrint* this, s32 x, s32 y);
|
||||||
@ -2210,6 +2210,14 @@ s8 PadUtils_GetRelYImpl(Input* input);
|
|||||||
s8 PadUtils_GetRelX(Input* input);
|
s8 PadUtils_GetRelX(Input* input);
|
||||||
s8 PadUtils_GetRelY(Input* input);
|
s8 PadUtils_GetRelY(Input* input);
|
||||||
void PadUtils_UpdateRelXY(Input* input);
|
void PadUtils_UpdateRelXY(Input* input);
|
||||||
|
s8 PadUtils_GetCurRX(Input* input);
|
||||||
|
s8 PadUtils_GetCurRY(Input* input);
|
||||||
|
void PadUtils_SetRelRXY(Input* input, s32 x, s32 y);
|
||||||
|
s8 PadUtils_GetRelRXImpl(Input* input);
|
||||||
|
s8 PadUtils_GetRelRYImpl(Input* input);
|
||||||
|
s8 PadUtils_GetRelRX(Input* input);
|
||||||
|
s8 PadUtils_GetRelRY(Input* input);
|
||||||
|
void PadUtils_UpdateRelRXY(Input* input);
|
||||||
s32 PadSetup_Init(OSMesgQueue* mq, u8* outMask, OSContStatus* status);
|
s32 PadSetup_Init(OSMesgQueue* mq, u8* outMask, OSContStatus* status);
|
||||||
f32 Math_FTanF(f32 x);
|
f32 Math_FTanF(f32 x);
|
||||||
f32 Math_FFloorF(f32 x);
|
f32 Math_FFloorF(f32 x);
|
||||||
@ -2459,6 +2467,10 @@ void Message_DrawText(PlayState* play, Gfx** gfxP);
|
|||||||
void Interface_CreateQuadVertexGroup(Vtx* vtxList, s32 xStart, s32 yStart, s32 width, s32 height, u8 flippedH);
|
void Interface_CreateQuadVertexGroup(Vtx* vtxList, s32 xStart, s32 yStart, s32 width, s32 height, u8 flippedH);
|
||||||
void Interface_RandoRestoreSwordless(void);
|
void Interface_RandoRestoreSwordless(void);
|
||||||
|
|
||||||
|
//Pause Warp
|
||||||
|
void PauseWarp_HandleSelection();
|
||||||
|
void PauseWarp_Execute();
|
||||||
|
|
||||||
// #endregion
|
// #endregion
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
|
@ -86,6 +86,8 @@
|
|||||||
#define R_ITEM_ICON_X(i) ZREG(82 + i)
|
#define R_ITEM_ICON_X(i) ZREG(82 + i)
|
||||||
#define R_ITEM_ICON_Y(i) ZREG(86 + i)
|
#define R_ITEM_ICON_Y(i) ZREG(86 + i)
|
||||||
#define R_ITEM_ICON_DD(i) ZREG(90 + i)
|
#define R_ITEM_ICON_DD(i) ZREG(90 + i)
|
||||||
|
#define R_TRANS_DBG_ENABLED CREG(11)
|
||||||
|
#define R_TRANS_DBG_TYPE CREG(12)
|
||||||
#define R_ENV_WIND_DIR(i) CREG(16 + i)
|
#define R_ENV_WIND_DIR(i) CREG(16 + i)
|
||||||
#define R_ENV_WIND_SPEED CREG(19)
|
#define R_ENV_WIND_SPEED CREG(19)
|
||||||
#define R_A_BTN_Y XREG(16)
|
#define R_A_BTN_Y XREG(16)
|
||||||
|
1934
soh/include/tables/entrance_table.h
Normal file
@ -107,7 +107,7 @@ extern "C"
|
|||||||
extern s16 gLinkObjectIds[2];
|
extern s16 gLinkObjectIds[2];
|
||||||
extern u32 gObjectTableSize;
|
extern u32 gObjectTableSize;
|
||||||
extern RomFile gObjectTable[OBJECT_ID_MAX];
|
extern RomFile gObjectTable[OBJECT_ID_MAX];
|
||||||
extern EntranceInfo gEntranceTable[1556];
|
extern EntranceInfo gEntranceTable[ENTR_MAX];
|
||||||
extern SceneTableEntry gSceneTable[SCENE_ID_MAX];
|
extern SceneTableEntry gSceneTable[SCENE_ID_MAX];
|
||||||
extern u16 gSramSlotOffsets[];
|
extern u16 gSramSlotOffsets[];
|
||||||
// 4 16-colors palettes
|
// 4 16-colors palettes
|
||||||
@ -224,7 +224,7 @@ extern "C"
|
|||||||
extern u16 gAudioSfxSwapSource[10];
|
extern u16 gAudioSfxSwapSource[10];
|
||||||
extern u16 gAudioSfxSwapTarget[10];
|
extern u16 gAudioSfxSwapTarget[10];
|
||||||
extern u8 gAudioSfxSwapMode[10];
|
extern u8 gAudioSfxSwapMode[10];
|
||||||
extern unk_D_8016E750 D_8016E750[4];
|
extern ActiveSequence gActiveSeqs[4];
|
||||||
extern AudioContext gAudioContext;
|
extern AudioContext gAudioContext;
|
||||||
extern void(*D_801755D0)(void);
|
extern void(*D_801755D0)(void);
|
||||||
|
|
||||||
|
@ -1122,6 +1122,82 @@ typedef struct {
|
|||||||
/* 0x4C */ u32 unk_4C;
|
/* 0x4C */ u32 unk_4C;
|
||||||
} PreRender; // size = 0x50
|
} PreRender; // size = 0x50
|
||||||
|
|
||||||
|
#define TRANS_TRIGGER_OFF 0 // transition is not active
|
||||||
|
#define TRANS_TRIGGER_START 20 // start transition (exiting an area)
|
||||||
|
#define TRANS_TRIGGER_END -20 // transition is ending (arriving in a new area)
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
/* 0 */ TRANS_MODE_OFF,
|
||||||
|
/* 1 */ TRANS_MODE_SETUP,
|
||||||
|
/* 2 */ TRANS_MODE_INSTANCE_INIT,
|
||||||
|
/* 3 */ TRANS_MODE_INSTANCE_RUNNING,
|
||||||
|
/* 4 */ TRANS_MODE_FILL_WHITE_INIT,
|
||||||
|
/* 5 */ TRANS_MODE_FILL_IN,
|
||||||
|
/* 6 */ TRANS_MODE_FILL_OUT,
|
||||||
|
/* 7 */ TRANS_MODE_FILL_BROWN_INIT,
|
||||||
|
/* 8 */ TRANS_MODE_08, // unused
|
||||||
|
/* 9 */ TRANS_MODE_09, // unused
|
||||||
|
/* 10 */ TRANS_MODE_INSTANT,
|
||||||
|
/* 11 */ TRANS_MODE_INSTANCE_WAIT,
|
||||||
|
/* 12 */ TRANS_MODE_SANDSTORM_INIT,
|
||||||
|
/* 13 */ TRANS_MODE_SANDSTORM,
|
||||||
|
/* 14 */ TRANS_MODE_SANDSTORM_END_INIT,
|
||||||
|
/* 15 */ TRANS_MODE_SANDSTORM_END,
|
||||||
|
/* 16 */ TRANS_MODE_CS_BLACK_FILL_INIT,
|
||||||
|
/* 17 */ TRANS_MODE_CS_BLACK_FILL
|
||||||
|
} TransitionMode;
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
/* 0 */ TRANS_TYPE_WIPE,
|
||||||
|
/* 1 */ TRANS_TYPE_TRIFORCE,
|
||||||
|
/* 2 */ TRANS_TYPE_FADE_BLACK,
|
||||||
|
/* 3 */ TRANS_TYPE_FADE_WHITE,
|
||||||
|
/* 4 */ TRANS_TYPE_FADE_BLACK_FAST,
|
||||||
|
/* 5 */ TRANS_TYPE_FADE_WHITE_FAST,
|
||||||
|
/* 6 */ TRANS_TYPE_FADE_BLACK_SLOW,
|
||||||
|
/* 7 */ TRANS_TYPE_FADE_WHITE_SLOW,
|
||||||
|
/* 8 */ TRANS_TYPE_WIPE_FAST,
|
||||||
|
/* 9 */ TRANS_TYPE_FILL_WHITE2,
|
||||||
|
/* 10 */ TRANS_TYPE_FILL_WHITE,
|
||||||
|
/* 11 */ TRANS_TYPE_INSTANT,
|
||||||
|
/* 12 */ TRANS_TYPE_FILL_BROWN,
|
||||||
|
/* 13 */ TRANS_TYPE_FADE_WHITE_CS_DELAYED,
|
||||||
|
/* 14 */ TRANS_TYPE_SANDSTORM_PERSIST,
|
||||||
|
/* 15 */ TRANS_TYPE_SANDSTORM_END,
|
||||||
|
/* 16 */ TRANS_TYPE_CS_BLACK_FILL,
|
||||||
|
/* 17 */ TRANS_TYPE_FADE_WHITE_INSTANT,
|
||||||
|
/* 18 */ TRANS_TYPE_FADE_GREEN,
|
||||||
|
/* 19 */ TRANS_TYPE_FADE_BLUE,
|
||||||
|
// transition types 20 - 31 are unused
|
||||||
|
// transition types 32 - 55 are constructed using the TRANS_TYPE_CIRCLE macro
|
||||||
|
/* 56 */ TRANS_TYPE_MAX = 56
|
||||||
|
} TransitionType;
|
||||||
|
|
||||||
|
#define TRANS_NEXT_TYPE_DEFAULT 0xFF // when `nextTransitionType` is set to default, the type will be taken from the entrance table for the ending transition
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
/* 0 */ TCA_NORMAL,
|
||||||
|
/* 1 */ TCA_WAVE,
|
||||||
|
/* 2 */ TCA_RIPPLE,
|
||||||
|
/* 3 */ TCA_STARBURST
|
||||||
|
} TransitionCircleAppearance;
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
/* 0 */ TCC_BLACK,
|
||||||
|
/* 1 */ TCC_WHITE,
|
||||||
|
/* 2 */ TCC_GRAY,
|
||||||
|
/* 3 */ TCC_SPECIAL // color varies depending on appearance. unused and appears broken
|
||||||
|
} TransitionCircleColor;
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
/* 0 */ TCS_FAST,
|
||||||
|
/* 1 */ TCS_SLOW
|
||||||
|
} TransitionCircleSpeed;
|
||||||
|
|
||||||
|
#define TC_SET_PARAMS (1 << 7)
|
||||||
|
|
||||||
|
#define TRANS_TYPE_CIRCLE(appearance, color, speed) ((1 << 5) | ((color & 3) << 3) | ((appearance & 3) << 1) | (speed & 1))
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
union {
|
union {
|
||||||
TransitionFade fade;
|
TransitionFade fade;
|
||||||
@ -1384,14 +1460,14 @@ typedef struct PlayState {
|
|||||||
/* 0x11E0C */ ElfMessage* cUpElfMsgs;
|
/* 0x11E0C */ ElfMessage* cUpElfMsgs;
|
||||||
/* 0x11E10 */ void* specialEffects;
|
/* 0x11E10 */ void* specialEffects;
|
||||||
/* 0x11E14 */ u8 skyboxId;
|
/* 0x11E14 */ u8 skyboxId;
|
||||||
/* 0x11E15 */ s8 sceneLoadFlag; // "fade_direction"
|
/* 0x11E15 */ s8 transitionTrigger; // "fade_direction"
|
||||||
/* 0x11E16 */ s16 unk_11E16;
|
/* 0x11E16 */ s16 unk_11E16;
|
||||||
/* 0x11E18 */ s16 unk_11E18;
|
/* 0x11E18 */ s16 unk_11E18;
|
||||||
/* 0x11E1A */ s16 nextEntranceIndex;
|
/* 0x11E1A */ s16 nextEntranceIndex;
|
||||||
/* 0x11E1C */ char unk_11E1C[0x40];
|
/* 0x11E1C */ char unk_11E1C[0x40];
|
||||||
/* 0x11E5C */ s8 shootingGalleryStatus;
|
/* 0x11E5C */ s8 shootingGalleryStatus;
|
||||||
/* 0x11E5D */ s8 bombchuBowlingStatus; // "bombchu_game_flag"
|
/* 0x11E5D */ s8 bombchuBowlingStatus; // "bombchu_game_flag"
|
||||||
/* 0x11E5E */ u8 fadeTransition;
|
/* 0x11E5E */ u8 transitionType;
|
||||||
/* 0x11E60 */ CollisionCheckContext colChkCtx;
|
/* 0x11E60 */ CollisionCheckContext colChkCtx;
|
||||||
/* 0x120FC */ u16 envFlags[20];
|
/* 0x120FC */ u16 envFlags[20];
|
||||||
/* 0x12124 */ PreRender pauseBgPreRender;
|
/* 0x12124 */ PreRender pauseBgPreRender;
|
||||||
@ -1513,6 +1589,20 @@ typedef struct {
|
|||||||
uint16_t bossRushArrowOffset;
|
uint16_t bossRushArrowOffset;
|
||||||
} FileChooseContext; // size = 0x1CAE0
|
} FileChooseContext; // size = 0x1CAE0
|
||||||
|
|
||||||
|
// Macros for `EntranceInfo.field`
|
||||||
|
#define ENTRANCE_INFO_CONTINUE_BGM_FLAG (1 << 15)
|
||||||
|
#define ENTRANCE_INFO_DISPLAY_TITLE_CARD_FLAG (1 << 14)
|
||||||
|
#define ENTRANCE_INFO_END_TRANS_TYPE_MASK 0x3F80
|
||||||
|
#define ENTRANCE_INFO_END_TRANS_TYPE_SHIFT 7
|
||||||
|
#define ENTRANCE_INFO_END_TRANS_TYPE(field) \
|
||||||
|
(((field) >> ENTRANCE_INFO_END_TRANS_TYPE_SHIFT) \
|
||||||
|
& (ENTRANCE_INFO_END_TRANS_TYPE_MASK >> ENTRANCE_INFO_END_TRANS_TYPE_SHIFT))
|
||||||
|
#define ENTRANCE_INFO_START_TRANS_TYPE_MASK 0x7F
|
||||||
|
#define ENTRANCE_INFO_START_TRANS_TYPE_SHIFT 0
|
||||||
|
#define ENTRANCE_INFO_START_TRANS_TYPE(field) \
|
||||||
|
(((field) >> ENTRANCE_INFO_START_TRANS_TYPE_SHIFT) \
|
||||||
|
& (ENTRANCE_INFO_START_TRANS_TYPE_MASK >> ENTRANCE_INFO_START_TRANS_TYPE_SHIFT))
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
DPM_UNK = 0,
|
DPM_UNK = 0,
|
||||||
DPM_PLAYER = 1,
|
DPM_PLAYER = 1,
|
||||||
|
@ -970,43 +970,43 @@ typedef struct {
|
|||||||
} AudioContextInitSizes; // size = 0xC
|
} AudioContextInitSizes; // size = 0xC
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
/* 0x00 */ f32 unk_00;
|
/* 0x00 */ f32 volCur;
|
||||||
/* 0x04 */ f32 unk_04;
|
/* 0x04 */ f32 volTarget;
|
||||||
/* 0x08 */ f32 unk_08;
|
/* 0x08 */ f32 volStep;
|
||||||
/* 0x0C */ u16 unk_0C;
|
/* 0x0C */ u16 volTimer;
|
||||||
/* 0x10 */ f32 unk_10;
|
/* 0x10 */ f32 freqScaleCur;
|
||||||
/* 0x14 */ f32 unk_14;
|
/* 0x14 */ f32 freqScaleTarget;
|
||||||
/* 0x18 */ f32 unk_18;
|
/* 0x18 */ f32 freqScaleStep;
|
||||||
/* 0x1C */ u16 unk_1C;
|
/* 0x1C */ u16 freqScaleTimer;
|
||||||
} unk_50_s; // size = 0x20
|
} ActiveSequenceChannelData; // size = 0x20
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
/* 0x000 */ f32 volCur;
|
/* 0x000 */ f32 volCur;
|
||||||
/* 0x004 */ f32 volTarget;
|
/* 0x004 */ f32 volTarget;
|
||||||
/* 0x008 */ f32 unk_08;
|
/* 0x008 */ f32 volStep;
|
||||||
/* 0x00C */ u16 unk_0C;
|
/* 0x00C */ u16 volTimer;
|
||||||
/* 0x00E */ u8 volScales[0x4];
|
/* 0x00E */ u8 volScales[4];
|
||||||
/* 0x012 */ u8 volFadeTimer;
|
/* 0x012 */ u8 volFadeTimer;
|
||||||
/* 0x013 */ u8 fadeVolUpdate;
|
/* 0x013 */ u8 fadeVolUpdate;
|
||||||
/* 0x014 */ u32 unk_14;
|
/* 0x014 */ u32 tempoCmd;
|
||||||
/* 0x018 */ u16 unk_18;
|
/* 0x018 */ u16 tempoOriginal; // stores the original tempo before modifying it (to reset back to)
|
||||||
/* 0x01C */ f32 unk_1C;
|
/* 0x01C */ f32 tempoCur;
|
||||||
/* 0x020 */ f32 unk_20;
|
/* 0x020 */ f32 tempoTarget;
|
||||||
/* 0x024 */ f32 unk_24;
|
/* 0x024 */ f32 tempoStep;
|
||||||
/* 0x028 */ u16 unk_28;
|
/* 0x028 */ u16 tempoTimer;
|
||||||
/* 0x02C */ u32 unk_2C[8];
|
/* 0x02C */ u32 setupCmd[8]; // a queue of cmds to execute once the player is disabled
|
||||||
/* 0x04C */ u8 unk_4C;
|
/* 0x04C */ u8 setupCmdTimer; // only execute setup commands when the timer is at 0.
|
||||||
/* 0x04D */ u8 unk_4D;
|
/* 0x04D */ u8 setupCmdNum; // number of setup commands requested once the player is disabled
|
||||||
/* 0x04E */ u8 unk_4E;
|
/* 0x04E */ u8 setupFadeTimer;
|
||||||
/* 0x050 */ unk_50_s unk_50[0x10];
|
/* 0x050 */ ActiveSequenceChannelData channelData[16];
|
||||||
/* 0x250 */ u16 unk_250;
|
/* 0x250 */ u16 freqScaleChannelFlags;
|
||||||
/* 0x252 */ u16 unk_252;
|
/* 0x252 */ u16 volChannelFlags;
|
||||||
/* 0x254 */ u16 unk_254;
|
/* 0x254 */ u16 seqId; // active seqId currently playing. Resets when sequence stops
|
||||||
/* 0x256 */ u16 unk_256;
|
/* 0x256 */ u16 prevSeqId; // last seqId played on a player. Does not reset when sequence stops
|
||||||
/* 0x258 */ u16 unk_258;
|
/* 0x258 */ u16 channelPortMask;
|
||||||
/* 0x25C */ u32 unk_25C;
|
/* 0x25C */ u32 startSeqCmd; // This name comes from MM
|
||||||
/* 0x260 */ u8 unk_260;
|
/* 0x260 */ u8 isWaitingForFonts; // This name comes from MM
|
||||||
} unk_D_8016E750; // size = 0x264
|
} ActiveSequence; // size = 0x264
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
/* 0 */ BANK_PLAYER,
|
/* 0 */ BANK_PLAYER,
|
||||||
|
@ -30,6 +30,14 @@ typedef enum {
|
|||||||
/* 13 */ SKYBOX_DMA_PAL2_START
|
/* 13 */ SKYBOX_DMA_PAL2_START
|
||||||
} SkyboxDmaState;
|
} SkyboxDmaState;
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
/* 0 */ SANDSTORM_OFF,
|
||||||
|
/* 1 */ SANDSTORM_FILL,
|
||||||
|
/* 2 */ SANDSTORM_UNFILL,
|
||||||
|
/* 3 */ SANDSTORM_ACTIVE,
|
||||||
|
/* 4 */ SANDSTORM_DISSIPATE
|
||||||
|
} SandstormState;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
/* 0x00 */ u8 state;
|
/* 0x00 */ u8 state;
|
||||||
/* 0x01 */ u8 flashRed;
|
/* 0x01 */ u8 flashRed;
|
||||||
|
@ -132,16 +132,6 @@ typedef enum {
|
|||||||
/* 0x40 */ PLAYER_IA_MASK_GERUDO,
|
/* 0x40 */ PLAYER_IA_MASK_GERUDO,
|
||||||
/* 0x41 */ PLAYER_IA_MASK_TRUTH,
|
/* 0x41 */ PLAYER_IA_MASK_TRUTH,
|
||||||
/* 0x42 */ PLAYER_IA_LENS_OF_TRUTH,
|
/* 0x42 */ PLAYER_IA_LENS_OF_TRUTH,
|
||||||
// Upstream TODO: Document why these entries were added
|
|
||||||
/* 0x43 */ PLAYER_IA_SHIELD_DEKU,
|
|
||||||
/* 0x44 */ PLAYER_IA_SHIELD_HYLIAN,
|
|
||||||
/* 0x45 */ PLAYER_IA_SHIELD_MIRROR,
|
|
||||||
/* 0x46 */ PLAYER_IA_TUNIC_KOKIRI,
|
|
||||||
/* 0x47 */ PLAYER_IA_TUNIC_GORON,
|
|
||||||
/* 0x48 */ PLAYER_IA_TUNIC_ZORA,
|
|
||||||
/* 0x49 */ PLAYER_IA_BOOTS_KOKIRI,
|
|
||||||
/* 0x4A */ PLAYER_IA_BOOTS_IRON,
|
|
||||||
/* 0x4B */ PLAYER_IA_BOOTS_HOVER,
|
|
||||||
/* 0x4C */ PLAYER_IA_MAX
|
/* 0x4C */ PLAYER_IA_MAX
|
||||||
} PlayerItemAction;
|
} PlayerItemAction;
|
||||||
|
|
||||||
@ -355,7 +345,7 @@ typedef enum {
|
|||||||
#define PLAYER_LIMB_BUF_COUNT LIMB_BUF_COUNT(PLAYER_LIMB_MAX)
|
#define PLAYER_LIMB_BUF_COUNT LIMB_BUF_COUNT(PLAYER_LIMB_MAX)
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
/* 0x00 */ f32 unk_00;
|
/* 0x00 */ f32 ceilingCheckHeight;
|
||||||
/* 0x04 */ f32 unk_04;
|
/* 0x04 */ f32 unk_04;
|
||||||
/* 0x08 */ f32 unk_08;
|
/* 0x08 */ f32 unk_08;
|
||||||
/* 0x0C */ f32 unk_0C;
|
/* 0x0C */ f32 unk_0C;
|
||||||
@ -369,7 +359,7 @@ typedef struct {
|
|||||||
/* 0x2C */ f32 unk_2C;
|
/* 0x2C */ f32 unk_2C;
|
||||||
/* 0x30 */ f32 unk_30;
|
/* 0x30 */ f32 unk_30;
|
||||||
/* 0x34 */ f32 unk_34;
|
/* 0x34 */ f32 unk_34;
|
||||||
/* 0x38 */ f32 unk_38;
|
/* 0x38 */ f32 wallCheckRadius;
|
||||||
/* 0x3C */ f32 unk_3C;
|
/* 0x3C */ f32 unk_3C;
|
||||||
/* 0x40 */ f32 unk_40;
|
/* 0x40 */ f32 unk_40;
|
||||||
/* 0x44 */ Vec3s unk_44;
|
/* 0x44 */ Vec3s unk_44;
|
||||||
@ -494,8 +484,8 @@ typedef struct {
|
|||||||
#define PLAYER_STATE3_RESTORE_NAYRUS_LOVE (1 << 6) // Set by ocarina effects actors when destroyed to signal Nayru's Love may be restored (see `ACTOROVL_ALLOC_ABSOLUTE`)
|
#define PLAYER_STATE3_RESTORE_NAYRUS_LOVE (1 << 6) // Set by ocarina effects actors when destroyed to signal Nayru's Love may be restored (see `ACTOROVL_ALLOC_ABSOLUTE`)
|
||||||
#define PLAYER_STATE3_HOOKSHOT_TRAVELLING (1 << 7) //Travelling to target
|
#define PLAYER_STATE3_HOOKSHOT_TRAVELLING (1 << 7) //Travelling to target
|
||||||
|
|
||||||
typedef void (*PlayerFunc674)(struct Player*, struct PlayState*);
|
typedef void (*PlayerActionFunc)(struct Player*, struct PlayState*);
|
||||||
typedef s32 (*PlayerFunc82C)(struct Player*, struct PlayState*);
|
typedef s32 (*UpperActionFunc)(struct Player*, struct PlayState*);
|
||||||
typedef void (*PlayerFuncA74)(struct PlayState*, struct Player*);
|
typedef void (*PlayerFuncA74)(struct PlayState*, struct Player*);
|
||||||
|
|
||||||
typedef struct Player {
|
typedef struct Player {
|
||||||
@ -512,7 +502,7 @@ typedef struct Player {
|
|||||||
/* 0x0155 */ char unk_155[0x003];
|
/* 0x0155 */ char unk_155[0x003];
|
||||||
/* 0x0158 */ u8 modelGroup;
|
/* 0x0158 */ u8 modelGroup;
|
||||||
/* 0x0159 */ u8 nextModelGroup;
|
/* 0x0159 */ u8 nextModelGroup;
|
||||||
/* 0x015A */ s8 unk_15A;
|
/* 0x015A */ s8 itemChangeType;
|
||||||
/* 0x015B */ u8 modelAnimType;
|
/* 0x015B */ u8 modelAnimType;
|
||||||
/* 0x015C */ u8 leftHandType;
|
/* 0x015C */ u8 leftHandType;
|
||||||
/* 0x015D */ u8 rightHandType;
|
/* 0x015D */ u8 rightHandType;
|
||||||
@ -548,11 +538,11 @@ typedef struct Player {
|
|||||||
/* 0x043C */ s8 mountSide;
|
/* 0x043C */ s8 mountSide;
|
||||||
/* 0x043D */ char unk_43D[0x003];
|
/* 0x043D */ char unk_43D[0x003];
|
||||||
/* 0x0440 */ Actor* rideActor;
|
/* 0x0440 */ Actor* rideActor;
|
||||||
/* 0x0444 */ u8 csMode;
|
/* 0x0444 */ u8 csAction;
|
||||||
/* 0x0445 */ u8 prevCsMode;
|
/* 0x0445 */ u8 prevCsAction;
|
||||||
/* 0x0446 */ u8 unk_446;
|
/* 0x0446 */ u8 cueId;
|
||||||
/* 0x0447 */ u8 unk_447;
|
/* 0x0447 */ u8 unk_447;
|
||||||
/* 0x0448 */ Actor* unk_448;
|
/* 0x0448 */ Actor* csActor; // Actor involved in a `csAction`. Typically the actor that invoked the cutscene.
|
||||||
/* 0x044C */ char unk_44C[0x004];
|
/* 0x044C */ char unk_44C[0x004];
|
||||||
/* 0x0450 */ Vec3f unk_450;
|
/* 0x0450 */ Vec3f unk_450;
|
||||||
/* 0x045C */ Vec3f unk_45C;
|
/* 0x045C */ Vec3f unk_45C;
|
||||||
@ -567,7 +557,7 @@ typedef struct Player {
|
|||||||
/* 0x0668 */ char unk_668[0x004];
|
/* 0x0668 */ char unk_668[0x004];
|
||||||
/* 0x066C */ s32 unk_66C;
|
/* 0x066C */ s32 unk_66C;
|
||||||
/* 0x0670 */ s32 meleeWeaponEffectIndex;
|
/* 0x0670 */ s32 meleeWeaponEffectIndex;
|
||||||
/* 0x0674 */ PlayerFunc674 func_674;
|
/* 0x0674 */ PlayerActionFunc actionFunc;
|
||||||
/* 0x0678 */ PlayerAgeProperties* ageProperties;
|
/* 0x0678 */ PlayerAgeProperties* ageProperties;
|
||||||
/* 0x067C */ u32 stateFlags1;
|
/* 0x067C */ u32 stateFlags1;
|
||||||
/* 0x0680 */ u32 stateFlags2;
|
/* 0x0680 */ u32 stateFlags2;
|
||||||
@ -581,7 +571,7 @@ typedef struct Player {
|
|||||||
/* 0x0698 */ f32 targetActorDistance;
|
/* 0x0698 */ f32 targetActorDistance;
|
||||||
/* 0x069C */ char unk_69C[0x004];
|
/* 0x069C */ char unk_69C[0x004];
|
||||||
/* 0x06A0 */ f32 unk_6A0;
|
/* 0x06A0 */ f32 unk_6A0;
|
||||||
/* 0x06A4 */ f32 unk_6A4;
|
/* 0x06A4 */ f32 closestSecretDistSq;
|
||||||
/* 0x06A8 */ Actor* unk_6A8;
|
/* 0x06A8 */ Actor* unk_6A8;
|
||||||
/* 0x06AC */ s8 unk_6AC;
|
/* 0x06AC */ s8 unk_6AC;
|
||||||
/* 0x06AD */ u8 unk_6AD;
|
/* 0x06AD */ u8 unk_6AD;
|
||||||
@ -596,18 +586,18 @@ typedef struct Player {
|
|||||||
/* 0x06C0 */ s16 unk_6C0;
|
/* 0x06C0 */ s16 unk_6C0;
|
||||||
/* 0x06C2 */ s16 unk_6C2;
|
/* 0x06C2 */ s16 unk_6C2;
|
||||||
/* 0x06C4 */ f32 unk_6C4;
|
/* 0x06C4 */ f32 unk_6C4;
|
||||||
/* 0x06C8 */ SkelAnime skelAnime2;
|
/* 0x06C8 */ SkelAnime upperSkelAnime;
|
||||||
/* 0x070C */ Vec3s jointTable2[PLAYER_LIMB_BUF_COUNT];
|
/* 0x070C */ Vec3s upperJointTable[PLAYER_LIMB_BUF_COUNT];
|
||||||
/* 0x079C */ Vec3s morphTable2[PLAYER_LIMB_BUF_COUNT];
|
/* 0x079C */ Vec3s upperMorphTable[PLAYER_LIMB_BUF_COUNT];
|
||||||
/* 0x082C */ PlayerFunc82C func_82C;
|
/* 0x082C */ UpperActionFunc upperActionFunc;
|
||||||
/* 0x0830 */ f32 unk_830;
|
/* 0x0830 */ f32 upperAnimBlendWeight;
|
||||||
/* 0x0834 */ s16 unk_834;
|
/* 0x0834 */ s16 unk_834;
|
||||||
/* 0x0836 */ s8 unk_836;
|
/* 0x0836 */ s8 unk_836;
|
||||||
/* 0x0837 */ u8 unk_837;
|
/* 0x0837 */ u8 unk_837;
|
||||||
/* 0x0838 */ f32 linearVelocity;
|
/* 0x0838 */ f32 linearVelocity;
|
||||||
/* 0x083C */ s16 currentYaw;
|
/* 0x083C */ s16 yaw; // General yaw value, used both for world and shape rotation. Current or target value depending on context.
|
||||||
/* 0x083E */ s16 targetYaw;
|
/* 0x083E */ s16 zTargetYaw; // yaw relating to Z targeting/"parallel" mode
|
||||||
/* 0x0840 */ u16 unk_840;
|
/* 0x0840 */ u16 underwaterTimer;
|
||||||
/* 0x0842 */ s8 meleeWeaponAnimation;
|
/* 0x0842 */ s8 meleeWeaponAnimation;
|
||||||
/* 0x0843 */ s8 meleeWeaponState;
|
/* 0x0843 */ s8 meleeWeaponState;
|
||||||
/* 0x0844 */ s8 unk_844;
|
/* 0x0844 */ s8 unk_844;
|
||||||
@ -615,8 +605,15 @@ typedef struct Player {
|
|||||||
/* 0x0846 */ u8 unk_846;
|
/* 0x0846 */ u8 unk_846;
|
||||||
/* 0x0847 */ s8 unk_847[4];
|
/* 0x0847 */ s8 unk_847[4];
|
||||||
/* 0x084B */ s8 unk_84B[4];
|
/* 0x084B */ s8 unk_84B[4];
|
||||||
/* 0x084F */ s8 unk_84F;
|
|
||||||
/* 0x0850 */ s16 unk_850; // multipurpose timer
|
/* 0x084F */ union {
|
||||||
|
s8 actionVar1;
|
||||||
|
} av1; // "Action Variable 1": context dependent variable that has different meanings depending on what action is currently running
|
||||||
|
|
||||||
|
/* 0x0850 */ union {
|
||||||
|
s16 actionVar2;
|
||||||
|
} av2; // "Action Variable 2": context dependent variable that has different meanings depending on what action is currently running
|
||||||
|
|
||||||
/* 0x0854 */ f32 unk_854;
|
/* 0x0854 */ f32 unk_854;
|
||||||
/* 0x0858 */ f32 unk_858;
|
/* 0x0858 */ f32 unk_858;
|
||||||
/* 0x085C */ f32 unk_85C; // stick length among other things
|
/* 0x085C */ f32 unk_85C; // stick length among other things
|
||||||
@ -631,44 +628,44 @@ typedef struct Player {
|
|||||||
/* 0x087C */ s16 unk_87C;
|
/* 0x087C */ s16 unk_87C;
|
||||||
/* 0x087E */ s16 unk_87E;
|
/* 0x087E */ s16 unk_87E;
|
||||||
/* 0x0880 */ f32 unk_880;
|
/* 0x0880 */ f32 unk_880;
|
||||||
/* 0x0884 */ f32 wallHeight; // height used to determine whether link can climb or grab a ledge at the top
|
/* 0x0884 */ f32 yDistToLedge; // y distance to ground above an interact wall. LEDGE_DIST_MAX if no ground is found
|
||||||
/* 0x0888 */ f32 wallDistance; // distance to the colliding wall plane
|
/* 0x0888 */ f32 distToInteractWall; // xyz distance to the interact wall
|
||||||
/* 0x088C */ u8 unk_88C;
|
/* 0x088C */ u8 ledgeClimbType;
|
||||||
/* 0x088D */ u8 unk_88D;
|
/* 0x088D */ u8 ledgeClimbDelayTimer;
|
||||||
/* 0x088E */ u8 unk_88E;
|
/* 0x088E */ u8 unk_88E;
|
||||||
/* 0x088F */ u8 unk_88F;
|
/* 0x088F */ u8 unk_88F;
|
||||||
/* 0x0890 */ u8 unk_890;
|
/* 0x0890 */ u8 unk_890;
|
||||||
/* 0x0891 */ u8 shockTimer;
|
/* 0x0891 */ u8 bodyShockTimer;
|
||||||
/* 0x0892 */ u8 unk_892;
|
/* 0x0892 */ u8 unk_892;
|
||||||
/* 0x0893 */ u8 hoverBootsTimer;
|
/* 0x0893 */ u8 hoverBootsTimer;
|
||||||
/* 0x0894 */ s16 fallStartHeight; // last truncated Y position before falling
|
/* 0x0894 */ s16 fallStartHeight; // last truncated Y position before falling
|
||||||
/* 0x0896 */ s16 fallDistance; // truncated Y distance the player has fallen so far (positive is down)
|
/* 0x0896 */ s16 fallDistance; // truncated Y distance the player has fallen so far (positive is down)
|
||||||
/* 0x0898 */ s16 unk_898;
|
/* 0x0898 */ s16 floorPitch; // angle of the floor slope in the direction of current world yaw (positive for ascending slope)
|
||||||
/* 0x089A */ s16 unk_89A;
|
/* 0x089A */ s16 floorPitchAlt; // the calculation for this value is bugged and doesn't represent anything meaningful
|
||||||
/* 0x089C */ s16 unk_89C;
|
/* 0x089C */ s16 unk_89C;
|
||||||
/* 0x089E */ u16 unk_89E;
|
/* 0x089E */ u16 floorSfxOffset;
|
||||||
/* 0x08A0 */ u8 unk_8A0;
|
/* 0x08A0 */ u8 unk_8A0;
|
||||||
/* 0x08A1 */ u8 unk_8A1;
|
/* 0x08A1 */ u8 unk_8A1;
|
||||||
/* 0x08A2 */ s16 unk_8A2;
|
/* 0x08A2 */ s16 unk_8A2;
|
||||||
/* 0x08A4 */ f32 unk_8A4;
|
/* 0x08A4 */ f32 unk_8A4;
|
||||||
/* 0x08A8 */ f32 unk_8A8;
|
/* 0x08A8 */ f32 unk_8A8;
|
||||||
/* 0x08AC */ f32 windSpeed; // Pushing player, examples include water currents, floor conveyors, climbing sloped surfaces // Upstream TODO: pushedSpeed
|
/* 0x08AC */ f32 pushedSpeed; // Pushing player, examples include water currents, floor conveyors, climbing sloped surfaces
|
||||||
/* 0x08B0 */ s16 windDirection; // Yaw direction of player being pushed // Upstream TODO: pushedYaw
|
/* 0x08B0 */ s16 pushedYaw; // Yaw direction of player being pushed
|
||||||
/* 0x08B4 */ WeaponInfo meleeWeaponInfo[3];
|
/* 0x08B4 */ WeaponInfo meleeWeaponInfo[3];
|
||||||
/* 0x0908 */ Vec3f bodyPartsPos[PLAYER_BODYPART_MAX];
|
/* 0x0908 */ Vec3f bodyPartsPos[PLAYER_BODYPART_MAX];
|
||||||
/* 0x09E0 */ MtxF mf_9E0;
|
/* 0x09E0 */ MtxF mf_9E0;
|
||||||
/* 0x0A20 */ MtxF shieldMf;
|
/* 0x0A20 */ MtxF shieldMf;
|
||||||
/* 0x0A60 */ u8 isBurning;
|
/* 0x0A60 */ u8 bodyIsBurning;
|
||||||
/* 0x0A61 */ u8 flameTimers[PLAYER_BODYPART_MAX]; // one flame per body part
|
/* 0x0A61 */ u8 bodyFlameTimers[PLAYER_BODYPART_MAX]; // one flame per body part
|
||||||
/* 0x0A73 */ u8 unk_A73;
|
/* 0x0A73 */ u8 unk_A73;
|
||||||
/* 0x0A74 */ PlayerFuncA74 func_A74;
|
/* 0x0A74 */ PlayerFuncA74 func_A74;
|
||||||
/* 0x0A78 */ s8 invincibilityTimer; // prevents damage when nonzero (positive = visible, counts towards zero each frame)
|
/* 0x0A78 */ s8 invincibilityTimer; // prevents damage when nonzero (positive = visible, counts towards zero each frame)
|
||||||
/* 0x0A79 */ u8 unk_A79;
|
/* 0x0A79 */ u8 floorTypeTimer; // counts up every frame the current floor type is the same as the last frame
|
||||||
/* 0x0A7A */ u8 unk_A7A;
|
/* 0x0A7A */ u8 floorProperty;
|
||||||
/* 0x0A7B */ u8 unk_A7B;
|
/* 0x0A7B */ u8 prevFloorType;
|
||||||
/* 0x0A7C */ f32 unk_A7C;
|
/* 0x0A7C */ f32 prevControlStickMagnitude;
|
||||||
/* 0x0A80 */ s16 unk_A80;
|
/* 0x0A80 */ s16 prevControlStickAngle;
|
||||||
/* 0x0A82 */ u16 unk_A82;
|
/* 0x0A82 */ u16 prevFloorSfxOffset;
|
||||||
/* 0x0A84 */ s16 unk_A84;
|
/* 0x0A84 */ s16 unk_A84;
|
||||||
/* 0x0A86 */ s8 unk_A86;
|
/* 0x0A86 */ s8 unk_A86;
|
||||||
/* 0x0A87 */ u8 unk_A87;
|
/* 0x0A87 */ u8 unk_A87;
|
||||||
|
@ -314,8 +314,34 @@ enum SceneID {
|
|||||||
/* 0x6E */ SCENE_ID_MAX
|
/* 0x6E */ SCENE_ID_MAX
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// this define exists to preserve shiftability for an unused scene that is
|
||||||
|
// listed in the entrance table
|
||||||
|
#define SCENE_UNUSED_6E SCENE_ID_MAX
|
||||||
|
|
||||||
#undef DEFINE_SCENE
|
#undef DEFINE_SCENE
|
||||||
|
|
||||||
|
// Entrance Index Enum
|
||||||
|
#define DEFINE_ENTRANCE(enum, _1, _2, _3, _4, _5, _6) enum,
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
#include "tables/entrance_table.h"
|
||||||
|
/* 0x614 */ ENTR_MAX
|
||||||
|
} EntranceIndex;
|
||||||
|
|
||||||
|
#define ENTR_LOAD_OPENING -1
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
/* 0x7FF9 */ ENTR_RETURN_YOUSEI_IZUMI_YOKO = 0x7FF9, // Great Fairy Fountain (spells)
|
||||||
|
/* 0x7FFA */ ENTR_RETURN_SYATEKIJYOU, // Shooting gallery
|
||||||
|
/* 0x7FFB */ ENTR_RETURN_2, // unused
|
||||||
|
/* 0x7FFC */ ENTR_RETURN_SHOP1, // Bazaar
|
||||||
|
/* 0x7FFD */ ENTR_RETURN_4, // unused
|
||||||
|
/* 0x7FFE */ ENTR_RETURN_DAIYOUSEI_IZUMI, // Great Fairy Fountain (magic, double magic, double defense)
|
||||||
|
/* 0x7FFF */ ENTR_RETURN_GROTTO // Grottos and normal Fairy Fountain
|
||||||
|
} ReturnEntranceIndex;
|
||||||
|
|
||||||
|
#undef DEFINE_ENTRANCE
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
/* 0 */ SDC_DEFAULT,
|
/* 0 */ SDC_DEFAULT,
|
||||||
/* 1 */ SDC_HYRULE_FIELD,
|
/* 1 */ SDC_HYRULE_FIELD,
|
||||||
|
@ -50,11 +50,16 @@ typedef struct {
|
|||||||
/* 0x004 */ Color_RGBA8_u32 envColor;
|
/* 0x004 */ Color_RGBA8_u32 envColor;
|
||||||
/* 0x008 */ s32 texX;
|
/* 0x008 */ s32 texX;
|
||||||
/* 0x00C */ s32 texY;
|
/* 0x00C */ s32 texY;
|
||||||
/* 0x010 */ s32 step;
|
// /* 0x010 */ s32 step;
|
||||||
/* 0x014 */ u8 unk_14;
|
// /* 0x014 */ u8 unk_14;
|
||||||
/* 0x015 */ u8 typeColor;
|
// /* 0x015 */ u8 typeColor;
|
||||||
/* 0x016 */ u8 speed;
|
// /* 0x016 */ u8 speed;
|
||||||
/* 0x017 */ u8 effect;
|
// /* 0x017 */ u8 effect;
|
||||||
|
/* 0x010 */ s32 speed;
|
||||||
|
/* 0x014 */ u8 direction;
|
||||||
|
/* 0x015 */ u8 colorType;
|
||||||
|
/* 0x016 */ u8 speedType;
|
||||||
|
/* 0x017 */ u8 appearanceType;
|
||||||
/* 0x018 */ u8 isDone;
|
/* 0x018 */ u8 isDone;
|
||||||
/* 0x019 */ u8 frame;
|
/* 0x019 */ u8 frame;
|
||||||
/* 0x01A */ u16 normal;
|
/* 0x01A */ u16 normal;
|
||||||
|
@ -33,5 +33,10 @@
|
|||||||
<string>public.app-category.games</string>
|
<string>public.app-category.games</string>
|
||||||
<key>LSMinimumSystemVersion</key>
|
<key>LSMinimumSystemVersion</key>
|
||||||
<string>10.15</string>
|
<string>10.15</string>
|
||||||
|
<key>LSArchitecturePriority</key>
|
||||||
|
<array>
|
||||||
|
<string>arm64</string>
|
||||||
|
<string>x86_64</string>
|
||||||
|
</array>
|
||||||
</dict>
|
</dict>
|
||||||
</plist>
|
</plist>
|
||||||
|
@ -14,11 +14,6 @@ if [ ! -e "$SHIP_HOME"/mods ]; then
|
|||||||
touch "$SHIP_HOME"/mods/custom_otr_files_go_here.txt
|
touch "$SHIP_HOME"/mods/custom_otr_files_go_here.txt
|
||||||
fi
|
fi
|
||||||
|
|
||||||
arch_name="$(uname -m)"
|
"$RESPATH"/soh-macos
|
||||||
launch_arch="arm64"
|
|
||||||
if [ "${arch_name}" = "x86_64" ] && [ "$(sysctl -in sysctl.proc_translated)" != "1" ]; then
|
|
||||||
launch_arch="x86_64"
|
|
||||||
fi
|
|
||||||
|
|
||||||
arch -${launch_arch} "$RESPATH"/soh-macos
|
|
||||||
exit
|
exit
|
||||||
|
@ -74,7 +74,7 @@ static std::unordered_map<u16, const char*> actorDescriptions = {
|
|||||||
{ ACTOR_EN_BUBBLE, "Shabom" },
|
{ ACTOR_EN_BUBBLE, "Shabom" },
|
||||||
{ ACTOR_DOOR_SHUTTER, "Shutter Door" },
|
{ ACTOR_DOOR_SHUTTER, "Shutter Door" },
|
||||||
{ ACTOR_EN_DODOJR, "Baby Dodongo" },
|
{ ACTOR_EN_DODOJR, "Baby Dodongo" },
|
||||||
{ ACTOR_EN_BDFIRE, "Empty" },
|
{ ACTOR_EN_BDFIRE, "King Dodongo's Fire Breath" },
|
||||||
{ ACTOR_EN_BOOM, "Boomerang" },
|
{ ACTOR_EN_BOOM, "Boomerang" },
|
||||||
{ ACTOR_EN_TORCH2, "Dark Link" },
|
{ ACTOR_EN_TORCH2, "Dark Link" },
|
||||||
{ ACTOR_EN_BILI, "Biri" },
|
{ ACTOR_EN_BILI, "Biri" },
|
||||||
@ -132,7 +132,7 @@ static std::unordered_map<u16, const char*> actorDescriptions = {
|
|||||||
{ ACTOR_BG_TOKI_HIKARI, "Windows (Temple of Time)" },
|
{ ACTOR_BG_TOKI_HIKARI, "Windows (Temple of Time)" },
|
||||||
{ ACTOR_EN_YUKABYUN, "Flying Floor Tile" },
|
{ ACTOR_EN_YUKABYUN, "Flying Floor Tile" },
|
||||||
{ ACTOR_BG_TOKI_SWD, "Master Sword" },
|
{ ACTOR_BG_TOKI_SWD, "Master Sword" },
|
||||||
{ ACTOR_EN_FHG_FIRE, "Empty" },
|
{ ACTOR_EN_FHG_FIRE, "Phantom Ganon's Lighting Attack" },
|
||||||
{ ACTOR_BG_MJIN, "Warp Song Pad" },
|
{ ACTOR_BG_MJIN, "Warp Song Pad" },
|
||||||
{ ACTOR_BG_HIDAN_KOUSI, "Sliding Metal Gate" },
|
{ ACTOR_BG_HIDAN_KOUSI, "Sliding Metal Gate" },
|
||||||
{ ACTOR_DOOR_TOKI, "Door of Time Collision" },
|
{ ACTOR_DOOR_TOKI, "Door of Time Collision" },
|
||||||
@ -548,6 +548,10 @@ int ActorDB::RetrieveId(const std::string& name) {
|
|||||||
return entry->second;
|
return entry->second;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int ActorDB::GetEntryCount() {
|
||||||
|
return db.size();
|
||||||
|
}
|
||||||
|
|
||||||
ActorDB::Entry::Entry() {
|
ActorDB::Entry::Entry() {
|
||||||
entry.name = nullptr;
|
entry.name = nullptr;
|
||||||
entry.desc = nullptr;
|
entry.desc = nullptr;
|
||||||
|
@ -64,6 +64,7 @@ public:
|
|||||||
|
|
||||||
static void AddBuiltInCustomActors();
|
static void AddBuiltInCustomActors();
|
||||||
|
|
||||||
|
int GetEntryCount();
|
||||||
private:
|
private:
|
||||||
Entry& AddEntry(const std::string& name, const std::string& desc, size_t index);
|
Entry& AddEntry(const std::string& name, const std::string& desc, size_t index);
|
||||||
Entry& AddEntry(const std::string& name, const std::string& desc, const ActorInit& init);
|
Entry& AddEntry(const std::string& name, const std::string& desc, const ActorInit& init);
|
||||||
|
@ -2,9 +2,10 @@
|
|||||||
#include "sequence.h"
|
#include "sequence.h"
|
||||||
#include "sfx.h"
|
#include "sfx.h"
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <Utils/StringHelper.h>
|
#include <utils/StringHelper.h>
|
||||||
#include <libultraship/bridge.h>
|
#include <libultraship/bridge.h>
|
||||||
#include <libultraship/classes.h>
|
#include <libultraship/classes.h>
|
||||||
|
#include <soh/OTRGlobals.h>
|
||||||
#include <locale>
|
#include <locale>
|
||||||
#include <filesystem>
|
#include <filesystem>
|
||||||
|
|
||||||
@ -330,11 +331,13 @@ AudioCollection::AudioCollection() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
std::string AudioCollection::GetCvarKey(std::string sfxKey) {
|
std::string AudioCollection::GetCvarKey(std::string sfxKey) {
|
||||||
return "gAudioEditor.ReplacedSequences." + sfxKey + ".value";
|
auto prefix = CVAR_AUDIO("ReplacedSequences.");
|
||||||
|
return prefix + sfxKey + ".value";
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string AudioCollection::GetCvarLockKey(std::string sfxKey) {
|
std::string AudioCollection::GetCvarLockKey(std::string sfxKey) {
|
||||||
return "gAudioEditor.ReplacedSequences." + sfxKey + ".locked";
|
auto prefix = std::string(CVAR_AUDIO("ReplacedSequences."));
|
||||||
|
return prefix + sfxKey + ".locked";
|
||||||
}
|
}
|
||||||
|
|
||||||
void AudioCollection::AddToCollection(char* otrPath, uint16_t seqNum) {
|
void AudioCollection::AddToCollection(char* otrPath, uint16_t seqNum) {
|
||||||
@ -362,7 +365,7 @@ uint16_t AudioCollection::GetReplacementSequence(uint16_t seqId) {
|
|||||||
// for Hyrule Field instead. Otherwise, leave it alone, so that without any sfx editor modifications we will
|
// for Hyrule Field instead. Otherwise, leave it alone, so that without any sfx editor modifications we will
|
||||||
// play the normal track as usual.
|
// play the normal track as usual.
|
||||||
if (seqId == NA_BGM_FIELD_MORNING) {
|
if (seqId == NA_BGM_FIELD_MORNING) {
|
||||||
if (CVarGetInteger("gAudioEditor.ReplacedSequences.NA_BGM_FIELD_LOGIC.value", NA_BGM_FIELD_LOGIC) != NA_BGM_FIELD_LOGIC) {
|
if (CVarGetInteger(CVAR_AUDIO("ReplacedSequences.NA_BGM_FIELD_LOGIC.value"), NA_BGM_FIELD_LOGIC) != NA_BGM_FIELD_LOGIC) {
|
||||||
seqId = NA_BGM_FIELD_LOGIC;
|
seqId = NA_BGM_FIELD_LOGIC;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -381,19 +384,19 @@ uint16_t AudioCollection::GetReplacementSequence(uint16_t seqId) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void AudioCollection::RemoveFromShufflePool(SequenceInfo* seqInfo) {
|
void AudioCollection::RemoveFromShufflePool(SequenceInfo* seqInfo) {
|
||||||
const std::string cvarKey = "gAudioEditor.Excluded." + seqInfo->sfxKey;
|
const std::string cvarKey = std::string(CVAR_AUDIO("Excluded.")) + seqInfo->sfxKey;
|
||||||
excludedSequences.insert(seqInfo);
|
excludedSequences.insert(seqInfo);
|
||||||
includedSequences.erase(seqInfo);
|
includedSequences.erase(seqInfo);
|
||||||
CVarSetInteger(cvarKey.c_str(), 1);
|
CVarSetInteger(cvarKey.c_str(), 1);
|
||||||
LUS::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesOnNextTick();
|
Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesOnNextTick();
|
||||||
}
|
}
|
||||||
|
|
||||||
void AudioCollection::AddToShufflePool(SequenceInfo* seqInfo) {
|
void AudioCollection::AddToShufflePool(SequenceInfo* seqInfo) {
|
||||||
const std::string cvarKey = "gAudioEditor.Excluded." + seqInfo->sfxKey;
|
const std::string cvarKey = std::string(CVAR_AUDIO("Excluded.")) + seqInfo->sfxKey;
|
||||||
includedSequences.insert(seqInfo);
|
includedSequences.insert(seqInfo);
|
||||||
excludedSequences.erase(seqInfo);
|
excludedSequences.erase(seqInfo);
|
||||||
CVarClear(cvarKey.c_str());
|
CVarClear(cvarKey.c_str());
|
||||||
LUS::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesOnNextTick();
|
Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesOnNextTick();
|
||||||
}
|
}
|
||||||
|
|
||||||
void AudioCollection::InitializeShufflePool() {
|
void AudioCollection::InitializeShufflePool() {
|
||||||
@ -401,7 +404,7 @@ void AudioCollection::InitializeShufflePool() {
|
|||||||
|
|
||||||
for (auto& [seqId, seqInfo] : sequenceMap) {
|
for (auto& [seqId, seqInfo] : sequenceMap) {
|
||||||
if (!seqInfo.canBeUsedAsReplacement) continue;
|
if (!seqInfo.canBeUsedAsReplacement) continue;
|
||||||
const std::string cvarKey = "gAudioEditor.Excluded." + seqInfo.sfxKey;
|
const std::string cvarKey = std::string(CVAR_AUDIO("Excluded.")) + seqInfo.sfxKey;
|
||||||
if (CVarGetInteger(cvarKey.c_str(), 0)) {
|
if (CVarGetInteger(cvarKey.c_str(), 0)) {
|
||||||
excludedSequences.insert(&seqInfo);
|
excludedSequences.insert(&seqInfo);
|
||||||
} else {
|
} else {
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
#pragma once
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
#include <map>
|
#include <map>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
@ -9,9 +9,10 @@
|
|||||||
#include <functions.h>
|
#include <functions.h>
|
||||||
#include "../randomizer/3drando/random.hpp"
|
#include "../randomizer/3drando/random.hpp"
|
||||||
#include "../../OTRGlobals.h"
|
#include "../../OTRGlobals.h"
|
||||||
#include <Utils/StringHelper.h>
|
#include <utils/StringHelper.h>
|
||||||
#include "../../UIWidgets.hpp"
|
#include "../../UIWidgets.hpp"
|
||||||
#include "AudioCollection.h"
|
#include "AudioCollection.h"
|
||||||
|
#include "soh/Enhancements/game-interactor/GameInteractor.h"
|
||||||
|
|
||||||
Vec3f pos = { 0.0f, 0.0f, 0.0f };
|
Vec3f pos = { 0.0f, 0.0f, 0.0f };
|
||||||
f32 freqScale = 1.0f;
|
f32 freqScale = 1.0f;
|
||||||
@ -79,6 +80,11 @@ void UpdateCurrentBGM(u16 seqKey, SeqType seqType) {
|
|||||||
void RandomizeGroup(SeqType type) {
|
void RandomizeGroup(SeqType type) {
|
||||||
std::vector<u16> values;
|
std::vector<u16> values;
|
||||||
|
|
||||||
|
// An empty IncludedSequences set means that the AudioEditor window has never been drawn
|
||||||
|
if (AudioCollection::Instance->GetIncludedSequences().empty()) {
|
||||||
|
AudioCollection::Instance->InitializeShufflePool();
|
||||||
|
}
|
||||||
|
|
||||||
// use a while loop to add duplicates if we don't have enough included sequences
|
// use a while loop to add duplicates if we don't have enough included sequences
|
||||||
while (values.size() < AuthenticCountBySequenceType(type)) {
|
while (values.size() < AuthenticCountBySequenceType(type)) {
|
||||||
for (const auto& seqData : AudioCollection::Instance->GetIncludedSequences()) {
|
for (const auto& seqData : AudioCollection::Instance->GetIncludedSequences()) {
|
||||||
@ -123,23 +129,51 @@ void ResetGroup(const std::map<u16, SequenceInfo>& map, SeqType type) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void LockGroup(const std::map<u16, SequenceInfo>& map, SeqType type) {
|
||||||
|
for (const auto& [defaultValue, seqData] : map) {
|
||||||
|
if (seqData.category == type) {
|
||||||
|
// Only save authentic sequence CVars
|
||||||
|
if (seqData.category == SEQ_FANFARE && defaultValue >= MAX_AUTHENTIC_SEQID) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
const std::string cvarKey = AudioCollection::Instance->GetCvarKey(seqData.sfxKey);
|
||||||
|
const std::string cvarLockKey = AudioCollection::Instance->GetCvarLockKey(seqData.sfxKey);
|
||||||
|
CVarSetInteger(cvarLockKey.c_str(), 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void UnlockGroup(const std::map<u16, SequenceInfo>& map, SeqType type) {
|
||||||
|
for (const auto& [defaultValue, seqData] : map) {
|
||||||
|
if (seqData.category == type) {
|
||||||
|
// Only save authentic sequence CVars
|
||||||
|
if (seqData.category == SEQ_FANFARE && defaultValue >= MAX_AUTHENTIC_SEQID) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
const std::string cvarKey = AudioCollection::Instance->GetCvarKey(seqData.sfxKey);
|
||||||
|
const std::string cvarLockKey = AudioCollection::Instance->GetCvarLockKey(seqData.sfxKey);
|
||||||
|
CVarSetInteger(cvarLockKey.c_str(), 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void DrawPreviewButton(uint16_t sequenceId, std::string sfxKey, SeqType sequenceType) {
|
void DrawPreviewButton(uint16_t sequenceId, std::string sfxKey, SeqType sequenceType) {
|
||||||
const std::string cvarKey = AudioCollection::Instance->GetCvarKey(sfxKey);
|
const std::string cvarKey = AudioCollection::Instance->GetCvarKey(sfxKey);
|
||||||
const std::string hiddenKey = "##" + cvarKey;
|
const std::string hiddenKey = "##" + cvarKey;
|
||||||
const std::string stopButton = ICON_FA_STOP + hiddenKey;
|
const std::string stopButton = ICON_FA_STOP + hiddenKey;
|
||||||
const std::string previewButton = ICON_FA_PLAY + hiddenKey;
|
const std::string previewButton = ICON_FA_PLAY + hiddenKey;
|
||||||
|
|
||||||
if (CVarGetInteger("gAudioEditor.Playing", 0) == sequenceId) {
|
if (CVarGetInteger(CVAR_AUDIO("Playing"), 0) == sequenceId) {
|
||||||
if (ImGui::Button(stopButton.c_str())) {
|
if (ImGui::Button(stopButton.c_str())) {
|
||||||
func_800F5C2C();
|
func_800F5C2C();
|
||||||
CVarSetInteger("gAudioEditor.Playing", 0);
|
CVarSetInteger(CVAR_AUDIO("Playing"), 0);
|
||||||
}
|
}
|
||||||
UIWidgets::Tooltip("Stop Preview");
|
UIWidgets::Tooltip("Stop Preview");
|
||||||
} else {
|
} else {
|
||||||
if (ImGui::Button(previewButton.c_str())) {
|
if (ImGui::Button(previewButton.c_str())) {
|
||||||
if (CVarGetInteger("gAudioEditor.Playing", 0) != 0) {
|
if (CVarGetInteger(CVAR_AUDIO("Playing"), 0) != 0) {
|
||||||
func_800F5C2C();
|
func_800F5C2C();
|
||||||
CVarSetInteger("gAudioEditor.Playing", 0);
|
CVarSetInteger(CVAR_AUDIO("Playing"), 0);
|
||||||
} else {
|
} else {
|
||||||
if (sequenceType == SEQ_SFX || sequenceType == SEQ_VOICE) {
|
if (sequenceType == SEQ_SFX || sequenceType == SEQ_VOICE) {
|
||||||
Audio_PlaySoundGeneral(sequenceId, &pos, 4, &freqScale, &freqScale, &reverbAdd);
|
Audio_PlaySoundGeneral(sequenceId, &pos, 4, &freqScale, &freqScale, &reverbAdd);
|
||||||
@ -149,7 +183,7 @@ void DrawPreviewButton(uint16_t sequenceId, std::string sfxKey, SeqType sequence
|
|||||||
} else {
|
} else {
|
||||||
// TODO: Cant do both here, so have to click preview button twice
|
// TODO: Cant do both here, so have to click preview button twice
|
||||||
PreviewSequence(sequenceId);
|
PreviewSequence(sequenceId);
|
||||||
CVarSetInteger("gAudioEditor.Playing", sequenceId);
|
CVarSetInteger(CVAR_AUDIO("Playing"), sequenceId);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -163,11 +197,13 @@ void Draw_SfxTab(const std::string& tabId, SeqType type) {
|
|||||||
const std::string hiddenTabId = "##" + tabId;
|
const std::string hiddenTabId = "##" + tabId;
|
||||||
const std::string resetAllButton = "Reset All" + hiddenTabId;
|
const std::string resetAllButton = "Reset All" + hiddenTabId;
|
||||||
const std::string randomizeAllButton = "Randomize All" + hiddenTabId;
|
const std::string randomizeAllButton = "Randomize All" + hiddenTabId;
|
||||||
|
const std::string lockAllButton = "Lock All" + hiddenTabId;
|
||||||
|
const std::string unlockAllButton = "Unlock All" + hiddenTabId;
|
||||||
if (ImGui::Button(resetAllButton.c_str())) {
|
if (ImGui::Button(resetAllButton.c_str())) {
|
||||||
auto currentBGM = func_800FA0B4(SEQ_PLAYER_BGM_MAIN);
|
auto currentBGM = func_800FA0B4(SEQ_PLAYER_BGM_MAIN);
|
||||||
auto prevReplacement = AudioCollection::Instance->GetReplacementSequence(currentBGM);
|
auto prevReplacement = AudioCollection::Instance->GetReplacementSequence(currentBGM);
|
||||||
ResetGroup(map, type);
|
ResetGroup(map, type);
|
||||||
LUS::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesOnNextTick();
|
Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesOnNextTick();
|
||||||
auto curReplacement = AudioCollection::Instance->GetReplacementSequence(currentBGM);
|
auto curReplacement = AudioCollection::Instance->GetReplacementSequence(currentBGM);
|
||||||
if (type == SEQ_BGM_WORLD && prevReplacement != curReplacement) {
|
if (type == SEQ_BGM_WORLD && prevReplacement != curReplacement) {
|
||||||
ReplayCurrentBGM();
|
ReplayCurrentBGM();
|
||||||
@ -178,7 +214,29 @@ void Draw_SfxTab(const std::string& tabId, SeqType type) {
|
|||||||
auto currentBGM = func_800FA0B4(SEQ_PLAYER_BGM_MAIN);
|
auto currentBGM = func_800FA0B4(SEQ_PLAYER_BGM_MAIN);
|
||||||
auto prevReplacement = AudioCollection::Instance->GetReplacementSequence(currentBGM);
|
auto prevReplacement = AudioCollection::Instance->GetReplacementSequence(currentBGM);
|
||||||
RandomizeGroup(type);
|
RandomizeGroup(type);
|
||||||
LUS::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesOnNextTick();
|
Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesOnNextTick();
|
||||||
|
auto curReplacement = AudioCollection::Instance->GetReplacementSequence(currentBGM);
|
||||||
|
if (type == SEQ_BGM_WORLD && prevReplacement != curReplacement) {
|
||||||
|
ReplayCurrentBGM();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ImGui::SameLine();
|
||||||
|
if (ImGui::Button(lockAllButton.c_str())) {
|
||||||
|
auto currentBGM = func_800FA0B4(SEQ_PLAYER_BGM_MAIN);
|
||||||
|
auto prevReplacement = AudioCollection::Instance->GetReplacementSequence(currentBGM);
|
||||||
|
LockGroup(map, type);
|
||||||
|
Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesOnNextTick();
|
||||||
|
auto curReplacement = AudioCollection::Instance->GetReplacementSequence(currentBGM);
|
||||||
|
if (type == SEQ_BGM_WORLD && prevReplacement != curReplacement) {
|
||||||
|
ReplayCurrentBGM();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ImGui::SameLine();
|
||||||
|
if (ImGui::Button(unlockAllButton.c_str())) {
|
||||||
|
auto currentBGM = func_800FA0B4(SEQ_PLAYER_BGM_MAIN);
|
||||||
|
auto prevReplacement = AudioCollection::Instance->GetReplacementSequence(currentBGM);
|
||||||
|
UnlockGroup(map, type);
|
||||||
|
Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesOnNextTick();
|
||||||
auto curReplacement = AudioCollection::Instance->GetReplacementSequence(currentBGM);
|
auto curReplacement = AudioCollection::Instance->GetReplacementSequence(currentBGM);
|
||||||
if (type == SEQ_BGM_WORLD && prevReplacement != curReplacement) {
|
if (type == SEQ_BGM_WORLD && prevReplacement != curReplacement) {
|
||||||
ReplayCurrentBGM();
|
ReplayCurrentBGM();
|
||||||
@ -223,7 +281,7 @@ void Draw_SfxTab(const std::string& tabId, SeqType type) {
|
|||||||
|
|
||||||
if (ImGui::Selectable(seqData.label.c_str())) {
|
if (ImGui::Selectable(seqData.label.c_str())) {
|
||||||
CVarSetInteger(cvarKey.c_str(), value);
|
CVarSetInteger(cvarKey.c_str(), value);
|
||||||
LUS::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesOnNextTick();
|
Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesOnNextTick();
|
||||||
UpdateCurrentBGM(defaultValue, type);
|
UpdateCurrentBGM(defaultValue, type);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -243,7 +301,7 @@ void Draw_SfxTab(const std::string& tabId, SeqType type) {
|
|||||||
if (ImGui::Button(resetButton.c_str())) {
|
if (ImGui::Button(resetButton.c_str())) {
|
||||||
CVarClear(cvarKey.c_str());
|
CVarClear(cvarKey.c_str());
|
||||||
CVarClear(cvarLockKey.c_str());
|
CVarClear(cvarLockKey.c_str());
|
||||||
LUS::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesOnNextTick();
|
Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesOnNextTick();
|
||||||
UpdateCurrentBGM(defaultValue, seqData.category);
|
UpdateCurrentBGM(defaultValue, seqData.category);
|
||||||
}
|
}
|
||||||
UIWidgets::Tooltip("Reset to default");
|
UIWidgets::Tooltip("Reset to default");
|
||||||
@ -264,7 +322,7 @@ void Draw_SfxTab(const std::string& tabId, SeqType type) {
|
|||||||
if (locked) {
|
if (locked) {
|
||||||
CVarClear(cvarLockKey.c_str());
|
CVarClear(cvarLockKey.c_str());
|
||||||
}
|
}
|
||||||
LUS::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesOnNextTick();
|
Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesOnNextTick();
|
||||||
UpdateCurrentBGM(defaultValue, type);
|
UpdateCurrentBGM(defaultValue, type);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -277,7 +335,7 @@ void Draw_SfxTab(const std::string& tabId, SeqType type) {
|
|||||||
} else {
|
} else {
|
||||||
CVarSetInteger(cvarLockKey.c_str(), 1);
|
CVarSetInteger(cvarLockKey.c_str(), 1);
|
||||||
}
|
}
|
||||||
LUS::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesOnNextTick();
|
Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesOnNextTick();
|
||||||
}
|
}
|
||||||
UIWidgets::Tooltip(locked ? "Sound locked" : "Sound unlocked");
|
UIWidgets::Tooltip(locked ? "Sound locked" : "Sound unlocked");
|
||||||
}
|
}
|
||||||
@ -350,6 +408,19 @@ void DrawTypeChip(SeqType type) {
|
|||||||
ImGui::EndDisabled();
|
ImGui::EndDisabled();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void AudioEditorRegisterOnSceneInitHook() {
|
||||||
|
GameInteractor::Instance->RegisterGameHook<GameInteractor::OnSceneInit>([](int16_t sceneNum) {
|
||||||
|
if (CVarGetInteger(CVAR_AUDIO("RandomizeAllOnNewScene"), 0)) {
|
||||||
|
AudioEditor_RandomizeAll();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
void AudioEditor::InitElement() {
|
||||||
|
AudioEditorRegisterOnSceneInitHook();
|
||||||
|
}
|
||||||
|
|
||||||
void AudioEditor::DrawElement() {
|
void AudioEditor::DrawElement() {
|
||||||
AudioCollection::Instance->InitializeShufflePool();
|
AudioCollection::Instance->InitializeShufflePool();
|
||||||
|
|
||||||
@ -359,6 +430,28 @@ void AudioEditor::DrawElement() {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
float buttonSegments = ImGui::GetContentRegionAvail().x / 4;
|
||||||
|
if (ImGui::Button("Randomize All Groups", ImVec2(buttonSegments, 30.0f))) {
|
||||||
|
AudioEditor_RandomizeAll();
|
||||||
|
}
|
||||||
|
UIWidgets::Tooltip("Randomizes all unlocked music and sound effects across tab groups");
|
||||||
|
ImGui::SameLine();
|
||||||
|
if (ImGui::Button("Reset All Groups", ImVec2(buttonSegments, 30.0f))) {
|
||||||
|
AudioEditor_ResetAll();
|
||||||
|
}
|
||||||
|
UIWidgets::Tooltip("Resets all unlocked music and sound effects across tab groups");
|
||||||
|
ImGui::SameLine();
|
||||||
|
if (ImGui::Button("Lock All Groups", ImVec2(buttonSegments, 30.0f))) {
|
||||||
|
AudioEditor_LockAll();
|
||||||
|
}
|
||||||
|
UIWidgets::Tooltip("Locks all music and sound effects across tab groups");
|
||||||
|
ImGui::SameLine();
|
||||||
|
if (ImGui::Button("Unlock All Groups", ImVec2(buttonSegments, 30.0f))) {
|
||||||
|
AudioEditor_UnlockAll();
|
||||||
|
}
|
||||||
|
UIWidgets::Tooltip("Unlocks all music and sound effects across tab groups");
|
||||||
|
|
||||||
|
|
||||||
if (ImGui::BeginTabBar("SfxContextTabBar", ImGuiTabBarFlags_NoCloseWithMiddleMouseButton)) {
|
if (ImGui::BeginTabBar("SfxContextTabBar", ImGuiTabBarFlags_NoCloseWithMiddleMouseButton)) {
|
||||||
if (ImGui::BeginTabItem("Background Music")) {
|
if (ImGui::BeginTabItem("Background Music")) {
|
||||||
Draw_SfxTab("backgroundMusic", SEQ_BGM_WORLD);
|
Draw_SfxTab("backgroundMusic", SEQ_BGM_WORLD);
|
||||||
@ -399,18 +492,18 @@ void AudioEditor::DrawElement() {
|
|||||||
ImGui::TableNextColumn();
|
ImGui::TableNextColumn();
|
||||||
if (ImGui::BeginChild("SfxOptions", ImVec2(0, -8))) {
|
if (ImGui::BeginChild("SfxOptions", ImVec2(0, -8))) {
|
||||||
ImGui::PushItemWidth(-FLT_MIN);
|
ImGui::PushItemWidth(-FLT_MIN);
|
||||||
UIWidgets::EnhancementCheckbox("Disable Enemy Proximity Music", "gEnemyBGMDisable");
|
UIWidgets::EnhancementCheckbox("Disable Enemy Proximity Music", CVAR_AUDIO("EnemyBGMDisable"));
|
||||||
UIWidgets::InsertHelpHoverText(
|
UIWidgets::InsertHelpHoverText(
|
||||||
"Disables the music change when getting close to enemies. Useful for hearing "
|
"Disables the music change when getting close to enemies. Useful for hearing "
|
||||||
"your custom music for each scene more often.");
|
"your custom music for each scene more often.");
|
||||||
UIWidgets::EnhancementCheckbox("Disable Leading Music in Lost Woods", "gLostWoodsConsistentVolume");
|
UIWidgets::EnhancementCheckbox("Disable Leading Music in Lost Woods", CVAR_AUDIO("LostWoodsConsistentVolume"));
|
||||||
UIWidgets::InsertHelpHoverText(
|
UIWidgets::InsertHelpHoverText(
|
||||||
"Disables the volume shifting in the Lost Woods. Useful for hearing "
|
"Disables the volume shifting in the Lost Woods. Useful for hearing "
|
||||||
"your custom music in the Lost Woods if you don't need the navigation assitance "
|
"your custom music in the Lost Woods if you don't need the navigation assitance "
|
||||||
"the volume changing provides. If toggling this while in the Lost Woods, reload "
|
"the volume changing provides. If toggling this while in the Lost Woods, reload "
|
||||||
"the area for the effect to kick in."
|
"the area for the effect to kick in."
|
||||||
);
|
);
|
||||||
UIWidgets::EnhancementCheckbox("Display Sequence Name on Overlay", "gSeqNameOverlay");
|
UIWidgets::EnhancementCheckbox("Display Sequence Name on Overlay", CVAR_AUDIO("SeqNameOverlay"));
|
||||||
UIWidgets::InsertHelpHoverText(
|
UIWidgets::InsertHelpHoverText(
|
||||||
"Displays the name of the current sequence in the corner of the screen whenever a new sequence "
|
"Displays the name of the current sequence in the corner of the screen whenever a new sequence "
|
||||||
"is loaded to the main sequence player (does not apply to fanfares or enemy BGM)."
|
"is loaded to the main sequence player (does not apply to fanfares or enemy BGM)."
|
||||||
@ -418,24 +511,28 @@ void AudioEditor::DrawElement() {
|
|||||||
ImGui::SameLine();
|
ImGui::SameLine();
|
||||||
ImGui::PushItemWidth(ImGui::GetContentRegionAvail().x);
|
ImGui::PushItemWidth(ImGui::GetContentRegionAvail().x);
|
||||||
UIWidgets::EnhancementSliderInt("Overlay Duration: %d seconds", "##SeqNameOverlayDuration",
|
UIWidgets::EnhancementSliderInt("Overlay Duration: %d seconds", "##SeqNameOverlayDuration",
|
||||||
"gSeqNameOverlayDuration", 1, 10, "", 5);
|
CVAR_AUDIO("SeqNameOverlayDuration"), 1, 10, "", 5);
|
||||||
ImGui::PopItemWidth();
|
ImGui::PopItemWidth();
|
||||||
ImGui::NewLine();
|
ImGui::NewLine();
|
||||||
ImGui::PopItemWidth();
|
ImGui::PopItemWidth();
|
||||||
UIWidgets::EnhancementSliderFloat("Link's voice pitch multiplier: %f", "##linkVoiceFreqMultiplier",
|
UIWidgets::EnhancementSliderFloat("Link's voice pitch multiplier: %.1f %%", "##linkVoiceFreqMultiplier",
|
||||||
"gLinkVoiceFreqMultiplier", 0.4, 2.5, "", 1.0, false, false);
|
CVAR_AUDIO("LinkVoiceFreqMultiplier"), 0.4, 2.5, "", 1.0, true, true);
|
||||||
ImGui::SameLine();
|
ImGui::SameLine();
|
||||||
const std::string resetButton = "Reset##linkVoiceFreqMultiplier";
|
const std::string resetButton = "Reset##linkVoiceFreqMultiplier";
|
||||||
if (ImGui::Button(resetButton.c_str())) {
|
if (ImGui::Button(resetButton.c_str())) {
|
||||||
CVarSetFloat("gLinkVoiceFreqMultiplier", 1.0f);
|
CVarSetFloat(CVAR_AUDIO("LinkVoiceFreqMultiplier"), 1.0f);
|
||||||
LUS::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesOnNextTick();
|
Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesOnNextTick();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ImGui::NewLine();
|
||||||
|
UIWidgets::EnhancementCheckbox("Randomize All Music and Sound Effects on New Scene", CVAR_AUDIO("RandomizeAllOnNewScene"));
|
||||||
|
UIWidgets::Tooltip("Enables randomizing all unlocked music and sound effects when you enter a new scene.");
|
||||||
|
|
||||||
ImGui::NewLine();
|
ImGui::NewLine();
|
||||||
ImGui::PushItemWidth(-FLT_MIN);
|
ImGui::PushItemWidth(-FLT_MIN);
|
||||||
UIWidgets::PaddedSeparator();
|
UIWidgets::PaddedSeparator();
|
||||||
UIWidgets::PaddedText("The following options are experimental and may cause music\nto sound odd or have other undesireable effects.");
|
UIWidgets::PaddedText("The following options are experimental and may cause music\nto sound odd or have other undesireable effects.");
|
||||||
UIWidgets::EnhancementCheckbox("Lower Octaves of Unplayable High Notes", "gExperimentalOctaveDrop");
|
UIWidgets::EnhancementCheckbox("Lower Octaves of Unplayable High Notes", CVAR_AUDIO("ExperimentalOctaveDrop"));
|
||||||
UIWidgets::InsertHelpHoverText("Some custom sequences may have notes that are too high for the game's audio "
|
UIWidgets::InsertHelpHoverText("Some custom sequences may have notes that are too high for the game's audio "
|
||||||
"engine to play. Enabling this checkbox will cause these notes to drop a "
|
"engine to play. Enabling this checkbox will cause these notes to drop a "
|
||||||
"couple of octaves so they can still harmonize with the other notes of the "
|
"couple of octaves so they can still harmonize with the other notes of the "
|
||||||
@ -613,7 +710,14 @@ void AudioEditor_RandomizeAll() {
|
|||||||
RandomizeGroup(type);
|
RandomizeGroup(type);
|
||||||
}
|
}
|
||||||
|
|
||||||
LUS::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesOnNextTick();
|
Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesOnNextTick();
|
||||||
|
ReplayCurrentBGM();
|
||||||
|
}
|
||||||
|
|
||||||
|
void AudioEditor_RandomizeGroup(SeqType group) {
|
||||||
|
RandomizeGroup(group);
|
||||||
|
|
||||||
|
Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesOnNextTick();
|
||||||
ReplayCurrentBGM();
|
ReplayCurrentBGM();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -622,6 +726,29 @@ void AudioEditor_ResetAll() {
|
|||||||
ResetGroup(AudioCollection::Instance->GetAllSequences(), type);
|
ResetGroup(AudioCollection::Instance->GetAllSequences(), type);
|
||||||
}
|
}
|
||||||
|
|
||||||
LUS::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesOnNextTick();
|
Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesOnNextTick();
|
||||||
ReplayCurrentBGM();
|
ReplayCurrentBGM();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void AudioEditor_ResetGroup(SeqType group) {
|
||||||
|
ResetGroup(AudioCollection::Instance->GetAllSequences(), group);
|
||||||
|
|
||||||
|
Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesOnNextTick();
|
||||||
|
ReplayCurrentBGM();
|
||||||
|
}
|
||||||
|
|
||||||
|
void AudioEditor_LockAll() {
|
||||||
|
for (auto type : allTypes) {
|
||||||
|
LockGroup(AudioCollection::Instance->GetAllSequences(), type);
|
||||||
|
}
|
||||||
|
|
||||||
|
Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesOnNextTick();
|
||||||
|
}
|
||||||
|
|
||||||
|
void AudioEditor_UnlockAll() {
|
||||||
|
for (auto type : allTypes) {
|
||||||
|
UnlockGroup(AudioCollection::Instance->GetAllSequences(), type);
|
||||||
|
}
|
||||||
|
|
||||||
|
Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesOnNextTick();
|
||||||
|
}
|
||||||
|
@ -4,20 +4,28 @@
|
|||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
|
|
||||||
#include <libultraship/libultraship.h>
|
#include <libultraship/libultraship.h>
|
||||||
#include <ImGui/imgui.h>
|
#ifndef IMGUI_DEFINE_MATH_OPERATORS
|
||||||
|
#define IMGUI_DEFINE_MATH_OPERATORS
|
||||||
|
#endif
|
||||||
|
#include <imgui.h>
|
||||||
|
#include "AudioCollection.h"
|
||||||
|
|
||||||
class AudioEditor : public LUS::GuiWindow {
|
class AudioEditor : public Ship::GuiWindow {
|
||||||
public:
|
public:
|
||||||
using LUS::GuiWindow::GuiWindow;
|
using GuiWindow::GuiWindow;
|
||||||
|
|
||||||
void DrawElement() override;
|
void DrawElement() override;
|
||||||
void InitElement() override {};
|
void InitElement() override;
|
||||||
void UpdateElement() override {};
|
void UpdateElement() override {};
|
||||||
~AudioEditor() {};
|
~AudioEditor() {};
|
||||||
};
|
};
|
||||||
|
|
||||||
void AudioEditor_RandomizeAll();
|
void AudioEditor_RandomizeAll();
|
||||||
|
void AudioEditor_RandomizeGroup(SeqType group);
|
||||||
void AudioEditor_ResetAll();
|
void AudioEditor_ResetAll();
|
||||||
|
void AudioEditor_ResetGroup(SeqType group);
|
||||||
|
void AudioEditor_LockAll();
|
||||||
|
void AudioEditor_UnlockAll();
|
||||||
|
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
@ -9,6 +9,7 @@
|
|||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
#include <z64.h>
|
#include <z64.h>
|
||||||
|
#include "soh/OTRGlobals.h"
|
||||||
|
|
||||||
uint8_t gLoadFileSelect = 0, gSkipLogoTest = 0;
|
uint8_t gLoadFileSelect = 0, gSkipLogoTest = 0;
|
||||||
|
|
||||||
@ -21,15 +22,15 @@ static BootCommand sCommands[] = { { "--skiplogo", BootCommands_Command_SkipLogo
|
|||||||
void BootCommands_Init()
|
void BootCommands_Init()
|
||||||
{
|
{
|
||||||
// Clears vars to prevent randomizer menu from being disabled
|
// Clears vars to prevent randomizer menu from being disabled
|
||||||
CVarClear("gRandoGenerating"); // Clear when a crash happened during rando seed generation
|
CVarClear(CVAR_GENERAL("RandoGenerating")); // Clear when a crash happened during rando seed generation
|
||||||
CVarClear("gNewSeedGenerated");
|
CVarClear(CVAR_GENERAL("NewSeedGenerated"));
|
||||||
CVarClear("gOnFileSelectNameEntry"); // Clear when soh is killed on the file name entry page
|
CVarClear(CVAR_GENERAL("OnFileSelectNameEntry")); // Clear when soh is killed on the file name entry page
|
||||||
CVarClear("gBetterDebugWarpScreenMQMode");
|
CVarClear(CVAR_GENERAL("BetterDebugWarpScreenMQMode"));
|
||||||
CVarClear("gBetterDebugWarpScreenMQModeScene");
|
CVarClear(CVAR_GENERAL("BetterDebugWarpScreenMQModeScene"));
|
||||||
CVarClear("gCheatEasyPauseBufferLastInputs");
|
CVarClear(CVAR_GENERAL("CheatEasyPauseBufferLastInputs"));
|
||||||
CVarClear("gCheatEasyPauseBufferTimer");
|
CVarClear(CVAR_GENERAL("CheatEasyPauseBufferTimer"));
|
||||||
#if defined(__SWITCH__) || defined(__WIIU__)
|
#if defined(__SWITCH__) || defined(__WIIU__)
|
||||||
CVarRegisterInteger("gControlNav", 1); // always enable controller nav on switch/wii u
|
CVarRegisterInteger(CVAR_IMGUI_CONTROLLER_NAV, 1); // always enable controller nav on switch/wii u
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -175,33 +175,33 @@ void BossRush_HandleBlueWarp(PlayState* play, f32 warpPosX, f32 warpPosZ) {
|
|||||||
// Gohma & Phantom Ganon
|
// Gohma & Phantom Ganon
|
||||||
if (warpPosX == -100 && warpPosZ == -170) {
|
if (warpPosX == -100 && warpPosZ == -170) {
|
||||||
if (gSaveContext.linkAge == LINK_AGE_CHILD) {
|
if (gSaveContext.linkAge == LINK_AGE_CHILD) {
|
||||||
play->nextEntranceIndex = 0x040F;
|
play->nextEntranceIndex = ENTR_DEKU_TREE_BOSS_0;
|
||||||
} else {
|
} else {
|
||||||
play->nextEntranceIndex = 0x000C;
|
play->nextEntranceIndex = ENTR_FOREST_TEMPLE_BOSS_0;
|
||||||
}
|
}
|
||||||
// King Dodongo & Volvagia
|
// King Dodongo & Volvagia
|
||||||
} else if (warpPosX == 100 && warpPosZ == -170) {
|
} else if (warpPosX == 100 && warpPosZ == -170) {
|
||||||
if (gSaveContext.linkAge == LINK_AGE_CHILD) {
|
if (gSaveContext.linkAge == LINK_AGE_CHILD) {
|
||||||
play->nextEntranceIndex = 0x040B;
|
play->nextEntranceIndex = ENTR_DODONGOS_CAVERN_BOSS_0;
|
||||||
} else {
|
} else {
|
||||||
play->nextEntranceIndex = 0x0305;
|
play->nextEntranceIndex = ENTR_FIRE_TEMPLE_BOSS_0;
|
||||||
}
|
}
|
||||||
// Barinade & Morb
|
// Barinade & Morb
|
||||||
} else if (warpPosX == 199 && warpPosZ == 0) {
|
} else if (warpPosX == 199 && warpPosZ == 0) {
|
||||||
if (gSaveContext.linkAge == LINK_AGE_CHILD) {
|
if (gSaveContext.linkAge == LINK_AGE_CHILD) {
|
||||||
play->nextEntranceIndex = 0x0301;
|
play->nextEntranceIndex = ENTR_JABU_JABU_BOSS_0;
|
||||||
} else {
|
} else {
|
||||||
play->nextEntranceIndex = 0x0417;
|
play->nextEntranceIndex = ENTR_WATER_TEMPLE_BOSS_0;
|
||||||
}
|
}
|
||||||
// Twinrova
|
// Twinrova
|
||||||
} else if (warpPosX == 100 && warpPosZ == 170) {
|
} else if (warpPosX == 100 && warpPosZ == 170) {
|
||||||
play->nextEntranceIndex = 0x05EC;
|
play->nextEntranceIndex = ENTR_SPIRIT_TEMPLE_BOSS_2;
|
||||||
// Bongo Bongo
|
// Bongo Bongo
|
||||||
} else if (warpPosX == -100 && warpPosZ == 170) {
|
} else if (warpPosX == -100 && warpPosZ == 170) {
|
||||||
play->nextEntranceIndex = 0x0413;
|
play->nextEntranceIndex = ENTR_SHADOW_TEMPLE_BOSS_0;
|
||||||
// Ganondork
|
// Ganondork
|
||||||
} else if (warpPosX == -199 && warpPosZ == 0) {
|
} else if (warpPosX == -199 && warpPosZ == 0) {
|
||||||
play->nextEntranceIndex = 0x041F;
|
play->nextEntranceIndex = ENTR_GANONDORF_BOSS_0;
|
||||||
}
|
}
|
||||||
// If coming from a boss room, teleport back to Chamber of Sages and set flag.
|
// If coming from a boss room, teleport back to Chamber of Sages and set flag.
|
||||||
} else {
|
} else {
|
||||||
@ -216,10 +216,10 @@ void BossRush_HandleBlueWarp(PlayState* play, f32 warpPosX, f32 warpPosZ) {
|
|||||||
BossRush_SetEquipment(LINK_AGE_ADULT);
|
BossRush_SetEquipment(LINK_AGE_ADULT);
|
||||||
// Warp to credits.
|
// Warp to credits.
|
||||||
} else if (gSaveContext.bossRushOptions[BR_OPTIONS_BOSSES] == BR_CHOICE_BOSSES_CHILD) {
|
} else if (gSaveContext.bossRushOptions[BR_OPTIONS_BOSSES] == BR_CHOICE_BOSSES_CHILD) {
|
||||||
play->nextEntranceIndex = 0x6B;
|
play->nextEntranceIndex = ENTR_CHAMBER_OF_THE_SAGES_0;
|
||||||
gSaveContext.nextCutsceneIndex = 0xFFF2;
|
gSaveContext.nextCutsceneIndex = 0xFFF2;
|
||||||
play->sceneLoadFlag = 0x14;
|
play->transitionTrigger = TRANS_TRIGGER_START;
|
||||||
play->fadeTransition = 3;
|
play->transitionType = TRANS_TYPE_FADE_WHITE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -293,7 +293,7 @@ void BossRush_InitSave() {
|
|||||||
|
|
||||||
gSaveContext.questId = QUEST_BOSSRUSH;
|
gSaveContext.questId = QUEST_BOSSRUSH;
|
||||||
gSaveContext.isBossRushPaused = 1;
|
gSaveContext.isBossRushPaused = 1;
|
||||||
gSaveContext.entranceIndex = 107;
|
gSaveContext.entranceIndex = ENTR_CHAMBER_OF_THE_SAGES_0;
|
||||||
gSaveContext.cutsceneIndex = 0x8000;
|
gSaveContext.cutsceneIndex = 0x8000;
|
||||||
gSaveContext.isMagicAcquired = 1;
|
gSaveContext.isMagicAcquired = 1;
|
||||||
|
|
||||||
|
@ -1,413 +0,0 @@
|
|||||||
#include "GameControlEditor.h"
|
|
||||||
|
|
||||||
#include <string>
|
|
||||||
#include <list>
|
|
||||||
#include <unordered_map>
|
|
||||||
#include <utility>
|
|
||||||
#include <iterator>
|
|
||||||
#include <variables.h>
|
|
||||||
|
|
||||||
#include <ImGui/imgui.h>
|
|
||||||
#include <ImGui/imgui_internal.h>
|
|
||||||
#include <libultraship/bridge.h>
|
|
||||||
#include <libultraship/libultra/controller.h>
|
|
||||||
#include <Utils/StringHelper.h>
|
|
||||||
#include <libultraship/libultraship.h>
|
|
||||||
|
|
||||||
#include "../../UIWidgets.hpp"
|
|
||||||
|
|
||||||
namespace GameControlEditor {
|
|
||||||
const ImGuiTableFlags PANEL_TABLE_FLAGS =
|
|
||||||
ImGuiTableFlags_BordersH |
|
|
||||||
ImGuiTableFlags_BordersV;
|
|
||||||
const ImGuiTableColumnFlags PANEL_TABLE_COLUMN_FLAGS =
|
|
||||||
ImGuiTableColumnFlags_IndentEnable |
|
|
||||||
ImGuiTableColumnFlags_NoSort;
|
|
||||||
|
|
||||||
namespace TableHelper {
|
|
||||||
void InitHeader(bool has_header = true) {
|
|
||||||
if (has_header) {
|
|
||||||
ImGui::TableHeadersRow();
|
|
||||||
}
|
|
||||||
ImGui::TableNextRow();
|
|
||||||
ImGui::TableNextColumn();
|
|
||||||
ImGui::AlignTextToFramePadding(); //This is to adjust Vertical pos of item in a cell to be normlized.
|
|
||||||
ImGui::PushItemWidth(ImGui::GetContentRegionAvail().x);
|
|
||||||
}
|
|
||||||
|
|
||||||
void NextCol() {
|
|
||||||
ImGui::TableNextColumn();
|
|
||||||
ImGui::AlignTextToFramePadding();
|
|
||||||
ImGui::PushItemWidth(ImGui::GetContentRegionAvail().x);
|
|
||||||
}
|
|
||||||
|
|
||||||
void NextLine() {
|
|
||||||
ImGui::TableNextRow();
|
|
||||||
ImGui::TableNextColumn();
|
|
||||||
ImGui::AlignTextToFramePadding();
|
|
||||||
ImGui::PushItemWidth(ImGui::GetContentRegionAvail().x);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void DrawHelpIcon(const std::string& helptext) {
|
|
||||||
// place the ? button to the most of the right side of the cell it is using.
|
|
||||||
ImGui::SetCursorPosY(ImGui::GetCursorPosY() - 22);
|
|
||||||
ImGui::SetCursorPosX(ImGui::GetCursorPosX() + ImGui::GetContentRegionAvail().x - 15);
|
|
||||||
ImGui::SmallButton("?");
|
|
||||||
UIWidgets::Tooltip(helptext.c_str());
|
|
||||||
}
|
|
||||||
|
|
||||||
typedef uint32_t N64ButtonMask;
|
|
||||||
|
|
||||||
// Used together for an incomplete linked hash map implementation in order to
|
|
||||||
// map button masks to their names and original mapping on N64
|
|
||||||
static std::list<std::pair<N64ButtonMask, const char*>> buttons;
|
|
||||||
static std::unordered_map<N64ButtonMask, decltype(buttons)::iterator> buttonNames;
|
|
||||||
|
|
||||||
void addButtonName(N64ButtonMask mask, const char* name) {
|
|
||||||
buttons.push_back(std::make_pair(mask, name));
|
|
||||||
buttonNames[mask] = std::prev(buttons.end());
|
|
||||||
}
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
const char* label;
|
|
||||||
const char* cVarName;
|
|
||||||
N64ButtonMask defaultBtn;
|
|
||||||
} CustomButtonMap;
|
|
||||||
|
|
||||||
// Ocarina button maps
|
|
||||||
static CustomButtonMap ocarinaD5 = {"D5", "gOcarinaD5BtnMap", BTN_CUP};
|
|
||||||
static CustomButtonMap ocarinaB4 = {"B4", "gOcarinaB4BtnMap", BTN_CLEFT};
|
|
||||||
static CustomButtonMap ocarinaA4 = {"A4", "gOcarinaA4BtnMap", BTN_CRIGHT};
|
|
||||||
static CustomButtonMap ocarinaF4 = {"F4", "gOcarinaF4BtnMap", BTN_CDOWN};
|
|
||||||
static CustomButtonMap ocarinaD4 = {"D4", "gOcarinaD4BtnMap", BTN_A};
|
|
||||||
static CustomButtonMap ocarinaSongDisable = {"Disable songs", "gOcarinaDisableBtnMap", BTN_L};
|
|
||||||
static CustomButtonMap ocarinaSharp = {"Pitch up", "gOcarinaSharpBtnMap", BTN_R};
|
|
||||||
static CustomButtonMap ocarinaFlat = {"Pitch down", "gOcarinaFlatBtnMap", BTN_Z};
|
|
||||||
|
|
||||||
void GameControlEditorWindow::InitElement() {
|
|
||||||
addButtonName(BTN_A, "A");
|
|
||||||
addButtonName(BTN_B, "B");
|
|
||||||
addButtonName(BTN_CUP, "C Up");
|
|
||||||
addButtonName(BTN_CDOWN, "C Down");
|
|
||||||
addButtonName(BTN_CLEFT, "C Left");
|
|
||||||
addButtonName(BTN_CRIGHT, "C Right");
|
|
||||||
addButtonName(BTN_L, "L");
|
|
||||||
addButtonName(BTN_Z, "Z");
|
|
||||||
addButtonName(BTN_R, "R");
|
|
||||||
addButtonName(BTN_START, "Start");
|
|
||||||
addButtonName(BTN_DUP, "D-pad up");
|
|
||||||
addButtonName(BTN_DDOWN, "D-pad down");
|
|
||||||
addButtonName(BTN_DLEFT, "D-pad left");
|
|
||||||
addButtonName(BTN_DRIGHT, "D-pad right");
|
|
||||||
addButtonName(0, "None");
|
|
||||||
}
|
|
||||||
|
|
||||||
// Draw a button mapping setting consisting of a padded label and button dropdown.
|
|
||||||
// excludedButtons indicates which buttons are unavailable to choose from.
|
|
||||||
void DrawMapping(CustomButtonMap& mapping, float labelWidth, N64ButtonMask excludedButtons) {
|
|
||||||
N64ButtonMask currentButton = CVarGetInteger(mapping.cVarName, mapping.defaultBtn);
|
|
||||||
|
|
||||||
const char* preview;
|
|
||||||
if (buttonNames.contains(currentButton)) {
|
|
||||||
preview = buttonNames[currentButton]->second;
|
|
||||||
} else {
|
|
||||||
preview = "Unknown";
|
|
||||||
}
|
|
||||||
|
|
||||||
UIWidgets::Spacer(0);
|
|
||||||
ImVec2 cursorPos = ImGui::GetCursorPos();
|
|
||||||
ImVec2 textSize = ImGui::CalcTextSize(mapping.label);
|
|
||||||
ImGui::SetCursorPosY(cursorPos.y + textSize.y / 4);
|
|
||||||
ImGui::SetCursorPosX(cursorPos.x + abs(textSize.x - labelWidth));
|
|
||||||
ImGui::Text("%s", mapping.label);
|
|
||||||
ImGui::SameLine();
|
|
||||||
ImGui::SetCursorPosY(cursorPos.y);
|
|
||||||
|
|
||||||
ImGui::SetNextItemWidth(ImGui::GetFontSize() * 8);
|
|
||||||
if (ImGui::BeginCombo(StringHelper::Sprintf("##%s", mapping.cVarName).c_str(), preview)) {
|
|
||||||
for (auto i = buttons.begin(); i != buttons.end(); i++) {
|
|
||||||
if ((i->first & excludedButtons) != 0) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if (ImGui::Selectable(i->second, i->first == currentButton)) {
|
|
||||||
CVarSetInteger(mapping.cVarName, i->first);
|
|
||||||
LUS::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesOnNextTick();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
ImGui::EndCombo();
|
|
||||||
}
|
|
||||||
UIWidgets::Spacer(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
void DrawOcarinaControlPanel(GameControlEditorWindow* window) {
|
|
||||||
if (!ImGui::CollapsingHeader("Ocarina Controls")) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!ImGui::BeginTable("tableCustomOcarinaControls", 1, PANEL_TABLE_FLAGS)) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
ImGui::TableSetupColumn("Custom Ocarina Controls", PANEL_TABLE_COLUMN_FLAGS | ImGuiTableColumnFlags_WidthStretch);
|
|
||||||
TableHelper::InitHeader(false);
|
|
||||||
|
|
||||||
ImVec2 cursor = ImGui::GetCursorPos();
|
|
||||||
ImGui::SetCursorPos(ImVec2(cursor.x + 5, cursor.y + 5));
|
|
||||||
UIWidgets::EnhancementCheckbox("Customize Ocarina Controls", "gCustomOcarinaControls");
|
|
||||||
|
|
||||||
if (CVarGetInteger("gCustomOcarinaControls", 0) == 1) {
|
|
||||||
if (ImGui::BeginTable("tableCustomMainOcarinaControls", 2, ImGuiTableFlags_SizingStretchProp)) {
|
|
||||||
float labelWidth;
|
|
||||||
N64ButtonMask disableMask = BTN_B;
|
|
||||||
if (CVarGetInteger("gDpadOcarina", 0)) {
|
|
||||||
disableMask |= BTN_DUP | BTN_DDOWN | BTN_DLEFT | BTN_DRIGHT;
|
|
||||||
}
|
|
||||||
|
|
||||||
ImGui::TableSetupColumn("Notes##CustomOcarinaNotes", PANEL_TABLE_COLUMN_FLAGS);
|
|
||||||
ImGui::TableSetupColumn("Modifiers##CustomOcaranaModifiers", PANEL_TABLE_COLUMN_FLAGS);
|
|
||||||
TableHelper::InitHeader(false);
|
|
||||||
|
|
||||||
window->BeginGroupPanelPublic("Notes", ImGui::GetContentRegionAvail());
|
|
||||||
labelWidth = ImGui::CalcTextSize("D5").x + 10;
|
|
||||||
DrawMapping(ocarinaD5, labelWidth, disableMask);
|
|
||||||
DrawMapping(ocarinaB4, labelWidth, disableMask);
|
|
||||||
DrawMapping(ocarinaA4, labelWidth, disableMask);
|
|
||||||
DrawMapping(ocarinaF4, labelWidth, disableMask);
|
|
||||||
DrawMapping(ocarinaD4, labelWidth, disableMask);
|
|
||||||
ImGui::Dummy(ImVec2(0, 5));
|
|
||||||
float cursorY = ImGui::GetCursorPosY();
|
|
||||||
window->EndGroupPanelPublic(0);
|
|
||||||
|
|
||||||
TableHelper::NextCol();
|
|
||||||
|
|
||||||
window->BeginGroupPanelPublic("Modifiers", ImGui::GetContentRegionAvail());
|
|
||||||
labelWidth = ImGui::CalcTextSize(ocarinaSongDisable.label).x + 10;
|
|
||||||
DrawMapping(ocarinaSongDisable, labelWidth, disableMask);
|
|
||||||
DrawMapping(ocarinaSharp, labelWidth, disableMask);
|
|
||||||
DrawMapping(ocarinaFlat, labelWidth, disableMask);
|
|
||||||
window->EndGroupPanelPublic(cursorY - ImGui::GetCursorPosY() + 2);
|
|
||||||
|
|
||||||
ImGui::EndTable();
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
UIWidgets::Spacer(0);
|
|
||||||
ImGui::SetCursorPosX(ImGui::GetCursorPosX() + 5);
|
|
||||||
ImGui::TextWrapped("To modify the main ocarina controls, select the \"Customize Ocarina Controls\" checkbox.");
|
|
||||||
UIWidgets::Spacer(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
window->BeginGroupPanelPublic("Alternate controls", ImGui::GetContentRegionAvail());
|
|
||||||
if (ImGui::BeginTable("tableOcarinaAlternateControls", 2, ImGuiTableFlags_SizingFixedSame)) {
|
|
||||||
ImGui::TableSetupColumn("D-pad", PANEL_TABLE_COLUMN_FLAGS);
|
|
||||||
ImGui::TableSetupColumn("Right stick", PANEL_TABLE_COLUMN_FLAGS);
|
|
||||||
TableHelper::InitHeader(false);
|
|
||||||
ImGui::SetCursorPosX(ImGui::GetCursorPosX() + 5);
|
|
||||||
UIWidgets::EnhancementCheckbox("Play with D-pad", "gDpadOcarina");
|
|
||||||
TableHelper::NextCol();
|
|
||||||
UIWidgets::EnhancementCheckbox("Play with camera stick", "gRStickOcarina");
|
|
||||||
UIWidgets::Spacer(0);
|
|
||||||
ImGui::EndTable();
|
|
||||||
}
|
|
||||||
window->EndGroupPanelPublic(0);
|
|
||||||
|
|
||||||
ImGui::EndTable();
|
|
||||||
}
|
|
||||||
|
|
||||||
// CurrentPort is indexed started at 1 here due to the Generic tab, instead of 0 like in InputEditorWindow
|
|
||||||
// Therefore CurrentPort - 1 must always be used inside this function instead of CurrentPort
|
|
||||||
void DrawCustomButtons() {
|
|
||||||
auto inputEditorWindow = std::reinterpret_pointer_cast<LUS::InputEditorWindow>(LUS::Context::GetInstance()->GetWindow()->GetGui()->GetGuiWindow("Input Editor"));
|
|
||||||
inputEditorWindow->DrawControllerSelect(CurrentPort - 1);
|
|
||||||
|
|
||||||
inputEditorWindow->DrawButton("Modifier 1", BTN_MODIFIER1, CurrentPort - 1, &BtnReading);
|
|
||||||
inputEditorWindow->DrawButton("Modifier 2", BTN_MODIFIER2, CurrentPort - 1, &BtnReading);
|
|
||||||
}
|
|
||||||
|
|
||||||
void DrawCameraControlPanel(GameControlEditorWindow* window) {
|
|
||||||
if (!ImGui::CollapsingHeader("Camera Controls")) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
UIWidgets::Spacer(0);
|
|
||||||
window->BeginGroupPanelPublic("Aiming/First-Person Camera", ImGui::GetContentRegionAvail());
|
|
||||||
UIWidgets::PaddedEnhancementCheckbox("Right Stick Aiming", "gRightStickAiming");
|
|
||||||
DrawHelpIcon("Allows for aiming with the right stick in:\n-First-Person/C-Up view\n-Weapon Aiming");
|
|
||||||
UIWidgets::PaddedEnhancementCheckbox("Invert Aiming X Axis", "gInvertAimingXAxis");
|
|
||||||
DrawHelpIcon("Inverts the Camera X Axis in:\n-First-Person/C-Up view\n-Weapon Aiming");
|
|
||||||
UIWidgets::PaddedEnhancementCheckbox("Invert Aiming Y Axis", "gInvertAimingYAxis", true, true, false, "", UIWidgets::CheckboxGraphics::Cross, true);
|
|
||||||
DrawHelpIcon("Inverts the Camera Y Axis in:\n-First-Person/C-Up view\n-Weapon Aiming");
|
|
||||||
UIWidgets::PaddedEnhancementCheckbox("Invert Shield Aiming Y Axis", "gInvertShieldAimingYAxis", true, true, false, "", UIWidgets::CheckboxGraphics::Cross, true);
|
|
||||||
DrawHelpIcon("Inverts the Shield Aiming Y Axis");
|
|
||||||
UIWidgets::PaddedEnhancementCheckbox("Invert Shield Aiming X Axis", "gInvertShieldAimingXAxis");
|
|
||||||
DrawHelpIcon("Inverts the Shield Aiming X Axis");
|
|
||||||
UIWidgets::PaddedEnhancementCheckbox("Disable Auto-Centering in First-Person View", "gDisableAutoCenterViewFirstPerson");
|
|
||||||
DrawHelpIcon("Prevents the C-Up view from auto-centering, allowing for Gyro Aiming");
|
|
||||||
if (UIWidgets::PaddedEnhancementCheckbox("Enable Custom Aiming/First-Person sensitivity", "gEnableFirstPersonSensitivity", true, false)) {
|
|
||||||
if (!CVarGetInteger("gEnableFirstPersonSensitivity", 0)) {
|
|
||||||
CVarClear("gFirstPersonCameraSensitivity");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (CVarGetInteger("gEnableFirstPersonSensitivity", 0)) {
|
|
||||||
UIWidgets::EnhancementSliderFloat("Aiming/First-Person Horizontal Sensitivity: %d %%", "##FirstPersonSensitivity Horizontal",
|
|
||||||
"gFirstPersonCameraSensitivityX", 0.01f, 5.0f, "", 1.0f, true);
|
|
||||||
UIWidgets::EnhancementSliderFloat("Aiming/First-Person Vertical Sensitivity: %d %%", "##FirstPersonSensitivity Vertical",
|
|
||||||
"gFirstPersonCameraSensitivityY", 0.01f, 5.0f, "", 1.0f, true);
|
|
||||||
}
|
|
||||||
UIWidgets::Spacer(0);
|
|
||||||
window->EndGroupPanelPublic(0);
|
|
||||||
|
|
||||||
UIWidgets::Spacer(0);
|
|
||||||
window->BeginGroupPanelPublic("Free Look/Third-person Camera", ImGui::GetContentRegionAvail());
|
|
||||||
|
|
||||||
UIWidgets::PaddedEnhancementCheckbox("Enable Free Look", "gFreeCamera");
|
|
||||||
DrawHelpIcon("Enables free look camera control\nNote: You must remap C buttons off of the right stick in the "
|
|
||||||
"controller config menu, and map the camera stick to the right stick.");
|
|
||||||
UIWidgets::PaddedEnhancementCheckbox("Invert X Axis", "gInvertXAxis");
|
|
||||||
DrawHelpIcon("Inverts the Camera X Axis in:\n-Free Look");
|
|
||||||
UIWidgets::PaddedEnhancementCheckbox("Invert Y Axis", "gInvertYAxis", true, true, false, "", UIWidgets::CheckboxGraphics::Cross, true);
|
|
||||||
DrawHelpIcon("Inverts the Camera Y Axis in:\n-Free Look");
|
|
||||||
UIWidgets::Spacer(0);
|
|
||||||
UIWidgets::PaddedEnhancementSliderFloat("Horizontal Sensitivity: %d %%", "##ThirdPersonSensitivity Horizontal",
|
|
||||||
"gThirdPersonCameraSensitivityX", 0.01f, 5.0f, "", 1.0f, true, true, false, true);
|
|
||||||
DrawHelpIcon("Changes the sensitivity of the X axis control for Free Look");
|
|
||||||
UIWidgets::PaddedEnhancementSliderFloat("Vertical Sensitivity: %d %%", "##ThirdPersonSensitivity Vertical",
|
|
||||||
"gThirdPersonCameraSensitivityY", 0.01f, 5.0f, "", 1.0f, true, true, false, true);
|
|
||||||
DrawHelpIcon("Changes the sensitivity of the Y axis control for Free Look");
|
|
||||||
UIWidgets::PaddedEnhancementSliderInt("Camera Distance: %d", "##CamDist",
|
|
||||||
"gFreeCameraDistMax", 100, 900, "", 185, true, false, true);
|
|
||||||
DrawHelpIcon("How far the camera sits from Link while in Free Look mode");
|
|
||||||
UIWidgets::PaddedEnhancementSliderInt("Transition Speed: %d", "##CamTranSpeed",
|
|
||||||
"gFreeCameraTransitionSpeed", 0, 900, "", 25, true, false, true);
|
|
||||||
DrawHelpIcon("How quickly the camera changes to the distance specified above");
|
|
||||||
window->EndGroupPanelPublic(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
void DrawDpadControlPanel(GameControlEditorWindow* window) {
|
|
||||||
if (!ImGui::CollapsingHeader("D-Pad Controls")) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
ImVec2 cursor = ImGui::GetCursorPos();
|
|
||||||
ImGui::SetCursorPos(ImVec2(cursor.x + 5, cursor.y + 5));
|
|
||||||
window->BeginGroupPanelPublic("D-Pad Options", ImGui::GetContentRegionAvail());
|
|
||||||
UIWidgets::PaddedEnhancementCheckbox("D-pad Support on Pause Screen", "gDpadPause");
|
|
||||||
DrawHelpIcon("Navigate Pause with the D-pad\nIf used with D-pad as Equip Items, you must hold C-Up to equip instead of navigate\n"
|
|
||||||
"To make the cursor only move a single space no matter how long a direction is held, manually set gDpadHoldChange to 0");
|
|
||||||
UIWidgets::PaddedEnhancementCheckbox("D-pad Support in Text Boxes", "gDpadText");
|
|
||||||
DrawHelpIcon("Navigate choices in text boxes, shop item selection, and the file select / name entry screens with the D-pad\n"
|
|
||||||
"To make the cursor only move a single space during name entry no matter how long a direction is held, manually set gDpadHoldChange to 0");
|
|
||||||
UIWidgets::PaddedEnhancementCheckbox("D-pad as Equip Items", "gDpadEquips");
|
|
||||||
DrawHelpIcon("Equip items and equipment on the D-pad\nIf used with D-pad on Pause Screen, you must hold C-Up to equip instead of navigate");
|
|
||||||
window->EndGroupPanelPublic(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
void DrawMiscControlPanel(GameControlEditorWindow* window) {
|
|
||||||
if (!ImGui::CollapsingHeader("Miscellaneous Controls")) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
ImVec2 cursor = ImGui::GetCursorPos();
|
|
||||||
ImGui::SetCursorPos(ImVec2(cursor.x + 5, cursor.y + 5));
|
|
||||||
window->BeginGroupPanelPublic("Misc Controls", ImGui::GetContentRegionAvail());
|
|
||||||
UIWidgets::PaddedText("Allow the cursor to be on any slot");
|
|
||||||
static const char* cursorOnAnySlot[3] = { "Only in Rando", "Always", "Never" };
|
|
||||||
UIWidgets::EnhancementCombobox("gPauseAnyCursor", cursorOnAnySlot, PAUSE_ANY_CURSOR_RANDO_ONLY);
|
|
||||||
DrawHelpIcon("Allows the cursor on the pause menu to be over any slot. Sometimes required in rando to select "
|
|
||||||
"certain items.");
|
|
||||||
UIWidgets::Spacer(0);
|
|
||||||
ImGui::BeginDisabled(CVarGetInteger("gDisableChangingSettings", 0));
|
|
||||||
UIWidgets::PaddedEnhancementCheckbox("Enable walk speed modifiers", "gEnableWalkModify", true, false);
|
|
||||||
DrawHelpIcon("Hold the assigned button to change the maximum walking speed\nTo change the assigned button, go into the Ports tabs above");
|
|
||||||
if (CVarGetInteger("gEnableWalkModify", 0)) {
|
|
||||||
UIWidgets::Spacer(5);
|
|
||||||
window->BeginGroupPanelPublic("Walk Modifier", ImGui::GetContentRegionAvail());
|
|
||||||
UIWidgets::PaddedEnhancementCheckbox("Toggle modifier instead of holding", "gWalkSpeedToggle", true, false);
|
|
||||||
UIWidgets::PaddedEnhancementCheckbox("Don't affect jump distance/velocity", "gWalkModifierDoesntChangeJump", true, false);
|
|
||||||
UIWidgets::PaddedEnhancementSliderFloat("Modifier 1: %d %%", "##WalkMod1", "gWalkModifierOne", 0.0f, 5.0f, "", 1.0f, true, true, false, true);
|
|
||||||
UIWidgets::PaddedEnhancementSliderFloat("Modifier 2: %d %%", "##WalkMod2", "gWalkModifierTwo", 0.0f, 5.0f, "", 1.0f, true, true, false, true);
|
|
||||||
window->EndGroupPanelPublic(0);
|
|
||||||
}
|
|
||||||
ImGui::EndDisabled();
|
|
||||||
UIWidgets::Spacer(0);
|
|
||||||
UIWidgets::PaddedEnhancementCheckbox("Answer Navi Prompt with L Button", "gNaviOnL");
|
|
||||||
DrawHelpIcon("Speak to Navi with L but enter first-person camera with C-Up");
|
|
||||||
window->EndGroupPanelPublic(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
void DrawLEDControlPanel(GameControlEditorWindow* window) {
|
|
||||||
window->BeginGroupPanelPublic("LED Colors", ImGui::GetContentRegionAvail());
|
|
||||||
static const char* ledSources[] = { "Original Tunic Colors", "Cosmetics Tunic Colors", "Health Colors",
|
|
||||||
"Original Navi Targeting Colors", "Cosmetics Navi Targeting Colors", "Custom" };
|
|
||||||
UIWidgets::PaddedText("Source");
|
|
||||||
UIWidgets::EnhancementCombobox("gLedColorSource", ledSources, LED_SOURCE_TUNIC_ORIGINAL);
|
|
||||||
DrawHelpIcon("Health\n- Red when health critical (13-20% depending on max health)\n- Yellow when health < 40%. Green otherwise.\n\n" \
|
|
||||||
"Tunics: colors will mirror currently equipped tunic, whether original or the current values in Cosmetics Editor.\n\n" \
|
|
||||||
"Custom: single, solid color");
|
|
||||||
if (CVarGetInteger("gLedColorSource", 1) == LED_SOURCE_CUSTOM) {
|
|
||||||
UIWidgets::Spacer(3);
|
|
||||||
auto port1Color = CVarGetColor24("gLedPort1Color", { 255, 255, 255 });
|
|
||||||
ImVec4 colorVec = { port1Color.r / 255.0f, port1Color.g / 255.0f, port1Color.b / 255.0f, 1.0f };
|
|
||||||
if (ImGui::ColorEdit3("", (float*)&colorVec, ImGuiColorEditFlags_NoInputs | ImGuiColorEditFlags_NoLabel)) {
|
|
||||||
Color_RGB8 color;
|
|
||||||
color.r = colorVec.x * 255.0;
|
|
||||||
color.g = colorVec.y * 255.0;
|
|
||||||
color.b = colorVec.z * 255.0;
|
|
||||||
|
|
||||||
CVarSetColor24("gLedPort1Color", color);
|
|
||||||
LUS::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesOnNextTick();
|
|
||||||
}
|
|
||||||
ImGui::SameLine();
|
|
||||||
ImGui::Text("Custom Color");
|
|
||||||
}
|
|
||||||
UIWidgets::PaddedEnhancementSliderFloat("Brightness: %d%%", "##LED_Brightness", "gLedBrightness",
|
|
||||||
0.0f, 1.0f, "", 1.0f, true, true);
|
|
||||||
DrawHelpIcon("Sets the brightness of controller LEDs. 0% brightness = LEDs off.");
|
|
||||||
UIWidgets::PaddedEnhancementCheckbox("Critical Health Override", "gLedCriticalOverride", true, true,
|
|
||||||
CVarGetInteger("gLedColorSource", LED_SOURCE_TUNIC_ORIGINAL) == LED_SOURCE_HEALTH, "Override redundant for health source.",
|
|
||||||
UIWidgets::CheckboxGraphics::Cross, true);
|
|
||||||
DrawHelpIcon("Shows red color when health is critical, otherwise displays according to color source.");
|
|
||||||
window->EndGroupPanelPublic(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
void GameControlEditorWindow::DrawElement() {
|
|
||||||
ImGui::SetNextWindowSize(ImVec2(465, 430), ImGuiCond_FirstUseEver);
|
|
||||||
if (ImGui::Begin("Game Controls Configuration", &mIsVisible)) {
|
|
||||||
ImGui::BeginTabBar("##CustomControllers");
|
|
||||||
if (ImGui::BeginTabItem("Generic")) {
|
|
||||||
CurrentPort = 0;
|
|
||||||
ImGui::EndTabItem();
|
|
||||||
}
|
|
||||||
|
|
||||||
for (int i = 1; i <= 4; i++) {
|
|
||||||
if (ImGui::BeginTabItem(StringHelper::Sprintf("Port %d", i).c_str())) {
|
|
||||||
CurrentPort = i;
|
|
||||||
ImGui::EndTabItem();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ImGui::EndTabBar();
|
|
||||||
|
|
||||||
if (CurrentPort == 0) {
|
|
||||||
DrawOcarinaControlPanel(this);
|
|
||||||
DrawCameraControlPanel(this);
|
|
||||||
DrawDpadControlPanel(this);
|
|
||||||
DrawMiscControlPanel(this);
|
|
||||||
} else {
|
|
||||||
DrawCustomButtons();
|
|
||||||
if (CurrentPort == 1 && LUS::Context::GetInstance()->GetControlDeck()->GetDeviceFromPortIndex(0)->CanSetLed()) {
|
|
||||||
DrawLEDControlPanel(this);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
ImGui::End();
|
|
||||||
}
|
|
||||||
|
|
||||||
void GameControlEditorWindow::BeginGroupPanelPublic(const char* name, const ImVec2& size) {
|
|
||||||
BeginGroupPanel(name, size);
|
|
||||||
}
|
|
||||||
|
|
||||||
void GameControlEditorWindow::EndGroupPanelPublic(float minHeight) {
|
|
||||||
EndGroupPanel(minHeight);
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,21 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#include <libultraship/libultraship.h>
|
|
||||||
|
|
||||||
namespace GameControlEditor {
|
|
||||||
class GameControlEditorWindow : public LUS::GuiWindow {
|
|
||||||
public:
|
|
||||||
using LUS::GuiWindow::GuiWindow;
|
|
||||||
|
|
||||||
void BeginGroupPanelPublic(const char* name, const ImVec2& size);
|
|
||||||
void EndGroupPanelPublic(float minHeight);
|
|
||||||
|
|
||||||
void InitElement() override;
|
|
||||||
void DrawElement() override;
|
|
||||||
void UpdateElement() override {};
|
|
||||||
};
|
|
||||||
|
|
||||||
static int CurrentPort = 0;
|
|
||||||
static int BtnReading = -1;
|
|
||||||
|
|
||||||
} // namespace GameControlEditor
|
|
520
soh/soh/Enhancements/controls/InputViewer.cpp
Normal file
@ -0,0 +1,520 @@
|
|||||||
|
#include "InputViewer.h"
|
||||||
|
|
||||||
|
#include "public/bridge/consolevariablebridge.h"
|
||||||
|
#include "libultraship/libultra/controller.h"
|
||||||
|
#include "Context.h"
|
||||||
|
#include "soh/OTRGlobals.h"
|
||||||
|
#ifndef IMGUI_DEFINE_MATH_OPERATORS
|
||||||
|
#define IMGUI_DEFINE_MATH_OPERATORS
|
||||||
|
#endif
|
||||||
|
#include <imgui.h>
|
||||||
|
#include <spdlog/spdlog.h>
|
||||||
|
#include <cmath>
|
||||||
|
|
||||||
|
#include "../../UIWidgets.hpp"
|
||||||
|
|
||||||
|
// Text colors
|
||||||
|
static ImVec4 textColor = ImVec4(1.0f, 1.0f, 1.0f, 1.0f);
|
||||||
|
static ImVec4 range1Color = ImVec4(1.0f, 0.7f, 0, 1.0f);
|
||||||
|
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* stickModeOptions[3] = { "Always", "While In Use", "Never" };
|
||||||
|
|
||||||
|
static Color_RGBA8 vec2Color(ImVec4 vec) {
|
||||||
|
Color_RGBA8 color;
|
||||||
|
color.r = vec.x * 255.0;
|
||||||
|
color.g = vec.y * 255.0;
|
||||||
|
color.b = vec.z * 255.0;
|
||||||
|
color.a = vec.w * 255.0;
|
||||||
|
return color;
|
||||||
|
}
|
||||||
|
|
||||||
|
static ImVec4 color2Vec(Color_RGBA8 color) {
|
||||||
|
return ImVec4(color.r / 255.0, color.g / 255.0, color.b / 255.0, color.a / 255.0);
|
||||||
|
}
|
||||||
|
|
||||||
|
InputViewer::~InputViewer() {
|
||||||
|
SPDLOG_TRACE("destruct input viewer");
|
||||||
|
}
|
||||||
|
|
||||||
|
void InputViewer::RenderButton(std::string btnTexture, std::string btnOutlineTexture, int state, ImVec2 size,
|
||||||
|
int outlineMode) {
|
||||||
|
const ImVec2 pos = ImGui::GetCursorPos();
|
||||||
|
ImGui::SetNextItemAllowOverlap();
|
||||||
|
// Render Outline based on settings
|
||||||
|
if (outlineMode == BUTTON_OUTLINE_ALWAYS_SHOWN || (outlineMode == BUTTON_OUTLINE_NOT_PRESSED && !state) ||
|
||||||
|
(outlineMode == BUTTON_OUTLINE_PRESSED && state)) {
|
||||||
|
ImGui::Image(Ship::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName(btnOutlineTexture), size,
|
||||||
|
ImVec2(0, 0), ImVec2(1.0f, 1.0f), ImVec4(255, 255, 255, 255));
|
||||||
|
}
|
||||||
|
// Render button if pressed
|
||||||
|
if (state) {
|
||||||
|
ImGui::SetCursorPos(pos);
|
||||||
|
ImGui::SetNextItemAllowOverlap();
|
||||||
|
ImGui::Image(Ship::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName(btnTexture), size,
|
||||||
|
ImVec2(0, 0), ImVec2(1.0f, 1.0f), ImVec4(255, 255, 255, 255));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void InputViewer::DrawElement() {
|
||||||
|
if (CVarGetInteger(CVAR_WINDOW("InputViewer"), 0)) {
|
||||||
|
static bool sButtonTexturesLoaded = false;
|
||||||
|
if (!sButtonTexturesLoaded) {
|
||||||
|
Ship::Context::GetInstance()->GetWindow()->GetGui()->LoadTextureFromRawImage(
|
||||||
|
"Input-Viewer-Background", "textures/buttons/InputViewerBackground.png");
|
||||||
|
Ship::Context::GetInstance()->GetWindow()->GetGui()->LoadTextureFromRawImage("A-Btn", "textures/buttons/ABtn.png");
|
||||||
|
Ship::Context::GetInstance()->GetWindow()->GetGui()->LoadTextureFromRawImage("B-Btn", "textures/buttons/BBtn.png");
|
||||||
|
Ship::Context::GetInstance()->GetWindow()->GetGui()->LoadTextureFromRawImage("L-Btn", "textures/buttons/LBtn.png");
|
||||||
|
Ship::Context::GetInstance()->GetWindow()->GetGui()->LoadTextureFromRawImage("R-Btn", "textures/buttons/RBtn.png");
|
||||||
|
Ship::Context::GetInstance()->GetWindow()->GetGui()->LoadTextureFromRawImage("Z-Btn", "textures/buttons/ZBtn.png");
|
||||||
|
Ship::Context::GetInstance()->GetWindow()->GetGui()->LoadTextureFromRawImage("Start-Btn",
|
||||||
|
"textures/buttons/StartBtn.png");
|
||||||
|
Ship::Context::GetInstance()->GetWindow()->GetGui()->LoadTextureFromRawImage("C-Left", "textures/buttons/CLeft.png");
|
||||||
|
Ship::Context::GetInstance()->GetWindow()->GetGui()->LoadTextureFromRawImage("C-Right", "textures/buttons/CRight.png");
|
||||||
|
Ship::Context::GetInstance()->GetWindow()->GetGui()->LoadTextureFromRawImage("C-Up", "textures/buttons/CUp.png");
|
||||||
|
Ship::Context::GetInstance()->GetWindow()->GetGui()->LoadTextureFromRawImage("C-Down", "textures/buttons/CDown.png");
|
||||||
|
Ship::Context::GetInstance()->GetWindow()->GetGui()->LoadTextureFromRawImage("Analog-Stick",
|
||||||
|
"textures/buttons/AnalogStick.png");
|
||||||
|
Ship::Context::GetInstance()->GetWindow()->GetGui()->LoadTextureFromRawImage("Dpad-Left",
|
||||||
|
"textures/buttons/DPadLeft.png");
|
||||||
|
Ship::Context::GetInstance()->GetWindow()->GetGui()->LoadTextureFromRawImage("Dpad-Right",
|
||||||
|
"textures/buttons/DPadRight.png");
|
||||||
|
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("Right-Stick",
|
||||||
|
"textures/buttons/RightStick.png");
|
||||||
|
Ship::Context::GetInstance()->GetWindow()->GetGui()->LoadTextureFromRawImage("A-Btn Outline",
|
||||||
|
"textures/buttons/ABtnOutline.png");
|
||||||
|
Ship::Context::GetInstance()->GetWindow()->GetGui()->LoadTextureFromRawImage("B-Btn Outline",
|
||||||
|
"textures/buttons/BBtnOutline.png");
|
||||||
|
Ship::Context::GetInstance()->GetWindow()->GetGui()->LoadTextureFromRawImage("L-Btn Outline",
|
||||||
|
"textures/buttons/LBtnOutline.png");
|
||||||
|
Ship::Context::GetInstance()->GetWindow()->GetGui()->LoadTextureFromRawImage("R-Btn Outline",
|
||||||
|
"textures/buttons/RBtnOutline.png");
|
||||||
|
Ship::Context::GetInstance()->GetWindow()->GetGui()->LoadTextureFromRawImage("Z-Btn Outline",
|
||||||
|
"textures/buttons/ZBtnOutline.png");
|
||||||
|
Ship::Context::GetInstance()->GetWindow()->GetGui()->LoadTextureFromRawImage("Start-Btn Outline",
|
||||||
|
"textures/buttons/StartBtnOutline.png");
|
||||||
|
Ship::Context::GetInstance()->GetWindow()->GetGui()->LoadTextureFromRawImage("C-Left Outline",
|
||||||
|
"textures/buttons/CLeftOutline.png");
|
||||||
|
Ship::Context::GetInstance()->GetWindow()->GetGui()->LoadTextureFromRawImage("C-Right Outline",
|
||||||
|
"textures/buttons/CRightOutline.png");
|
||||||
|
Ship::Context::GetInstance()->GetWindow()->GetGui()->LoadTextureFromRawImage("C-Up Outline",
|
||||||
|
"textures/buttons/CUpOutline.png");
|
||||||
|
Ship::Context::GetInstance()->GetWindow()->GetGui()->LoadTextureFromRawImage("C-Down Outline",
|
||||||
|
"textures/buttons/CDownOutline.png");
|
||||||
|
Ship::Context::GetInstance()->GetWindow()->GetGui()->LoadTextureFromRawImage("Analog-Stick Outline",
|
||||||
|
"textures/buttons/AnalogStickOutline.png");
|
||||||
|
Ship::Context::GetInstance()->GetWindow()->GetGui()->LoadTextureFromRawImage("Dpad-Left Outline",
|
||||||
|
"textures/buttons/DPadLeftOutline.png");
|
||||||
|
Ship::Context::GetInstance()->GetWindow()->GetGui()->LoadTextureFromRawImage("Dpad-Right Outline",
|
||||||
|
"textures/buttons/DPadRightOutline.png");
|
||||||
|
Ship::Context::GetInstance()->GetWindow()->GetGui()->LoadTextureFromRawImage("Dpad-Up Outline",
|
||||||
|
"textures/buttons/DPadUpOutline.png");
|
||||||
|
Ship::Context::GetInstance()->GetWindow()->GetGui()->LoadTextureFromRawImage("Dpad-Down Outline",
|
||||||
|
"textures/buttons/DPadDownOutline.png");
|
||||||
|
Ship::Context::GetInstance()->GetWindow()->GetGui()->LoadTextureFromRawImage("Right-Stick Outline",
|
||||||
|
"textures/buttons/RightStickOutline.png");
|
||||||
|
sButtonTexturesLoaded = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
ImVec2 mainPos = ImGui::GetWindowPos();
|
||||||
|
ImVec2 size = ImGui::GetContentRegionAvail();
|
||||||
|
|
||||||
|
#ifdef __WIIU__
|
||||||
|
const float scale = CVarGetFloat(CVAR_INPUT_VIEWER("Scale"), 1.0f) * 2.0f;
|
||||||
|
#else
|
||||||
|
const float scale = CVarGetFloat(CVAR_INPUT_VIEWER("Scale"), 1.0f);
|
||||||
|
#endif
|
||||||
|
const int showAnalogAngles = CVarGetInteger(CVAR_INPUT_VIEWER("AnalogAngles.Enabled"), 0);
|
||||||
|
const int buttonOutlineMode = CVarGetInteger(CVAR_INPUT_VIEWER("ButtonOutlineMode"), BUTTON_OUTLINE_NOT_PRESSED);
|
||||||
|
|
||||||
|
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::SetNextWindowContentSize(
|
||||||
|
ImVec2(scaledBGSize.x, scaledBGSize.y + (showAnalogAngles ? 15 : 0) * scale *
|
||||||
|
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);
|
||||||
|
|
||||||
|
ImGui::PushStyleColor(ImGuiCol_WindowBg, ImVec4(0, 0, 0, 0));
|
||||||
|
ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2(0.0f, 0.0f));
|
||||||
|
|
||||||
|
OSContPad* pads = Ship::Context::GetInstance()->GetControlDeck()->GetPads();
|
||||||
|
|
||||||
|
ImGuiWindowFlags windowFlags = ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoScrollbar |
|
||||||
|
ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoBackground |
|
||||||
|
ImGuiWindowFlags_NoFocusOnAppearing;
|
||||||
|
|
||||||
|
if (!CVarGetInteger(CVAR_INPUT_VIEWER("EnableDragging"), 1)) {
|
||||||
|
windowFlags |= ImGuiWindowFlags_NoInputs | ImGuiWindowFlags_NoMove;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pads != nullptr && ImGui::Begin("Input Viewer", nullptr, windowFlags)) {
|
||||||
|
ImGui::SetCursorPos(ImVec2(10, 10));
|
||||||
|
const ImVec2 aPos = ImGui::GetCursorPos();
|
||||||
|
|
||||||
|
if (CVarGetInteger(CVAR_INPUT_VIEWER("ShowBackground"), 1)) {
|
||||||
|
ImGui::SetNextItemAllowOverlap();
|
||||||
|
// Background
|
||||||
|
ImGui::Image(
|
||||||
|
Ship::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName("Input-Viewer-Background"),
|
||||||
|
scaledBGSize, ImVec2(0, 0), ImVec2(1.0f, 1.0f), ImVec4(255, 255, 255, 255));
|
||||||
|
}
|
||||||
|
|
||||||
|
// A/B
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 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);
|
||||||
|
}
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 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);
|
||||||
|
}
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Start
|
||||||
|
if (CVarGetInteger(CVAR_INPUT_VIEWER("StartBtn"), 1)) {
|
||||||
|
ImGui::SetNextItemAllowOverlap();
|
||||||
|
ImGui::SetCursorPos(aPos);
|
||||||
|
RenderButton("Start-Btn", "Start-Btn Outline", pads[0].button & BTN_START, scaledBGSize,
|
||||||
|
buttonOutlineMode);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Dpad
|
||||||
|
if (CVarGetInteger(CVAR_INPUT_VIEWER("Dpad"), 0)) {
|
||||||
|
ImGui::SetNextItemAllowOverlap();
|
||||||
|
ImGui::SetCursorPos(aPos);
|
||||||
|
RenderButton("Dpad-Left", "Dpad-Left Outline", pads[0].button & BTN_DLEFT, scaledBGSize,
|
||||||
|
buttonOutlineMode);
|
||||||
|
ImGui::SetNextItemAllowOverlap();
|
||||||
|
ImGui::SetCursorPos(aPos);
|
||||||
|
RenderButton("Dpad-Right", "Dpad-Right Outline", pads[0].button & BTN_DRIGHT, scaledBGSize,
|
||||||
|
buttonOutlineMode);
|
||||||
|
ImGui::SetNextItemAllowOverlap();
|
||||||
|
ImGui::SetCursorPos(aPos);
|
||||||
|
RenderButton("Dpad-Up", "Dpad-Up Outline", pads[0].button & BTN_DUP, scaledBGSize, buttonOutlineMode);
|
||||||
|
ImGui::SetNextItemAllowOverlap();
|
||||||
|
ImGui::SetCursorPos(aPos);
|
||||||
|
RenderButton("Dpad-Down", "Dpad-Down Outline", pads[0].button & BTN_DDOWN, scaledBGSize,
|
||||||
|
buttonOutlineMode);
|
||||||
|
}
|
||||||
|
|
||||||
|
const bool analogStickIsInDeadzone = !pads[0].stick_x && !pads[0].stick_y;
|
||||||
|
const bool rightStickIsInDeadzone = !pads[0].right_stick_x && !pads[0].right_stick_y;
|
||||||
|
|
||||||
|
// Analog Stick
|
||||||
|
const int analogOutlineMode =
|
||||||
|
CVarGetInteger(CVAR_INPUT_VIEWER("AnalogStick.OutlineMode"), STICK_MODE_ALWAYS_SHOWN);
|
||||||
|
const float maxStickDistance = CVarGetInteger(CVAR_INPUT_VIEWER("AnalogStick.Movement"), 12);
|
||||||
|
if (analogOutlineMode == STICK_MODE_ALWAYS_SHOWN ||
|
||||||
|
(analogOutlineMode == STICK_MODE_HIDDEN_IN_DEADZONE && !analogStickIsInDeadzone)) {
|
||||||
|
ImGui::SetNextItemAllowOverlap();
|
||||||
|
ImGui::SetCursorPos(aPos);
|
||||||
|
ImGui::Image(
|
||||||
|
Ship::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName("Analog-Stick Outline"),
|
||||||
|
scaledBGSize, ImVec2(0, 0), ImVec2(1.0f, 1.0f), ImVec4(255, 255, 255, 255));
|
||||||
|
}
|
||||||
|
const int analogStickMode =
|
||||||
|
CVarGetInteger(CVAR_INPUT_VIEWER("AnalogStick.VisibilityMode"), STICK_MODE_ALWAYS_SHOWN);
|
||||||
|
if (analogStickMode == STICK_MODE_ALWAYS_SHOWN ||
|
||||||
|
(analogStickMode == STICK_MODE_HIDDEN_IN_DEADZONE && !analogStickIsInDeadzone)) {
|
||||||
|
ImGui::SetNextItemAllowOverlap();
|
||||||
|
ImGui::SetCursorPos(
|
||||||
|
ImVec2(aPos.x + maxStickDistance * ((float)(pads[0].stick_x) / MAX_AXIS_RANGE) * scale,
|
||||||
|
aPos.y - maxStickDistance * ((float)(pads[0].stick_y) / MAX_AXIS_RANGE) * scale));
|
||||||
|
ImGui::Image(Ship::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName("Analog-Stick"),
|
||||||
|
scaledBGSize, ImVec2(0, 0), ImVec2(1.0f, 1.0f), ImVec4(255, 255, 255, 255));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Right Stick
|
||||||
|
const float maxRightStickDistance = CVarGetInteger(CVAR_INPUT_VIEWER("RightStick.Movement"), 7);
|
||||||
|
const int rightOutlineMode =
|
||||||
|
CVarGetInteger(CVAR_INPUT_VIEWER("RightStick.OutlineMode"), STICK_MODE_ALWAYS_HIDDEN);
|
||||||
|
if (rightOutlineMode == STICK_MODE_ALWAYS_SHOWN ||
|
||||||
|
(rightOutlineMode == STICK_MODE_HIDDEN_IN_DEADZONE && !rightStickIsInDeadzone)) {
|
||||||
|
ImGui::SetNextItemAllowOverlap();
|
||||||
|
ImGui::SetCursorPos(aPos);
|
||||||
|
ImGui::Image(
|
||||||
|
Ship::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName("Right-Stick Outline"),
|
||||||
|
scaledBGSize, ImVec2(0, 0), ImVec2(1.0f, 1.0f), ImVec4(255, 255, 255, 255));
|
||||||
|
}
|
||||||
|
const int rightStickMode =
|
||||||
|
CVarGetInteger(CVAR_INPUT_VIEWER("RightStick.VisibilityMode"), STICK_MODE_ALWAYS_HIDDEN);
|
||||||
|
if (rightStickMode == STICK_MODE_ALWAYS_SHOWN ||
|
||||||
|
(rightStickMode == STICK_MODE_HIDDEN_IN_DEADZONE && !rightStickIsInDeadzone)) {
|
||||||
|
ImGui::SetNextItemAllowOverlap();
|
||||||
|
ImGui::SetCursorPos(
|
||||||
|
ImVec2(aPos.x + maxRightStickDistance * ((float)(pads[0].right_stick_x) / MAX_AXIS_RANGE) * scale,
|
||||||
|
aPos.y - maxRightStickDistance * ((float)(pads[0].right_stick_y) / MAX_AXIS_RANGE) * scale));
|
||||||
|
ImGui::Image(Ship::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName("Right-Stick"),
|
||||||
|
scaledBGSize, ImVec2(0, 0), ImVec2(1.0f, 1.0f), ImVec4(255, 255, 255, 255));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Analog stick angle text
|
||||||
|
if (showAnalogAngles) {
|
||||||
|
ImGui::SetCursorPos(ImVec2(aPos.x + 10 + CVarGetInteger(CVAR_INPUT_VIEWER("AnalogAngles.Offset"), 0) * scale,
|
||||||
|
scaledBGSize.y + aPos.y + 10));
|
||||||
|
// Scale font with input viewer scale
|
||||||
|
float oldFontScale = ImGui::GetFont()->Scale;
|
||||||
|
ImGui::GetFont()->Scale *= scale * CVarGetFloat(CVAR_INPUT_VIEWER("AnalogAngles.Scale"), 1.0f);
|
||||||
|
ImGui::PushFont(ImGui::GetFont());
|
||||||
|
|
||||||
|
// Calculate polar R coordinate from X and Y angles, squared to avoid sqrt
|
||||||
|
const float rSquared = pads[0].stick_x * pads[0].stick_x + pads[0].stick_y * pads[0].stick_y;
|
||||||
|
|
||||||
|
// ESS range
|
||||||
|
const int range1Min = CVarGetInteger(CVAR_INPUT_VIEWER("AnalogAngles.Range1.Min"), 8);
|
||||||
|
const int range1Max = CVarGetInteger(CVAR_INPUT_VIEWER("AnalogAngles.Range1.Max"), 27);
|
||||||
|
// Walking speed range
|
||||||
|
const int range2Min = CVarGetInteger(CVAR_INPUT_VIEWER("AnalogAngles.Range2.Min"), 27);
|
||||||
|
const int range2Max = CVarGetInteger(CVAR_INPUT_VIEWER("AnalogAngles.Range2.Max"), 62);
|
||||||
|
|
||||||
|
// Push color based on angle ranges
|
||||||
|
if (CVarGetInteger(CVAR_INPUT_VIEWER("AnalogAngles.Range1.Enabled"), 0) &&
|
||||||
|
(rSquared >= (range1Min * range1Min)) && (rSquared < (range1Max * range1Max))) {
|
||||||
|
ImGui::PushStyleColor(
|
||||||
|
ImGuiCol_Text,
|
||||||
|
color2Vec(CVarGetColor(CVAR_INPUT_VIEWER("AnalogAngles.Range1.Color"), vec2Color(range1Color))));
|
||||||
|
} else if (CVarGetInteger(CVAR_INPUT_VIEWER("AnalogAngles.Range2.Enabled"), 0) &&
|
||||||
|
(rSquared >= (range2Min * range2Min)) && (rSquared < (range2Max * range2Max))) {
|
||||||
|
ImGui::PushStyleColor(
|
||||||
|
ImGuiCol_Text,
|
||||||
|
color2Vec(CVarGetColor(CVAR_INPUT_VIEWER("AnalogAngles.Range2.Color"), vec2Color(range2Color))));
|
||||||
|
} else {
|
||||||
|
ImGui::PushStyleColor(ImGuiCol_Text, color2Vec(CVarGetColor(CVAR_INPUT_VIEWER("AnalogAngles.TextColor"),
|
||||||
|
vec2Color(textColor))));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Render text
|
||||||
|
ImGui::Text("X: %-3d Y: %-3d", pads[0].stick_x, pads[0].stick_y);
|
||||||
|
// Restore original color
|
||||||
|
ImGui::PopStyleColor();
|
||||||
|
// Restore original font scale
|
||||||
|
ImGui::GetFont()->Scale = oldFontScale;
|
||||||
|
ImGui::PopFont();
|
||||||
|
}
|
||||||
|
|
||||||
|
ImGui::End();
|
||||||
|
}
|
||||||
|
|
||||||
|
ImGui::PopStyleVar();
|
||||||
|
ImGui::PopStyleColor();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
InputViewerSettingsWindow::~InputViewerSettingsWindow() {
|
||||||
|
SPDLOG_TRACE("destruct input viewer settings window");
|
||||||
|
}
|
||||||
|
|
||||||
|
void InputViewerSettingsWindow::DrawElement() {
|
||||||
|
ImGui::SetNextWindowSize(ImVec2(450, 525), ImGuiCond_FirstUseEver);
|
||||||
|
|
||||||
|
if (ImGui::Begin("Input Viewer Settings", &mIsVisible)) {
|
||||||
|
|
||||||
|
// gInputViewer.Scale
|
||||||
|
UIWidgets::EnhancementSliderFloat("Input Viewer Scale: %.2f", "##Input", CVAR_INPUT_VIEWER("Scale"), 0.1f, 5.0f, "",
|
||||||
|
1.0f, false, true);
|
||||||
|
UIWidgets::Tooltip("Sets the on screen size of the input viewer");
|
||||||
|
|
||||||
|
// gInputViewer.EnableDragging
|
||||||
|
UIWidgets::EnhancementCheckbox("Enable Dragging", CVAR_INPUT_VIEWER("EnableDragging"), false, "",
|
||||||
|
UIWidgets::CheckboxGraphics::Checkmark, true);
|
||||||
|
|
||||||
|
UIWidgets::PaddedSeparator(true, true);
|
||||||
|
|
||||||
|
// gInputViewer.ShowBackground
|
||||||
|
UIWidgets::EnhancementCheckbox("Show Background Layer", CVAR_INPUT_VIEWER("ShowBackground"), false, "",
|
||||||
|
UIWidgets::CheckboxGraphics::Checkmark, true);
|
||||||
|
|
||||||
|
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::Tooltip(
|
||||||
|
"Sets the desired visibility behavior for the button outline/background layers. Useful for "
|
||||||
|
"custom input viewers.");
|
||||||
|
|
||||||
|
UIWidgets::PaddedSeparator(true, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ImGui::CollapsingHeader("Analog Stick")) {
|
||||||
|
// gInputViewer.AnalogStick.VisibilityMode
|
||||||
|
UIWidgets::PaddedText("Analog Stick Visibility", true, false);
|
||||||
|
UIWidgets::EnhancementCombobox(CVAR_INPUT_VIEWER("AnalogStick.VisibilityMode"), stickModeOptions,
|
||||||
|
STICK_MODE_ALWAYS_SHOWN);
|
||||||
|
UIWidgets::Tooltip(
|
||||||
|
"Determines the conditions under which the moving layer of the analog stick texture is visible.");
|
||||||
|
|
||||||
|
// gInputViewer.AnalogStick.OutlineMode
|
||||||
|
UIWidgets::PaddedText("Analog Stick Outline/Background Visibility", true, false);
|
||||||
|
UIWidgets::EnhancementCombobox(CVAR_INPUT_VIEWER("AnalogStick.OutlineMode"), stickModeOptions,
|
||||||
|
STICK_MODE_ALWAYS_SHOWN);
|
||||||
|
UIWidgets::Tooltip(
|
||||||
|
"Determines the conditions under which the analog stick outline/background texture is visible.");
|
||||||
|
|
||||||
|
// gInputViewer.AnalogStick.Movement
|
||||||
|
UIWidgets::EnhancementSliderInt("Analog Stick Movement: %dpx", "##AnalogMovement",
|
||||||
|
CVAR_INPUT_VIEWER("AnalogStick.Movement"), 0, 200, "", 12, true);
|
||||||
|
UIWidgets::Tooltip(
|
||||||
|
"Sets the distance to move the analog stick in the input viewer. Useful for custom input viewers.");
|
||||||
|
UIWidgets::PaddedSeparator(true, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ImGui::CollapsingHeader("Additional (\"Right\") Stick")) {
|
||||||
|
// gInputViewer.RightStick.VisibilityMode
|
||||||
|
UIWidgets::PaddedText("Right Stick Visibility", true, false);
|
||||||
|
UIWidgets::EnhancementCombobox(CVAR_INPUT_VIEWER("RightStick.VisibilityMode"), stickModeOptions,
|
||||||
|
STICK_MODE_HIDDEN_IN_DEADZONE);
|
||||||
|
UIWidgets::Tooltip(
|
||||||
|
"Determines the conditions under which the moving layer of the right stick texture is visible.");
|
||||||
|
|
||||||
|
// gInputViewer.RightStick.OutlineMode
|
||||||
|
UIWidgets::PaddedText("Right Stick Outline/Background Visibility", true, false);
|
||||||
|
UIWidgets::EnhancementCombobox(CVAR_INPUT_VIEWER("RightStick.OutlineMode"), stickModeOptions,
|
||||||
|
STICK_MODE_HIDDEN_IN_DEADZONE);
|
||||||
|
UIWidgets::Tooltip(
|
||||||
|
"Determines the conditions under which the right stick outline/background texture is visible.");
|
||||||
|
|
||||||
|
// gInputViewer.RightStick.Movement
|
||||||
|
UIWidgets::EnhancementSliderInt("Right Stick Movement: %dpx", "##RightMovement",
|
||||||
|
CVAR_INPUT_VIEWER("RightStick.Movement"), 0, 200, "", 7, true);
|
||||||
|
UIWidgets::Tooltip(
|
||||||
|
"Sets the distance to move the right stick in the input viewer. Useful for custom input viewers.");
|
||||||
|
UIWidgets::PaddedSeparator(true, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ImGui::CollapsingHeader("Analog Angle Values")) {
|
||||||
|
// gAnalogAngles
|
||||||
|
UIWidgets::EnhancementCheckbox("Show Analog Stick Angle Values", CVAR_INPUT_VIEWER("AnalogAngles.Enabled"));
|
||||||
|
UIWidgets::Tooltip("Displays analog stick angle values in the input viewer");
|
||||||
|
if (CVarGetInteger(CVAR_INPUT_VIEWER("AnalogAngles.Enabled"), 0)) {
|
||||||
|
// gInputViewer.AnalogAngles.TextColor
|
||||||
|
if (ImGui::ColorEdit4("Text Color", (float*)&textColor)) {
|
||||||
|
CVarSetColor(CVAR_INPUT_VIEWER("AnalogAngles.TextColor"), vec2Color(textColor));
|
||||||
|
}
|
||||||
|
// gAnalogAngleScale
|
||||||
|
UIWidgets::EnhancementSliderFloat("Angle Text Scale: %.2f%%", "##AnalogAngleScale",
|
||||||
|
CVAR_INPUT_VIEWER("AnalogAngles.Scale"), 0.1f, 5.0f, "", 1.0f, true, true);
|
||||||
|
// gInputViewer.AnalogAngles.Offset
|
||||||
|
UIWidgets::EnhancementSliderInt("Angle Text Offset: %dpx", "##AnalogAngleOffset",
|
||||||
|
CVAR_INPUT_VIEWER("AnalogAngles.Offset"), 0, 400, "", 0, true);
|
||||||
|
UIWidgets::PaddedSeparator(true, true);
|
||||||
|
// gInputViewer.AnalogAngles.Range1.Enabled
|
||||||
|
UIWidgets::EnhancementCheckbox("Highlight ESS Position", CVAR_INPUT_VIEWER("AnalogAngles.Range1.Enabled"));
|
||||||
|
UIWidgets::Tooltip(
|
||||||
|
"Highlights the angle value text when the analog stick is in ESS position (on flat ground)");
|
||||||
|
if (CVarGetInteger(CVAR_INPUT_VIEWER("AnalogAngles.Range1.Enabled"), 0)) {
|
||||||
|
// gInputViewer.AnalogAngles.Range1.Color
|
||||||
|
if (ImGui::ColorEdit4("ESS Color", (float*)&range1Color)) {
|
||||||
|
CVarSetColor(CVAR_INPUT_VIEWER("AnalogAngles.Range1.Color"), vec2Color(range1Color));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
UIWidgets::PaddedSeparator(true, true);
|
||||||
|
// gInputViewer.AnalogAngles.Range2.Enabled
|
||||||
|
UIWidgets::EnhancementCheckbox("Highlight Walking Speed Angles",
|
||||||
|
CVAR_INPUT_VIEWER("AnalogAngles.Range2.Enabled"));
|
||||||
|
UIWidgets::Tooltip("Highlights the angle value text when the analog stick is at an angle that would "
|
||||||
|
"produce a walking speed (on flat ground)\n\n"
|
||||||
|
"Useful for 1.0 Empty Jumpslash Quick Put Away");
|
||||||
|
if (CVarGetInteger(CVAR_INPUT_VIEWER("AnalogAngles.Range2.Enabled"), 0)) {
|
||||||
|
// gInputViewer.AnalogAngles.Range2.Color
|
||||||
|
if (ImGui::ColorEdit4("Walking Speed Color", (float*)&range2Color)) {
|
||||||
|
CVarSetColor(CVAR_INPUT_VIEWER("AnalogAngles.Range2.Color"), vec2Color(range2Color));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ImGui::End();
|
||||||
|
}
|
||||||
|
}
|
49
soh/soh/Enhancements/controls/InputViewer.h
Normal file
@ -0,0 +1,49 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <libultraship/libultraship.h>
|
||||||
|
|
||||||
|
#define CVAR_INPUT_VIEWER(var) "gInputViewer." var
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
BUTTON_OUTLINE_ALWAYS_SHOWN,
|
||||||
|
BUTTON_OUTLINE_NOT_PRESSED,
|
||||||
|
BUTTON_OUTLINE_PRESSED,
|
||||||
|
BUTTON_OUTLINE_ALWAYS_HIDDEN
|
||||||
|
} ButtonOutlineMode;
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
STICK_MODE_ALWAYS_SHOWN,
|
||||||
|
STICK_MODE_HIDDEN_IN_DEADZONE,
|
||||||
|
STICK_MODE_ALWAYS_HIDDEN,
|
||||||
|
} StickMode;
|
||||||
|
|
||||||
|
class InputViewer : public Ship::GuiWindow {
|
||||||
|
public:
|
||||||
|
using GuiWindow::GuiWindow;
|
||||||
|
|
||||||
|
void InitElement() override {};
|
||||||
|
void DrawElement() override;
|
||||||
|
void UpdateElement() override {};
|
||||||
|
|
||||||
|
InputViewer();
|
||||||
|
~InputViewer();
|
||||||
|
|
||||||
|
void Draw();
|
||||||
|
|
||||||
|
private:
|
||||||
|
void RenderButton(std::string btn, std::string btnOutline, int state, ImVec2 size, int outlineMode);
|
||||||
|
};
|
||||||
|
|
||||||
|
class InputViewerSettingsWindow : public Ship::GuiWindow {
|
||||||
|
public:
|
||||||
|
using GuiWindow::GuiWindow;
|
||||||
|
|
||||||
|
void InitElement() override {};
|
||||||
|
void DrawElement() override;
|
||||||
|
void UpdateElement() override {};
|
||||||
|
|
||||||
|
InputViewerSettingsWindow();
|
||||||
|
~InputViewerSettingsWindow();
|
||||||
|
|
||||||
|
void Draw();
|
||||||
|
};
|
2256
soh/soh/Enhancements/controls/SohInputEditorWindow.cpp
Normal file
107
soh/soh/Enhancements/controls/SohInputEditorWindow.h
Normal file
@ -0,0 +1,107 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "stdint.h"
|
||||||
|
#include <libultraship/libultraship.h>
|
||||||
|
#ifndef IMGUI_DEFINE_MATH_OPERATORS
|
||||||
|
#define IMGUI_DEFINE_MATH_OPERATORS
|
||||||
|
#endif
|
||||||
|
#include <imgui.h>
|
||||||
|
#include <unordered_map>
|
||||||
|
#include <string>
|
||||||
|
#include <vector>
|
||||||
|
#include <set>
|
||||||
|
#include <list>
|
||||||
|
|
||||||
|
typedef uint32_t N64ButtonMask;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
const char* label;
|
||||||
|
const char* cVarName;
|
||||||
|
N64ButtonMask defaultBtn;
|
||||||
|
} CustomButtonMap;
|
||||||
|
|
||||||
|
class SohInputEditorWindow : public Ship::GuiWindow {
|
||||||
|
public:
|
||||||
|
using GuiWindow::GuiWindow;
|
||||||
|
~SohInputEditorWindow();
|
||||||
|
|
||||||
|
void DrawButton(const char* label, int32_t n64Btn, int32_t currentPort, int32_t* btnReading);
|
||||||
|
|
||||||
|
void DrawInputChip(const char* buttonName, ImVec4 color);
|
||||||
|
void DrawAnalogPreview(const char* label, ImVec2 stick, float deadzone = 0, bool gyro = false);
|
||||||
|
void DrawControllerSchema();
|
||||||
|
bool TestingRumble();
|
||||||
|
|
||||||
|
protected:
|
||||||
|
void InitElement() override;
|
||||||
|
void DrawElement() override;
|
||||||
|
void UpdateElement() override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
void DrawStickDirectionLine(const char* axisDirectionName, uint8_t port, uint8_t stick, Ship::Direction direction,
|
||||||
|
ImVec4 color);
|
||||||
|
void DrawButtonLine(const char* buttonName, uint8_t port, uint16_t bitmask, ImVec4 color);
|
||||||
|
void DrawButtonLineEditMappingButton(uint8_t port, uint16_t bitmask, std::string id);
|
||||||
|
void DrawButtonLineAddMappingButton(uint8_t port, uint16_t bitmask);
|
||||||
|
|
||||||
|
void DrawStickDirectionLineEditMappingButton(uint8_t port, uint8_t stick, Ship::Direction direction, std::string id);
|
||||||
|
void DrawStickDirectionLineAddMappingButton(uint8_t port, uint8_t stick, Ship::Direction direction);
|
||||||
|
void DrawStickSection(uint8_t port, uint8_t stick, int32_t id, ImVec4 color);
|
||||||
|
|
||||||
|
void DrawRumbleSection(uint8_t port);
|
||||||
|
void DrawRemoveRumbleMappingButton(uint8_t port, std::string id);
|
||||||
|
void DrawAddRumbleMappingButton(uint8_t port);
|
||||||
|
|
||||||
|
void DrawLEDSection(uint8_t port);
|
||||||
|
void DrawRemoveLEDMappingButton(uint8_t port, std::string id);
|
||||||
|
void DrawAddLEDMappingButton(uint8_t port);
|
||||||
|
|
||||||
|
void DrawGyroSection(uint8_t port);
|
||||||
|
void DrawRemoveGyroMappingButton(uint8_t port, std::string id);
|
||||||
|
void DrawAddGyroMappingButton(uint8_t port);
|
||||||
|
|
||||||
|
// Used together for an incomplete linked hash map implementation in order to
|
||||||
|
// map button masks to their names and original mapping on N64
|
||||||
|
std::list<std::pair<N64ButtonMask, const char*>> buttons;
|
||||||
|
std::unordered_map<N64ButtonMask, decltype(buttons)::iterator> buttonNames;
|
||||||
|
void addButtonName(N64ButtonMask mask, const char* name);
|
||||||
|
void DrawMapping(CustomButtonMap& mapping, float labelWidth, N64ButtonMask excludedButtons);
|
||||||
|
void DrawOcarinaControlPanel();
|
||||||
|
void DrawCameraControlPanel();
|
||||||
|
void DrawDpadControlPanel();
|
||||||
|
void DrawMiscControlPanel();
|
||||||
|
|
||||||
|
int32_t mGameInputBlockTimer;
|
||||||
|
int32_t mMappingInputBlockTimer;
|
||||||
|
int32_t mRumbleTimer;
|
||||||
|
std::shared_ptr<Ship::ControllerRumbleMapping> mRumbleMappingToTest;
|
||||||
|
|
||||||
|
// mBitmaskToMappingIds[port][bitmask] = { id0, id1, ... }
|
||||||
|
std::unordered_map<uint8_t, std::unordered_map<uint16_t, std::vector<std::string>>> mBitmaskToMappingIds;
|
||||||
|
|
||||||
|
// mStickDirectionToMappingIds[port][stick][direction] = { id0, id1, ... }
|
||||||
|
std::unordered_map<uint8_t,
|
||||||
|
std::unordered_map<uint8_t, std::unordered_map<Ship::Direction, std::vector<std::string>>>>
|
||||||
|
mStickDirectionToMappingIds;
|
||||||
|
|
||||||
|
void UpdateBitmaskToMappingIds(uint8_t port);
|
||||||
|
void UpdateStickDirectionToMappingIds(uint8_t port);
|
||||||
|
|
||||||
|
void GetButtonColorsForLUSDeviceIndex(Ship::ShipDeviceIndex lusIndex, ImVec4& buttonColor,
|
||||||
|
ImVec4& buttonHoveredColor);
|
||||||
|
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;
|
||||||
|
void DrawButtonDeviceIcons(uint8_t portIndex, std::set<uint16_t> bitmasks);
|
||||||
|
void DrawAnalogStickDeviceIcons(uint8_t portIndex, Ship::Stick stick);
|
||||||
|
void DrawRumbleDeviceIcons(uint8_t portIndex);
|
||||||
|
void DrawGyroDeviceIcons(uint8_t portIndex);
|
||||||
|
void DrawLEDDeviceIcons(uint8_t portIndex);
|
||||||
|
bool mInputEditorPopupOpen;
|
||||||
|
void DrawSetDefaultsButton(uint8_t portIndex);
|
||||||
|
void DrawClearAllButton(uint8_t portIndex);
|
||||||
|
};
|
@ -8,6 +8,29 @@
|
|||||||
ResourceMgr_UnpatchGfxByName(path, name); \
|
ResourceMgr_UnpatchGfxByName(path, name); \
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Not to be confused with tabs, groups are 1:1 with the boxes shown in the UI, grouping them allows us to reset/randomize
|
||||||
|
// every item in a group at once. If you are looking for tabs they are rendered manually in ImGui in `DrawCosmeticsEditor`
|
||||||
|
typedef enum {
|
||||||
|
COSMETICS_GROUP_LINK,
|
||||||
|
COSMETICS_GROUP_MIRRORSHIELD,
|
||||||
|
COSMETICS_GROUP_SWORDS,
|
||||||
|
COSMETICS_GROUP_GLOVES,
|
||||||
|
COSMETICS_GROUP_EQUIPMENT,
|
||||||
|
COSMETICS_GROUP_CONSUMABLE,
|
||||||
|
COSMETICS_GROUP_HUD,
|
||||||
|
COSMETICS_GROUP_KALEIDO,
|
||||||
|
COSMETICS_GROUP_TITLE,
|
||||||
|
COSMETICS_GROUP_NPC,
|
||||||
|
COSMETICS_GROUP_WORLD,
|
||||||
|
COSMETICS_GROUP_MAGIC,
|
||||||
|
COSMETICS_GROUP_ARROWS,
|
||||||
|
COSMETICS_GROUP_SPIN_ATTACK,
|
||||||
|
COSMETICS_GROUP_TRAILS,
|
||||||
|
COSMETICS_GROUP_NAVI,
|
||||||
|
COSMETICS_GROUP_IVAN,
|
||||||
|
COSMETICS_GROUP_MAX
|
||||||
|
} CosmeticGroup;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
const std::string Name;
|
const std::string Name;
|
||||||
const std::string ToolTip;
|
const std::string ToolTip;
|
||||||
@ -26,10 +49,12 @@ static ImGuiTableColumnFlags FlagsCell = ImGuiTableColumnFlags_WidthStretch | Im
|
|||||||
void InitCosmeticsEditor();//Init the menu itself
|
void InitCosmeticsEditor();//Init the menu itself
|
||||||
ImVec4 GetRandomValue(int MaximumPossible);
|
ImVec4 GetRandomValue(int MaximumPossible);
|
||||||
void CosmeticsEditor_RandomizeAll();
|
void CosmeticsEditor_RandomizeAll();
|
||||||
|
void CosmeticsEditor_RandomizeGroup(CosmeticGroup group);
|
||||||
void CosmeticsEditor_ResetAll();
|
void CosmeticsEditor_ResetAll();
|
||||||
|
void CosmeticsEditor_ResetGroup(CosmeticGroup group);
|
||||||
void ApplyOrResetCustomGfxPatches(bool manualChange = true);
|
void ApplyOrResetCustomGfxPatches(bool manualChange = true);
|
||||||
|
|
||||||
class CosmeticsEditorWindow : public LUS::GuiWindow {
|
class CosmeticsEditorWindow : public Ship::GuiWindow {
|
||||||
public:
|
public:
|
||||||
using GuiWindow::GuiWindow;
|
using GuiWindow::GuiWindow;
|
||||||
|
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
#include <libultraship/bridge.h>
|
#include <libultraship/bridge.h>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
#include "soh/OTRGlobals.h"
|
||||||
|
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#include <libultraship/libultra.h>
|
#include <libultraship/libultra.h>
|
||||||
@ -81,7 +82,7 @@ void PatchDekuStickTextureOverflow() {
|
|||||||
const char* dlist = gLinkChildLinkDekuStickDL;
|
const char* dlist = gLinkChildLinkDekuStickDL;
|
||||||
int start = 5;
|
int start = 5;
|
||||||
|
|
||||||
if (!CVarGetInteger("gFixTexturesOOB", 0)) {
|
if (!CVarGetInteger(CVAR_ENHANCEMENT("FixTexturesOOB"), 0)) {
|
||||||
// Unpatch the other texture fix
|
// Unpatch the other texture fix
|
||||||
for (size_t i = 0; i < 7; i++) {
|
for (size_t i = 0; i < 7; i++) {
|
||||||
int instruction = start + (i == 0 ? 0 : i + 1);
|
int instruction = start + (i == 0 ? 0 : i + 1);
|
||||||
@ -121,7 +122,7 @@ void PatchFreezardTextureOverflow() {
|
|||||||
char patchNameBuf[24];
|
char patchNameBuf[24];
|
||||||
|
|
||||||
// Patch using custom overflowed texture
|
// Patch using custom overflowed texture
|
||||||
if (!CVarGetInteger("gFixTexturesOOB", 0)) {
|
if (!CVarGetInteger(CVAR_ENHANCEMENT("FixTexturesOOB"), 0)) {
|
||||||
// Unpatch the other texture fix
|
// Unpatch the other texture fix
|
||||||
for (size_t i = 0; i < 7; i++) {
|
for (size_t i = 0; i < 7; i++) {
|
||||||
int instruction = start + (i == 0 ? 0 : i + 1);
|
int instruction = start + (i == 0 ? 0 : i + 1);
|
||||||
@ -163,7 +164,7 @@ void PatchIronKnuckleTextureOverflow() {
|
|||||||
// Until this is solved, Iron Knuckle will be hardcoded to always display with the "authentic" texture fix
|
// Until this is solved, Iron Knuckle will be hardcoded to always display with the "authentic" texture fix
|
||||||
|
|
||||||
// Patch using custom overflowed texture
|
// Patch using custom overflowed texture
|
||||||
// if (!CVarGetInteger("gFixTexturesOOB", 0)) {
|
// if (!CVarGetInteger(CVAR_ENHANCEMENT("FixTexturesOOB"), 0)) {
|
||||||
// Unpatch the other texture fix
|
// Unpatch the other texture fix
|
||||||
for (size_t i = 0; i < 7; i++) {
|
for (size_t i = 0; i < 7; i++) {
|
||||||
int instruction = start + (i == 0 ? 0 : i + 1);
|
int instruction = start + (i == 0 ? 0 : i + 1);
|
||||||
@ -222,7 +223,7 @@ void PatchMirroredSoldOutGI() {
|
|||||||
G_TX_NOMIRROR | G_TX_CLAMP, 5, 5, G_TX_NOLOD, G_TX_NOLOD),
|
G_TX_NOMIRROR | G_TX_CLAMP, 5, 5, G_TX_NOLOD, G_TX_NOLOD),
|
||||||
};
|
};
|
||||||
|
|
||||||
if (CVarGetInteger("gMirroredWorld", 0)) {
|
if (CVarGetInteger(CVAR_ENHANCEMENT("MirroredWorld"), 0)) {
|
||||||
if (mirroredSoldOutVtx == nullptr) {
|
if (mirroredSoldOutVtx == nullptr) {
|
||||||
// Copy the original vertices that we want to modify (4 at the beginning of the resource)
|
// Copy the original vertices that we want to modify (4 at the beginning of the resource)
|
||||||
mirroredSoldOutVtx = (Vtx*)malloc(sizeof(Vtx) * 4);
|
mirroredSoldOutVtx = (Vtx*)malloc(sizeof(Vtx) * 4);
|
||||||
@ -269,7 +270,7 @@ void PatchMirroredSunSongEtching() {
|
|||||||
G_TX_NOMIRROR | G_TX_CLAMP, 7, 5, G_TX_NOLOD, G_TX_NOLOD)
|
G_TX_NOMIRROR | G_TX_CLAMP, 7, 5, G_TX_NOLOD, G_TX_NOLOD)
|
||||||
};
|
};
|
||||||
|
|
||||||
if (CVarGetInteger("gMirroredWorld", 0)) {
|
if (CVarGetInteger(CVAR_ENHANCEMENT("MirroredWorld"), 0)) {
|
||||||
if (mirroredSunSongVtx == nullptr) {
|
if (mirroredSunSongVtx == nullptr) {
|
||||||
// Copy the original vertices that we want to modify (4 at the beginning of the resource)
|
// Copy the original vertices that we want to modify (4 at the beginning of the resource)
|
||||||
mirroredSunSongVtx = (Vtx*)malloc(sizeof(Vtx) * 4);
|
mirroredSunSongVtx = (Vtx*)malloc(sizeof(Vtx) * 4);
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
#ifdef ENABLE_CROWD_CONTROL
|
#ifdef ENABLE_REMOTE_CONTROL
|
||||||
|
|
||||||
#include "CrowdControl.h"
|
#include "CrowdControl.h"
|
||||||
#include "CrowdControlTypes.h"
|
#include "CrowdControlTypes.h"
|
||||||
@ -17,25 +17,17 @@ extern "C" {
|
|||||||
extern PlayState* gPlayState;
|
extern PlayState* gPlayState;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CrowdControl::Init() {
|
|
||||||
SDLNet_Init();
|
|
||||||
}
|
|
||||||
|
|
||||||
void CrowdControl::Shutdown() {
|
|
||||||
SDLNet_Quit();
|
|
||||||
}
|
|
||||||
|
|
||||||
void CrowdControl::Enable() {
|
void CrowdControl::Enable() {
|
||||||
if (isEnabled) {
|
if (isEnabled) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (SDLNet_ResolveHost(&ip, "127.0.0.1", 43384) == -1) {
|
|
||||||
SPDLOG_ERROR("[CrowdControl] SDLNet_ResolveHost: {}", SDLNet_GetError());
|
|
||||||
}
|
|
||||||
|
|
||||||
isEnabled = true;
|
isEnabled = true;
|
||||||
ccThreadReceive = std::thread(&CrowdControl::ListenToServer, this);
|
GameInteractor::Instance->EnableRemoteInteractor();
|
||||||
|
GameInteractor::Instance->RegisterRemoteJsonHandler([&](nlohmann::json payload) {
|
||||||
|
HandleRemoteData(payload);
|
||||||
|
});
|
||||||
|
|
||||||
ccThreadProcess = std::thread(&CrowdControl::ProcessActiveEffects, this);
|
ccThreadProcess = std::thread(&CrowdControl::ProcessActiveEffects, this);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -45,64 +37,27 @@ void CrowdControl::Disable() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
isEnabled = false;
|
isEnabled = false;
|
||||||
ccThreadReceive.join();
|
|
||||||
ccThreadProcess.join();
|
ccThreadProcess.join();
|
||||||
|
GameInteractor::Instance->DisableRemoteInteractor();
|
||||||
}
|
}
|
||||||
|
|
||||||
void CrowdControl::ListenToServer() {
|
void CrowdControl::HandleRemoteData(nlohmann::json payload) {
|
||||||
while (isEnabled) {
|
Effect* incomingEffect = ParseMessage(payload);
|
||||||
while (!connected && isEnabled) {
|
|
||||||
SPDLOG_TRACE("[CrowdControl] Attempting to make connection to server...");
|
|
||||||
tcpsock = SDLNet_TCP_Open(&ip);
|
|
||||||
|
|
||||||
if (tcpsock) {
|
|
||||||
connected = true;
|
|
||||||
SPDLOG_TRACE("[CrowdControl] Connection to server established!");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
SDLNet_SocketSet socketSet = SDLNet_AllocSocketSet(1);
|
|
||||||
if (tcpsock) {
|
|
||||||
SDLNet_TCP_AddSocket(socketSet, tcpsock);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Listen to socket messages
|
|
||||||
while (connected && tcpsock && isEnabled) {
|
|
||||||
// we check first if socket has data, to not block in the TCP_Recv
|
|
||||||
int socketsReady = SDLNet_CheckSockets(socketSet, 0);
|
|
||||||
|
|
||||||
if (socketsReady == -1) {
|
|
||||||
SPDLOG_ERROR("[CrowdControl] SDLNet_CheckSockets: {}", SDLNet_GetError());
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (socketsReady == 0) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
int len = SDLNet_TCP_Recv(tcpsock, &received, sizeof(received));
|
|
||||||
if (!len || !tcpsock || len == -1) {
|
|
||||||
SPDLOG_ERROR("[CrowdControl] SDLNet_TCP_Recv: {}", SDLNet_GetError());
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
Effect* incomingEffect = ParseMessage(received);
|
|
||||||
if (!incomingEffect) {
|
if (!incomingEffect) {
|
||||||
continue;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// If effect is not a timed effect, execute and return result.
|
// If effect is not a timed effect, execute and return result.
|
||||||
if (!incomingEffect->timeRemaining) {
|
if (!incomingEffect->timeRemaining) {
|
||||||
EffectResult result = CrowdControl::ExecuteEffect(incomingEffect);
|
EffectResult result = CrowdControl::ExecuteEffect(incomingEffect);
|
||||||
EmitMessage(tcpsock, incomingEffect->id, incomingEffect->timeRemaining, result);
|
EmitMessage(incomingEffect->id, incomingEffect->timeRemaining, result);
|
||||||
} else {
|
} else {
|
||||||
// If another timed effect is already active that conflicts with the incoming effect.
|
// If another timed effect is already active that conflicts with the incoming effect.
|
||||||
bool isConflictingEffectActive = false;
|
bool isConflictingEffectActive = false;
|
||||||
for (Effect* effect : activeEffects) {
|
for (Effect* effect : activeEffects) {
|
||||||
if (effect != incomingEffect && effect->category == incomingEffect->category && effect->id < incomingEffect->id) {
|
if (effect != incomingEffect && effect->category == incomingEffect->category && effect->id < incomingEffect->id) {
|
||||||
isConflictingEffectActive = true;
|
isConflictingEffectActive = true;
|
||||||
EmitMessage(tcpsock, incomingEffect->id, incomingEffect->timeRemaining, EffectResult::Retry);
|
EmitMessage(incomingEffect->id, incomingEffect->timeRemaining, EffectResult::Retry);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -111,8 +66,8 @@ void CrowdControl::ListenToServer() {
|
|||||||
// Check if effect can be applied, if it can't, let CC know.
|
// Check if effect can be applied, if it can't, let CC know.
|
||||||
EffectResult result = CrowdControl::CanApplyEffect(incomingEffect);
|
EffectResult result = CrowdControl::CanApplyEffect(incomingEffect);
|
||||||
if (result == EffectResult::Retry || result == EffectResult::Failure) {
|
if (result == EffectResult::Retry || result == EffectResult::Failure) {
|
||||||
EmitMessage(tcpsock, incomingEffect->id, incomingEffect->timeRemaining, result);
|
EmitMessage(incomingEffect->id, incomingEffect->timeRemaining, result);
|
||||||
continue;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
activeEffectsMutex.lock();
|
activeEffectsMutex.lock();
|
||||||
@ -120,14 +75,6 @@ void CrowdControl::ListenToServer() {
|
|||||||
activeEffectsMutex.unlock();
|
activeEffectsMutex.unlock();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if (connected) {
|
|
||||||
SDLNet_TCP_Close(tcpsock);
|
|
||||||
connected = false;
|
|
||||||
SPDLOG_TRACE("[CrowdControl] Ending Listen thread...");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void CrowdControl::ProcessActiveEffects() {
|
void CrowdControl::ProcessActiveEffects() {
|
||||||
@ -147,13 +94,13 @@ void CrowdControl::ProcessActiveEffects() {
|
|||||||
if (effect->timeRemaining <= 0) {
|
if (effect->timeRemaining <= 0) {
|
||||||
it = activeEffects.erase(std::remove(activeEffects.begin(), activeEffects.end(), effect),
|
it = activeEffects.erase(std::remove(activeEffects.begin(), activeEffects.end(), effect),
|
||||||
activeEffects.end());
|
activeEffects.end());
|
||||||
GameInteractor::RemoveEffect(effect->giEffect);
|
GameInteractor::RemoveEffect(dynamic_cast<RemovableGameInteractionEffect*>(effect->giEffect));
|
||||||
delete effect;
|
delete effect;
|
||||||
} else {
|
} else {
|
||||||
// If we have a success after previously being paused, tell CC to resume timer.
|
// If we have a success after previously being paused, tell CC to resume timer.
|
||||||
if (effect->isPaused) {
|
if (effect->isPaused) {
|
||||||
effect->isPaused = false;
|
effect->isPaused = false;
|
||||||
EmitMessage(tcpsock, effect->id, effect->timeRemaining, EffectResult::Resumed);
|
EmitMessage(effect->id, effect->timeRemaining, EffectResult::Resumed);
|
||||||
// If not paused before, subtract time from the timer and send a Success event if
|
// If not paused before, subtract time from the timer and send a Success event if
|
||||||
// the result is different from the last time this was ran.
|
// the result is different from the last time this was ran.
|
||||||
// Timed events are put on a thread that runs once per second.
|
// Timed events are put on a thread that runs once per second.
|
||||||
@ -161,7 +108,7 @@ void CrowdControl::ProcessActiveEffects() {
|
|||||||
effect->timeRemaining -= 1000;
|
effect->timeRemaining -= 1000;
|
||||||
if (result != effect->lastExecutionResult) {
|
if (result != effect->lastExecutionResult) {
|
||||||
effect->lastExecutionResult = result;
|
effect->lastExecutionResult = result;
|
||||||
EmitMessage(tcpsock, effect->id, effect->timeRemaining, EffectResult::Success);
|
EmitMessage(effect->id, effect->timeRemaining, EffectResult::Success);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
it++;
|
it++;
|
||||||
@ -169,7 +116,7 @@ void CrowdControl::ProcessActiveEffects() {
|
|||||||
} else { // Timed effects only do Success or Retry
|
} else { // Timed effects only do Success or Retry
|
||||||
if (!effect->isPaused && effect->timeRemaining > 0) {
|
if (!effect->isPaused && effect->timeRemaining > 0) {
|
||||||
effect->isPaused = true;
|
effect->isPaused = true;
|
||||||
EmitMessage(tcpsock, effect->id, effect->timeRemaining, EffectResult::Paused);
|
EmitMessage(effect->id, effect->timeRemaining, EffectResult::Paused);
|
||||||
}
|
}
|
||||||
it++;
|
it++;
|
||||||
}
|
}
|
||||||
@ -182,7 +129,7 @@ void CrowdControl::ProcessActiveEffects() {
|
|||||||
SPDLOG_TRACE("[CrowdControl] Ending Process thread...");
|
SPDLOG_TRACE("[CrowdControl] Ending Process thread...");
|
||||||
}
|
}
|
||||||
|
|
||||||
void CrowdControl::EmitMessage(TCPsocket socket, uint32_t eventId, long timeRemaining, EffectResult status) {
|
void CrowdControl::EmitMessage(uint32_t eventId, long timeRemaining, EffectResult status) {
|
||||||
nlohmann::json payload;
|
nlohmann::json payload;
|
||||||
|
|
||||||
payload["id"] = eventId;
|
payload["id"] = eventId;
|
||||||
@ -190,8 +137,9 @@ void CrowdControl::EmitMessage(TCPsocket socket, uint32_t eventId, long timeRema
|
|||||||
payload["timeRemaining"] = timeRemaining;
|
payload["timeRemaining"] = timeRemaining;
|
||||||
payload["status"] = status;
|
payload["status"] = status;
|
||||||
|
|
||||||
std::string jsonPayload = payload.dump();
|
SPDLOG_INFO("[CrowdControl] Sending payload:\n{}", payload.dump());
|
||||||
SDLNet_TCP_Send(socket, jsonPayload.c_str(), jsonPayload.size() + 1);
|
|
||||||
|
GameInteractor::Instance->TransmitJsonToRemote(payload);
|
||||||
}
|
}
|
||||||
|
|
||||||
CrowdControl::EffectResult CrowdControl::ExecuteEffect(Effect* effect) {
|
CrowdControl::EffectResult CrowdControl::ExecuteEffect(Effect* effect) {
|
||||||
@ -229,13 +177,14 @@ CrowdControl::EffectResult CrowdControl::TranslateGiEnum(GameInteractionEffectQu
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
CrowdControl::Effect* CrowdControl::ParseMessage(char payload[512]) {
|
CrowdControl::Effect* CrowdControl::ParseMessage(nlohmann::json dataReceived) {
|
||||||
nlohmann::json dataReceived = nlohmann::json::parse(payload, nullptr, false);
|
if (!dataReceived.contains("id") || !dataReceived.contains("type")) {
|
||||||
if (dataReceived.is_discarded()) {
|
SPDLOG_ERROR("[CrowdControl] Invalid payload received:\n{}", dataReceived.dump());
|
||||||
SPDLOG_ERROR("Error parsing JSON");
|
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SPDLOG_INFO("[CrowdControl] Received payload:\n{}", dataReceived.dump());
|
||||||
|
|
||||||
Effect* effect = new Effect();
|
Effect* effect = new Effect();
|
||||||
effect->lastExecutionResult = EffectResult::Initiate;
|
effect->lastExecutionResult = EffectResult::Initiate;
|
||||||
effect->id = dataReceived["id"];
|
effect->id = dataReceived["id"];
|
||||||
@ -333,13 +282,13 @@ CrowdControl::Effect* CrowdControl::ParseMessage(char payload[512]) {
|
|||||||
effect->category = kEffectCatDamageTaken;
|
effect->category = kEffectCatDamageTaken;
|
||||||
effect->timeRemaining = 30000;
|
effect->timeRemaining = 30000;
|
||||||
effect->giEffect = new GameInteractionEffect::ModifyDefenseModifier();
|
effect->giEffect = new GameInteractionEffect::ModifyDefenseModifier();
|
||||||
effect->giEffect->parameters[0] = 2;
|
dynamic_cast<ParameterizedGameInteractionEffect*>(effect->giEffect)->parameters[0] = 2;
|
||||||
break;
|
break;
|
||||||
case kEffectTakeDoubleDamage:
|
case kEffectTakeDoubleDamage:
|
||||||
effect->category = kEffectCatDamageTaken;
|
effect->category = kEffectCatDamageTaken;
|
||||||
effect->timeRemaining = 30000;
|
effect->timeRemaining = 30000;
|
||||||
effect->giEffect = new GameInteractionEffect::ModifyDefenseModifier();
|
effect->giEffect = new GameInteractionEffect::ModifyDefenseModifier();
|
||||||
effect->giEffect->parameters[0] = -2;
|
dynamic_cast<ParameterizedGameInteractionEffect*>(effect->giEffect)->parameters[0] = -2;
|
||||||
break;
|
break;
|
||||||
case kEffectOneHitKo:
|
case kEffectOneHitKo:
|
||||||
effect->category = kEffectCatDamageTaken;
|
effect->category = kEffectCatDamageTaken;
|
||||||
@ -356,37 +305,37 @@ CrowdControl::Effect* CrowdControl::ParseMessage(char payload[512]) {
|
|||||||
effect->category = kEffectCatSpeed;
|
effect->category = kEffectCatSpeed;
|
||||||
effect->timeRemaining = 30000;
|
effect->timeRemaining = 30000;
|
||||||
effect->giEffect = new GameInteractionEffect::ModifyRunSpeedModifier();
|
effect->giEffect = new GameInteractionEffect::ModifyRunSpeedModifier();
|
||||||
effect->giEffect->parameters[0] = 2;
|
dynamic_cast<ParameterizedGameInteractionEffect*>(effect->giEffect)->parameters[0] = 2;
|
||||||
break;
|
break;
|
||||||
case kEffectDecreaseSpeed:
|
case kEffectDecreaseSpeed:
|
||||||
effect->category = kEffectCatSpeed;
|
effect->category = kEffectCatSpeed;
|
||||||
effect->timeRemaining = 30000;
|
effect->timeRemaining = 30000;
|
||||||
effect->giEffect = new GameInteractionEffect::ModifyRunSpeedModifier();
|
effect->giEffect = new GameInteractionEffect::ModifyRunSpeedModifier();
|
||||||
effect->giEffect->parameters[0] = -2;
|
dynamic_cast<ParameterizedGameInteractionEffect*>(effect->giEffect)->parameters[0] = -2;
|
||||||
break;
|
break;
|
||||||
case kEffectLowGravity:
|
case kEffectLowGravity:
|
||||||
effect->category = kEffectCatGravity;
|
effect->category = kEffectCatGravity;
|
||||||
effect->timeRemaining = 30000;
|
effect->timeRemaining = 30000;
|
||||||
effect->giEffect = new GameInteractionEffect::ModifyGravity();
|
effect->giEffect = new GameInteractionEffect::ModifyGravity();
|
||||||
effect->giEffect->parameters[0] = GI_GRAVITY_LEVEL_LIGHT;
|
dynamic_cast<ParameterizedGameInteractionEffect*>(effect->giEffect)->parameters[0] = GI_GRAVITY_LEVEL_LIGHT;
|
||||||
break;
|
break;
|
||||||
case kEffectHighGravity:
|
case kEffectHighGravity:
|
||||||
effect->category = kEffectCatGravity;
|
effect->category = kEffectCatGravity;
|
||||||
effect->timeRemaining = 30000;
|
effect->timeRemaining = 30000;
|
||||||
effect->giEffect = new GameInteractionEffect::ModifyGravity();
|
effect->giEffect = new GameInteractionEffect::ModifyGravity();
|
||||||
effect->giEffect->parameters[0] = GI_GRAVITY_LEVEL_HEAVY;
|
dynamic_cast<ParameterizedGameInteractionEffect*>(effect->giEffect)->parameters[0] = GI_GRAVITY_LEVEL_HEAVY;
|
||||||
break;
|
break;
|
||||||
case kEffectForceIronBoots:
|
case kEffectForceIronBoots:
|
||||||
effect->category = kEffectCatBoots;
|
effect->category = kEffectCatBoots;
|
||||||
effect->timeRemaining = 30000;
|
effect->timeRemaining = 30000;
|
||||||
effect->giEffect = new GameInteractionEffect::ForceEquipBoots();
|
effect->giEffect = new GameInteractionEffect::ForceEquipBoots();
|
||||||
effect->giEffect->parameters[0] = EQUIP_VALUE_BOOTS_IRON;
|
dynamic_cast<ParameterizedGameInteractionEffect*>(effect->giEffect)->parameters[0] = EQUIP_VALUE_BOOTS_IRON;
|
||||||
break;
|
break;
|
||||||
case kEffectForceHoverBoots:
|
case kEffectForceHoverBoots:
|
||||||
effect->category = kEffectCatBoots;
|
effect->category = kEffectCatBoots;
|
||||||
effect->timeRemaining = 30000;
|
effect->timeRemaining = 30000;
|
||||||
effect->giEffect = new GameInteractionEffect::ForceEquipBoots();
|
effect->giEffect = new GameInteractionEffect::ForceEquipBoots();
|
||||||
effect->giEffect->parameters[0] = EQUIP_VALUE_BOOTS_HOVER;
|
dynamic_cast<ParameterizedGameInteractionEffect*>(effect->giEffect)->parameters[0] = EQUIP_VALUE_BOOTS_HOVER;
|
||||||
break;
|
break;
|
||||||
case kEffectSlipperyFloor:
|
case kEffectSlipperyFloor:
|
||||||
effect->category = kEffectCatSlipperyFloor;
|
effect->category = kEffectCatSlipperyFloor;
|
||||||
@ -412,23 +361,23 @@ CrowdControl::Effect* CrowdControl::ParseMessage(char payload[512]) {
|
|||||||
// Hurt or Heal Link
|
// Hurt or Heal Link
|
||||||
case kEffectEmptyHeart:
|
case kEffectEmptyHeart:
|
||||||
effect->giEffect = new GameInteractionEffect::ModifyHealth();
|
effect->giEffect = new GameInteractionEffect::ModifyHealth();
|
||||||
effect->giEffect->parameters[0] = receivedParameter * -1;
|
dynamic_cast<ParameterizedGameInteractionEffect*>(effect->giEffect)->parameters[0] = receivedParameter * -1;
|
||||||
break;
|
break;
|
||||||
case kEffectFillHeart:
|
case kEffectFillHeart:
|
||||||
effect->giEffect = new GameInteractionEffect::ModifyHealth();
|
effect->giEffect = new GameInteractionEffect::ModifyHealth();
|
||||||
effect->giEffect->parameters[0] = receivedParameter;
|
dynamic_cast<ParameterizedGameInteractionEffect*>(effect->giEffect)->parameters[0] = receivedParameter;
|
||||||
break;
|
break;
|
||||||
case kEffectKnockbackLinkWeak:
|
case kEffectKnockbackLinkWeak:
|
||||||
effect->giEffect = new GameInteractionEffect::KnockbackPlayer();
|
effect->giEffect = new GameInteractionEffect::KnockbackPlayer();
|
||||||
effect->giEffect->parameters[0] = 1;
|
dynamic_cast<ParameterizedGameInteractionEffect*>(effect->giEffect)->parameters[0] = 1;
|
||||||
break;
|
break;
|
||||||
case kEffectKnockbackLinkStrong:
|
case kEffectKnockbackLinkStrong:
|
||||||
effect->giEffect = new GameInteractionEffect::KnockbackPlayer();
|
effect->giEffect = new GameInteractionEffect::KnockbackPlayer();
|
||||||
effect->giEffect->parameters[0] = 3;
|
dynamic_cast<ParameterizedGameInteractionEffect*>(effect->giEffect)->parameters[0] = 3;
|
||||||
break;
|
break;
|
||||||
case kEffectKnockbackLinkMega:
|
case kEffectKnockbackLinkMega:
|
||||||
effect->giEffect = new GameInteractionEffect::KnockbackPlayer();
|
effect->giEffect = new GameInteractionEffect::KnockbackPlayer();
|
||||||
effect->giEffect->parameters[0] = 6;
|
dynamic_cast<ParameterizedGameInteractionEffect*>(effect->giEffect)->parameters[0] = 6;
|
||||||
break;
|
break;
|
||||||
case kEffectBurnLink:
|
case kEffectBurnLink:
|
||||||
effect->giEffect = new GameInteractionEffect::BurnPlayer();
|
effect->giEffect = new GameInteractionEffect::BurnPlayer();
|
||||||
@ -441,109 +390,109 @@ CrowdControl::Effect* CrowdControl::ParseMessage(char payload[512]) {
|
|||||||
break;
|
break;
|
||||||
case kEffectKillLink:
|
case kEffectKillLink:
|
||||||
effect->giEffect = new GameInteractionEffect::SetPlayerHealth();
|
effect->giEffect = new GameInteractionEffect::SetPlayerHealth();
|
||||||
effect->giEffect->parameters[0] = 0;
|
dynamic_cast<ParameterizedGameInteractionEffect*>(effect->giEffect)->parameters[0] = 0;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
// Give Items and Consumables
|
// Give Items and Consumables
|
||||||
case kEffectAddHeartContainer:
|
case kEffectAddHeartContainer:
|
||||||
effect->giEffect = new GameInteractionEffect::ModifyHeartContainers();
|
effect->giEffect = new GameInteractionEffect::ModifyHeartContainers();
|
||||||
effect->giEffect->parameters[0] = 1;
|
dynamic_cast<ParameterizedGameInteractionEffect*>(effect->giEffect)->parameters[0] = 1;
|
||||||
break;
|
break;
|
||||||
case kEffectFillMagic:
|
case kEffectFillMagic:
|
||||||
effect->giEffect = new GameInteractionEffect::FillMagic();
|
effect->giEffect = new GameInteractionEffect::FillMagic();
|
||||||
break;
|
break;
|
||||||
case kEffectAddRupees:
|
case kEffectAddRupees:
|
||||||
effect->giEffect = new GameInteractionEffect::ModifyRupees();
|
effect->giEffect = new GameInteractionEffect::ModifyRupees();
|
||||||
effect->giEffect->parameters[0] = receivedParameter;
|
dynamic_cast<ParameterizedGameInteractionEffect*>(effect->giEffect)->parameters[0] = receivedParameter;
|
||||||
break;
|
break;
|
||||||
case kEffectGiveDekuShield:
|
case kEffectGiveDekuShield:
|
||||||
effect->giEffect = new GameInteractionEffect::GiveOrTakeShield();
|
effect->giEffect = new GameInteractionEffect::GiveOrTakeShield();
|
||||||
effect->giEffect->parameters[0] = ITEM_SHIELD_DEKU;
|
dynamic_cast<ParameterizedGameInteractionEffect*>(effect->giEffect)->parameters[0] = ITEM_SHIELD_DEKU;
|
||||||
break;
|
break;
|
||||||
case kEffectGiveHylianShield:
|
case kEffectGiveHylianShield:
|
||||||
effect->giEffect = new GameInteractionEffect::GiveOrTakeShield();
|
effect->giEffect = new GameInteractionEffect::GiveOrTakeShield();
|
||||||
effect->giEffect->parameters[0] = ITEM_SHIELD_HYLIAN;
|
dynamic_cast<ParameterizedGameInteractionEffect*>(effect->giEffect)->parameters[0] = ITEM_SHIELD_HYLIAN;
|
||||||
break;
|
break;
|
||||||
case kEffectRefillSticks:
|
case kEffectRefillSticks:
|
||||||
effect->giEffect = new GameInteractionEffect::AddOrTakeAmmo();
|
effect->giEffect = new GameInteractionEffect::AddOrTakeAmmo();
|
||||||
effect->giEffect->parameters[0] = receivedParameter;
|
dynamic_cast<ParameterizedGameInteractionEffect*>(effect->giEffect)->parameters[0] = receivedParameter;
|
||||||
effect->giEffect->parameters[1] = ITEM_STICK;
|
dynamic_cast<ParameterizedGameInteractionEffect*>(effect->giEffect)->parameters[1] = ITEM_STICK;
|
||||||
break;
|
break;
|
||||||
case kEffectRefillNuts:
|
case kEffectRefillNuts:
|
||||||
effect->giEffect = new GameInteractionEffect::AddOrTakeAmmo();
|
effect->giEffect = new GameInteractionEffect::AddOrTakeAmmo();
|
||||||
effect->giEffect->parameters[0] = receivedParameter;
|
dynamic_cast<ParameterizedGameInteractionEffect*>(effect->giEffect)->parameters[0] = receivedParameter;
|
||||||
effect->giEffect->parameters[1] = ITEM_NUT;
|
dynamic_cast<ParameterizedGameInteractionEffect*>(effect->giEffect)->parameters[1] = ITEM_NUT;
|
||||||
break;
|
break;
|
||||||
case kEffectRefillBombs:
|
case kEffectRefillBombs:
|
||||||
effect->giEffect = new GameInteractionEffect::AddOrTakeAmmo();
|
effect->giEffect = new GameInteractionEffect::AddOrTakeAmmo();
|
||||||
effect->giEffect->parameters[0] = receivedParameter;
|
dynamic_cast<ParameterizedGameInteractionEffect*>(effect->giEffect)->parameters[0] = receivedParameter;
|
||||||
effect->giEffect->parameters[1] = ITEM_BOMB;
|
dynamic_cast<ParameterizedGameInteractionEffect*>(effect->giEffect)->parameters[1] = ITEM_BOMB;
|
||||||
break;
|
break;
|
||||||
case kEffectRefillSeeds:
|
case kEffectRefillSeeds:
|
||||||
effect->giEffect = new GameInteractionEffect::AddOrTakeAmmo();
|
effect->giEffect = new GameInteractionEffect::AddOrTakeAmmo();
|
||||||
effect->giEffect->parameters[0] = receivedParameter;
|
dynamic_cast<ParameterizedGameInteractionEffect*>(effect->giEffect)->parameters[0] = receivedParameter;
|
||||||
effect->giEffect->parameters[1] = ITEM_SLINGSHOT;
|
dynamic_cast<ParameterizedGameInteractionEffect*>(effect->giEffect)->parameters[1] = ITEM_SLINGSHOT;
|
||||||
break;
|
break;
|
||||||
case kEffectRefillArrows:
|
case kEffectRefillArrows:
|
||||||
effect->giEffect = new GameInteractionEffect::AddOrTakeAmmo();
|
effect->giEffect = new GameInteractionEffect::AddOrTakeAmmo();
|
||||||
effect->giEffect->parameters[0] = receivedParameter;
|
dynamic_cast<ParameterizedGameInteractionEffect*>(effect->giEffect)->parameters[0] = receivedParameter;
|
||||||
effect->giEffect->parameters[1] = ITEM_BOW;
|
dynamic_cast<ParameterizedGameInteractionEffect*>(effect->giEffect)->parameters[1] = ITEM_BOW;
|
||||||
break;
|
break;
|
||||||
case kEffectRefillBombchus:
|
case kEffectRefillBombchus:
|
||||||
effect->giEffect = new GameInteractionEffect::AddOrTakeAmmo();
|
effect->giEffect = new GameInteractionEffect::AddOrTakeAmmo();
|
||||||
effect->giEffect->parameters[0] = receivedParameter;
|
dynamic_cast<ParameterizedGameInteractionEffect*>(effect->giEffect)->parameters[0] = receivedParameter;
|
||||||
effect->giEffect->parameters[1] = ITEM_BOMBCHU;
|
dynamic_cast<ParameterizedGameInteractionEffect*>(effect->giEffect)->parameters[1] = ITEM_BOMBCHU;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
// Take Items and Consumables
|
// Take Items and Consumables
|
||||||
case kEffectRemoveHeartContainer:
|
case kEffectRemoveHeartContainer:
|
||||||
effect->giEffect = new GameInteractionEffect::ModifyHeartContainers();
|
effect->giEffect = new GameInteractionEffect::ModifyHeartContainers();
|
||||||
effect->giEffect->parameters[0] = -1;
|
dynamic_cast<ParameterizedGameInteractionEffect*>(effect->giEffect)->parameters[0] = -1;
|
||||||
break;
|
break;
|
||||||
case kEffectEmptyMagic:
|
case kEffectEmptyMagic:
|
||||||
effect->giEffect = new GameInteractionEffect::EmptyMagic();
|
effect->giEffect = new GameInteractionEffect::EmptyMagic();
|
||||||
break;
|
break;
|
||||||
case kEffectRemoveRupees:
|
case kEffectRemoveRupees:
|
||||||
effect->giEffect = new GameInteractionEffect::ModifyRupees();
|
effect->giEffect = new GameInteractionEffect::ModifyRupees();
|
||||||
effect->giEffect->parameters[0] = receivedParameter * -1;
|
dynamic_cast<ParameterizedGameInteractionEffect*>(effect->giEffect)->parameters[0] = receivedParameter * -1;
|
||||||
break;
|
break;
|
||||||
case kEffectTakeDekuShield:
|
case kEffectTakeDekuShield:
|
||||||
effect->giEffect = new GameInteractionEffect::GiveOrTakeShield();
|
effect->giEffect = new GameInteractionEffect::GiveOrTakeShield();
|
||||||
effect->giEffect->parameters[0] = -ITEM_SHIELD_DEKU;
|
dynamic_cast<ParameterizedGameInteractionEffect*>(effect->giEffect)->parameters[0] = -ITEM_SHIELD_DEKU;
|
||||||
break;
|
break;
|
||||||
case kEffectTakeHylianShield:
|
case kEffectTakeHylianShield:
|
||||||
effect->giEffect = new GameInteractionEffect::GiveOrTakeShield();
|
effect->giEffect = new GameInteractionEffect::GiveOrTakeShield();
|
||||||
effect->giEffect->parameters[0] = -ITEM_SHIELD_HYLIAN;
|
dynamic_cast<ParameterizedGameInteractionEffect*>(effect->giEffect)->parameters[0] = -ITEM_SHIELD_HYLIAN;
|
||||||
break;
|
break;
|
||||||
case kEffectTakeSticks:
|
case kEffectTakeSticks:
|
||||||
effect->giEffect = new GameInteractionEffect::AddOrTakeAmmo();
|
effect->giEffect = new GameInteractionEffect::AddOrTakeAmmo();
|
||||||
effect->giEffect->parameters[0] = receivedParameter * -1;
|
dynamic_cast<ParameterizedGameInteractionEffect*>(effect->giEffect)->parameters[0] = receivedParameter * -1;
|
||||||
effect->giEffect->parameters[1] = ITEM_STICK;
|
dynamic_cast<ParameterizedGameInteractionEffect*>(effect->giEffect)->parameters[1] = ITEM_STICK;
|
||||||
break;
|
break;
|
||||||
case kEffectTakeNuts:
|
case kEffectTakeNuts:
|
||||||
effect->giEffect = new GameInteractionEffect::AddOrTakeAmmo();
|
effect->giEffect = new GameInteractionEffect::AddOrTakeAmmo();
|
||||||
effect->giEffect->parameters[0] = receivedParameter * -1;
|
dynamic_cast<ParameterizedGameInteractionEffect*>(effect->giEffect)->parameters[0] = receivedParameter * -1;
|
||||||
effect->giEffect->parameters[1] = ITEM_NUT;
|
dynamic_cast<ParameterizedGameInteractionEffect*>(effect->giEffect)->parameters[1] = ITEM_NUT;
|
||||||
break;
|
break;
|
||||||
case kEffectTakeBombs:
|
case kEffectTakeBombs:
|
||||||
effect->giEffect = new GameInteractionEffect::AddOrTakeAmmo();
|
effect->giEffect = new GameInteractionEffect::AddOrTakeAmmo();
|
||||||
effect->giEffect->parameters[0] = receivedParameter * -1;
|
dynamic_cast<ParameterizedGameInteractionEffect*>(effect->giEffect)->parameters[0] = receivedParameter * -1;
|
||||||
effect->giEffect->parameters[1] = ITEM_BOMB;
|
dynamic_cast<ParameterizedGameInteractionEffect*>(effect->giEffect)->parameters[1] = ITEM_BOMB;
|
||||||
break;
|
break;
|
||||||
case kEffectTakeSeeds:
|
case kEffectTakeSeeds:
|
||||||
effect->giEffect = new GameInteractionEffect::AddOrTakeAmmo();
|
effect->giEffect = new GameInteractionEffect::AddOrTakeAmmo();
|
||||||
effect->giEffect->parameters[0] = receivedParameter * -1;
|
dynamic_cast<ParameterizedGameInteractionEffect*>(effect->giEffect)->parameters[0] = receivedParameter * -1;
|
||||||
effect->giEffect->parameters[1] = ITEM_SLINGSHOT;
|
dynamic_cast<ParameterizedGameInteractionEffect*>(effect->giEffect)->parameters[1] = ITEM_SLINGSHOT;
|
||||||
break;
|
break;
|
||||||
case kEffectTakeArrows:
|
case kEffectTakeArrows:
|
||||||
effect->giEffect = new GameInteractionEffect::AddOrTakeAmmo();
|
effect->giEffect = new GameInteractionEffect::AddOrTakeAmmo();
|
||||||
effect->giEffect->parameters[0] = receivedParameter * -1;
|
dynamic_cast<ParameterizedGameInteractionEffect*>(effect->giEffect)->parameters[0] = receivedParameter * -1;
|
||||||
effect->giEffect->parameters[1] = ITEM_BOW;
|
dynamic_cast<ParameterizedGameInteractionEffect*>(effect->giEffect)->parameters[1] = ITEM_BOW;
|
||||||
break;
|
break;
|
||||||
case kEffectTakeBombchus:
|
case kEffectTakeBombchus:
|
||||||
effect->giEffect = new GameInteractionEffect::AddOrTakeAmmo();
|
effect->giEffect = new GameInteractionEffect::AddOrTakeAmmo();
|
||||||
effect->giEffect->parameters[0] = receivedParameter * -1;
|
dynamic_cast<ParameterizedGameInteractionEffect*>(effect->giEffect)->parameters[0] = receivedParameter * -1;
|
||||||
effect->giEffect->parameters[1] = ITEM_BOMBCHU;
|
dynamic_cast<ParameterizedGameInteractionEffect*>(effect->giEffect)->parameters[1] = ITEM_BOMBCHU;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
// Link Size Modifiers
|
// Link Size Modifiers
|
||||||
@ -551,25 +500,25 @@ CrowdControl::Effect* CrowdControl::ParseMessage(char payload[512]) {
|
|||||||
effect->category = kEffectCatLinkSize;
|
effect->category = kEffectCatLinkSize;
|
||||||
effect->timeRemaining = 30000;
|
effect->timeRemaining = 30000;
|
||||||
effect->giEffect = new GameInteractionEffect::ModifyLinkSize();
|
effect->giEffect = new GameInteractionEffect::ModifyLinkSize();
|
||||||
effect->giEffect->parameters[0] = GI_LINK_SIZE_GIANT;
|
dynamic_cast<ParameterizedGameInteractionEffect*>(effect->giEffect)->parameters[0] = GI_LINK_SIZE_GIANT;
|
||||||
break;
|
break;
|
||||||
case kEffectMinishLink:
|
case kEffectMinishLink:
|
||||||
effect->category = kEffectCatLinkSize;
|
effect->category = kEffectCatLinkSize;
|
||||||
effect->timeRemaining = 30000;
|
effect->timeRemaining = 30000;
|
||||||
effect->giEffect = new GameInteractionEffect::ModifyLinkSize();
|
effect->giEffect = new GameInteractionEffect::ModifyLinkSize();
|
||||||
effect->giEffect->parameters[0] = GI_LINK_SIZE_MINISH;
|
dynamic_cast<ParameterizedGameInteractionEffect*>(effect->giEffect)->parameters[0] = GI_LINK_SIZE_MINISH;
|
||||||
break;
|
break;
|
||||||
case kEffectPaperLink:
|
case kEffectPaperLink:
|
||||||
effect->category = kEffectCatLinkSize;
|
effect->category = kEffectCatLinkSize;
|
||||||
effect->timeRemaining = 30000;
|
effect->timeRemaining = 30000;
|
||||||
effect->giEffect = new GameInteractionEffect::ModifyLinkSize();
|
effect->giEffect = new GameInteractionEffect::ModifyLinkSize();
|
||||||
effect->giEffect->parameters[0] = GI_LINK_SIZE_PAPER;
|
dynamic_cast<ParameterizedGameInteractionEffect*>(effect->giEffect)->parameters[0] = GI_LINK_SIZE_PAPER;
|
||||||
break;
|
break;
|
||||||
case kEffectSquishedLink:
|
case kEffectSquishedLink:
|
||||||
effect->category = kEffectCatLinkSize;
|
effect->category = kEffectCatLinkSize;
|
||||||
effect->timeRemaining = 30000;
|
effect->timeRemaining = 30000;
|
||||||
effect->giEffect = new GameInteractionEffect::ModifyLinkSize();
|
effect->giEffect = new GameInteractionEffect::ModifyLinkSize();
|
||||||
effect->giEffect->parameters[0] = GI_LINK_SIZE_SQUISHED;
|
dynamic_cast<ParameterizedGameInteractionEffect*>(effect->giEffect)->parameters[0] = GI_LINK_SIZE_SQUISHED;
|
||||||
break;
|
break;
|
||||||
case kEffectInvisibleLink:
|
case kEffectInvisibleLink:
|
||||||
effect->category = kEffectCatLinkSize;
|
effect->category = kEffectCatLinkSize;
|
||||||
@ -585,11 +534,11 @@ CrowdControl::Effect* CrowdControl::ParseMessage(char payload[512]) {
|
|||||||
break;
|
break;
|
||||||
case kEffectSetTimeToDawn:
|
case kEffectSetTimeToDawn:
|
||||||
effect->giEffect = new GameInteractionEffect::SetTimeOfDay();
|
effect->giEffect = new GameInteractionEffect::SetTimeOfDay();
|
||||||
effect->giEffect->parameters[0] = GI_TIMEOFDAY_DAWN;
|
dynamic_cast<ParameterizedGameInteractionEffect*>(effect->giEffect)->parameters[0] = GI_TIMEOFDAY_DAWN;
|
||||||
break;
|
break;
|
||||||
case kEffectSetTimeToDusk:
|
case kEffectSetTimeToDusk:
|
||||||
effect->giEffect = new GameInteractionEffect::SetTimeOfDay();
|
effect->giEffect = new GameInteractionEffect::SetTimeOfDay();
|
||||||
effect->giEffect->parameters[0] = GI_TIMEOFDAY_DUSK;
|
dynamic_cast<ParameterizedGameInteractionEffect*>(effect->giEffect)->parameters[0] = GI_TIMEOFDAY_DUSK;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
// Visual Effects
|
// Visual Effects
|
||||||
@ -632,186 +581,186 @@ CrowdControl::Effect* CrowdControl::ParseMessage(char payload[512]) {
|
|||||||
effect->category = kEffectCatRandomButtons;
|
effect->category = kEffectCatRandomButtons;
|
||||||
effect->timeRemaining = 30000;
|
effect->timeRemaining = 30000;
|
||||||
effect->giEffect = new GameInteractionEffect::PressRandomButton();
|
effect->giEffect = new GameInteractionEffect::PressRandomButton();
|
||||||
effect->giEffect->parameters[0] = 30;
|
dynamic_cast<ParameterizedGameInteractionEffect*>(effect->giEffect)->parameters[0] = 30;
|
||||||
break;
|
break;
|
||||||
case kEffectClearCbuttons:
|
case kEffectClearCbuttons:
|
||||||
effect->giEffect = new GameInteractionEffect::ClearAssignedButtons();
|
effect->giEffect = new GameInteractionEffect::ClearAssignedButtons();
|
||||||
effect->giEffect->parameters[0] = GI_BUTTONS_CBUTTONS;
|
dynamic_cast<ParameterizedGameInteractionEffect*>(effect->giEffect)->parameters[0] = GI_BUTTONS_CBUTTONS;
|
||||||
break;
|
break;
|
||||||
case kEffectClearDpad:
|
case kEffectClearDpad:
|
||||||
effect->giEffect = new GameInteractionEffect::ClearAssignedButtons();
|
effect->giEffect = new GameInteractionEffect::ClearAssignedButtons();
|
||||||
effect->giEffect->parameters[0] = GI_BUTTONS_DPAD;
|
dynamic_cast<ParameterizedGameInteractionEffect*>(effect->giEffect)->parameters[0] = GI_BUTTONS_DPAD;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
// Teleport Player
|
// Teleport Player
|
||||||
case kEffectTpLinksHouse:
|
case kEffectTpLinksHouse:
|
||||||
effect->giEffect = new GameInteractionEffect::TeleportPlayer();
|
effect->giEffect = new GameInteractionEffect::TeleportPlayer();
|
||||||
effect->giEffect->parameters[0] = GI_TP_DEST_LINKSHOUSE;
|
dynamic_cast<ParameterizedGameInteractionEffect*>(effect->giEffect)->parameters[0] = GI_TP_DEST_LINKSHOUSE;
|
||||||
break;
|
break;
|
||||||
case kEffectTpMinuet:
|
case kEffectTpMinuet:
|
||||||
effect->giEffect = new GameInteractionEffect::TeleportPlayer();
|
effect->giEffect = new GameInteractionEffect::TeleportPlayer();
|
||||||
effect->giEffect->parameters[0] = GI_TP_DEST_MINUET;
|
dynamic_cast<ParameterizedGameInteractionEffect*>(effect->giEffect)->parameters[0] = GI_TP_DEST_MINUET;
|
||||||
break;
|
break;
|
||||||
case kEffectTpBolero:
|
case kEffectTpBolero:
|
||||||
effect->giEffect = new GameInteractionEffect::TeleportPlayer();
|
effect->giEffect = new GameInteractionEffect::TeleportPlayer();
|
||||||
effect->giEffect->parameters[0] = GI_TP_DEST_BOLERO;
|
dynamic_cast<ParameterizedGameInteractionEffect*>(effect->giEffect)->parameters[0] = GI_TP_DEST_BOLERO;
|
||||||
break;
|
break;
|
||||||
case kEffectTpSerenade:
|
case kEffectTpSerenade:
|
||||||
effect->giEffect = new GameInteractionEffect::TeleportPlayer();
|
effect->giEffect = new GameInteractionEffect::TeleportPlayer();
|
||||||
effect->giEffect->parameters[0] = GI_TP_DEST_SERENADE;
|
dynamic_cast<ParameterizedGameInteractionEffect*>(effect->giEffect)->parameters[0] = GI_TP_DEST_SERENADE;
|
||||||
break;
|
break;
|
||||||
case kEffectTpRequiem:
|
case kEffectTpRequiem:
|
||||||
effect->giEffect = new GameInteractionEffect::TeleportPlayer();
|
effect->giEffect = new GameInteractionEffect::TeleportPlayer();
|
||||||
effect->giEffect->parameters[0] = GI_TP_DEST_REQUIEM;
|
dynamic_cast<ParameterizedGameInteractionEffect*>(effect->giEffect)->parameters[0] = GI_TP_DEST_REQUIEM;
|
||||||
break;
|
break;
|
||||||
case kEffectTpNocturne:
|
case kEffectTpNocturne:
|
||||||
effect->giEffect = new GameInteractionEffect::TeleportPlayer();
|
effect->giEffect = new GameInteractionEffect::TeleportPlayer();
|
||||||
effect->giEffect->parameters[0] = GI_TP_DEST_NOCTURNE;
|
dynamic_cast<ParameterizedGameInteractionEffect*>(effect->giEffect)->parameters[0] = GI_TP_DEST_NOCTURNE;
|
||||||
break;
|
break;
|
||||||
case kEffectTpPrelude:
|
case kEffectTpPrelude:
|
||||||
effect->giEffect = new GameInteractionEffect::TeleportPlayer();
|
effect->giEffect = new GameInteractionEffect::TeleportPlayer();
|
||||||
effect->giEffect->parameters[0] = GI_TP_DEST_PRELUDE;
|
dynamic_cast<ParameterizedGameInteractionEffect*>(effect->giEffect)->parameters[0] = GI_TP_DEST_PRELUDE;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
// Tunic Color (Bidding War)
|
// Tunic Color (Bidding War)
|
||||||
case kEffectTunicRed:
|
case kEffectTunicRed:
|
||||||
effect->giEffect = new GameInteractionEffect::SetCosmeticsColor();
|
effect->giEffect = new GameInteractionEffect::SetCosmeticsColor();
|
||||||
effect->giEffect->parameters[0] = GI_COSMETICS_TUNICS;
|
dynamic_cast<ParameterizedGameInteractionEffect*>(effect->giEffect)->parameters[0] = GI_COSMETICS_TUNICS;
|
||||||
effect->giEffect->parameters[1] = GI_COLOR_RED;
|
dynamic_cast<ParameterizedGameInteractionEffect*>(effect->giEffect)->parameters[1] = GI_COLOR_RED;
|
||||||
break;
|
break;
|
||||||
case kEffectTunicGreen:
|
case kEffectTunicGreen:
|
||||||
effect->giEffect = new GameInteractionEffect::SetCosmeticsColor();
|
effect->giEffect = new GameInteractionEffect::SetCosmeticsColor();
|
||||||
effect->giEffect->parameters[0] = GI_COSMETICS_TUNICS;
|
dynamic_cast<ParameterizedGameInteractionEffect*>(effect->giEffect)->parameters[0] = GI_COSMETICS_TUNICS;
|
||||||
effect->giEffect->parameters[1] = GI_COLOR_GREEN;
|
dynamic_cast<ParameterizedGameInteractionEffect*>(effect->giEffect)->parameters[1] = GI_COLOR_GREEN;
|
||||||
break;
|
break;
|
||||||
case kEffectTunicBlue:
|
case kEffectTunicBlue:
|
||||||
effect->giEffect = new GameInteractionEffect::SetCosmeticsColor();
|
effect->giEffect = new GameInteractionEffect::SetCosmeticsColor();
|
||||||
effect->giEffect->parameters[0] = GI_COSMETICS_TUNICS;
|
dynamic_cast<ParameterizedGameInteractionEffect*>(effect->giEffect)->parameters[0] = GI_COSMETICS_TUNICS;
|
||||||
effect->giEffect->parameters[1] = GI_COLOR_BLUE;
|
dynamic_cast<ParameterizedGameInteractionEffect*>(effect->giEffect)->parameters[1] = GI_COLOR_BLUE;
|
||||||
break;
|
break;
|
||||||
case kEffectTunicOrange:
|
case kEffectTunicOrange:
|
||||||
effect->giEffect = new GameInteractionEffect::SetCosmeticsColor();
|
effect->giEffect = new GameInteractionEffect::SetCosmeticsColor();
|
||||||
effect->giEffect->parameters[0] = GI_COSMETICS_TUNICS;
|
dynamic_cast<ParameterizedGameInteractionEffect*>(effect->giEffect)->parameters[0] = GI_COSMETICS_TUNICS;
|
||||||
effect->giEffect->parameters[1] = GI_COLOR_ORANGE;
|
dynamic_cast<ParameterizedGameInteractionEffect*>(effect->giEffect)->parameters[1] = GI_COLOR_ORANGE;
|
||||||
break;
|
break;
|
||||||
case kEffectTunicYellow:
|
case kEffectTunicYellow:
|
||||||
effect->giEffect = new GameInteractionEffect::SetCosmeticsColor();
|
effect->giEffect = new GameInteractionEffect::SetCosmeticsColor();
|
||||||
effect->giEffect->parameters[0] = GI_COSMETICS_TUNICS;
|
dynamic_cast<ParameterizedGameInteractionEffect*>(effect->giEffect)->parameters[0] = GI_COSMETICS_TUNICS;
|
||||||
effect->giEffect->parameters[1] = GI_COLOR_YELLOW;
|
dynamic_cast<ParameterizedGameInteractionEffect*>(effect->giEffect)->parameters[1] = GI_COLOR_YELLOW;
|
||||||
break;
|
break;
|
||||||
case kEffectTunicPurple:
|
case kEffectTunicPurple:
|
||||||
effect->giEffect = new GameInteractionEffect::SetCosmeticsColor();
|
effect->giEffect = new GameInteractionEffect::SetCosmeticsColor();
|
||||||
effect->giEffect->parameters[0] = GI_COSMETICS_TUNICS;
|
dynamic_cast<ParameterizedGameInteractionEffect*>(effect->giEffect)->parameters[0] = GI_COSMETICS_TUNICS;
|
||||||
effect->giEffect->parameters[1] = GI_COLOR_PURPLE;
|
dynamic_cast<ParameterizedGameInteractionEffect*>(effect->giEffect)->parameters[1] = GI_COLOR_PURPLE;
|
||||||
break;
|
break;
|
||||||
case kEffectTunicPink:
|
case kEffectTunicPink:
|
||||||
effect->giEffect = new GameInteractionEffect::SetCosmeticsColor();
|
effect->giEffect = new GameInteractionEffect::SetCosmeticsColor();
|
||||||
effect->giEffect->parameters[0] = GI_COSMETICS_TUNICS;
|
dynamic_cast<ParameterizedGameInteractionEffect*>(effect->giEffect)->parameters[0] = GI_COSMETICS_TUNICS;
|
||||||
effect->giEffect->parameters[1] = GI_COLOR_PINK;
|
dynamic_cast<ParameterizedGameInteractionEffect*>(effect->giEffect)->parameters[1] = GI_COLOR_PINK;
|
||||||
break;
|
break;
|
||||||
case kEffectTunicBrown:
|
case kEffectTunicBrown:
|
||||||
effect->giEffect = new GameInteractionEffect::SetCosmeticsColor();
|
effect->giEffect = new GameInteractionEffect::SetCosmeticsColor();
|
||||||
effect->giEffect->parameters[0] = GI_COSMETICS_TUNICS;
|
dynamic_cast<ParameterizedGameInteractionEffect*>(effect->giEffect)->parameters[0] = GI_COSMETICS_TUNICS;
|
||||||
effect->giEffect->parameters[1] = GI_COLOR_BROWN;
|
dynamic_cast<ParameterizedGameInteractionEffect*>(effect->giEffect)->parameters[1] = GI_COLOR_BROWN;
|
||||||
break;
|
break;
|
||||||
case kEffectTunicBlack:
|
case kEffectTunicBlack:
|
||||||
effect->giEffect = new GameInteractionEffect::SetCosmeticsColor();
|
effect->giEffect = new GameInteractionEffect::SetCosmeticsColor();
|
||||||
effect->giEffect->parameters[0] = GI_COSMETICS_TUNICS;
|
dynamic_cast<ParameterizedGameInteractionEffect*>(effect->giEffect)->parameters[0] = GI_COSMETICS_TUNICS;
|
||||||
effect->giEffect->parameters[1] = GI_COLOR_BLACK;
|
dynamic_cast<ParameterizedGameInteractionEffect*>(effect->giEffect)->parameters[1] = GI_COLOR_BLACK;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
// Navi Color (Bidding War)
|
// Navi Color (Bidding War)
|
||||||
case kEffectNaviRed:
|
case kEffectNaviRed:
|
||||||
effect->giEffect = new GameInteractionEffect::SetCosmeticsColor();
|
effect->giEffect = new GameInteractionEffect::SetCosmeticsColor();
|
||||||
effect->giEffect->parameters[0] = GI_COSMETICS_NAVI;
|
dynamic_cast<ParameterizedGameInteractionEffect*>(effect->giEffect)->parameters[0] = GI_COSMETICS_NAVI;
|
||||||
effect->giEffect->parameters[1] = GI_COLOR_RED;
|
dynamic_cast<ParameterizedGameInteractionEffect*>(effect->giEffect)->parameters[1] = GI_COLOR_RED;
|
||||||
break;
|
break;
|
||||||
case kEffectNaviGreen:
|
case kEffectNaviGreen:
|
||||||
effect->giEffect = new GameInteractionEffect::SetCosmeticsColor();
|
effect->giEffect = new GameInteractionEffect::SetCosmeticsColor();
|
||||||
effect->giEffect->parameters[0] = GI_COSMETICS_NAVI;
|
dynamic_cast<ParameterizedGameInteractionEffect*>(effect->giEffect)->parameters[0] = GI_COSMETICS_NAVI;
|
||||||
effect->giEffect->parameters[1] = GI_COLOR_GREEN;
|
dynamic_cast<ParameterizedGameInteractionEffect*>(effect->giEffect)->parameters[1] = GI_COLOR_GREEN;
|
||||||
break;
|
break;
|
||||||
case kEffectNaviBlue:
|
case kEffectNaviBlue:
|
||||||
effect->giEffect = new GameInteractionEffect::SetCosmeticsColor();
|
effect->giEffect = new GameInteractionEffect::SetCosmeticsColor();
|
||||||
effect->giEffect->parameters[0] = GI_COSMETICS_NAVI;
|
dynamic_cast<ParameterizedGameInteractionEffect*>(effect->giEffect)->parameters[0] = GI_COSMETICS_NAVI;
|
||||||
effect->giEffect->parameters[1] = GI_COLOR_BLUE;
|
dynamic_cast<ParameterizedGameInteractionEffect*>(effect->giEffect)->parameters[1] = GI_COLOR_BLUE;
|
||||||
break;
|
break;
|
||||||
case kEffectNaviOrange:
|
case kEffectNaviOrange:
|
||||||
effect->giEffect = new GameInteractionEffect::SetCosmeticsColor();
|
effect->giEffect = new GameInteractionEffect::SetCosmeticsColor();
|
||||||
effect->giEffect->parameters[0] = GI_COSMETICS_NAVI;
|
dynamic_cast<ParameterizedGameInteractionEffect*>(effect->giEffect)->parameters[0] = GI_COSMETICS_NAVI;
|
||||||
effect->giEffect->parameters[1] = GI_COLOR_ORANGE;
|
dynamic_cast<ParameterizedGameInteractionEffect*>(effect->giEffect)->parameters[1] = GI_COLOR_ORANGE;
|
||||||
break;
|
break;
|
||||||
case kEffectNaviYellow:
|
case kEffectNaviYellow:
|
||||||
effect->giEffect = new GameInteractionEffect::SetCosmeticsColor();
|
effect->giEffect = new GameInteractionEffect::SetCosmeticsColor();
|
||||||
effect->giEffect->parameters[0] = GI_COSMETICS_NAVI;
|
dynamic_cast<ParameterizedGameInteractionEffect*>(effect->giEffect)->parameters[0] = GI_COSMETICS_NAVI;
|
||||||
effect->giEffect->parameters[1] = GI_COLOR_YELLOW;
|
dynamic_cast<ParameterizedGameInteractionEffect*>(effect->giEffect)->parameters[1] = GI_COLOR_YELLOW;
|
||||||
break;
|
break;
|
||||||
case kEffectNaviPurple:
|
case kEffectNaviPurple:
|
||||||
effect->giEffect = new GameInteractionEffect::SetCosmeticsColor();
|
effect->giEffect = new GameInteractionEffect::SetCosmeticsColor();
|
||||||
effect->giEffect->parameters[0] = GI_COSMETICS_NAVI;
|
dynamic_cast<ParameterizedGameInteractionEffect*>(effect->giEffect)->parameters[0] = GI_COSMETICS_NAVI;
|
||||||
effect->giEffect->parameters[1] = GI_COLOR_PURPLE;
|
dynamic_cast<ParameterizedGameInteractionEffect*>(effect->giEffect)->parameters[1] = GI_COLOR_PURPLE;
|
||||||
break;
|
break;
|
||||||
case kEffectNaviPink:
|
case kEffectNaviPink:
|
||||||
effect->giEffect = new GameInteractionEffect::SetCosmeticsColor();
|
effect->giEffect = new GameInteractionEffect::SetCosmeticsColor();
|
||||||
effect->giEffect->parameters[0] = GI_COSMETICS_NAVI;
|
dynamic_cast<ParameterizedGameInteractionEffect*>(effect->giEffect)->parameters[0] = GI_COSMETICS_NAVI;
|
||||||
effect->giEffect->parameters[1] = GI_COLOR_PINK;
|
dynamic_cast<ParameterizedGameInteractionEffect*>(effect->giEffect)->parameters[1] = GI_COLOR_PINK;
|
||||||
break;
|
break;
|
||||||
case kEffectNaviBrown:
|
case kEffectNaviBrown:
|
||||||
effect->giEffect = new GameInteractionEffect::SetCosmeticsColor();
|
effect->giEffect = new GameInteractionEffect::SetCosmeticsColor();
|
||||||
effect->giEffect->parameters[0] = GI_COSMETICS_NAVI;
|
dynamic_cast<ParameterizedGameInteractionEffect*>(effect->giEffect)->parameters[0] = GI_COSMETICS_NAVI;
|
||||||
effect->giEffect->parameters[1] = GI_COLOR_BROWN;
|
dynamic_cast<ParameterizedGameInteractionEffect*>(effect->giEffect)->parameters[1] = GI_COLOR_BROWN;
|
||||||
break;
|
break;
|
||||||
case kEffectNaviBlack:
|
case kEffectNaviBlack:
|
||||||
effect->giEffect = new GameInteractionEffect::SetCosmeticsColor();
|
effect->giEffect = new GameInteractionEffect::SetCosmeticsColor();
|
||||||
effect->giEffect->parameters[0] = GI_COSMETICS_NAVI;
|
dynamic_cast<ParameterizedGameInteractionEffect*>(effect->giEffect)->parameters[0] = GI_COSMETICS_NAVI;
|
||||||
effect->giEffect->parameters[1] = GI_COLOR_BLACK;
|
dynamic_cast<ParameterizedGameInteractionEffect*>(effect->giEffect)->parameters[1] = GI_COLOR_BLACK;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
// Link's Hair Color (Bidding War)
|
// Link's Hair Color (Bidding War)
|
||||||
case kEffectHairRed:
|
case kEffectHairRed:
|
||||||
effect->giEffect = new GameInteractionEffect::SetCosmeticsColor();
|
effect->giEffect = new GameInteractionEffect::SetCosmeticsColor();
|
||||||
effect->giEffect->parameters[0] = GI_COSMETICS_HAIR;
|
dynamic_cast<ParameterizedGameInteractionEffect*>(effect->giEffect)->parameters[0] = GI_COSMETICS_HAIR;
|
||||||
effect->giEffect->parameters[1] = GI_COLOR_RED;
|
dynamic_cast<ParameterizedGameInteractionEffect*>(effect->giEffect)->parameters[1] = GI_COLOR_RED;
|
||||||
break;
|
break;
|
||||||
case kEffectHairGreen:
|
case kEffectHairGreen:
|
||||||
effect->giEffect = new GameInteractionEffect::SetCosmeticsColor();
|
effect->giEffect = new GameInteractionEffect::SetCosmeticsColor();
|
||||||
effect->giEffect->parameters[0] = GI_COSMETICS_HAIR;
|
dynamic_cast<ParameterizedGameInteractionEffect*>(effect->giEffect)->parameters[0] = GI_COSMETICS_HAIR;
|
||||||
effect->giEffect->parameters[1] = GI_COLOR_GREEN;
|
dynamic_cast<ParameterizedGameInteractionEffect*>(effect->giEffect)->parameters[1] = GI_COLOR_GREEN;
|
||||||
break;
|
break;
|
||||||
case kEffectHairBlue:
|
case kEffectHairBlue:
|
||||||
effect->giEffect = new GameInteractionEffect::SetCosmeticsColor();
|
effect->giEffect = new GameInteractionEffect::SetCosmeticsColor();
|
||||||
effect->giEffect->parameters[0] = GI_COSMETICS_HAIR;
|
dynamic_cast<ParameterizedGameInteractionEffect*>(effect->giEffect)->parameters[0] = GI_COSMETICS_HAIR;
|
||||||
effect->giEffect->parameters[1] = GI_COLOR_BLUE;
|
dynamic_cast<ParameterizedGameInteractionEffect*>(effect->giEffect)->parameters[1] = GI_COLOR_BLUE;
|
||||||
break;
|
break;
|
||||||
case kEffectHairOrange:
|
case kEffectHairOrange:
|
||||||
effect->giEffect = new GameInteractionEffect::SetCosmeticsColor();
|
effect->giEffect = new GameInteractionEffect::SetCosmeticsColor();
|
||||||
effect->giEffect->parameters[0] = GI_COSMETICS_HAIR;
|
dynamic_cast<ParameterizedGameInteractionEffect*>(effect->giEffect)->parameters[0] = GI_COSMETICS_HAIR;
|
||||||
effect->giEffect->parameters[1] = GI_COLOR_ORANGE;
|
dynamic_cast<ParameterizedGameInteractionEffect*>(effect->giEffect)->parameters[1] = GI_COLOR_ORANGE;
|
||||||
break;
|
break;
|
||||||
case kEffectHairYellow:
|
case kEffectHairYellow:
|
||||||
effect->giEffect = new GameInteractionEffect::SetCosmeticsColor();
|
effect->giEffect = new GameInteractionEffect::SetCosmeticsColor();
|
||||||
effect->giEffect->parameters[0] = GI_COSMETICS_HAIR;
|
dynamic_cast<ParameterizedGameInteractionEffect*>(effect->giEffect)->parameters[0] = GI_COSMETICS_HAIR;
|
||||||
effect->giEffect->parameters[1] = GI_COLOR_YELLOW;
|
dynamic_cast<ParameterizedGameInteractionEffect*>(effect->giEffect)->parameters[1] = GI_COLOR_YELLOW;
|
||||||
break;
|
break;
|
||||||
case kEffectHairPurple:
|
case kEffectHairPurple:
|
||||||
effect->giEffect = new GameInteractionEffect::SetCosmeticsColor();
|
effect->giEffect = new GameInteractionEffect::SetCosmeticsColor();
|
||||||
effect->giEffect->parameters[0] = GI_COSMETICS_HAIR;
|
dynamic_cast<ParameterizedGameInteractionEffect*>(effect->giEffect)->parameters[0] = GI_COSMETICS_HAIR;
|
||||||
effect->giEffect->parameters[1] = GI_COLOR_PURPLE;
|
dynamic_cast<ParameterizedGameInteractionEffect*>(effect->giEffect)->parameters[1] = GI_COLOR_PURPLE;
|
||||||
break;
|
break;
|
||||||
case kEffectHairPink:
|
case kEffectHairPink:
|
||||||
effect->giEffect = new GameInteractionEffect::SetCosmeticsColor();
|
effect->giEffect = new GameInteractionEffect::SetCosmeticsColor();
|
||||||
effect->giEffect->parameters[0] = GI_COSMETICS_HAIR;
|
dynamic_cast<ParameterizedGameInteractionEffect*>(effect->giEffect)->parameters[0] = GI_COSMETICS_HAIR;
|
||||||
effect->giEffect->parameters[1] = GI_COLOR_PINK;
|
dynamic_cast<ParameterizedGameInteractionEffect*>(effect->giEffect)->parameters[1] = GI_COLOR_PINK;
|
||||||
break;
|
break;
|
||||||
case kEffectHairBrown:
|
case kEffectHairBrown:
|
||||||
effect->giEffect = new GameInteractionEffect::SetCosmeticsColor();
|
effect->giEffect = new GameInteractionEffect::SetCosmeticsColor();
|
||||||
effect->giEffect->parameters[0] = GI_COSMETICS_HAIR;
|
dynamic_cast<ParameterizedGameInteractionEffect*>(effect->giEffect)->parameters[0] = GI_COSMETICS_HAIR;
|
||||||
effect->giEffect->parameters[1] = GI_COLOR_BROWN;
|
dynamic_cast<ParameterizedGameInteractionEffect*>(effect->giEffect)->parameters[1] = GI_COLOR_BROWN;
|
||||||
break;
|
break;
|
||||||
case kEffectHairBlack:
|
case kEffectHairBlack:
|
||||||
effect->giEffect = new GameInteractionEffect::SetCosmeticsColor();
|
effect->giEffect = new GameInteractionEffect::SetCosmeticsColor();
|
||||||
effect->giEffect->parameters[0] = GI_COSMETICS_HAIR;
|
dynamic_cast<ParameterizedGameInteractionEffect*>(effect->giEffect)->parameters[0] = GI_COSMETICS_HAIR;
|
||||||
effect->giEffect->parameters[1] = GI_COLOR_BLACK;
|
dynamic_cast<ParameterizedGameInteractionEffect*>(effect->giEffect)->parameters[1] = GI_COLOR_BLACK;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
#ifdef ENABLE_CROWD_CONTROL
|
#ifdef ENABLE_REMOTE_CONTROL
|
||||||
|
|
||||||
#ifndef _CROWDCONTROL_C
|
#ifndef _CROWDCONTROL_C
|
||||||
#define _CROWDCONTROL_C
|
#define _CROWDCONTROL_C
|
||||||
@ -73,33 +73,24 @@ class CrowdControl {
|
|||||||
EffectResult lastExecutionResult;
|
EffectResult lastExecutionResult;
|
||||||
} Effect;
|
} Effect;
|
||||||
|
|
||||||
std::thread ccThreadReceive;
|
|
||||||
std::thread ccThreadProcess;
|
std::thread ccThreadProcess;
|
||||||
|
|
||||||
TCPsocket tcpsock;
|
|
||||||
IPaddress ip;
|
|
||||||
|
|
||||||
bool isEnabled;
|
bool isEnabled;
|
||||||
bool connected;
|
|
||||||
|
|
||||||
char received[512];
|
|
||||||
|
|
||||||
std::vector<Effect*> activeEffects;
|
std::vector<Effect*> activeEffects;
|
||||||
std::mutex activeEffectsMutex;
|
std::mutex activeEffectsMutex;
|
||||||
|
|
||||||
void ListenToServer();
|
void HandleRemoteData(nlohmann::json payload);
|
||||||
void ProcessActiveEffects();
|
void ProcessActiveEffects();
|
||||||
|
|
||||||
void EmitMessage(TCPsocket socket, uint32_t eventId, long timeRemaining, EffectResult status);
|
void EmitMessage(uint32_t eventId, long timeRemaining, EffectResult status);
|
||||||
Effect* ParseMessage(char payload[512]);
|
Effect* ParseMessage(nlohmann::json payload);
|
||||||
EffectResult ExecuteEffect(Effect* effect);
|
EffectResult ExecuteEffect(Effect* effect);
|
||||||
EffectResult CanApplyEffect(Effect *effect);
|
EffectResult CanApplyEffect(Effect *effect);
|
||||||
EffectResult TranslateGiEnum(GameInteractionEffectQueryResult giResult);
|
EffectResult TranslateGiEnum(GameInteractionEffectQueryResult giResult);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
static CrowdControl* Instance;
|
static CrowdControl* Instance;
|
||||||
void Init();
|
|
||||||
void Shutdown();
|
|
||||||
void Enable();
|
void Enable();
|
||||||
void Disable();
|
void Disable();
|
||||||
};
|
};
|
||||||
|
@ -38,6 +38,7 @@ typedef enum {
|
|||||||
TEXT_CARPET_SALESMAN_1 = 0x6077,
|
TEXT_CARPET_SALESMAN_1 = 0x6077,
|
||||||
TEXT_CARPET_SALESMAN_2 = 0x6078,
|
TEXT_CARPET_SALESMAN_2 = 0x6078,
|
||||||
TEXT_MARKET_GUARD_NIGHT = 0x7003,
|
TEXT_MARKET_GUARD_NIGHT = 0x7003,
|
||||||
|
TEXT_FISHERMAN_LEAVE = 0x409E,
|
||||||
TEXT_SHEIK_NEED_HOOK = 0x700F,
|
TEXT_SHEIK_NEED_HOOK = 0x700F,
|
||||||
TEXT_SHEIK_HAVE_HOOK = 0x7010,
|
TEXT_SHEIK_HAVE_HOOK = 0x7010,
|
||||||
TEXT_SCRUB_RANDOM = 0x9000,
|
TEXT_SCRUB_RANDOM = 0x9000,
|
||||||
@ -54,6 +55,22 @@ typedef enum {
|
|||||||
TEXT_SHOOTING_GALLERY_MAN_COME_BACK_WITH_BOW = 0x9210,
|
TEXT_SHOOTING_GALLERY_MAN_COME_BACK_WITH_BOW = 0x9210,
|
||||||
TEXT_LAKE_HYLIA_WATER_SWITCH_SIGN = 0x346, // 0x3yy for cuttable sign range
|
TEXT_LAKE_HYLIA_WATER_SWITCH_SIGN = 0x346, // 0x3yy for cuttable sign range
|
||||||
TEXT_LAKE_HYLIA_WATER_SWITCH_NAVI = 0x1B3, // 0x1yy for Navi msg range
|
TEXT_LAKE_HYLIA_WATER_SWITCH_NAVI = 0x1B3, // 0x1yy for Navi msg range
|
||||||
|
TEXT_SARIAS_SONG_CHANNELING_POWER = 0x016D,
|
||||||
|
TEXT_BEAN_SALESMAN_BUY_FOR_10 = 0x405E,
|
||||||
|
TEXT_BEAN_SALESMAN_BUY_FOR_20 = 0x405F,
|
||||||
|
TEXT_BEAN_SALESMAN_BUY_FOR_30 = 0x4060,
|
||||||
|
TEXT_BEAN_SALESMAN_BUY_FOR_40 = 0x4061,
|
||||||
|
TEXT_BEAN_SALESMAN_BUY_FOR_50 = 0x4062,
|
||||||
|
TEXT_BEAN_SALESMAN_BUY_FOR_60 = 0x4063,
|
||||||
|
TEXT_BEAN_SALESMAN_BUY_FOR_70 = 0x4064,
|
||||||
|
TEXT_BEAN_SALESMAN_BUY_FOR_80 = 0x4065,
|
||||||
|
TEXT_BEAN_SALESMAN_BUY_FOR_90 = 0x4066,
|
||||||
|
TEXT_BEAN_SALESMAN_BUY_FOR_100 = 0x4067,
|
||||||
|
TEXT_BEAN_SALESMAN_OH_WELL = 0x4068,
|
||||||
|
TEXT_BEAN_SALESMAN_NOT_ENOUGH_MONEY = 0x4069,
|
||||||
|
TEXT_BEAN_SALESMAN_SET_A_BEAN_TO_C = 0x406A,
|
||||||
|
TEXT_BEAN_SALESMAN_SOLD_OUT = 0x406B,
|
||||||
|
TEXT_BEAN_SALESMAN_WANT_TO_PLANT = 0x406C,
|
||||||
} TextIDs;
|
} TextIDs;
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
|
271
soh/soh/Enhancements/debugger/MessageViewer.cpp
Normal file
@ -0,0 +1,271 @@
|
|||||||
|
#include "MessageViewer.h"
|
||||||
|
|
||||||
|
#include <soh/UIWidgets.hpp>
|
||||||
|
#include <textures/message_static/message_static.h>
|
||||||
|
|
||||||
|
#include "../custom-message/CustomMessageManager.h"
|
||||||
|
#include "functions.h"
|
||||||
|
#include "macros.h"
|
||||||
|
#include "message_data_static.h"
|
||||||
|
#include "variables.h"
|
||||||
|
#include "soh/util.h"
|
||||||
|
|
||||||
|
extern "C" u8 sMessageHasSetSfx;
|
||||||
|
|
||||||
|
void MessageViewer::InitElement() {
|
||||||
|
CustomMessageManager::Instance->AddCustomMessageTable(TABLE_ID);
|
||||||
|
mTableIdBuf = static_cast<char*>(calloc(MAX_STRING_SIZE, sizeof(char)));
|
||||||
|
mTextIdBuf = static_cast<char*>(calloc(MAX_STRING_SIZE, sizeof(char)));
|
||||||
|
mCustomMessageBuf = static_cast<char*>(calloc(MAX_STRING_SIZE, sizeof(char)));
|
||||||
|
}
|
||||||
|
|
||||||
|
void MessageViewer::DrawElement() {
|
||||||
|
ImGui::SetNextWindowSize(ImVec2(520, 600), ImGuiCond_FirstUseEver);
|
||||||
|
if (!ImGui::Begin("Custom Message Debugger", &mIsVisible, ImGuiWindowFlags_NoFocusOnAppearing)) {
|
||||||
|
ImGui::End();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
ImGui::Text("Table ID");
|
||||||
|
ImGui::SameLine();
|
||||||
|
ImGui::InputText("##TableID", mTableIdBuf, MAX_STRING_SIZE, ImGuiInputTextFlags_CallbackCharFilter, UIWidgets::TextFilters::FilterAlphaNum);
|
||||||
|
UIWidgets::InsertHelpHoverText("Leave blank for vanilla table");
|
||||||
|
ImGui::Text("Text ID");
|
||||||
|
ImGui::SameLine();
|
||||||
|
switch (mTextIdBase) {
|
||||||
|
case DECIMAL:
|
||||||
|
ImGui::InputText("##TextID", mTextIdBuf, MAX_STRING_SIZE, ImGuiInputTextFlags_CharsDecimal);
|
||||||
|
UIWidgets::InsertHelpHoverText("Decimal Text ID of the message to load. Decimal digits only (0-9).");
|
||||||
|
break;
|
||||||
|
case HEXADECIMAL:
|
||||||
|
default:
|
||||||
|
ImGui::InputText("##TextID", mTextIdBuf, MAX_STRING_SIZE, ImGuiInputTextFlags_CharsHexadecimal);
|
||||||
|
UIWidgets::InsertHelpHoverText("Hexadecimal Text ID of the message to load. Hexadecimal digits only (0-9/A-F).");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (ImGui::RadioButton("Hexadecimal", &mTextIdBase, HEXADECIMAL)) {
|
||||||
|
memset(mTextIdBuf, 0, sizeof(char) * MAX_STRING_SIZE);
|
||||||
|
}
|
||||||
|
ImGui::SameLine();
|
||||||
|
if (ImGui::RadioButton("Decimal", &mTextIdBase, DECIMAL)) {
|
||||||
|
memset(mTextIdBuf, 0, sizeof(char) * MAX_STRING_SIZE);
|
||||||
|
}
|
||||||
|
ImGui::Text("Language");
|
||||||
|
ImGui::SameLine();
|
||||||
|
if (ImGui::BeginCombo("##Language", mLanguages[mLanguage])) {
|
||||||
|
// ReSharper disable CppDFAUnreachableCode
|
||||||
|
for (size_t i = 0; i < mLanguages.size(); i++) {
|
||||||
|
if (strlen(mLanguages[i]) > 0) {
|
||||||
|
if (ImGui::Selectable(mLanguages[i], i == mLanguage)) {
|
||||||
|
mLanguage = i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ImGui::EndCombo();
|
||||||
|
}
|
||||||
|
UIWidgets::InsertHelpHoverText("Which language to load from the selected text ID");
|
||||||
|
if (ImGui::Button("Display Message##ExistingMessage")) {
|
||||||
|
mDisplayExistingMessageClicked = true;
|
||||||
|
}
|
||||||
|
ImGui::Text("Custom Message");
|
||||||
|
UIWidgets::InsertHelpHoverText("Enter a string using Custom Message Syntax to preview it in-game. "
|
||||||
|
"Any newline (\\n) characters inserted by the Enter key will be stripped "
|
||||||
|
"from the output.");
|
||||||
|
ImGui::InputTextMultiline("##CustomMessage", mCustomMessageBuf, MAX_STRING_SIZE);
|
||||||
|
if (ImGui::Button("Display Message##CustomMessage")) {
|
||||||
|
mDisplayCustomMessageClicked = true;
|
||||||
|
}
|
||||||
|
ImGui::End();
|
||||||
|
// ReSharper restore CppDFAUnreachableCode
|
||||||
|
}
|
||||||
|
|
||||||
|
void MessageViewer::UpdateElement() {
|
||||||
|
if (mDisplayExistingMessageClicked) {
|
||||||
|
mTableId = std::string(mTableIdBuf);
|
||||||
|
switch (mTextIdBase) {
|
||||||
|
case DECIMAL:
|
||||||
|
mTextId = std::stoi(std::string(mTextIdBuf), nullptr, 10);
|
||||||
|
break;
|
||||||
|
case HEXADECIMAL:
|
||||||
|
default:
|
||||||
|
mTextId = std::stoi(std::string(mTextIdBuf), nullptr, 16);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
DisplayExistingMessage();
|
||||||
|
mDisplayExistingMessageClicked = false;
|
||||||
|
}
|
||||||
|
if (mDisplayCustomMessageClicked) {
|
||||||
|
mCustomMessageString = std::string(mCustomMessageBuf);
|
||||||
|
std::erase(mCustomMessageString, '\n');
|
||||||
|
DisplayCustomMessage();
|
||||||
|
mDisplayCustomMessageClicked = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void MessageViewer::DisplayExistingMessage() const {
|
||||||
|
MessageDebug_StartTextBox(mTableId.c_str(), mTextId, mLanguage);
|
||||||
|
}
|
||||||
|
|
||||||
|
void MessageViewer::DisplayCustomMessage() const {
|
||||||
|
MessageDebug_DisplayCustomMessage(mCustomMessageString.c_str());
|
||||||
|
}
|
||||||
|
|
||||||
|
extern "C" MessageTableEntry* sNesMessageEntryTablePtr;
|
||||||
|
extern "C" MessageTableEntry* sGerMessageEntryTablePtr;
|
||||||
|
extern "C" MessageTableEntry* sFraMessageEntryTablePtr;
|
||||||
|
extern "C" MessageTableEntry* sStaffMessageEntryTablePtr;
|
||||||
|
|
||||||
|
void FindMessage(PlayState* play, const uint16_t textId, const uint8_t language) {
|
||||||
|
const char* foundSeg;
|
||||||
|
const char* nextSeg;
|
||||||
|
MessageTableEntry* messageTableEntry = sNesMessageEntryTablePtr;
|
||||||
|
Font* font;
|
||||||
|
u16 bufferId = textId;
|
||||||
|
// Use the better owl message if better owl is enabled
|
||||||
|
if (CVarGetInteger(CVAR_ENHANCEMENT("BetterOwl"), 0) != 0 && (bufferId == 0x2066 || bufferId == 0x607B ||
|
||||||
|
bufferId == 0x10C2 || bufferId == 0x10C6 || bufferId == 0x206A))
|
||||||
|
{
|
||||||
|
bufferId = 0x71B3;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (language == LANGUAGE_GER)
|
||||||
|
messageTableEntry = sGerMessageEntryTablePtr;
|
||||||
|
else if (language == LANGUAGE_FRA)
|
||||||
|
messageTableEntry = sFraMessageEntryTablePtr;
|
||||||
|
|
||||||
|
// If PAL languages are not present in the OTR file, default to English
|
||||||
|
if (messageTableEntry == nullptr)
|
||||||
|
messageTableEntry = sNesMessageEntryTablePtr;
|
||||||
|
|
||||||
|
const char* seg = messageTableEntry->segment;
|
||||||
|
|
||||||
|
while (messageTableEntry->textId != 0xFFFF) {
|
||||||
|
font = &play->msgCtx.font;
|
||||||
|
|
||||||
|
if (messageTableEntry->textId == bufferId) {
|
||||||
|
foundSeg = messageTableEntry->segment;
|
||||||
|
font->charTexBuf[0] = messageTableEntry->typePos;
|
||||||
|
|
||||||
|
nextSeg = messageTableEntry->segment;
|
||||||
|
font->msgOffset = reinterpret_cast<uintptr_t>(messageTableEntry->segment);
|
||||||
|
font->msgLength = messageTableEntry->msgSize;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
messageTableEntry++;
|
||||||
|
}
|
||||||
|
|
||||||
|
font = &play->msgCtx.font;
|
||||||
|
messageTableEntry = sNesMessageEntryTablePtr;
|
||||||
|
|
||||||
|
foundSeg = messageTableEntry->segment;
|
||||||
|
font->charTexBuf[0] = messageTableEntry->typePos;
|
||||||
|
messageTableEntry++;
|
||||||
|
nextSeg = messageTableEntry->segment;
|
||||||
|
font->msgOffset = foundSeg - seg;
|
||||||
|
font->msgLength = nextSeg - foundSeg;
|
||||||
|
}
|
||||||
|
|
||||||
|
static const char* msgStaticTbl[] =
|
||||||
|
{
|
||||||
|
gDefaultMessageBackgroundTex,
|
||||||
|
gSignMessageBackgroundTex,
|
||||||
|
gNoteStaffMessageBackgroundTex,
|
||||||
|
gFadingMessageBackgroundTex,
|
||||||
|
gMessageContinueTriangleTex,
|
||||||
|
gMessageEndSquareTex,
|
||||||
|
gMessageArrowTex
|
||||||
|
};
|
||||||
|
|
||||||
|
void MessageDebug_StartTextBox(const char* tableId, uint16_t textId, uint8_t language) {
|
||||||
|
PlayState* play = gPlayState;
|
||||||
|
static int16_t messageStaticIndices[] = { 0, 1, 3, 2 };
|
||||||
|
const auto player = GET_PLAYER(gPlayState);
|
||||||
|
player->actor.flags |= ACTOR_FLAG_PLAYER_TALKED_TO;
|
||||||
|
MessageContext* msgCtx = &play->msgCtx;
|
||||||
|
msgCtx->ocarinaAction = 0xFFFF;
|
||||||
|
Font* font = &msgCtx->font;
|
||||||
|
sMessageHasSetSfx = 0;
|
||||||
|
for (u32 i = 0; i < FONT_CHAR_TEX_SIZE * 120; i += FONT_CHAR_TEX_SIZE) {
|
||||||
|
if (&font->charTexBuf[i] != nullptr) {
|
||||||
|
gSPInvalidateTexCache(play->state.gfxCtx->polyOpa.p++, reinterpret_cast<uintptr_t>(&font->charTexBuf[i]));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
R_TEXT_CHAR_SCALE = 75;
|
||||||
|
R_TEXT_LINE_SPACING = 12;
|
||||||
|
R_TEXT_INIT_XPOS = 65;
|
||||||
|
char* buffer = font->msgBuf;
|
||||||
|
msgCtx->textId = textId;
|
||||||
|
if (strlen(tableId) == 0) {
|
||||||
|
FindMessage(play, textId, language);
|
||||||
|
msgCtx->msgLength = static_cast<int32_t>(font->msgLength);
|
||||||
|
const uintptr_t src = font->msgOffset;
|
||||||
|
memcpy(font->msgBuf, reinterpret_cast<void const *>(src), font->msgLength);
|
||||||
|
} else {
|
||||||
|
constexpr int maxBufferSize = sizeof(font->msgBuf);
|
||||||
|
const CustomMessage messageEntry = CustomMessageManager::Instance->RetrieveMessage(tableId, textId);
|
||||||
|
font->charTexBuf[0] = (messageEntry.GetTextBoxType() << 4) | messageEntry.GetTextBoxPosition();
|
||||||
|
switch (language) {
|
||||||
|
case LANGUAGE_FRA:
|
||||||
|
font->msgLength = SohUtils::CopyStringToCharBuffer(buffer, messageEntry.GetFrench(), maxBufferSize);
|
||||||
|
break;
|
||||||
|
case LANGUAGE_GER:
|
||||||
|
font->msgLength = SohUtils::CopyStringToCharBuffer(buffer, messageEntry.GetGerman(), maxBufferSize);
|
||||||
|
break;
|
||||||
|
case LANGUAGE_ENG:
|
||||||
|
default:
|
||||||
|
font->msgLength = SohUtils::CopyStringToCharBuffer(buffer, messageEntry.GetEnglish(), maxBufferSize);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
msgCtx->msgLength = static_cast<int32_t>(font->msgLength);
|
||||||
|
}
|
||||||
|
msgCtx->textBoxProperties = font->charTexBuf[0];
|
||||||
|
msgCtx->textBoxType = msgCtx->textBoxProperties >> 4;
|
||||||
|
msgCtx->textBoxPos = msgCtx->textBoxProperties & 0xF;
|
||||||
|
const int16_t textBoxType = msgCtx->textBoxType;
|
||||||
|
// "Text Box Type"
|
||||||
|
osSyncPrintf("吹き出し種類=%d\n", msgCtx->textBoxType);
|
||||||
|
if (textBoxType < TEXTBOX_TYPE_NONE_BOTTOM) {
|
||||||
|
const char* textureName = msgStaticTbl[messageStaticIndices[textBoxType]];
|
||||||
|
memcpy(msgCtx->textboxSegment, textureName, strlen(textureName) + 1);
|
||||||
|
if (textBoxType == TEXTBOX_TYPE_BLACK) {
|
||||||
|
msgCtx->textboxColorRed = 0;
|
||||||
|
msgCtx->textboxColorGreen = 0;
|
||||||
|
msgCtx->textboxColorBlue = 0;
|
||||||
|
} else if (textBoxType == TEXTBOX_TYPE_WOODEN) {
|
||||||
|
msgCtx->textboxColorRed = 70;
|
||||||
|
msgCtx->textboxColorGreen = 50;
|
||||||
|
msgCtx->textboxColorBlue = 30;
|
||||||
|
} else if (textBoxType == TEXTBOX_TYPE_BLUE) {
|
||||||
|
msgCtx->textboxColorRed = 0;
|
||||||
|
msgCtx->textboxColorGreen = 10;
|
||||||
|
msgCtx->textboxColorBlue = 50;
|
||||||
|
} else {
|
||||||
|
msgCtx->textboxColorRed = 255;
|
||||||
|
msgCtx->textboxColorGreen = 0;
|
||||||
|
msgCtx->textboxColorBlue = 0;
|
||||||
|
}
|
||||||
|
if (textBoxType == TEXTBOX_TYPE_WOODEN) {
|
||||||
|
msgCtx->textboxColorAlphaTarget = 230;
|
||||||
|
} else if (textBoxType == TEXTBOX_TYPE_OCARINA) {
|
||||||
|
msgCtx->textboxColorAlphaTarget = 180;
|
||||||
|
} else {
|
||||||
|
msgCtx->textboxColorAlphaTarget = 170;
|
||||||
|
}
|
||||||
|
msgCtx->textboxColorAlphaCurrent = 0;
|
||||||
|
}
|
||||||
|
msgCtx->choiceNum = msgCtx->textUnskippable = msgCtx->textboxEndType = 0;
|
||||||
|
msgCtx->msgBufPos = msgCtx->unk_E3D0 = msgCtx->textDrawPos = 0;
|
||||||
|
msgCtx->talkActor = &player->actor;
|
||||||
|
msgCtx->msgMode = MSGMODE_TEXT_START;
|
||||||
|
msgCtx->stateTimer = 0;
|
||||||
|
msgCtx->textDelayTimer = 0;
|
||||||
|
msgCtx->ocarinaMode = OCARINA_MODE_00;
|
||||||
|
}
|
||||||
|
|
||||||
|
void MessageDebug_DisplayCustomMessage(const char* customMessage) {
|
||||||
|
CustomMessageManager::Instance->ClearMessageTable(MessageViewer::TABLE_ID);
|
||||||
|
CustomMessageManager::Instance->CreateMessage(MessageViewer::TABLE_ID, 0,
|
||||||
|
CustomMessage(customMessage, customMessage, customMessage));
|
||||||
|
MessageDebug_StartTextBox(MessageViewer::TABLE_ID, 0, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
62
soh/soh/Enhancements/debugger/MessageViewer.h
Normal file
@ -0,0 +1,62 @@
|
|||||||
|
#ifndef CUSTOMMESSAGEDEBUGGER_H
|
||||||
|
#define CUSTOMMESSAGEDEBUGGER_H
|
||||||
|
#include "z64.h"
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
#include "GuiWindow.h"
|
||||||
|
#include <array>
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
/**
|
||||||
|
* \brief Pulls a message from the specified message table and kicks off the process of displaying that message
|
||||||
|
* in a text box on screen.
|
||||||
|
* \param tableId the tableId string for the table we want to pull from. Empty string for authentic/vanilla messages
|
||||||
|
* \param textId The textId corresponding to the message to display. Putting in a textId that doesn't exist will
|
||||||
|
* probably result in a crash.
|
||||||
|
* \param language The Language to display on the screen.
|
||||||
|
*/
|
||||||
|
void MessageDebug_StartTextBox(const char* tableId, uint16_t textId, uint8_t language);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief
|
||||||
|
* \param customMessage A string using Custom Message Syntax.
|
||||||
|
*/
|
||||||
|
void MessageDebug_DisplayCustomMessage(const char* customMessage);
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
class MessageViewer : public Ship::GuiWindow {
|
||||||
|
public:
|
||||||
|
static inline const char* TABLE_ID = "MessageViewer";
|
||||||
|
using GuiWindow::GuiWindow;
|
||||||
|
|
||||||
|
void InitElement() override;
|
||||||
|
void DrawElement() override;
|
||||||
|
void UpdateElement() override;
|
||||||
|
|
||||||
|
virtual ~MessageViewer() = default;
|
||||||
|
|
||||||
|
private:
|
||||||
|
void DisplayExistingMessage() const;
|
||||||
|
void DisplayCustomMessage() const;
|
||||||
|
|
||||||
|
static constexpr uint16_t MAX_STRING_SIZE = 1024;
|
||||||
|
static constexpr std::array<const char*, LANGUAGE_MAX> mLanguages = {"English", "German", "French"};
|
||||||
|
static constexpr int HEXADECIMAL = 0;
|
||||||
|
static constexpr int DECIMAL = 1;
|
||||||
|
char* mTableIdBuf;
|
||||||
|
std::string mTableId;
|
||||||
|
char* mTextIdBuf;
|
||||||
|
uint16_t mTextId;
|
||||||
|
int mTextIdBase = HEXADECIMAL;
|
||||||
|
size_t mLanguage = LANGUAGE_ENG;
|
||||||
|
char* mCustomMessageBuf;
|
||||||
|
std::string mCustomMessageString;
|
||||||
|
bool mDisplayExistingMessageClicked = false;
|
||||||
|
bool mDisplayCustomMessageClicked = false;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
#endif //__cplusplus
|
||||||
|
#endif //CUSTOMMESSAGEDEBUGGER_H
|
@ -8,9 +8,11 @@
|
|||||||
#include <array>
|
#include <array>
|
||||||
#include <bit>
|
#include <bit>
|
||||||
#include <map>
|
#include <map>
|
||||||
|
#include <unordered_map>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <libultraship/bridge.h>
|
#include <libultraship/bridge.h>
|
||||||
#include <libultraship/libultraship.h>
|
#include <libultraship/libultraship.h>
|
||||||
|
#include "soh/OTRGlobals.h"
|
||||||
|
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#include <z64.h>
|
#include <z64.h>
|
||||||
@ -24,6 +26,7 @@ extern PlayState* gPlayState;
|
|||||||
#include "textures/icon_item_24_static/icon_item_24_static.h"
|
#include "textures/icon_item_24_static/icon_item_24_static.h"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#define DEKUNUTS_FLOWER 10
|
||||||
#define DEBUG_ACTOR_NAMETAG_TAG "debug_actor_viewer"
|
#define DEBUG_ACTOR_NAMETAG_TAG "debug_actor_viewer"
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
@ -107,8 +110,785 @@ void PopulateActorDropdown(int i, std::vector<Actor*>& data) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//actors that don't use params at all
|
||||||
|
static std::vector<u16> noParamsActors = {
|
||||||
|
ACTOR_ARMS_HOOK,
|
||||||
|
ACTOR_ARROW_FIRE,
|
||||||
|
ACTOR_ARROW_ICE,
|
||||||
|
ACTOR_ARROW_LIGHT,
|
||||||
|
ACTOR_BG_BOM_GUARD,
|
||||||
|
ACTOR_BG_DY_YOSEIZO,
|
||||||
|
ACTOR_BG_GATE_SHUTTER,
|
||||||
|
ACTOR_BG_GJYO_BRIDGE,
|
||||||
|
ACTOR_BG_HIDAN_FSLIFT,
|
||||||
|
ACTOR_BG_HIDAN_RSEKIZOU,
|
||||||
|
ACTOR_BG_HIDAN_SYOKU,
|
||||||
|
ACTOR_BG_JYA_GOROIWA,
|
||||||
|
ACTOR_BG_MIZU_UZU,
|
||||||
|
ACTOR_BG_MORI_RAKKATENJO,
|
||||||
|
ACTOR_BG_PUSHBOX,
|
||||||
|
ACTOR_BG_SPOT01_FUSYA,
|
||||||
|
ACTOR_BG_SPOT01_IDOHASHIRA,
|
||||||
|
ACTOR_BG_SPOT01_IDOMIZU,
|
||||||
|
ACTOR_BG_SPOT01_IDOSOKO,
|
||||||
|
ACTOR_BG_SPOT11_OASIS,
|
||||||
|
ACTOR_BG_SPOT15_SAKU,
|
||||||
|
ACTOR_BG_SPOT18_FUTA,
|
||||||
|
ACTOR_BG_TOKI_SWD,
|
||||||
|
ACTOR_BG_TREEMOUTH,
|
||||||
|
ACTOR_BG_VB_SIMA,
|
||||||
|
ACTOR_BOSS_DODONGO,
|
||||||
|
ACTOR_BOSS_FD,
|
||||||
|
ACTOR_BOSS_GOMA,
|
||||||
|
ACTOR_DEMO_EXT,
|
||||||
|
ACTOR_DEMO_SHD,
|
||||||
|
ACTOR_DEMO_TRE_LGT,
|
||||||
|
ACTOR_DOOR_TOKI,
|
||||||
|
ACTOR_EFC_ERUPC,
|
||||||
|
ACTOR_EN_ANI,
|
||||||
|
ACTOR_EN_AROW_TRAP,
|
||||||
|
ACTOR_EN_BIRD,
|
||||||
|
ACTOR_EN_BLKOBJ,
|
||||||
|
ACTOR_EN_BOM_BOWL_MAN,
|
||||||
|
ACTOR_EN_BOM_BOWL_PIT,
|
||||||
|
ACTOR_EN_BOM_CHU,
|
||||||
|
ACTOR_EN_BUBBLE,
|
||||||
|
ACTOR_EN_DIVING_GAME,
|
||||||
|
ACTOR_EN_DNT_DEMO,
|
||||||
|
ACTOR_EN_DNT_JIJI,
|
||||||
|
ACTOR_EN_DS,
|
||||||
|
ACTOR_EN_DU,
|
||||||
|
ACTOR_EN_EG,
|
||||||
|
ACTOR_EN_FU,
|
||||||
|
ACTOR_EN_GB,
|
||||||
|
ACTOR_EN_GE3,
|
||||||
|
ACTOR_EN_GUEST,
|
||||||
|
ACTOR_EN_HATA,
|
||||||
|
ACTOR_EN_HORSE_GANON,
|
||||||
|
ACTOR_EN_HORSE_LINK_CHILD,
|
||||||
|
ACTOR_EN_HORSE_ZELDA,
|
||||||
|
ACTOR_EN_HS2,
|
||||||
|
ACTOR_EN_JS,
|
||||||
|
ACTOR_EN_KAKASI,
|
||||||
|
ACTOR_EN_KAKASI3,
|
||||||
|
ACTOR_EN_MA1,
|
||||||
|
ACTOR_EN_MA2,
|
||||||
|
ACTOR_EN_MA3,
|
||||||
|
ACTOR_EN_MAG,
|
||||||
|
ACTOR_EN_MK,
|
||||||
|
ACTOR_EN_MS,
|
||||||
|
ACTOR_EN_NIW_LADY,
|
||||||
|
ACTOR_EN_NWC,
|
||||||
|
ACTOR_EN_OE2,
|
||||||
|
ACTOR_EN_OKARINA_EFFECT,
|
||||||
|
ACTOR_EN_RR,
|
||||||
|
ACTOR_EN_SA,
|
||||||
|
ACTOR_EN_SCENE_CHANGE,
|
||||||
|
ACTOR_EN_SKJNEEDLE,
|
||||||
|
ACTOR_EN_SYATEKI_ITM,
|
||||||
|
ACTOR_EN_SYATEKI_MAN,
|
||||||
|
ACTOR_EN_TAKARA_MAN,
|
||||||
|
ACTOR_EN_TORYO,
|
||||||
|
ACTOR_EN_VASE,
|
||||||
|
ACTOR_EN_ZL1,
|
||||||
|
ACTOR_MAGIC_DARK,
|
||||||
|
ACTOR_MAGIC_FIRE,
|
||||||
|
ACTOR_OBJ_DEKUJR,
|
||||||
|
ACTOR_OCEFF_SPOT,
|
||||||
|
|
||||||
|
ACTOR_UNSET_1,
|
||||||
|
ACTOR_UNSET_3,
|
||||||
|
ACTOR_UNSET_5,
|
||||||
|
ACTOR_UNSET_6,
|
||||||
|
ACTOR_UNSET_17,
|
||||||
|
ACTOR_UNSET_1A,
|
||||||
|
ACTOR_UNSET_1F,
|
||||||
|
ACTOR_UNSET_22,
|
||||||
|
ACTOR_UNSET_31,
|
||||||
|
ACTOR_UNSET_36,
|
||||||
|
ACTOR_UNSET_53,
|
||||||
|
ACTOR_UNSET_73,
|
||||||
|
ACTOR_UNSET_74,
|
||||||
|
ACTOR_UNSET_75,
|
||||||
|
ACTOR_UNSET_76,
|
||||||
|
ACTOR_UNSET_78,
|
||||||
|
ACTOR_UNSET_79,
|
||||||
|
ACTOR_UNSET_7A,
|
||||||
|
ACTOR_UNSET_7B,
|
||||||
|
ACTOR_UNSET_7E,
|
||||||
|
ACTOR_UNSET_7F,
|
||||||
|
ACTOR_UNSET_83,
|
||||||
|
ACTOR_UNSET_A0,
|
||||||
|
ACTOR_UNSET_B2,
|
||||||
|
ACTOR_UNSET_CE,
|
||||||
|
ACTOR_UNSET_D8,
|
||||||
|
ACTOR_UNSET_EA,
|
||||||
|
ACTOR_UNSET_EB,
|
||||||
|
ACTOR_UNSET_F2,
|
||||||
|
ACTOR_UNSET_F3,
|
||||||
|
ACTOR_UNSET_FB,
|
||||||
|
ACTOR_UNSET_109,
|
||||||
|
ACTOR_UNSET_10D,
|
||||||
|
ACTOR_UNSET_10E,
|
||||||
|
ACTOR_UNSET_128,
|
||||||
|
ACTOR_UNSET_129,
|
||||||
|
ACTOR_UNSET_134,
|
||||||
|
ACTOR_UNSET_154,
|
||||||
|
ACTOR_UNSET_15D,
|
||||||
|
ACTOR_UNSET_161,
|
||||||
|
ACTOR_UNSET_180,
|
||||||
|
ACTOR_UNSET_1AA
|
||||||
|
};
|
||||||
|
|
||||||
|
static std::unordered_map<u16, std::function<s16(s16)>> actorSpecificData;
|
||||||
|
|
||||||
|
void CreateActorSpecificData() {
|
||||||
|
if (!actorSpecificData.empty()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
actorSpecificData[ACTOR_EN_DEKUNUTS] = [](s16 params) -> s16 {
|
||||||
|
bool isFlower = params == DEKUNUTS_FLOWER;
|
||||||
|
s16 shotsPerRound = (params >> 8) & 0xFF;
|
||||||
|
if (shotsPerRound == 0xFF || shotsPerRound == 0) {
|
||||||
|
shotsPerRound = 1;
|
||||||
|
}
|
||||||
|
ImGui::Checkbox("Flower", &isFlower);
|
||||||
|
if (!isFlower) {
|
||||||
|
ImGui::InputScalar("Shots Per Round", ImGuiDataType_S16, &shotsPerRound);
|
||||||
|
}
|
||||||
|
|
||||||
|
return isFlower ? DEKUNUTS_FLOWER : (shotsPerRound << 8);
|
||||||
|
};
|
||||||
|
|
||||||
|
actorSpecificData[ACTOR_EN_TITE] = [](s16 params) -> s16 {
|
||||||
|
static const char* items[] = { "Blue", "Red" };
|
||||||
|
if (params == 0) {
|
||||||
|
params = -2;
|
||||||
|
}
|
||||||
|
//the + 2 is because the params are -2 & -1 instead of 0 & 1
|
||||||
|
int selectedItem = params + 2;
|
||||||
|
if (ImGui::Combo("Type", &selectedItem, items, IM_ARRAYSIZE(items))) {
|
||||||
|
return selectedItem - 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
return params;
|
||||||
|
};
|
||||||
|
|
||||||
|
actorSpecificData[ACTOR_EN_AM] = [](s16 params) -> s16 {
|
||||||
|
static const char* items[] = { "Statue", "Enemy" };
|
||||||
|
int selectedItem = params;
|
||||||
|
if (ImGui::Combo("Type", &selectedItem, items, IM_ARRAYSIZE(items))) {
|
||||||
|
return selectedItem;
|
||||||
|
}
|
||||||
|
|
||||||
|
return params;
|
||||||
|
};
|
||||||
|
|
||||||
|
actorSpecificData[ACTOR_BG_ICE_TURARA] = [](s16 params) -> s16 {
|
||||||
|
static const char* items[] = { "Stalagmite", "Stalactite", "Stalactite (Regrow)" };
|
||||||
|
int selectedItem = params;
|
||||||
|
if (ImGui::Combo("Type", &selectedItem, items, IM_ARRAYSIZE(items))) {
|
||||||
|
return selectedItem;
|
||||||
|
}
|
||||||
|
|
||||||
|
return params;
|
||||||
|
};
|
||||||
|
|
||||||
|
actorSpecificData[ACTOR_BG_BREAKWALL] = [](s16 params) -> s16 {
|
||||||
|
static const char* items[] = { "DC Entrance", "Wall", "KD Floor", "KD Lava Cover" };
|
||||||
|
int selectedItem = params;
|
||||||
|
if (ImGui::Combo("Type", &selectedItem, items, IM_ARRAYSIZE(items))) {
|
||||||
|
return selectedItem;
|
||||||
|
}
|
||||||
|
|
||||||
|
return params;
|
||||||
|
};
|
||||||
|
|
||||||
|
actorSpecificData[ACTOR_EN_TEST] = [](s16 params) -> s16 {
|
||||||
|
static const char* items[] = { "Invisible", "1", "2", "Ceiling", "4", "5" };
|
||||||
|
int selectedItem = params;
|
||||||
|
if (ImGui::Combo("Type", &selectedItem, items, IM_ARRAYSIZE(items))) {
|
||||||
|
return selectedItem;
|
||||||
|
}
|
||||||
|
|
||||||
|
return params;
|
||||||
|
};
|
||||||
|
|
||||||
|
actorSpecificData[ACTOR_EN_TANA] = [](s16 params) -> s16 {
|
||||||
|
static const char* items[] = { "Wooden", "Stone (1)", "Stone (2)" };
|
||||||
|
int selectedItem = params;
|
||||||
|
if (ImGui::Combo("Type", &selectedItem, items, IM_ARRAYSIZE(items))) {
|
||||||
|
return selectedItem;
|
||||||
|
}
|
||||||
|
|
||||||
|
return params;
|
||||||
|
};
|
||||||
|
|
||||||
|
actorSpecificData[ACTOR_EN_XC] = [](s16 params) -> s16 {
|
||||||
|
static const char* items[] = { "0", "1", "2", "3", "4", "5", "Minuet", "Bolero", "Serenade", "9" };
|
||||||
|
int selectedItem = params;
|
||||||
|
if (ImGui::Combo("Type", &selectedItem, items, IM_ARRAYSIZE(items))) {
|
||||||
|
return selectedItem;
|
||||||
|
}
|
||||||
|
|
||||||
|
return params;
|
||||||
|
};
|
||||||
|
|
||||||
|
actorSpecificData[ACTOR_SHOT_SUN] = [](s16 params) -> s16 {
|
||||||
|
static const char* items[] = { "Sun's Song", "Song of Storms", "LH Sun" };
|
||||||
|
if (params == 0) {
|
||||||
|
params = 0x40;
|
||||||
|
}
|
||||||
|
//the - 0x40 is because the params are 0x40 & 0x41 instead of 0 & 1
|
||||||
|
int selectedItem = params - 0x40;
|
||||||
|
if (ImGui::Combo("Type", &selectedItem, items, IM_ARRAYSIZE(items))) {
|
||||||
|
return selectedItem + 0x40;
|
||||||
|
}
|
||||||
|
|
||||||
|
return params;
|
||||||
|
};
|
||||||
|
|
||||||
|
actorSpecificData[ACTOR_EN_HONOTRAP] = [](s16 params) -> s16 {
|
||||||
|
static const char* items[] = { "Eye", "Flame Move", "Flame Drop" };
|
||||||
|
int selectedItem = params;
|
||||||
|
if (ImGui::Combo("Type", &selectedItem, items, IM_ARRAYSIZE(items))) {
|
||||||
|
return selectedItem;
|
||||||
|
}
|
||||||
|
|
||||||
|
return params;
|
||||||
|
};
|
||||||
|
|
||||||
|
actorSpecificData[ACTOR_EN_REEBA] = [](s16 params) -> s16 {
|
||||||
|
bool isBig = params != 0;
|
||||||
|
ImGui::Checkbox("Big", &isBig);
|
||||||
|
|
||||||
|
return isBig;
|
||||||
|
};
|
||||||
|
|
||||||
|
actorSpecificData[ACTOR_EN_TK] = [](s16 params) -> s16 {
|
||||||
|
bool canTurn = params >= 0;
|
||||||
|
ImGui::Checkbox("Can Turn", &canTurn);
|
||||||
|
|
||||||
|
return canTurn ? 0 : -1;
|
||||||
|
};
|
||||||
|
|
||||||
|
actorSpecificData[ACTOR_EN_ITEM00] = [](s16 params) -> s16 {
|
||||||
|
bool autoCollect = params & 0x8000;
|
||||||
|
ImGui::Checkbox("Automatically Collect", &autoCollect);
|
||||||
|
u8 collectibleFlag = (params & 0x3F00) >> 8;
|
||||||
|
ImGui::InputScalar("Collectible Flag", ImGuiDataType_U8, &collectibleFlag);
|
||||||
|
if (collectibleFlag > 0x3F) {
|
||||||
|
collectibleFlag = 0x3F;
|
||||||
|
}
|
||||||
|
|
||||||
|
static const char* items[] = {
|
||||||
|
"Green Rupee",
|
||||||
|
"Blue Rupee",
|
||||||
|
"Red Rupee",
|
||||||
|
"Recovery Heart",
|
||||||
|
"Bombs (A)",
|
||||||
|
"Arrow",
|
||||||
|
"Heart Piece",
|
||||||
|
"Heart Container",
|
||||||
|
"Arrows (5)",
|
||||||
|
"Arrows (10)",
|
||||||
|
"Arrows (30)",
|
||||||
|
"Bombs (B)",
|
||||||
|
"Deku Nuts (5)",
|
||||||
|
"Deku Stick",
|
||||||
|
"Magic (Large)",
|
||||||
|
"Magic (Small)",
|
||||||
|
"Deku Seeds (5)",
|
||||||
|
"Small Key",
|
||||||
|
"Flexible",
|
||||||
|
"Gold Rupee",
|
||||||
|
"Purple Rupee",
|
||||||
|
"Deku Shield",
|
||||||
|
"Hylian Shield",
|
||||||
|
"Zora Tunic",
|
||||||
|
"Goron Tunic",
|
||||||
|
"Bombs (Special)",
|
||||||
|
"Bombchus"
|
||||||
|
};
|
||||||
|
|
||||||
|
int selectedItem = params & 0xFF;
|
||||||
|
ImGui::Combo("Item", &selectedItem, items, IM_ARRAYSIZE(items));
|
||||||
|
|
||||||
|
return autoCollect * 0x8000 + (collectibleFlag << 8) + selectedItem;
|
||||||
|
};
|
||||||
|
|
||||||
|
actorSpecificData[ACTOR_OBJ_COMB] = [](s16 params) -> s16 {
|
||||||
|
static const char* items[] = {
|
||||||
|
"Green Rupee",
|
||||||
|
"Blue Rupee",
|
||||||
|
"Red Rupee",
|
||||||
|
"Recovery Heart",
|
||||||
|
"Bombs (A)",
|
||||||
|
"Arrow",
|
||||||
|
"Heart Piece",
|
||||||
|
"Heart Container",
|
||||||
|
"Arrows (5)",
|
||||||
|
"Arrows (10)",
|
||||||
|
"Arrows (30)",
|
||||||
|
"Bombs (B)",
|
||||||
|
"Deku Nuts (5)",
|
||||||
|
"Deku Stick",
|
||||||
|
"Magic (Large)",
|
||||||
|
"Magic (Small)",
|
||||||
|
"Deku Seeds (5)",
|
||||||
|
"Small Key",
|
||||||
|
"Flexible",
|
||||||
|
"Gold Rupee",
|
||||||
|
"Purple Rupee",
|
||||||
|
"Deku Shield",
|
||||||
|
"Hylian Shield",
|
||||||
|
"Zora Tunic",
|
||||||
|
"Goron Tunic",
|
||||||
|
"Bombs (Special)",
|
||||||
|
"Bombchus"
|
||||||
|
};
|
||||||
|
|
||||||
|
int selectedItem = params & 0xFF;
|
||||||
|
ImGui::Combo("Item Drop", &selectedItem, items, IM_ARRAYSIZE(items));
|
||||||
|
|
||||||
|
u8 collectibleFlag = (params & 0x3F00) >> 8;
|
||||||
|
if (selectedItem == 6) {
|
||||||
|
ImGui::InputScalar("PoH Collectible Flag", ImGuiDataType_U8, &collectibleFlag);
|
||||||
|
if (collectibleFlag > 0x3F) {
|
||||||
|
collectibleFlag = 0x3F;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return (collectibleFlag << 8) + selectedItem;
|
||||||
|
};
|
||||||
|
|
||||||
|
actorSpecificData[ACTOR_EN_GM] = [](s16 params) -> s16 {
|
||||||
|
u8 switchFlag = (params & 0x3F00) >> 8;
|
||||||
|
|
||||||
|
ImGui::InputScalar("Switch Flag", ImGuiDataType_U8, &switchFlag);
|
||||||
|
if (switchFlag > 0x3F) {
|
||||||
|
switchFlag = 0x3F;
|
||||||
|
}
|
||||||
|
|
||||||
|
return switchFlag << 8;
|
||||||
|
};
|
||||||
|
|
||||||
|
actorSpecificData[ACTOR_EN_GIRLA] = [](s16 params) -> s16 {
|
||||||
|
static const char* items[] = {
|
||||||
|
"Deku Nuts (5)",
|
||||||
|
"Arrows (30)",
|
||||||
|
"Arrows (50)",
|
||||||
|
"Bombs (5) (25 Rupees)",
|
||||||
|
"Deku Nuts (10)",
|
||||||
|
"Deku Stick",
|
||||||
|
"Bombs (10)",
|
||||||
|
"Fish",
|
||||||
|
"Red Potion (30 Rupees)",
|
||||||
|
"Green Potion",
|
||||||
|
"Blue Potion",
|
||||||
|
"Longsword",
|
||||||
|
"Hylian Shield",
|
||||||
|
"Deku Shield",
|
||||||
|
"Goron Tunic",
|
||||||
|
"Zora Tunic",
|
||||||
|
"Heart",
|
||||||
|
"Milk Bottle",
|
||||||
|
"Weird Egg",
|
||||||
|
"19",
|
||||||
|
"20",
|
||||||
|
"Bomchu (10) [1]",
|
||||||
|
"Bomchu (20) [1]",
|
||||||
|
"Bomchu (20) [2]",
|
||||||
|
"Bomchu (10) [2]",
|
||||||
|
"Bomchu (10) [3]",
|
||||||
|
"Bomchu (20) [3]",
|
||||||
|
"Bomchu (20) [4]",
|
||||||
|
"Bomchu (10) [4]",
|
||||||
|
"Deku Seeds (30)",
|
||||||
|
"Keaton Mask",
|
||||||
|
"Spooky Mask",
|
||||||
|
"Skull Mask",
|
||||||
|
"Bunny Hood",
|
||||||
|
"Mask Of Truth",
|
||||||
|
"Zora Mask",
|
||||||
|
"Goron Mask",
|
||||||
|
"Gerudo Mask",
|
||||||
|
"Sold Out",
|
||||||
|
"Blue Fire",
|
||||||
|
"Bugs",
|
||||||
|
"Big Poe",
|
||||||
|
"Poe",
|
||||||
|
"Fairy",
|
||||||
|
"Arrows (10)",
|
||||||
|
"Bombs (20)",
|
||||||
|
"Bombs (30)",
|
||||||
|
"Bombs (5) (35 Rupees)",
|
||||||
|
"Red Potion (40 Rupees)",
|
||||||
|
"Red Potion (50 Rupees)",
|
||||||
|
"Randomizer Item"
|
||||||
|
};
|
||||||
|
int selectedItem = params;
|
||||||
|
if (ImGui::Combo("Type", &selectedItem, items, IM_ARRAYSIZE(items))) {
|
||||||
|
return selectedItem;
|
||||||
|
}
|
||||||
|
|
||||||
|
return params;
|
||||||
|
};
|
||||||
|
|
||||||
|
actorSpecificData[ACTOR_EN_FIRE_ROCK] = [](s16 params) -> s16 {
|
||||||
|
static const char* items[] = {
|
||||||
|
"Spawned Falling (1)",
|
||||||
|
"Broken Piece (1)",
|
||||||
|
"Broken Piece (2)",
|
||||||
|
"Spawned Falling (2)",
|
||||||
|
//"INVALID",
|
||||||
|
"Ceiling Spot Spawner",
|
||||||
|
"On Floor"
|
||||||
|
};
|
||||||
|
int selectedItem = params > 3 ? params - 1 : params;
|
||||||
|
if (ImGui::Combo("Type", &selectedItem, items, IM_ARRAYSIZE(items))) {
|
||||||
|
return selectedItem > 3 ? selectedItem + 1 : selectedItem;
|
||||||
|
}
|
||||||
|
|
||||||
|
return params;
|
||||||
|
};
|
||||||
|
|
||||||
|
actorSpecificData[ACTOR_EN_EX_ITEM] = [](s16 params) -> s16 {
|
||||||
|
static const char* items[] = {
|
||||||
|
"Bomb Bag Bowling",
|
||||||
|
"Heart Piece Bowling",
|
||||||
|
"Bombchus Bowling",
|
||||||
|
"Bombs Bowling",
|
||||||
|
"Purple Rupee Bowling",
|
||||||
|
"Bomb Bag Counter",
|
||||||
|
"Heart Piece Counter",
|
||||||
|
"Bombchus Counter",
|
||||||
|
"Bombs Counter",
|
||||||
|
"Purple Rupee Counter",
|
||||||
|
"Green Rupee Chest",
|
||||||
|
"Blue Rupee Chest",
|
||||||
|
"Red Rupee Chest",
|
||||||
|
"13",
|
||||||
|
"14",
|
||||||
|
"Small Key Chest",
|
||||||
|
"Magic Fire",
|
||||||
|
"Magic Wind",
|
||||||
|
"Magic Dark",
|
||||||
|
"Bullet Bag"
|
||||||
|
};
|
||||||
|
int selectedItem = params;
|
||||||
|
if (ImGui::Combo("Type", &selectedItem, items, IM_ARRAYSIZE(items))) {
|
||||||
|
return selectedItem;
|
||||||
|
}
|
||||||
|
|
||||||
|
return params;
|
||||||
|
};
|
||||||
|
|
||||||
|
actorSpecificData[ACTOR_EN_ELF] = [](s16 params) -> s16 {
|
||||||
|
static const char* items[] = {
|
||||||
|
"Navi",
|
||||||
|
"Revive Bottle",
|
||||||
|
"Heal Timed",
|
||||||
|
"Kokiri",
|
||||||
|
"Spawner",
|
||||||
|
"Revive Death",
|
||||||
|
"Heal",
|
||||||
|
"Heal Big"
|
||||||
|
};
|
||||||
|
int selectedItem = params;
|
||||||
|
if (ImGui::Combo("Type", &selectedItem, items, IM_ARRAYSIZE(items))) {
|
||||||
|
return selectedItem;
|
||||||
|
}
|
||||||
|
|
||||||
|
return params;
|
||||||
|
};
|
||||||
|
|
||||||
|
actorSpecificData[ACTOR_EN_CLEAR_TAG] = [](s16 params) -> s16 {
|
||||||
|
static const char* items[] = {
|
||||||
|
"Cutscene", //0
|
||||||
|
"Normal", //1
|
||||||
|
"Laser" //100
|
||||||
|
};
|
||||||
|
int selectedItem = params == 100 ? 2 : params;
|
||||||
|
if (ImGui::Combo("Type", &selectedItem, items, IM_ARRAYSIZE(items))) {
|
||||||
|
return selectedItem == 2 ? 100 : selectedItem;
|
||||||
|
}
|
||||||
|
|
||||||
|
return params;
|
||||||
|
};
|
||||||
|
|
||||||
|
actorSpecificData[ACTOR_EN_BOMBF] = [](s16 params) -> s16 {
|
||||||
|
static const char* items[] = { "Flower", "Body", "Explosion" };
|
||||||
|
//the + 1 is because the params are -1, 0 & 1 instead of 0, 1 & 2
|
||||||
|
int selectedItem = params + 1;
|
||||||
|
if (ImGui::Combo("Type", &selectedItem, items, IM_ARRAYSIZE(items))) {
|
||||||
|
return selectedItem - 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return params;
|
||||||
|
};
|
||||||
|
|
||||||
|
actorSpecificData[ACTOR_EN_BOM] = [](s16 params) -> s16 {
|
||||||
|
static const char* items[] = { "Body", "Explosion" };
|
||||||
|
|
||||||
|
int selectedItem = params;
|
||||||
|
if (ImGui::Combo("Type", &selectedItem, items, IM_ARRAYSIZE(items))) {
|
||||||
|
return selectedItem;
|
||||||
|
}
|
||||||
|
|
||||||
|
return params;
|
||||||
|
};
|
||||||
|
|
||||||
|
actorSpecificData[ACTOR_DOOR_WARP1] = [](s16 params) -> s16 {
|
||||||
|
static const char* items[] = {
|
||||||
|
"Blue Crystal", // -2
|
||||||
|
"Dungeon Adult",
|
||||||
|
"Dungeon Child",
|
||||||
|
"Clear Flag", // Activate on temp clear flag
|
||||||
|
"Sages", // Used by sages warping into chamber of sages during their cutscene
|
||||||
|
"Purple Crystal",
|
||||||
|
"Yellow", // The colored variants don't warp, they are cutscene setpieces
|
||||||
|
"Blue Ruto",
|
||||||
|
"Destination", // Spawning in after having taken a warp
|
||||||
|
"UNK 7",
|
||||||
|
"Orange",
|
||||||
|
"Green",
|
||||||
|
"Red"
|
||||||
|
};
|
||||||
|
int selectedItem = params + 2;
|
||||||
|
if (ImGui::Combo("Type", &selectedItem, items, IM_ARRAYSIZE(items))) {
|
||||||
|
return selectedItem - 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
return params;
|
||||||
|
};
|
||||||
|
|
||||||
|
actorSpecificData[ACTOR_EN_DY_EXTRA] = [](s16 params) -> s16 {
|
||||||
|
static const char* items[] = { "Orange", "Green" };
|
||||||
|
|
||||||
|
int selectedItem = params;
|
||||||
|
if (ImGui::Combo("Color", &selectedItem, items, IM_ARRAYSIZE(items))) {
|
||||||
|
return selectedItem;
|
||||||
|
}
|
||||||
|
|
||||||
|
return params;
|
||||||
|
};
|
||||||
|
|
||||||
|
actorSpecificData[ACTOR_EN_SKB] = [](s16 params) -> s16 {
|
||||||
|
u8 size = params;
|
||||||
|
ImGui::InputScalar("Size", ImGuiDataType_U8, &size);
|
||||||
|
|
||||||
|
return size;
|
||||||
|
};
|
||||||
|
|
||||||
|
actorSpecificData[ACTOR_EN_WF] = [](s16 params) -> s16 {
|
||||||
|
static const char* items[] = { "Normal", "White" };
|
||||||
|
|
||||||
|
int selectedItem = params;
|
||||||
|
ImGui::Combo("Type", &selectedItem, items, IM_ARRAYSIZE(items));
|
||||||
|
|
||||||
|
u8 switchFlag = (params & 0x3F00) >> 8;
|
||||||
|
ImGui::InputScalar("Switch Flag", ImGuiDataType_U8, &switchFlag);
|
||||||
|
return (switchFlag << 8) + selectedItem;
|
||||||
|
};
|
||||||
|
|
||||||
|
actorSpecificData[ACTOR_EN_BOX] = [](s16 params) -> s16 {
|
||||||
|
/*
|
||||||
|
trasureFlag = params & 0x1F; //0b0000 0000 0001 1111
|
||||||
|
itemId = (params >> 5) & 0x7F; //0b0000 1111 1110 0000
|
||||||
|
type = (params >> 12) & 0xF; //0b1111 0000 0000 0000
|
||||||
|
*/
|
||||||
|
u8 treasureFlag = params & 0x1F;
|
||||||
|
ImGui::InputScalar("Treasure Flag", ImGuiDataType_U8, &treasureFlag);
|
||||||
|
if (treasureFlag > 0x1F) {
|
||||||
|
treasureFlag = 0x1F;
|
||||||
|
}
|
||||||
|
|
||||||
|
u8 itemId = (params >> 5) & 0x7F;
|
||||||
|
ImGui::InputScalar("Item Id", ImGuiDataType_U8, &itemId);
|
||||||
|
if (itemId > 0x7F) {
|
||||||
|
itemId = 0x7F;
|
||||||
|
}
|
||||||
|
|
||||||
|
static const char* items[] = {
|
||||||
|
"Big (Default)",
|
||||||
|
"Room Clear Big",
|
||||||
|
"Decorated Big",
|
||||||
|
"Switch Flag Fall Big",
|
||||||
|
"4",
|
||||||
|
"Small",
|
||||||
|
"6",
|
||||||
|
"Room Clear Small",
|
||||||
|
"Switch Flag Fall Small",
|
||||||
|
"9",
|
||||||
|
"10",
|
||||||
|
"Switch Flag Big"
|
||||||
|
};
|
||||||
|
|
||||||
|
int type = (params >> 12) & 0xF;
|
||||||
|
ImGui::Combo("Type", &type, items, IM_ARRAYSIZE(items));
|
||||||
|
if (type > 0xF) {
|
||||||
|
type = 0xF;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (type << 12) + (itemId << 5) + treasureFlag;
|
||||||
|
};
|
||||||
|
|
||||||
|
actorSpecificData[ACTOR_EN_DOOR] = [](s16 params) -> s16 {
|
||||||
|
/**
|
||||||
|
* Actor Parameters
|
||||||
|
*
|
||||||
|
* | | | |
|
||||||
|
* | Transition Index | Type | Double Door | Switch Flag OR Text Id - 0x0200
|
||||||
|
* |------------------|-------|-------------|---------------------------------
|
||||||
|
* | 0 0 0 0 0 0 | 0 0 0 | 0 | 0 0 0 0 0 0
|
||||||
|
* | 6 | 3 | 1 | 6
|
||||||
|
* |
|
||||||
|
*
|
||||||
|
* Transition Index 1111110000000000 Set by the actor engine when the door is spawned
|
||||||
|
* Type 0000001110000000
|
||||||
|
* Double Door 0000000001000000
|
||||||
|
* Switch Flag 0000000000111111 For use with the `DOOR_LOCKED` type
|
||||||
|
* Text id - 0x0200 0000000000111111 For use with the `DOOR_CHECKABLE` type
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
u8 transitionIndex = params >> 10;
|
||||||
|
ImGui::InputScalar("Transition Index", ImGuiDataType_U8, &transitionIndex);
|
||||||
|
if (transitionIndex > 0x3F) {
|
||||||
|
transitionIndex = 0x3F;
|
||||||
|
}
|
||||||
|
|
||||||
|
static const char* items[] = {
|
||||||
|
"Room Load", // loads rooms
|
||||||
|
"Locked", // small key locked door
|
||||||
|
"Room Load (2)", // loads rooms
|
||||||
|
"Scene Exit", // doesn't load rooms, used for doors paired with scene transition polygons
|
||||||
|
"Ajar", // open slightly but slams shut if Link gets too close
|
||||||
|
"Checkable", // doors that display a textbox when interacting
|
||||||
|
"Evening", // unlocked between 18:00 and 21:00, Dampé's hut
|
||||||
|
"Room Load (7)" // loads rooms
|
||||||
|
};
|
||||||
|
|
||||||
|
int type = (params >> 7) & 7;
|
||||||
|
ImGui::Combo("Type", &type, items, IM_ARRAYSIZE(items));
|
||||||
|
if (type > 7) {
|
||||||
|
type = 7;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool doubleDoor = ((params >> 6) & 1) != 0;
|
||||||
|
ImGui::Checkbox("Double Door", &doubleDoor);
|
||||||
|
|
||||||
|
u8 lowerBits = params & 0x3F;
|
||||||
|
if (type == 1) {
|
||||||
|
ImGui::InputScalar("Switch Flag", ImGuiDataType_U8, &lowerBits);
|
||||||
|
if (lowerBits > 0x3F) {
|
||||||
|
lowerBits = 0x3F;
|
||||||
|
}
|
||||||
|
} else if (type == 5) {
|
||||||
|
ImGui::InputScalar("Text ID - 0x200", ImGuiDataType_U8, &lowerBits);
|
||||||
|
if (lowerBits > 0x3F) {
|
||||||
|
lowerBits = 0x3F;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
lowerBits = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (transitionIndex << 10) + (type << 7) + (doubleDoor << 6) + lowerBits;
|
||||||
|
};
|
||||||
|
|
||||||
|
actorSpecificData[ACTOR_EN_PO_DESERT] = [](s16 params) -> s16 {
|
||||||
|
u8 switchFlag = params >> 8;
|
||||||
|
|
||||||
|
ImGui::InputScalar("Path", ImGuiDataType_U8, &switchFlag);
|
||||||
|
|
||||||
|
return switchFlag << 8;
|
||||||
|
};
|
||||||
|
|
||||||
|
actorSpecificData[ACTOR_EN_KANBAN] = [](s16 params) -> s16 {
|
||||||
|
bool piece = params == (s16)0xFFDD;
|
||||||
|
bool fishingSign = params == 0x300;
|
||||||
|
if (ImGui::Checkbox("Piece", &piece)) {
|
||||||
|
fishingSign = false;
|
||||||
|
}
|
||||||
|
if (ImGui::Checkbox("Fishing Sign", &fishingSign)) {
|
||||||
|
piece = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
u8 textId = params;
|
||||||
|
if (!piece && !fishingSign) {
|
||||||
|
if (ImGui::InputScalar("Text ID", ImGuiDataType_U8, &textId)) {
|
||||||
|
textId |= 0x300;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return piece ? (s16)0xFFDD : (fishingSign ? 0x300 : textId);
|
||||||
|
};
|
||||||
|
|
||||||
|
actorSpecificData[ACTOR_EN_KUSA] = [](s16 params) -> s16 {
|
||||||
|
static const char* items[] = {
|
||||||
|
"0",
|
||||||
|
"1",
|
||||||
|
"2"
|
||||||
|
};
|
||||||
|
|
||||||
|
int type = params & 3;
|
||||||
|
ImGui::Combo("Type", &type, items, IM_ARRAYSIZE(items));
|
||||||
|
|
||||||
|
bool bugs = ((params >> 4) & 1) != 0;
|
||||||
|
ImGui::Checkbox("Bugs", &bugs);
|
||||||
|
|
||||||
|
u8 drop = (params >> 8) & 0xF;
|
||||||
|
if (type == 2) {
|
||||||
|
ImGui::InputScalar("Random Drop Params", ImGuiDataType_U8, &drop);
|
||||||
|
if (drop > 0xD) {
|
||||||
|
drop = 0xD;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
drop = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (drop << 8) + (bugs << 4) + type;
|
||||||
|
};
|
||||||
|
|
||||||
|
actorSpecificData[ActorDB::Instance->RetrieveId("En_Partner")] = [](s16 params) -> s16 {
|
||||||
|
static const char* items[] = {
|
||||||
|
"Port 1",
|
||||||
|
"Port 2",
|
||||||
|
"Port 3",
|
||||||
|
"Port 4"
|
||||||
|
};
|
||||||
|
int selectedItem = params;
|
||||||
|
if (ImGui::Combo("Controller Port", &selectedItem, items, IM_ARRAYSIZE(items))) {
|
||||||
|
return selectedItem;
|
||||||
|
}
|
||||||
|
|
||||||
|
return params;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<u16> GetActorsWithDescriptionContainingString(std::string s) {
|
||||||
|
std::locale loc;
|
||||||
|
for (size_t i = 0; i < s.length(); i += 1) {
|
||||||
|
s[i] = std::tolower(s[i], loc);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<u16> actors;
|
||||||
|
for (int i = 0; i < ActorDB::Instance->GetEntryCount(); i += 1) {
|
||||||
|
ActorDB::Entry actorEntry = ActorDB::Instance->RetrieveEntry(i);
|
||||||
|
std::string desc = actorEntry.desc;
|
||||||
|
for (size_t j = 0; j < desc.length(); j += 1) {
|
||||||
|
desc[j] = std::tolower(desc[j], loc);
|
||||||
|
}
|
||||||
|
if (desc.find(s) != std::string::npos) {
|
||||||
|
actors.push_back((u16)i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return actors;
|
||||||
|
}
|
||||||
|
|
||||||
void ActorViewer_AddTagForActor(Actor* actor) {
|
void ActorViewer_AddTagForActor(Actor* actor) {
|
||||||
int val = CVarGetInteger("gDebugActorViewerNameTags", ACTORVIEWER_NAMETAGS_NONE);
|
int val = CVarGetInteger(CVAR_DEVELOPER_TOOLS("ActorViewer.NameTags"), ACTORVIEWER_NAMETAGS_NONE);
|
||||||
auto entry = ActorDB::Instance->RetrieveEntry(actor->id);
|
auto entry = ActorDB::Instance->RetrieveEntry(actor->id);
|
||||||
std::string tag;
|
std::string tag;
|
||||||
|
|
||||||
@ -163,6 +943,9 @@ void ActorViewerWindow::DrawElement() {
|
|||||||
static std::string filler = "Please select";
|
static std::string filler = "Please select";
|
||||||
static std::vector<Actor*> list;
|
static std::vector<Actor*> list;
|
||||||
static u16 lastSceneId = 0;
|
static u16 lastSceneId = 0;
|
||||||
|
static char searchString[64] = "";
|
||||||
|
static s16 currentSelectedInDropdown;
|
||||||
|
static std::vector<u16> actors;
|
||||||
|
|
||||||
if (gPlayState != nullptr) {
|
if (gPlayState != nullptr) {
|
||||||
needs_reset = lastSceneId != gPlayState->sceneNum;
|
needs_reset = lastSceneId != gPlayState->sceneNum;
|
||||||
@ -173,6 +956,11 @@ void ActorViewerWindow::DrawElement() {
|
|||||||
filler = "Please Select";
|
filler = "Please Select";
|
||||||
list.clear();
|
list.clear();
|
||||||
needs_reset = false;
|
needs_reset = false;
|
||||||
|
for (size_t i = 0; i < ARRAY_COUNT(searchString); i += 1) {
|
||||||
|
searchString[i] = 0;
|
||||||
|
}
|
||||||
|
currentSelectedInDropdown = -1;
|
||||||
|
actors.clear();
|
||||||
}
|
}
|
||||||
lastSceneId = gPlayState->sceneNum;
|
lastSceneId = gPlayState->sceneNum;
|
||||||
if (ImGui::BeginCombo("Actor Type", acMapping[category])) {
|
if (ImGui::BeginCombo("Actor Type", acMapping[category])) {
|
||||||
@ -316,9 +1104,48 @@ void ActorViewerWindow::DrawElement() {
|
|||||||
if (ImGui::TreeNode("New...")) {
|
if (ImGui::TreeNode("New...")) {
|
||||||
ImGui::PushItemWidth(ImGui::GetFontSize() * 10);
|
ImGui::PushItemWidth(ImGui::GetFontSize() * 10);
|
||||||
|
|
||||||
|
if (ImGui::InputText("Search Actor", searchString, ARRAY_COUNT(searchString))) {
|
||||||
|
actors = GetActorsWithDescriptionContainingString(std::string(searchString));
|
||||||
|
currentSelectedInDropdown = -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (searchString[0] != 0 && !actors.empty()) {
|
||||||
|
std::string preview = currentSelectedInDropdown == -1 ? "Please Select" : ActorDB::Instance->RetrieveEntry(actors[currentSelectedInDropdown]).desc;
|
||||||
|
if (ImGui::BeginCombo("Results", preview.c_str())) {
|
||||||
|
for (u8 i = 0; i < actors.size(); i++) {
|
||||||
|
if (ImGui::Selectable(
|
||||||
|
ActorDB::Instance->RetrieveEntry(actors[i]).desc.c_str(),
|
||||||
|
i == currentSelectedInDropdown
|
||||||
|
)) {
|
||||||
|
currentSelectedInDropdown = i;
|
||||||
|
newActor.id = actors[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ImGui::EndCombo();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
ImGui::Text("%s", GetActorDescription(newActor.id).c_str());
|
ImGui::Text("%s", GetActorDescription(newActor.id).c_str());
|
||||||
ImGui::InputScalar("ID", ImGuiDataType_S16, &newActor.id, &one);
|
if (ImGui::InputScalar("ID", ImGuiDataType_S16, &newActor.id, &one)) {
|
||||||
|
newActor.params = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
UIWidgets::EnhancementCheckbox("Advanced mode", CVAR_DEVELOPER_TOOLS("ActorViewer.AdvancedParams"));
|
||||||
|
UIWidgets::InsertHelpHoverText("Changes the actor specific param menus with a direct input");
|
||||||
|
|
||||||
|
if (CVarGetInteger(CVAR_DEVELOPER_TOOLS("ActorViewer.AdvancedParams"), 0)) {
|
||||||
ImGui::InputScalar("params", ImGuiDataType_S16, &newActor.params, &one);
|
ImGui::InputScalar("params", ImGuiDataType_S16, &newActor.params, &one);
|
||||||
|
} else if (std::find(noParamsActors.begin(), noParamsActors.end(), newActor.id) == noParamsActors.end()) {
|
||||||
|
CreateActorSpecificData();
|
||||||
|
if (actorSpecificData.find(newActor.id) == actorSpecificData.end()) {
|
||||||
|
ImGui::InputScalar("params", ImGuiDataType_S16, &newActor.params, &one);
|
||||||
|
} else {
|
||||||
|
DrawGroupWithBorder([&]() {
|
||||||
|
ImGui::Text("Actor Specific Data");
|
||||||
|
newActor.params = actorSpecificData[newActor.id](newActor.params);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
ImGui::PushItemWidth(ImGui::GetFontSize() * 6);
|
ImGui::PushItemWidth(ImGui::GetFontSize() * 6);
|
||||||
|
|
||||||
@ -388,7 +1215,7 @@ void ActorViewerWindow::DrawElement() {
|
|||||||
UIWidgets::Spacer(0);
|
UIWidgets::Spacer(0);
|
||||||
|
|
||||||
ImGui::Text("Actor Name Tags");
|
ImGui::Text("Actor Name Tags");
|
||||||
if (UIWidgets::EnhancementCombobox("gDebugActorViewerNameTags", nameTagOptions, ACTORVIEWER_NAMETAGS_NONE)) {
|
if (UIWidgets::EnhancementCombobox(CVAR_DEVELOPER_TOOLS("ActorViewer.NameTags"), nameTagOptions, ACTORVIEWER_NAMETAGS_NONE)) {
|
||||||
NameTag_RemoveAllByTag(DEBUG_ACTOR_NAMETAG_TAG);
|
NameTag_RemoveAllByTag(DEBUG_ACTOR_NAMETAG_TAG);
|
||||||
ActorViewer_AddTagForAllActors();
|
ActorViewer_AddTagForAllActors();
|
||||||
}
|
}
|
||||||
@ -401,6 +1228,11 @@ void ActorViewerWindow::DrawElement() {
|
|||||||
filler = "Please Select";
|
filler = "Please Select";
|
||||||
list.clear();
|
list.clear();
|
||||||
needs_reset = false;
|
needs_reset = false;
|
||||||
|
for (size_t i = 0; i < ARRAY_COUNT(searchString); i += 1) {
|
||||||
|
searchString[i] = 0;
|
||||||
|
}
|
||||||
|
currentSelectedInDropdown = -1;
|
||||||
|
actors.clear();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
#include <libultraship/libultraship.h>
|
#include <libultraship/libultraship.h>
|
||||||
|
|
||||||
class ActorViewerWindow : public LUS::GuiWindow {
|
class ActorViewerWindow : public Ship::GuiWindow {
|
||||||
public:
|
public:
|
||||||
using GuiWindow::GuiWindow;
|
using GuiWindow::GuiWindow;
|
||||||
|
|
||||||
|
@ -7,6 +7,7 @@
|
|||||||
#include <cmath>
|
#include <cmath>
|
||||||
#include <libultraship/bridge.h>
|
#include <libultraship/bridge.h>
|
||||||
#include <libultraship/libultraship.h>
|
#include <libultraship/libultraship.h>
|
||||||
|
#include "soh/OTRGlobals.h"
|
||||||
|
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#include <z64.h>
|
#include <z64.h>
|
||||||
@ -57,17 +58,17 @@ void ColViewerWindow::DrawElement() {
|
|||||||
ImGui::End();
|
ImGui::End();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
UIWidgets::EnhancementCheckbox("Enabled", "gColViewerEnabled");
|
UIWidgets::EnhancementCheckbox("Enabled", CVAR_DEVELOPER_TOOLS("ColViewer.Enabled"));
|
||||||
|
|
||||||
UIWidgets::LabeledRightAlignedEnhancementCombobox("Scene", "gColViewerScene", ColRenderSettingNames, COLVIEW_DISABLED);
|
UIWidgets::LabeledRightAlignedEnhancementCombobox("Scene", CVAR_DEVELOPER_TOOLS("ColViewer.Scene"), ColRenderSettingNames, COLVIEW_DISABLED);
|
||||||
UIWidgets::LabeledRightAlignedEnhancementCombobox("Bg Actors", "gColViewerBgActors", ColRenderSettingNames, COLVIEW_DISABLED);
|
UIWidgets::LabeledRightAlignedEnhancementCombobox("Bg Actors", CVAR_DEVELOPER_TOOLS("ColViewer.BGActors"), ColRenderSettingNames, COLVIEW_DISABLED);
|
||||||
UIWidgets::LabeledRightAlignedEnhancementCombobox("Col Check", "gColViewerColCheck", ColRenderSettingNames, COLVIEW_DISABLED);
|
UIWidgets::LabeledRightAlignedEnhancementCombobox("Col Check", CVAR_DEVELOPER_TOOLS("ColViewer.ColCheck"), ColRenderSettingNames, COLVIEW_DISABLED);
|
||||||
UIWidgets::LabeledRightAlignedEnhancementCombobox("Waterbox", "gColViewerWaterbox", ColRenderSettingNames, COLVIEW_DISABLED);
|
UIWidgets::LabeledRightAlignedEnhancementCombobox("Waterbox", CVAR_DEVELOPER_TOOLS("ColViewer.Waterbox"), ColRenderSettingNames, COLVIEW_DISABLED);
|
||||||
|
|
||||||
UIWidgets::EnhancementCheckbox("Apply as decal", "gColViewerDecal");
|
UIWidgets::EnhancementCheckbox("Apply as decal", CVAR_DEVELOPER_TOOLS("ColViewer.Decal"));
|
||||||
UIWidgets::InsertHelpHoverText("Applies the collision as a decal display. This can be useful if there is z-fighting occuring "
|
UIWidgets::InsertHelpHoverText("Applies the collision as a decal display. This can be useful if there is z-fighting occuring "
|
||||||
"with the scene geometry, but can cause other artifacts.");
|
"with the scene geometry, but can cause other artifacts.");
|
||||||
UIWidgets::EnhancementCheckbox("Shaded", "gColViewerShaded");
|
UIWidgets::EnhancementCheckbox("Shaded", CVAR_DEVELOPER_TOOLS("ColViewer.Shaded"));
|
||||||
UIWidgets::InsertHelpHoverText("Applies the scene's shading to the collision display.");
|
UIWidgets::InsertHelpHoverText("Applies the scene's shading to the collision display.");
|
||||||
|
|
||||||
// This has to be duplicated in both code paths due to the nature of ImGui::IsItemHovered()
|
// This has to be duplicated in both code paths due to the nature of ImGui::IsItemHovered()
|
||||||
@ -75,20 +76,20 @@ void ColViewerWindow::DrawElement() {
|
|||||||
if (ImGui::TreeNode("Colors")) {
|
if (ImGui::TreeNode("Colors")) {
|
||||||
UIWidgets::InsertHelpHoverText(colorHelpText);
|
UIWidgets::InsertHelpHoverText(colorHelpText);
|
||||||
|
|
||||||
UIWidgets::EnhancementColor("Normal", "gColViewerColorNormal", scene_col, ImVec4(255, 255, 255, 255), false);
|
UIWidgets::EnhancementColor("Normal", CVAR_DEVELOPER_TOOLS("ColViewer.ColorNormal"), scene_col, ImVec4(255, 255, 255, 255), false);
|
||||||
UIWidgets::EnhancementColor("Hookshot", "gColViewerColorHookshot", hookshot_col, ImVec4(128, 128, 255, 255),
|
UIWidgets::EnhancementColor("Hookshot", CVAR_DEVELOPER_TOOLS("ColViewer.ColorHookshot"), hookshot_col, ImVec4(128, 128, 255, 255),
|
||||||
false);
|
false);
|
||||||
UIWidgets::EnhancementColor("Entrance", "gColViewerColorEntrance", entrance_col, ImVec4(0, 255, 0, 255), false);
|
UIWidgets::EnhancementColor("Entrance", CVAR_DEVELOPER_TOOLS("ColViewer.ColorEntrance"), entrance_col, ImVec4(0, 255, 0, 255), false);
|
||||||
UIWidgets::EnhancementColor("Special Surface (Grass/Sand/Etc)", "gColViewerColorSpecialSurface",
|
UIWidgets::EnhancementColor("Special Surface (Grass/Sand/Etc)", CVAR_DEVELOPER_TOOLS("ColViewer.ColorSpecialSurface"),
|
||||||
specialSurface_col, ImVec4(192, 255, 192, 255), false);
|
specialSurface_col, ImVec4(192, 255, 192, 255), false);
|
||||||
UIWidgets::EnhancementColor("Interactable (Vines/Crawlspace/Etc)", "gColViewerColorInteractable",
|
UIWidgets::EnhancementColor("Interactable (Vines/Crawlspace/Etc)", CVAR_DEVELOPER_TOOLS("ColViewer.ColorInteractable"),
|
||||||
interactable_col, ImVec4(192, 0, 192, 255), false);
|
interactable_col, ImVec4(192, 0, 192, 255), false);
|
||||||
UIWidgets::EnhancementColor("Slope", "gColViewerColorSlope", slope_col, ImVec4(255, 255, 128, 255), false);
|
UIWidgets::EnhancementColor("Slope", CVAR_DEVELOPER_TOOLS("ColViewer.ColorSlope"), slope_col, ImVec4(255, 255, 128, 255), false);
|
||||||
UIWidgets::EnhancementColor("Void", "gColViewerColorVoid", void_col, ImVec4(255, 0, 0, 255), false);
|
UIWidgets::EnhancementColor("Void", CVAR_DEVELOPER_TOOLS("ColViewer.ColorVoid"), void_col, ImVec4(255, 0, 0, 255), false);
|
||||||
UIWidgets::EnhancementColor("OC", "gColViewerColorOC", oc_col, ImVec4(255, 255, 255, 255), false);
|
UIWidgets::EnhancementColor("OC", CVAR_DEVELOPER_TOOLS("ColViewer.ColorOC"), oc_col, ImVec4(255, 255, 255, 255), false);
|
||||||
UIWidgets::EnhancementColor("AC", "gColViewerColorAC", ac_col, ImVec4(0, 0, 255, 255), false);
|
UIWidgets::EnhancementColor("AC", CVAR_DEVELOPER_TOOLS("ColViewer.ColorAC"), ac_col, ImVec4(0, 0, 255, 255), false);
|
||||||
UIWidgets::EnhancementColor("AT", "gColViewerColorAT", at_col, ImVec4(255, 0, 0, 255), false);
|
UIWidgets::EnhancementColor("AT", CVAR_DEVELOPER_TOOLS("ColViewer.ColorAT"), at_col, ImVec4(255, 0, 0, 255), false);
|
||||||
UIWidgets::EnhancementColor("Waterbox", "gColViewerColorWaterbox", waterbox_col, ImVec4(0, 0, 255, 255), false);
|
UIWidgets::EnhancementColor("Waterbox", CVAR_DEVELOPER_TOOLS("ColViewer.ColorWaterbox"), waterbox_col, ImVec4(0, 0, 255, 255), false);
|
||||||
|
|
||||||
ImGui::TreePop();
|
ImGui::TreePop();
|
||||||
} else {
|
} else {
|
||||||
@ -308,7 +309,7 @@ void InitGfx(std::vector<Gfx>& gfx, ColRenderSetting setting) {
|
|||||||
alpha = 0xFF;
|
alpha = 0xFF;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (CVarGetInteger("gColViewerDecal", 0) != 0) {
|
if (CVarGetInteger(CVAR_DEVELOPER_TOOLS("ColViewer.Decal"), 0) != 0) {
|
||||||
rm |= ZMODE_DEC;
|
rm |= ZMODE_DEC;
|
||||||
} else if (setting == ColRenderSetting::Transparent) {
|
} else if (setting == ColRenderSetting::Transparent) {
|
||||||
rm |= ZMODE_XLU;
|
rm |= ZMODE_XLU;
|
||||||
@ -320,7 +321,7 @@ void InitGfx(std::vector<Gfx>& gfx, ColRenderSetting setting) {
|
|||||||
gfx.push_back(gsDPSetCycleType(G_CYC_1CYCLE));
|
gfx.push_back(gsDPSetCycleType(G_CYC_1CYCLE));
|
||||||
gfx.push_back(gsDPSetRenderMode(rm | blc1, rm | blc2));
|
gfx.push_back(gsDPSetRenderMode(rm | blc1, rm | blc2));
|
||||||
|
|
||||||
if (CVarGetInteger("gColViewerShaded", 0) != 0) {
|
if (CVarGetInteger(CVAR_DEVELOPER_TOOLS("ColViewer.Shaded"), 0) != 0) {
|
||||||
gfx.push_back(gsDPSetCombineMode(G_CC_MODULATERGB_PRIM_ENVA, G_CC_MODULATERGB_PRIM_ENVA));
|
gfx.push_back(gsDPSetCombineMode(G_CC_MODULATERGB_PRIM_ENVA, G_CC_MODULATERGB_PRIM_ENVA));
|
||||||
gfx.push_back(gsSPLoadGeometryMode(G_CULL_BACK | G_ZBUFFER | G_LIGHTING));
|
gfx.push_back(gsSPLoadGeometryMode(G_CULL_BACK | G_ZBUFFER | G_LIGHTING));
|
||||||
} else {
|
} else {
|
||||||
@ -333,16 +334,13 @@ void InitGfx(std::vector<Gfx>& gfx, ColRenderSetting setting) {
|
|||||||
|
|
||||||
// Draws a dynapoly structure (scenes or Bg Actors)
|
// Draws a dynapoly structure (scenes or Bg Actors)
|
||||||
void DrawDynapoly(std::vector<Gfx>& dl, CollisionHeader* col, int32_t bgId) {
|
void DrawDynapoly(std::vector<Gfx>& dl, CollisionHeader* col, int32_t bgId) {
|
||||||
uint32_t colorR = CVarGetInteger("gColViewerColorNormalR", 255);
|
Color_RGBA8 color = {255, 255, 255, 255};
|
||||||
uint32_t colorG = CVarGetInteger("gColViewerColorNormalG", 255);
|
|
||||||
uint32_t colorB = CVarGetInteger("gColViewerColorNormalB", 255);
|
|
||||||
uint32_t colorA = 255;
|
|
||||||
|
|
||||||
uint32_t lastColorR = colorR;
|
uint32_t lastColorR = color.r;
|
||||||
uint32_t lastColorG = colorG;
|
uint32_t lastColorG = color.g;
|
||||||
uint32_t lastColorB = colorB;
|
uint32_t lastColorB = color.b;
|
||||||
|
|
||||||
dl.push_back(gsDPSetPrimColor(0, 0, colorR, colorG, colorB, colorA));
|
dl.push_back(gsDPSetPrimColor(0, 0, color.r, color.g, color.b, 255));
|
||||||
|
|
||||||
// This keeps track of if we have processed a poly, but not drawn it yet so we can batch them.
|
// This keeps track of if we have processed a poly, but not drawn it yet so we can batch them.
|
||||||
// This saves several hundred commands in larger scenes
|
// This saves several hundred commands in larger scenes
|
||||||
@ -352,49 +350,35 @@ void DrawDynapoly(std::vector<Gfx>& dl, CollisionHeader* col, int32_t bgId) {
|
|||||||
CollisionPoly* poly = &col->polyList[i];
|
CollisionPoly* poly = &col->polyList[i];
|
||||||
|
|
||||||
if (SurfaceType_IsHookshotSurface(&gPlayState->colCtx, poly, bgId)) {
|
if (SurfaceType_IsHookshotSurface(&gPlayState->colCtx, poly, bgId)) {
|
||||||
colorR = CVarGetInteger("gColViewerColorHookshotR", 128);
|
color = CVarGetColor(CVAR_DEVELOPER_TOOLS("ColViewer.ColorHookshot"), { 128, 128, 255, 255 });
|
||||||
colorG = CVarGetInteger("gColViewerColorHookshotG", 128);
|
|
||||||
colorB = CVarGetInteger("gColViewerColorHookshotB", 255);
|
|
||||||
} else if (func_80041D94(&gPlayState->colCtx, poly, bgId) > 0x01) {
|
} else if (func_80041D94(&gPlayState->colCtx, poly, bgId) > 0x01) {
|
||||||
colorR = CVarGetInteger("gColViewerColorInteractableR", 192);
|
color = CVarGetColor(CVAR_DEVELOPER_TOOLS("ColViewer.ColorInteractable"), {192, 0, 192, 255});
|
||||||
colorG = CVarGetInteger("gColViewerColorInteractableG", 0);
|
|
||||||
colorB = CVarGetInteger("gColViewerColorInteractableB", 192);
|
|
||||||
} else if (func_80041E80(&gPlayState->colCtx, poly, bgId) == 0x0C) {
|
} else if (func_80041E80(&gPlayState->colCtx, poly, bgId) == 0x0C) {
|
||||||
colorR = CVarGetInteger("gColViewerColorVoidR", 255);
|
color = CVarGetColor(CVAR_DEVELOPER_TOOLS("ColViewer.ColorVoid"), { 255, 0, 0, 255 });
|
||||||
colorG = CVarGetInteger("gColViewerColorVoidG", 0);
|
|
||||||
colorB = CVarGetInteger("gColViewerColorVoidB", 0);
|
|
||||||
} else if (SurfaceType_GetSceneExitIndex(&gPlayState->colCtx, poly, bgId) ||
|
} else if (SurfaceType_GetSceneExitIndex(&gPlayState->colCtx, poly, bgId) ||
|
||||||
func_80041E80(&gPlayState->colCtx, poly, bgId) == 0x05) {
|
func_80041E80(&gPlayState->colCtx, poly, bgId) == 0x05) {
|
||||||
colorR = CVarGetInteger("gColViewerColorEntranceR", 0);
|
color = CVarGetColor(CVAR_DEVELOPER_TOOLS("ColViewer.ColorEntrance"), { 0, 255, 0, 255 });
|
||||||
colorG = CVarGetInteger("gColViewerColorEntranceG", 255);
|
|
||||||
colorB = CVarGetInteger("gColViewerColorEntranceB", 0);
|
|
||||||
} else if (func_80041D4C(&gPlayState->colCtx, poly, bgId) != 0 ||
|
} else if (func_80041D4C(&gPlayState->colCtx, poly, bgId) != 0 ||
|
||||||
SurfaceType_IsWallDamage(&gPlayState->colCtx, poly, bgId)) {
|
SurfaceType_IsWallDamage(&gPlayState->colCtx, poly, bgId)) {
|
||||||
colorR = CVarGetInteger("gColViewerColorSpecialSurfaceR", 192);
|
color = CVarGetColor(CVAR_DEVELOPER_TOOLS("ColViewer.ColorSpecialSurface"), { 192, 255, 192, 255 });
|
||||||
colorG = CVarGetInteger("gColViewerColorSpecialSurfaceG", 255);
|
|
||||||
colorB = CVarGetInteger("gColViewerColorSpecialSurfaceB", 192);
|
|
||||||
} else if (SurfaceType_GetSlope(&gPlayState->colCtx, poly, bgId) == 0x01) {
|
} else if (SurfaceType_GetSlope(&gPlayState->colCtx, poly, bgId) == 0x01) {
|
||||||
colorR = CVarGetInteger("gColViewerColorSlopeR", 255);
|
color = CVarGetColor(CVAR_DEVELOPER_TOOLS("ColViewer.ColorSlope"), { 255, 255, 128, 255 });
|
||||||
colorG = CVarGetInteger("gColViewerColorSlopeG", 255);
|
|
||||||
colorB = CVarGetInteger("gColViewerColorSlopeB", 128);
|
|
||||||
} else {
|
} else {
|
||||||
colorR = CVarGetInteger("gColViewerColorNormalR", 255);
|
color = CVarGetColor(CVAR_DEVELOPER_TOOLS("ColViewer.ColorNormal"), { 255, 255, 255, 255 });
|
||||||
colorG = CVarGetInteger("gColViewerColorNormalG", 255);
|
|
||||||
colorB = CVarGetInteger("gColViewerColorNormalB", 255);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (colorR != lastColorR || colorG != lastColorG || colorB != lastColorB) {
|
if (color.r != lastColorR || color.g != lastColorG || color.b != lastColorB) {
|
||||||
// Color changed, flush previous poly
|
// Color changed, flush previous poly
|
||||||
if (previousPoly) {
|
if (previousPoly) {
|
||||||
dl.push_back(gsSPVertex((uintptr_t)&vtxDl.at(vtxDl.size() - 3), 3, 0));
|
dl.push_back(gsSPVertex((uintptr_t)&vtxDl.at(vtxDl.size() - 3), 3, 0));
|
||||||
dl.push_back(gsSP1Triangle(0, 1, 2, 0));
|
dl.push_back(gsSP1Triangle(0, 1, 2, 0));
|
||||||
previousPoly = false;
|
previousPoly = false;
|
||||||
}
|
}
|
||||||
dl.push_back(gsDPSetPrimColor(0, 0, colorR, colorG, colorB, colorA));
|
dl.push_back(gsDPSetPrimColor(0, 0, color.r, color.g, color.b, 255));
|
||||||
}
|
}
|
||||||
lastColorR = colorR;
|
lastColorR = color.r;
|
||||||
lastColorG = colorG;
|
lastColorG = color.g;
|
||||||
lastColorB = colorB;
|
lastColorB = color.b;
|
||||||
|
|
||||||
Vec3s* va = &col->vtxList[COLPOLY_VTX_INDEX(poly->flags_vIA)];
|
Vec3s* va = &col->vtxList[COLPOLY_VTX_INDEX(poly->flags_vIA)];
|
||||||
Vec3s* vb = &col->vtxList[COLPOLY_VTX_INDEX(poly->flags_vIB)];
|
Vec3s* vb = &col->vtxList[COLPOLY_VTX_INDEX(poly->flags_vIB)];
|
||||||
@ -428,9 +412,9 @@ void DrawDynapoly(std::vector<Gfx>& dl, CollisionHeader* col, int32_t bgId) {
|
|||||||
|
|
||||||
// Draws the scene
|
// Draws the scene
|
||||||
void DrawSceneCollision() {
|
void DrawSceneCollision() {
|
||||||
ColRenderSetting showSceneColSetting = (ColRenderSetting)CVarGetInteger("gColViewerScene", COLVIEW_DISABLED);
|
ColRenderSetting showSceneColSetting = (ColRenderSetting)CVarGetInteger(CVAR_DEVELOPER_TOOLS("ColViewer.Scene"), COLVIEW_DISABLED);
|
||||||
|
|
||||||
if (showSceneColSetting == ColRenderSetting::Disabled || !CVarGetInteger("gColViewerEnabled", 0)) {
|
if (showSceneColSetting == ColRenderSetting::Disabled || !CVarGetInteger(CVAR_DEVELOPER_TOOLS("ColViewer.Enabled"), 0)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -443,8 +427,8 @@ void DrawSceneCollision() {
|
|||||||
|
|
||||||
// Draws all Bg Actors
|
// Draws all Bg Actors
|
||||||
void DrawBgActorCollision() {
|
void DrawBgActorCollision() {
|
||||||
ColRenderSetting showBgActorSetting = (ColRenderSetting)CVarGetInteger("gColViewerBgActors", COLVIEW_DISABLED);
|
ColRenderSetting showBgActorSetting = (ColRenderSetting)CVarGetInteger(CVAR_DEVELOPER_TOOLS("ColViewer.BGActors"), COLVIEW_DISABLED);
|
||||||
if (showBgActorSetting == ColRenderSetting::Disabled || !CVarGetInteger("gColViewerEnabled", 0)) {
|
if (showBgActorSetting == ColRenderSetting::Disabled || !CVarGetInteger(CVAR_DEVELOPER_TOOLS("ColViewer.Enabled"), 0)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -568,8 +552,8 @@ void DrawColCheckList(std::vector<Gfx>& dl, Collider** objects, int32_t count) {
|
|||||||
|
|
||||||
// Draws all Col Check objects
|
// Draws all Col Check objects
|
||||||
void DrawColCheckCollision() {
|
void DrawColCheckCollision() {
|
||||||
ColRenderSetting showColCheckSetting = (ColRenderSetting)CVarGetInteger("gColViewerColCheck", COLVIEW_DISABLED);
|
ColRenderSetting showColCheckSetting = (ColRenderSetting)CVarGetInteger(CVAR_DEVELOPER_TOOLS("ColViewer.ColCheck"), COLVIEW_DISABLED);
|
||||||
if (showColCheckSetting == ColRenderSetting::Disabled || !CVarGetInteger("gColViewerEnabled", 0)) {
|
if (showColCheckSetting == ColRenderSetting::Disabled || !CVarGetInteger(CVAR_DEVELOPER_TOOLS("ColViewer.Enabled"), 0)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -578,15 +562,14 @@ void DrawColCheckCollision() {
|
|||||||
dl.push_back(gsSPMatrix(&gMtxClear, G_MTX_MODELVIEW | G_MTX_LOAD | G_MTX_NOPUSH));
|
dl.push_back(gsSPMatrix(&gMtxClear, G_MTX_MODELVIEW | G_MTX_LOAD | G_MTX_NOPUSH));
|
||||||
|
|
||||||
CollisionCheckContext& col = gPlayState->colChkCtx;
|
CollisionCheckContext& col = gPlayState->colChkCtx;
|
||||||
|
Color_RGBA8 color = CVarGetColor(CVAR_DEVELOPER_TOOLS("ColViewer.ColorOC"), { 255, 255, 255, 255 });
|
||||||
dl.push_back(gsDPSetPrimColor(0, 0, CVarGetInteger("gColViewerColorOCR", 255), CVarGetInteger("gColViewerColorOCG", 255),
|
dl.push_back(gsDPSetPrimColor(0, 0, color.r, color.g, color.b, 255));
|
||||||
CVarGetInteger("gColViewerColorOCB", 255), 255));
|
|
||||||
DrawColCheckList(dl, col.colOC, col.colOCCount);
|
DrawColCheckList(dl, col.colOC, col.colOCCount);
|
||||||
dl.push_back(gsDPSetPrimColor(0, 0, CVarGetInteger("gColViewerColorACR", 0), CVarGetInteger("gColViewerColorACG", 0),
|
color = CVarGetColor(CVAR_DEVELOPER_TOOLS("ColViewer.ColorAC"), { 0, 0, 255, 255 });
|
||||||
CVarGetInteger("gColViewerColorACB", 255), 255));
|
dl.push_back(gsDPSetPrimColor(0, 0, color.r, color.g, color.b, 255));
|
||||||
DrawColCheckList(dl, col.colAC, col.colACCount);
|
DrawColCheckList(dl, col.colAC, col.colACCount);
|
||||||
dl.push_back(gsDPSetPrimColor(0, 0, CVarGetInteger("gColViewerColorATR", 255), CVarGetInteger("gColViewerColorATG", 0),
|
color = CVarGetColor(CVAR_DEVELOPER_TOOLS("ColViewer.ColorAT"), { 0, 0, 255, 255 });
|
||||||
CVarGetInteger("gColViewerColorATB", 0), 255));
|
dl.push_back(gsDPSetPrimColor(0, 0, color.r, color.g, color.b, 255));
|
||||||
|
|
||||||
DrawColCheckList(dl, col.colAT, col.colATCount);
|
DrawColCheckList(dl, col.colAT, col.colATCount);
|
||||||
}
|
}
|
||||||
@ -621,8 +604,8 @@ extern "C" f32 zdWaterBoxMinY;
|
|||||||
|
|
||||||
// Draws all waterboxes
|
// Draws all waterboxes
|
||||||
void DrawWaterboxList() {
|
void DrawWaterboxList() {
|
||||||
ColRenderSetting showWaterboxSetting = (ColRenderSetting)CVarGetInteger("gColViewerWaterbox", COLVIEW_DISABLED);
|
ColRenderSetting showWaterboxSetting = (ColRenderSetting)CVarGetInteger(CVAR_DEVELOPER_TOOLS("ColViewer.Waterbox"), COLVIEW_DISABLED);
|
||||||
if (showWaterboxSetting == ColRenderSetting::Disabled || !CVarGetInteger("gColViewerEnabled", 0)) {
|
if (showWaterboxSetting == ColRenderSetting::Disabled || !CVarGetInteger(CVAR_DEVELOPER_TOOLS("ColViewer.Enabled"), 0)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -630,9 +613,9 @@ void DrawWaterboxList() {
|
|||||||
InitGfx(dl, showWaterboxSetting);
|
InitGfx(dl, showWaterboxSetting);
|
||||||
dl.push_back(gsSPMatrix(&gMtxClear, G_MTX_MODELVIEW | G_MTX_LOAD | G_MTX_NOPUSH));
|
dl.push_back(gsSPMatrix(&gMtxClear, G_MTX_MODELVIEW | G_MTX_LOAD | G_MTX_NOPUSH));
|
||||||
|
|
||||||
dl.push_back(gsDPSetPrimColor(0, 0, CVarGetInteger("gColViewerColorWaterboxR", 0),
|
Color_RGBA8 color = CVarGetColor(CVAR_DEVELOPER_TOOLS("ColViewer.ColorWaterbox"), { 0, 0, 255, 255 });
|
||||||
CVarGetInteger("gColViewerColorWaterboxG", 0),
|
|
||||||
CVarGetInteger("gColViewerColorWaterboxB", 255), 255));
|
dl.push_back(gsDPSetPrimColor(0, 0, color.r, color.g, color.b, 255));
|
||||||
|
|
||||||
CollisionHeader* col = gPlayState->colCtx.colHeader;
|
CollisionHeader* col = gPlayState->colCtx.colHeader;
|
||||||
for (int32_t waterboxIndex = 0; waterboxIndex < col->numWaterBoxes; waterboxIndex++) {
|
for (int32_t waterboxIndex = 0; waterboxIndex < col->numWaterBoxes; waterboxIndex++) {
|
||||||
@ -693,7 +676,7 @@ extern "C" void DrawColViewer() {
|
|||||||
|
|
||||||
OPEN_DISPS(gPlayState->state.gfxCtx);
|
OPEN_DISPS(gPlayState->state.gfxCtx);
|
||||||
|
|
||||||
uint8_t mirroredWorld = CVarGetInteger("gMirroredWorld", 0);
|
uint8_t mirroredWorld = CVarGetInteger(CVAR_ENHANCEMENT("MirroredWorld"), 0);
|
||||||
// Col viewer needs inverted culling in mirror mode for both OPA and XLU buffers
|
// Col viewer needs inverted culling in mirror mode for both OPA and XLU buffers
|
||||||
if (mirroredWorld) {
|
if (mirroredWorld) {
|
||||||
gSPSetExtraGeometryMode(POLY_OPA_DISP++, G_EX_INVERT_CULLING);
|
gSPSetExtraGeometryMode(POLY_OPA_DISP++, G_EX_INVERT_CULLING);
|
||||||
|
@ -14,7 +14,7 @@ typedef enum {
|
|||||||
} ColViewerRenderSetting;
|
} ColViewerRenderSetting;
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
class ColViewerWindow : public LUS::GuiWindow {
|
class ColViewerWindow : public Ship::GuiWindow {
|
||||||
public:
|
public:
|
||||||
using GuiWindow::GuiWindow;
|
using GuiWindow::GuiWindow;
|
||||||
|
|
||||||
|
@ -515,7 +515,7 @@ void DrawInfoTab() {
|
|||||||
UIWidgets::InsertHelpHoverText("Z-Targeting behavior");
|
UIWidgets::InsertHelpHoverText("Z-Targeting behavior");
|
||||||
|
|
||||||
if (IS_RANDO && OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_TRIFORCE_HUNT)) {
|
if (IS_RANDO && OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_TRIFORCE_HUNT)) {
|
||||||
ImGui::InputScalar("Triforce Pieces", ImGuiDataType_U16, &gSaveContext.triforcePiecesCollected);
|
ImGui::InputScalar("Triforce Pieces", ImGuiDataType_U8, &gSaveContext.triforcePiecesCollected);
|
||||||
UIWidgets::InsertHelpHoverText("Currently obtained Triforce Pieces. For Triforce Hunt.");
|
UIWidgets::InsertHelpHoverText("Currently obtained Triforce Pieces. For Triforce Hunt.");
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -614,7 +614,7 @@ void DrawInfoTab() {
|
|||||||
|
|
||||||
void DrawBGSItemFlag(uint8_t itemID) {
|
void DrawBGSItemFlag(uint8_t itemID) {
|
||||||
const ItemMapEntry& slotEntry = itemMapping[itemID];
|
const ItemMapEntry& slotEntry = itemMapping[itemID];
|
||||||
ImGui::Image(LUS::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName(slotEntry.name), ImVec2(32.0f, 32.0f), ImVec2(0, 0), ImVec2(1, 1));
|
ImGui::Image(Ship::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName(slotEntry.name), ImVec2(32.0f, 32.0f), ImVec2(0, 0), ImVec2(1, 1));
|
||||||
ImGui::SameLine();
|
ImGui::SameLine();
|
||||||
int tradeIndex = itemID - ITEM_POCKET_EGG;
|
int tradeIndex = itemID - ITEM_POCKET_EGG;
|
||||||
bool hasItem = (gSaveContext.adultTradeItems & (1 << tradeIndex)) != 0;
|
bool hasItem = (gSaveContext.adultTradeItems & (1 << tradeIndex)) != 0;
|
||||||
@ -656,7 +656,7 @@ void DrawInventoryTab() {
|
|||||||
uint8_t item = gSaveContext.inventory.items[index];
|
uint8_t item = gSaveContext.inventory.items[index];
|
||||||
if (item != ITEM_NONE) {
|
if (item != ITEM_NONE) {
|
||||||
const ItemMapEntry& slotEntry = itemMapping.find(item)->second;
|
const ItemMapEntry& slotEntry = itemMapping.find(item)->second;
|
||||||
if (ImGui::ImageButton(LUS::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName(slotEntry.name), ImVec2(32.0f, 32.0f), ImVec2(0, 0),
|
if (ImGui::ImageButton(Ship::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName(slotEntry.name), ImVec2(32.0f, 32.0f), ImVec2(0, 0),
|
||||||
ImVec2(1, 1), 0)) {
|
ImVec2(1, 1), 0)) {
|
||||||
selectedIndex = index;
|
selectedIndex = index;
|
||||||
ImGui::OpenPopup(itemPopupPicker);
|
ImGui::OpenPopup(itemPopupPicker);
|
||||||
@ -704,7 +704,7 @@ void DrawInventoryTab() {
|
|||||||
ImGui::SameLine();
|
ImGui::SameLine();
|
||||||
}
|
}
|
||||||
const ItemMapEntry& slotEntry = possibleItems[pickerIndex];
|
const ItemMapEntry& slotEntry = possibleItems[pickerIndex];
|
||||||
if (ImGui::ImageButton(LUS::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName(slotEntry.name), ImVec2(32.0f, 32.0f),
|
if (ImGui::ImageButton(Ship::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName(slotEntry.name), ImVec2(32.0f, 32.0f),
|
||||||
ImVec2(0, 0), ImVec2(1, 1), 0)) {
|
ImVec2(0, 0), ImVec2(1, 1), 0)) {
|
||||||
gSaveContext.inventory.items[selectedIndex] = slotEntry.id;
|
gSaveContext.inventory.items[selectedIndex] = slotEntry.id;
|
||||||
// Set adult trade item flag if you're playing adult trade shuffle in rando
|
// Set adult trade item flag if you're playing adult trade shuffle in rando
|
||||||
@ -742,7 +742,7 @@ void DrawInventoryTab() {
|
|||||||
ImGui::PushItemWidth(32.0f);
|
ImGui::PushItemWidth(32.0f);
|
||||||
ImGui::BeginGroup();
|
ImGui::BeginGroup();
|
||||||
|
|
||||||
ImGui::Image(LUS::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName(itemMapping[item].name), ImVec2(32.0f, 32.0f));
|
ImGui::Image(Ship::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName(itemMapping[item].name), ImVec2(32.0f, 32.0f));
|
||||||
ImGui::InputScalar("##ammoInput", ImGuiDataType_S8, &AMMO(item));
|
ImGui::InputScalar("##ammoInput", ImGuiDataType_S8, &AMMO(item));
|
||||||
|
|
||||||
ImGui::EndGroup();
|
ImGui::EndGroup();
|
||||||
@ -1157,7 +1157,7 @@ void DrawUpgradeIcon(const std::string& categoryName, int32_t categoryId, const
|
|||||||
uint8_t item = items[CUR_UPG_VALUE(categoryId)];
|
uint8_t item = items[CUR_UPG_VALUE(categoryId)];
|
||||||
if (item != ITEM_NONE) {
|
if (item != ITEM_NONE) {
|
||||||
const ItemMapEntry& slotEntry = itemMapping[item];
|
const ItemMapEntry& slotEntry = itemMapping[item];
|
||||||
if (ImGui::ImageButton(LUS::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName(slotEntry.name), ImVec2(32.0f, 32.0f), ImVec2(0, 0),
|
if (ImGui::ImageButton(Ship::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName(slotEntry.name), ImVec2(32.0f, 32.0f), ImVec2(0, 0),
|
||||||
ImVec2(1, 1), 0)) {
|
ImVec2(1, 1), 0)) {
|
||||||
ImGui::OpenPopup(upgradePopupPicker);
|
ImGui::OpenPopup(upgradePopupPicker);
|
||||||
}
|
}
|
||||||
@ -1185,7 +1185,7 @@ void DrawUpgradeIcon(const std::string& categoryName, int32_t categoryId, const
|
|||||||
UIWidgets::SetLastItemHoverText("None");
|
UIWidgets::SetLastItemHoverText("None");
|
||||||
} else {
|
} else {
|
||||||
const ItemMapEntry& slotEntry = itemMapping[items[pickerIndex]];
|
const ItemMapEntry& slotEntry = itemMapping[items[pickerIndex]];
|
||||||
if (ImGui::ImageButton(LUS::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName(slotEntry.name), ImVec2(32.0f, 32.0f), ImVec2(0, 0),
|
if (ImGui::ImageButton(Ship::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName(slotEntry.name), ImVec2(32.0f, 32.0f), ImVec2(0, 0),
|
||||||
ImVec2(1, 1), 0)) {
|
ImVec2(1, 1), 0)) {
|
||||||
Inventory_ChangeUpgrade(categoryId, pickerIndex);
|
Inventory_ChangeUpgrade(categoryId, pickerIndex);
|
||||||
ImGui::CloseCurrentPopup();
|
ImGui::CloseCurrentPopup();
|
||||||
@ -1222,7 +1222,7 @@ void DrawEquipmentTab() {
|
|||||||
bool hasEquip = (bitMask & gSaveContext.inventory.equipment) != 0;
|
bool hasEquip = (bitMask & gSaveContext.inventory.equipment) != 0;
|
||||||
const ItemMapEntry& entry = itemMapping[equipmentValues[i]];
|
const ItemMapEntry& entry = itemMapping[equipmentValues[i]];
|
||||||
ImGui::PushStyleColor(ImGuiCol_Button, ImVec4(0, 0, 0, 0));
|
ImGui::PushStyleColor(ImGuiCol_Button, ImVec4(0, 0, 0, 0));
|
||||||
if (ImGui::ImageButton(LUS::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName(hasEquip ? entry.name : entry.nameFaded),
|
if (ImGui::ImageButton(Ship::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName(hasEquip ? entry.name : entry.nameFaded),
|
||||||
ImVec2(32.0f, 32.0f), ImVec2(0, 0), ImVec2(1, 1), 0)) {
|
ImVec2(32.0f, 32.0f), ImVec2(0, 0), ImVec2(1, 1), 0)) {
|
||||||
if (hasEquip) {
|
if (hasEquip) {
|
||||||
gSaveContext.inventory.equipment &= ~bitMask;
|
gSaveContext.inventory.equipment &= ~bitMask;
|
||||||
@ -1321,7 +1321,7 @@ void DrawQuestItemButton(uint32_t item) {
|
|||||||
uint32_t bitMask = 1 << entry.id;
|
uint32_t bitMask = 1 << entry.id;
|
||||||
bool hasQuestItem = (bitMask & gSaveContext.inventory.questItems) != 0;
|
bool hasQuestItem = (bitMask & gSaveContext.inventory.questItems) != 0;
|
||||||
ImGui::PushStyleColor(ImGuiCol_Button, ImVec4(0, 0, 0, 0));
|
ImGui::PushStyleColor(ImGuiCol_Button, ImVec4(0, 0, 0, 0));
|
||||||
if (ImGui::ImageButton(LUS::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName(hasQuestItem ? entry.name : entry.nameFaded),
|
if (ImGui::ImageButton(Ship::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName(hasQuestItem ? entry.name : entry.nameFaded),
|
||||||
ImVec2(32.0f, 32.0f), ImVec2(0, 0), ImVec2(1, 1), 0)) {
|
ImVec2(32.0f, 32.0f), ImVec2(0, 0), ImVec2(1, 1), 0)) {
|
||||||
if (hasQuestItem) {
|
if (hasQuestItem) {
|
||||||
gSaveContext.inventory.questItems &= ~bitMask;
|
gSaveContext.inventory.questItems &= ~bitMask;
|
||||||
@ -1339,7 +1339,7 @@ void DrawDungeonItemButton(uint32_t item, uint32_t scene) {
|
|||||||
uint32_t bitMask = 1 << (entry.id - ITEM_KEY_BOSS); // Bitset starts at ITEM_KEY_BOSS == 0. the rest are sequential
|
uint32_t bitMask = 1 << (entry.id - ITEM_KEY_BOSS); // Bitset starts at ITEM_KEY_BOSS == 0. the rest are sequential
|
||||||
bool hasItem = (bitMask & gSaveContext.inventory.dungeonItems[scene]) != 0;
|
bool hasItem = (bitMask & gSaveContext.inventory.dungeonItems[scene]) != 0;
|
||||||
ImGui::PushStyleColor(ImGuiCol_Button, ImVec4(0, 0, 0, 0));
|
ImGui::PushStyleColor(ImGuiCol_Button, ImVec4(0, 0, 0, 0));
|
||||||
if (ImGui::ImageButton(LUS::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName(hasItem ? entry.name : entry.nameFaded),
|
if (ImGui::ImageButton(Ship::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName(hasItem ? entry.name : entry.nameFaded),
|
||||||
ImVec2(32.0f, 32.0f), ImVec2(0, 0), ImVec2(1, 1), 0)) {
|
ImVec2(32.0f, 32.0f), ImVec2(0, 0), ImVec2(1, 1), 0)) {
|
||||||
if (hasItem) {
|
if (hasItem) {
|
||||||
gSaveContext.inventory.dungeonItems[scene] &= ~bitMask;
|
gSaveContext.inventory.dungeonItems[scene] &= ~bitMask;
|
||||||
@ -1386,7 +1386,7 @@ void DrawQuestStatusTab() {
|
|||||||
uint32_t bitMask = 1 << entry.id;
|
uint32_t bitMask = 1 << entry.id;
|
||||||
bool hasQuestItem = (bitMask & gSaveContext.inventory.questItems) != 0;
|
bool hasQuestItem = (bitMask & gSaveContext.inventory.questItems) != 0;
|
||||||
ImGui::PushStyleColor(ImGuiCol_Button, ImVec4(0, 0, 0, 0));
|
ImGui::PushStyleColor(ImGuiCol_Button, ImVec4(0, 0, 0, 0));
|
||||||
if (ImGui::ImageButton(LUS::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName(hasQuestItem ? entry.name : entry.nameFaded),
|
if (ImGui::ImageButton(Ship::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName(hasQuestItem ? entry.name : entry.nameFaded),
|
||||||
ImVec2(16.0f, 24.0f), ImVec2(0, 0), ImVec2(1, 1), 0)) {
|
ImVec2(16.0f, 24.0f), ImVec2(0, 0), ImVec2(1, 1), 0)) {
|
||||||
if (hasQuestItem) {
|
if (hasQuestItem) {
|
||||||
gSaveContext.inventory.questItems &= ~bitMask;
|
gSaveContext.inventory.questItems &= ~bitMask;
|
||||||
@ -1449,7 +1449,7 @@ void DrawQuestStatusTab() {
|
|||||||
|
|
||||||
if (dungeonItemsScene != SCENE_JABU_JABU_BOSS) {
|
if (dungeonItemsScene != SCENE_JABU_JABU_BOSS) {
|
||||||
float lineHeight = ImGui::GetTextLineHeightWithSpacing();
|
float lineHeight = ImGui::GetTextLineHeightWithSpacing();
|
||||||
ImGui::Image(LUS::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName(itemMapping[ITEM_KEY_SMALL].name), ImVec2(lineHeight, lineHeight));
|
ImGui::Image(Ship::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName(itemMapping[ITEM_KEY_SMALL].name), ImVec2(lineHeight, lineHeight));
|
||||||
ImGui::SameLine();
|
ImGui::SameLine();
|
||||||
if (ImGui::InputScalar("##Keys", ImGuiDataType_S8, gSaveContext.inventory.dungeonKeys + dungeonItemsScene)) {
|
if (ImGui::InputScalar("##Keys", ImGuiDataType_S8, gSaveContext.inventory.dungeonKeys + dungeonItemsScene)) {
|
||||||
gSaveContext.sohStats.dungeonKeys[dungeonItemsScene] = gSaveContext.inventory.dungeonKeys[dungeonItemsScene];
|
gSaveContext.sohStats.dungeonKeys[dungeonItemsScene] = gSaveContext.inventory.dungeonKeys[dungeonItemsScene];
|
||||||
@ -1573,7 +1573,7 @@ void DrawPlayerTab() {
|
|||||||
ImGui::InputScalar("Y Velocity", ImGuiDataType_Float, &player->actor.velocity.y);
|
ImGui::InputScalar("Y Velocity", ImGuiDataType_Float, &player->actor.velocity.y);
|
||||||
UIWidgets::InsertHelpHoverText("Link's speed along the Y plane. Caps at -20");
|
UIWidgets::InsertHelpHoverText("Link's speed along the Y plane. Caps at -20");
|
||||||
|
|
||||||
ImGui::InputScalar("Wall Height", ImGuiDataType_Float, &player->wallHeight);
|
ImGui::InputScalar("Wall Height", ImGuiDataType_Float, &player->yDistToLedge);
|
||||||
UIWidgets::InsertHelpHoverText("Height used to determine whether Link can climb or grab a ledge at the top");
|
UIWidgets::InsertHelpHoverText("Height used to determine whether Link can climb or grab a ledge at the top");
|
||||||
|
|
||||||
ImGui::InputScalar("Invincibility Timer", ImGuiDataType_S8, &player->invincibilityTimer);
|
ImGui::InputScalar("Invincibility Timer", ImGuiDataType_S8, &player->invincibilityTimer);
|
||||||
@ -1705,7 +1705,7 @@ void DrawPlayerTab() {
|
|||||||
ImGui::SameLine();
|
ImGui::SameLine();
|
||||||
ImGui::InputScalar("C Right", ImGuiDataType_U8, &gSaveContext.equips.buttonItems[3], &one, NULL);
|
ImGui::InputScalar("C Right", ImGuiDataType_U8, &gSaveContext.equips.buttonItems[3], &one, NULL);
|
||||||
|
|
||||||
if (CVarGetInteger("gDpadEquips", 0)) {
|
if (CVarGetInteger(CVAR_SETTING("DpadEquips"), 0)) {
|
||||||
ImGui::NewLine();
|
ImGui::NewLine();
|
||||||
ImGui::Text("Current D-pad Equips");
|
ImGui::Text("Current D-pad Equips");
|
||||||
ImGui::InputScalar("D-pad Up ", ImGuiDataType_U8, &gSaveContext.equips.buttonItems[4], &one, NULL); // Two spaces at the end for aligning, not elegant but it's working
|
ImGui::InputScalar("D-pad Up ", ImGuiDataType_U8, &gSaveContext.equips.buttonItems[4], &one, NULL); // Two spaces at the end for aligning, not elegant but it's working
|
||||||
@ -1793,34 +1793,34 @@ void SaveEditorWindow::DrawElement() {
|
|||||||
void SaveEditorWindow::InitElement() {
|
void SaveEditorWindow::InitElement() {
|
||||||
// Load item icons into ImGui
|
// Load item icons into ImGui
|
||||||
for (const auto& entry : itemMapping) {
|
for (const auto& entry : itemMapping) {
|
||||||
LUS::Context::GetInstance()->GetWindow()->GetGui()->LoadGuiTexture(entry.second.name, entry.second.texturePath, ImVec4(1, 1, 1, 1));
|
Ship::Context::GetInstance()->GetWindow()->GetGui()->LoadGuiTexture(entry.second.name, entry.second.texturePath, ImVec4(1, 1, 1, 1));
|
||||||
LUS::Context::GetInstance()->GetWindow()->GetGui()->LoadGuiTexture(entry.second.nameFaded, entry.second.texturePath, ImVec4(1, 1, 1, 0.3f));
|
Ship::Context::GetInstance()->GetWindow()->GetGui()->LoadGuiTexture(entry.second.nameFaded, entry.second.texturePath, ImVec4(1, 1, 1, 0.3f));
|
||||||
}
|
}
|
||||||
for (const auto& entry : gregMapping) {
|
for (const auto& entry : gregMapping) {
|
||||||
ImVec4 gregGreen = ImVec4(42.0f / 255.0f, 169.0f / 255.0f, 40.0f / 255.0f, 1.0f);
|
ImVec4 gregGreen = ImVec4(42.0f / 255.0f, 169.0f / 255.0f, 40.0f / 255.0f, 1.0f);
|
||||||
ImVec4 gregFadedGreen = gregGreen;
|
ImVec4 gregFadedGreen = gregGreen;
|
||||||
gregFadedGreen.w = 0.3f;
|
gregFadedGreen.w = 0.3f;
|
||||||
LUS::Context::GetInstance()->GetWindow()->GetGui()->LoadGuiTexture(entry.second.name, entry.second.texturePath, gregGreen);
|
Ship::Context::GetInstance()->GetWindow()->GetGui()->LoadGuiTexture(entry.second.name, entry.second.texturePath, gregGreen);
|
||||||
LUS::Context::GetInstance()->GetWindow()->GetGui()->LoadGuiTexture(entry.second.nameFaded, entry.second.texturePath, gregFadedGreen);
|
Ship::Context::GetInstance()->GetWindow()->GetGui()->LoadGuiTexture(entry.second.nameFaded, entry.second.texturePath, gregFadedGreen);
|
||||||
}
|
}
|
||||||
for (const auto& entry : triforcePieceMapping) {
|
for (const auto& entry : triforcePieceMapping) {
|
||||||
LUS::Context::GetInstance()->GetWindow()->GetGui()->LoadGuiTexture(entry.second.name, entry.second.texturePath, ImVec4(1, 1, 1, 1));
|
Ship::Context::GetInstance()->GetWindow()->GetGui()->LoadGuiTexture(entry.second.name, entry.second.texturePath, ImVec4(1, 1, 1, 1));
|
||||||
LUS::Context::GetInstance()->GetWindow()->GetGui()->LoadGuiTexture(entry.second.nameFaded, entry.second.texturePath, ImVec4(1, 1, 1, 0.3f));
|
Ship::Context::GetInstance()->GetWindow()->GetGui()->LoadGuiTexture(entry.second.nameFaded, entry.second.texturePath, ImVec4(1, 1, 1, 0.3f));
|
||||||
}
|
}
|
||||||
for (const auto& entry : questMapping) {
|
for (const auto& entry : questMapping) {
|
||||||
LUS::Context::GetInstance()->GetWindow()->GetGui()->LoadGuiTexture(entry.second.name, entry.second.texturePath, ImVec4(1, 1, 1, 1));
|
Ship::Context::GetInstance()->GetWindow()->GetGui()->LoadGuiTexture(entry.second.name, entry.second.texturePath, ImVec4(1, 1, 1, 1));
|
||||||
LUS::Context::GetInstance()->GetWindow()->GetGui()->LoadGuiTexture(entry.second.nameFaded, entry.second.texturePath, ImVec4(1, 1, 1, 0.3f));
|
Ship::Context::GetInstance()->GetWindow()->GetGui()->LoadGuiTexture(entry.second.nameFaded, entry.second.texturePath, ImVec4(1, 1, 1, 0.3f));
|
||||||
}
|
}
|
||||||
for (const auto& entry : songMapping) {
|
for (const auto& entry : songMapping) {
|
||||||
LUS::Context::GetInstance()->GetWindow()->GetGui()->LoadGuiTexture(entry.name, gSongNoteTex, entry.color);
|
Ship::Context::GetInstance()->GetWindow()->GetGui()->LoadGuiTexture(entry.name, gSongNoteTex, entry.color);
|
||||||
ImVec4 fadedCol = entry.color;
|
ImVec4 fadedCol = entry.color;
|
||||||
fadedCol.w = 0.3f;
|
fadedCol.w = 0.3f;
|
||||||
LUS::Context::GetInstance()->GetWindow()->GetGui()->LoadGuiTexture(entry.nameFaded, gSongNoteTex, fadedCol);
|
Ship::Context::GetInstance()->GetWindow()->GetGui()->LoadGuiTexture(entry.nameFaded, gSongNoteTex, fadedCol);
|
||||||
}
|
}
|
||||||
for (const auto& entry : vanillaSongMapping) {
|
for (const auto& entry : vanillaSongMapping) {
|
||||||
LUS::Context::GetInstance()->GetWindow()->GetGui()->LoadGuiTexture(entry.name, gSongNoteTex, entry.color);
|
Ship::Context::GetInstance()->GetWindow()->GetGui()->LoadGuiTexture(entry.name, gSongNoteTex, entry.color);
|
||||||
ImVec4 fadedCol = entry.color;
|
ImVec4 fadedCol = entry.color;
|
||||||
fadedCol.w = 0.3f;
|
fadedCol.w = 0.3f;
|
||||||
LUS::Context::GetInstance()->GetWindow()->GetGui()->LoadGuiTexture(entry.nameFaded, gSongNoteTex, fadedCol);
|
Ship::Context::GetInstance()->GetWindow()->GetGui()->LoadGuiTexture(entry.nameFaded, gSongNoteTex, fadedCol);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|